fix(wm): eliminate visual glitches across resize, drag, hover, and presentation#13
Closed
devin-ai-integration[bot] wants to merge 2 commits into
Closed
fix(wm): eliminate visual glitches across resize, drag, hover, and presentation#13devin-ai-integration[bot] wants to merge 2 commits into
devin-ai-integration[bot] wants to merge 2 commits into
Conversation
…d clipped chrome paint * wm_logic.cpp: transparent windows now report no opaque coverage / no occlusion bounds, so the compositor keeps painting the dock, menubar and stacked windows underneath them instead of skipping repaint and leaving stale or black pixels behind transparent surfaces. * wm_main.cpp: re-establish an sfence before submitting a present, so backbuffer stores are globally visible before the display engine latches the present buffer (prevents tearing/sparkle on weakly ordered cores or write-combining stores). * wm_render.cpp: restore gui_fill_rounded_rect_clipped / gui_draw_rounded_rect_clipped helpers and use them for the window decoration shadow, frame, body fill and inner stroke so we never overdraw beyond the dirty region during partial repaints (which previously corrupted neighbouring already-composited windows). Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
When the pointer is over a window's close/minimize/maximize button the cursor was switching to GUI_CURSOR_MOVE because update_cursor_kind only inspected hover_frame_index without checking hover_button. The move cursor visually implies a drag affordance, which conflicts with the button click affordance and momentarily flickers as the pointer crosses into the button. Keep the arrow cursor for the button case so the control affordance is unambiguous. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
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.
Description
Fixes four classes of visual glitches in the window manager that produced tearing, stale pixels through transparent surfaces, overdraw beyond dirty regions, and the wrong cursor over chrome buttons.
wm_logic.cpp— transparent-window opacity bookkeepingget_window_opaque_cover_rects(w)no longer reports a transparent window's client rect as opaque coverage. Treating transparent windows as opaque caused the compositor to skip painting the dock, menubar, and stacked windows behind them, producing black or stale pixels through the transparent surface.window_opaque_bounds(w)returns{0,0,0,0}for transparent windows instead of the client bounds, so callers that gate "fully covered" decisions don't falsely treat a transparent surface as an occluder.window_occlusion_bounds(w)now also explicitly returns an empty rect for transparent windows, matching the opaque-bounds contract.wm_render.cpp— clipped chrome paintgui_fill_rounded_rect_clipped/gui_draw_rounded_rect_clippedhelpers that intersect the requested rect with the dirty clip before drawing, falling back to an axis-aligned clipped fill when the rounded shape would extend past the clip. This prevents the decoration paint from overdrawing pixels owned by neighbouring windows already composited into this frame.draw_window_decoration_framenow uses the clipped helpers for every shadow / outline / frame body / inner stroke fill.wm_main.cpp— present fencesfencebeforepresent_frameso all backbuffer stores are globally visible before the display engine latches the present buffer. Without this fence, weakly-ordered cores or write-combining stores can let the scanout latch a partially composited frame, manifesting as tearing or sparkle.wm_logic.cpp— cursor kind on chrome buttonsupdate_cursor_kindpreviously set the move cursor wheneverhover_frame_index >= 2, even when the pointer was specifically over a close/minimize/maximize button (hover_button >= 0). The cursor now stays as the arrow when hovering a chrome button, so the click affordance isn't visually contradicted by a drag affordance.Type of Change
Area
Checklist
meson compile -C build/release boot-disk isomeson compile -C build/debug boot-disk iso(builtwm.elftarget)meson test -C build/debug --suite smoke --print-errorlogs/datapersistence when changing storage, FAT32, USB storage, rootfs staging, or image generationValidation
End-to-end QEMU exercise of the resize / drag / hover / button paths was not run as part of this change; reviewer or follow-up should confirm visually.
Notes for review
Things most worth a careful eye:
window_opaque_boundsandwindow_occlusion_boundsnow return{0,0,0,0}. All current call sites either early-out onw.transparent(e.g.refresh_window_visible_regions,get_window_opaque_cover_rects) or are guarded byrect_intersection/rect_contains, both of which handle empty rects safely. Worth a second pass to confirm no caller relies on the old "opaque == client bounds" behaviour.asm volatile("sfence" ::: "memory")is x86-only. The supported boot target is x86_64 so this is fine, but flagging it explicitly.gui_fill_rounded_rect_clippedfallback. When the rounded rect is not fully contained in the dirty clip, it falls back to an axis-aligned clipped fill (square corners). In current callers the cache surface used byensure_window_decoration_cacheis sized to fully contain the rect, so the rounded path is always taken; the fallback is defensive. Please confirm no caller passes a smaller clip in the future.wm_compose.cpppaints opaque windows first then transparent windows, which can cause a transparent window to draw over an opaque window above it in z-order. The user's listed files did not includewm_compose.cpp, so this PR does not touch that path. Worth a follow-up if confirmed.Link to Devin session: https://app.devin.ai/sessions/a59e645119c741de9eedffd4f027c160
Requested by: @unionyxx