Skip to content

Support multiple monitors #939

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions openadapt/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -722,14 +722,15 @@ def read_screen_events(
logger.info("Starting")
started = False
while not terminate_processing.is_set():
screenshot = utils.take_screenshot()
if screenshot is None:
logger.warning("Screenshot was None")
screenshots = utils.take_screenshots()
if not screenshots:
logger.warning("Screenshots were None")
continue
if not started:
started_event.set()
started = True
event_q.put(Event(utils.get_timestamp(), "screen", screenshot))
for screenshot in screenshots:
event_q.put(Event(utils.get_timestamp(), "screen", screenshot))
logger.info("Done")


Expand Down
17 changes: 16 additions & 1 deletion openadapt/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,14 +467,28 @@ def take_screenshot() -> Image.Image:
Returns:
PIL.Image: The screenshot image.
"""
# monitor 0 is all in one
sct = get_process_local_sct()
monitor = sct.monitors[0]
sct_img = sct.grab(monitor)
image = Image.frombytes("RGB", sct_img.size, sct_img.bgra, "raw", "BGRX")
return image


def take_screenshots() -> list[Image.Image]:
"""Take screenshots of all monitors.

Returns:
list[PIL.Image]: List of screenshot images from all monitors.
"""
sct = get_process_local_sct()
screenshots = []
for monitor in sct.monitors[1:]:
sct_img = sct.grab(monitor)
image = Image.frombytes("RGB", sct_img.size, sct_img.bgra, "raw", "BGRX")
screenshots.append(image)
return screenshots


def get_strategy_class_by_name() -> dict:
"""Get a dictionary of strategy classes by their names.

Expand Down Expand Up @@ -629,6 +643,7 @@ def parse_code_snippet(snippet: str) -> dict:
```json
{ "foo": true }
```

Returns:

{ "foo": True }
Expand Down
23 changes: 23 additions & 0 deletions openadapt/visualize.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
row2dict,
rows2dicts,
truncate_html,
take_screenshots,
)

SCRUB = config.SCRUB_ENABLED
Expand Down Expand Up @@ -437,6 +438,28 @@ def main(

progress.close()

# Display screenshots from all monitors
screenshots = take_screenshots()
for idx, screenshot in enumerate(screenshots):
screenshot_utf8 = image2utf8(screenshot)
width, height = screenshot.size
rows.append(
row(
Div(
text=f"""
<div class="screenshot">
<img
src="{screenshot_utf8}"
style="
aspect-ratio: {width}/{height};
"
>
</div>
""",
),
)
)

title = f"recording-{recording.id}"

fname_out = RECORDING_DIR_PATH / f"recording-{recording.id}.html"
Expand Down
9 changes: 9 additions & 0 deletions tests/openadapt/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,12 @@ def test_posthog_capture() -> None:
},
distinct_id=config.UNIQUE_USER_ID,
)


def test_take_screenshots() -> None:
"""Tests utils.take_screenshots."""
screenshots = utils.take_screenshots()

assert isinstance(screenshots, list), f"Expected list, got {type(screenshots).__name__}"
for screenshot in screenshots:
assert isinstance(screenshot, utils.Image.Image), f"Expected PIL.Image, got {type(screenshot).__name__}"