fix(screenshot): capture display containing Thuki window on multi-monitor setups#191
Merged
Merged
Conversation
…itor setups Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
/screenpreviously always captured the primary (menu-bar) display. On a multi-monitor setup, users invoking/screenwhile Thuki is shown on a secondary display would receive a screenshot of the wrong monitor. This PR makes/screencapture the display Thuki's own window is currently shown on.How it works
WebviewWindowand asks AppKit ([NSScreen deviceDescription][NSScreenNumber]) for theCGDirectDisplayIDof the screen the window lives on. This is the canonical multi-monitor query and sidesteps the coordinate-conversion mismatches that occur on mixed-DPI setups (e.g. a 2x retina primary + 1x secondary).CGDisplayBoundsand reduced to a center anchor point.capture_full_screen_rawaccepts anOption<(f64, f64)>anchor. The anchor is hit-tested withCGGetDisplaysWithPoint; the matching display's bounds are passed toCGWindowListCreateImage.The CoreGraphics display helpers that previously lived inline inside
lib.rsare extracted intosrc-tauri/src/cg_displays.rs, with one new functionbounds_for_display(display_id)for ID-based lookup. The activator continues to use the existing point-based helpers without change.Highlights
src-tauri/src/cg_displays.rsconsolidatesCGGetDisplaysWithPoint,CGDisplayBounds,CGMainDisplayIDFFI behind three small wrappers.nswindow_display_idperforms raw Objective-C messaging (screen→deviceDescription→NSScreenNumber) without pulling in extraobjc2-app-kitfeatures.display_bounds_centeris a pure helper, unit-tested for primary, offset, negative-origin, and zero-size cases.NSWindowpointer is fetched off-thread but only dereferenced insiderun_on_main_thread.capture_full_screen_pixelstakesOption<(f64, f64)>;Nonereproduces prior single-display behavior.Testing
bun run test:all:coverage— frontend + backend tests pass; backend cargo llvm-cov gate holds at 100% line and function coverage. CoreGraphics and Objective-C FFI wrappers are marked#[cfg_attr(coverage_nightly, coverage(off))]because they require a live window server and a realNSWindowto exercise; their consumers exercise the surrounding logic.bun run validate-build— lint, format, typecheck, and release build complete with zero warnings/errors./screenon a multi-monitor setup with Thuki shown on the secondary display; resulting screenshot is the secondary display, not the primary. Confirmed fallback to primary when Thuki is hidden.Note
The Objective-C messaging in
nswindow_display_idrelies on the autorelease pool maintained by the main-thread runloop. This is the standard contract for AppKit calls dispatched viarun_on_main_threadand is consistent with the existing screenshot pipeline's use ofCGWindowListCreateImage.