fix(ssd): keep frames on-screen below panels; refresh cursor leaving borders#68
Merged
Conversation
…borders Two follow-up issues with server-side decorations and a panel (Waybar in the bottom layer with a 30px top exclusive zone). 1) SSD windows were placed with their frame partly off-screen / under the panel. Placement positions the *client* inside the usable area, but at map time the frame does not exist yet (insets are zero), so a client at the area's top-left left its border off the left edge (x<0) and its titlebar up inside the panel's reserved zone. constrain_to_usable only reserves panel-inset edges, not the output bounds, so the left border stayed clipped. Build the frame before logging/placement and add clamp_frame_into_area(): once the insets are known, pull the whole frame (client + insets) inside the placement area so every border is on-screen and the titlebar sits below the panel. The "mapped" geometry is logged after the clamp so restore geometry matches (keeps integration_window_state green). 2) The resize cursor stuck when moving from a frame border back into the window. Hovering a border/corner sets a resize xcursor and returns without releasing the client's pointer focus, so moving back inside the same surface sent no pointer-enter and the client never reasserted its cursor. Clear the client's pointer focus while the cursor is over our decoration; re-entering the client now re-sends enter and the client restores its own cursor. Verified: full suite 27 green (g++/ASan), clang + release clean; headless with real Waybar shows foot mapping at +1+54 (left border on-screen, frame top flush at the 30px panel edge) instead of poking into / under the panel. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.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.
Follow-up to the SSD work, fixing two issues you hit with Waybar (which runs in the bottom layer with a 30px top exclusive zone).
1. SSD frame placed off-screen / under the panel
Placement positions the client inside the usable area, but at map time the frame doesn't exist yet (insets are zero). So a client at the area's top-left left its border off the left edge (x<0) and its titlebar up inside the panel's reserved zone — exactly the "client at x=0, left border not shown, y a few pixels from the top" you described.
constrain_to_usableonly reserves panel-inset edges, not the output bounds, so the left border stayed clipped.Fix: build the frame before placement/logging and add
clamp_frame_into_area()— once the insets are known, pull the whole frame (client + insets) inside the placement area so every border is on-screen and the titlebar sits flush below the panel. Themappedgeometry is logged after the clamp so restore geometry matches.With real Waybar, foot now maps at +1+54: client x=1 → left border at x=0 on-screen; frame top = 54−24 = 30, exactly the panel's bottom edge. No overlap, nothing clipped.
2. Resize cursor stuck when moving back into the window
Hovering a border/corner set a resize xcursor and returned without releasing the client's pointer focus, so moving back inside the same surface sent no pointer-enter and the client never reasserted its cursor — it kept the resize shape. Fix: clear the client's pointer focus while the cursor is over our decoration; re-entering the client re-sends enter and it restores its own cursor.
Testing
integration_window_state(restore geometry now matches the clamped mapped position) andintegration_ssd; clang + release clean.Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com