Fix KDE portal Freeze and Zoom capture on mixed-scale displays - #400
Merged
Merged
Conversation
SCTK can advertise a new output before the geometry refresh callback runs. Freeze now checks the live count before accepting a worker result or interpreting its raster error, matching Zoom. The regression failed before this repair and now retains the original acquisition for one retry.
Do not request an immediate dispatch wake while every swapchain slot is owned by the compositor. A buffer release already wakes Wayland dispatch. When a slot is available, honor the no-vsync frame cap before the hidden frame attempt. The pacing regression failed on the unconditional zero timeout and now passes.
Use a full desktop generation for portal preflight, worker results and pending portal images. Direct capture and installed modal sources retain an active viewport generation, so another monitor cannot invalidate their pixels. Preflight retains its backend to select the correct guard; Zoom now names that backend explicitly. Regression coverage checks direct Freeze activation and installed Zoom source validity while portal admission goes stale.
Keep the original request suppressed while waiting for complete geometry and 100 ms without a desktop change, bounded to one second. Pace incomplete metadata checks at 50 ms instead of polling with a zero timeout. Share this admission and deadline policy across Freeze and Zoom. Extract runtime retry coordination from barrier.rs so the presentation barrier stays below its size review threshold; controller tests cover lost suppression, output switches, settling failure, activation-time retry and exactly one completion.
Portal workers already return a completed output crop. Remove the raw desktop setter, cropped flag and test-only activation crop branch; retain the installation guards and move raster acceptance coverage to portal_raster. Add marked-pixel checks for rotated output dimensions and unknown multi-output bounds. Split activation and direct attempt resources from state.rs; frozen state and capture barrier now remain below 500 production lines. Restore logical blank-line groups in the touched raster and retry functions.
Give Plasma/KWin an explicit support-matrix entry explaining that Freeze and Zoom require its screenshot portal. Update scoped guides for portal raster validation, separate generations, retry settling, image activation, and direct capture resources.
Return typed retry admission errors so an output switch remains StaleLayout for Zoom rather than becoming a generic failure. The coordinator regression failed on that category change and now passes. Limit the removed Zoom wrapper imports to tests so strict production builds remain warning-free.
- Replace string-matched capture terminals with CapturePreflightError. Stale layouts and layouts that never settle end as StaleLayout in both Freeze and Zoom, so region capture does not fall back silently. - Share active-output/desktop generation bookkeeping. Board PDF desktop captures use the full-desktop generation again. - Abandon unowned Freeze preflight failures and clear pending retries. - Move Zoom request, waiter and terminal ownership to zoom/state/source.rs and select the Zoom backend with ZoomCaptureBackend. - Compute the frame-cap delay once for render and capture wakes. - Cover buffer availability, packed mixed-density crops, desktop PDF contexts and typed terminal categories. - Update capture invalidation docs and module guides.
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.
Summary
Related to #398.
KDE captures the entire desktop at the highest output scale. Wayscriber expected a raster assembled from each monitor's native pixel density, causing valid screenshots to fail geometry validation.
Review follow-up
Seven focused commits address the accepted review findings:
new_outputrefreshes geometry.croppedflag; validate and install the worker's completed crop.Validation
./tools/lint-and-test.sh: passed at8b124b76, including strict workspace Clippy and all-feature/no-default-feature builds and tests../tools/test-gtk-widgets.sh: 84 parent-harness tests passed in private headless Weston, with both actual GTK execution markers.docs/CONFIG.mdedit is excluded.The KWin lab binary was built immediately before a final whitespace-only amend; its code behavior matches the final head. The full local and GTK gates used the final head.
Limitations
The request stays bound to its original
wl_output. Recreating that object remains terminal: connector name/make/model fields are not a guaranteed unique physical identity for safely redirecting a pending capture. The reporter's physical Samsung EDID behavior and specific GTK popover timeout were not reproduced. The 100 ms quiet period is bounded; a later update during the retry barrier remains terminal.A separate GTK output-cycling failure and the restricted KWin ScreenShot2 backend remain outside this change. The lab pacing cases use normal compositor buffer releases; forced withholding of all buffers is covered by the wakeup policy regression and source guard, not a runtime CPU measurement. Portal chooser dismissal is controller-tested; lab acceptance uses a private consent store. No host desktop was used.