srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland/src/state/lifecycle.rs
AgeCommit message (Collapse)AuthorFilesLines
2025-09-10Wayland backend: desktop icons v2, menu rebuild, layer-shell/scale fixes,srdusr1-0/+5
XWayland stability, GPU rendering, and multi-cursor Phase 2 The bulk of a multi-session shift's real work landed in crates/wayland. Full root-cause/verification narrative for every item below lives in docs/TODO.md (each has its own dated entry); this is the summary: Desktop shell: - Real desktop icons v2 (state/desktop_icons.rs, desktop_icons.rs): fixed origin-baked-before-the-bar-connects, fixed-icon sort order, and a proper Rename/Delete-to-Trash menu (window_memory.rs backs the rename-persistence side). Rubber-band marquee multi-select. - icon_theme.rs: real freedesktop icon-theme lookup (inherits chain, hicolor fallback) rendering actual theme SVGs via resvg/tiny-skia, replacing the hand-drawn placeholder glyphs. - Context/desktop menus (decoration.rs, desktop_menu.rs, state/menu.rs) rebuilt to match the project's own AGS panel styling: rounded floating panel, tinted-fill row highlight, real separators, a much fuller titlebar window-menu action set. Layer-shell / multi-monitor: - Layer-shell hit-testing and render positioning (input/pointer.rs, udev/render.rs's element placement) now correctly convert LayerMap's logical geometry into physical pixels on a fractionally-scaled output - root cause of a bottom-anchored dock being unclickable and unpainted while a top-anchored bar on the same output worked. udev/outputs.rs's relayout_outputs gained the same physical/logical split for cross-output positioning, now backed by a real unit test (next_logical_x) built from the original measured incident numbers. - state/geometry.rs: a window's border/decoration no longer briefly clips when moved between differently-scaled monitors mid-drag. XWayland / stability: - xwayland.rs, udev/session.rs, udev/platform.rs: fixed a 100%- reproducible cold-start XKEYBOARD crash-loop (XWayland's own stdin inherited a real, already-owned VT; env passthrough and idle-callback spawn timing were both real, independent gaps) that had silently taken down all X11-app support and the global-menu registrar every session. - state/toplevel.rs, state/lifecycle.rs: XWayland dialog detection via WM_TRANSIENT_FOR, not just a native xdg_toplevel parent. Rendering: - udev/render.rs, decoration.rs: real GPU (GBM+EGL+DrmCompositor) window-content and cursor rendering on the udev backend, falling back to the untouched Pixman path automatically on any init failure. - decoration/tests.rs, state/mod.rs: rounded-corner/border fixes for interactive resize lag and cross-monitor moves. Multi-cursor Phase 2 (virtual_pointer.rs, new; state/mod.rs, udev/ platform.rs, winit/nested_platform.rs): pins a zwlr_virtual_pointer_ unstable_v1 object to a specific window, bypassing the shared seat/ focus/pointer_pos path entirely via hand-rolled wl_pointer.enter/motion/ button/frame/leave against every WlPointer the target client has bound (PointerHandle::client_pointers). Lets an agent operate one window while a human uses another, genuinely simultaneously, with zero client cooperation and no second wl_seat (confirmed a dead end: real clients only ever bind the first seat advertised). Full workspace build/test/clippy clean.
2025-05-30Detect XWayland dialogs via WM_TRANSIENT_FOR, not just native xdg_toplevel ↵srdusr1-5/+18
parent Window::is_dialog (close-button-only titlebar, no traffic lights) was only ever set from a native xdg_toplevel's own parent() - redraw_ decoration_buffer's is_dialog computation called dw.toplevel(), which is always None for an XWayland-backed DWindow (X11Surface's own accessor is x11_surface(), a different method), so the .unwrap_or(false) fallback made every XWayland dialog - a GTK "Save As", an app's own "About" box, anything setting the ICCCM transient-for hint - always draw with the full three-button titlebar and traffic-light colours, even though the feature this was built for explicitly wanted the opposite. Documented as a known gap at the time; now closed. redraw_decoration_buffer now also checks X11Surface::is_transient_for() for an XWayland window. property_notify gained a WmWindowProperty:: TransientFor arm that re-runs redraw_decoration_buffer, for a client that sets the hint slightly after its own initial map - the same "read fresh every call" pattern the existing xdg_toplevel::parent() check already relied on, extended to catch a late X11 property the way the Wayland equivalent (set_parent, any time) already was.
2025-05-23Fix the border ring's inner cut using the wrong circle for undecorated windowssrdusr1-1/+1
carve_inner_corner_pixel (an earlier ring fix) cut the border strip's own disk using an inner circle at the *same* centre as the outer cut, radius - border_width - correct when a titlebar sits underneath (it shares that exact circle, by construction), but wrong whenever client content sits underneath instead: content's own rounded-corner mask (rounded_corners_pixman.rs's apply_corner_mask) is centred radius from *its own* buffer's edges, and that buffer starts border_width rows/columns inside the border strip's - a same-radius circle offset (border_width, border_width) diagonally from the border's own outer one, not a smaller concentric one. Reusing the titlebar-style ring left a real, if very small, gap along part of the seam and a thin sliver of double coverage along the rest - reported live, at extreme zoom against a solid-colour wallpaper (chosen specifically to make a sub-pixel gap easy to spot against, unlike the usual desktop image): "very tiny gaps... corner radius does not match." round_top_corners/round_bottom_corners's own `inner_radius: Option<u32>` parameter is now `inner: Option<InnerRing>`, an explicit (center_row, center_col, radius) rather than an implicit "same centre, smaller radius" - InnerRing's own doc comment has the full geometry for both cases. render_border_top gained a `decorated` parameter to pick the right one (titlebar-aligned when true, content-aligned - centre shifted by border_width on both axes, radius unchanged - when false); render_border_bottom always uses the content-aligned ring, since this compositor never draws a bottom titlebar. apply_corner_mask (rounded_corners_pixman.rs) made pub(crate) so the new regression test can build a real masked content buffer via the actual production function, not a reimplementation of its math. border_top_and_content_mask_have_no_gap_along_the_corner_diagonal_when_undecorated checks coverage along the diagonal ray between the two circles' centres - the direction they're actually offset along, and so the worst case for a gap opening up between them - against the real render_border_top/apply_corner_mask output, not a hand-rederived formula.
2025-02-21Remove resolved corner-rounding diagnosticssrdusr1-25/+0
The top-rounds-but-bottom-doesn't investigation these were tracking is closed: live-verified via a real screenshot (pixel-level, not eyeballed) that both corners round correctly on both a decorated window and an undecorated/CSD one relying on content masking. Removes three log::debug! blocks (corner-mask state, TOP/BOTTOM border strip position dumps, and a raw alpha-byte dump of the bottom border buffer) that were firing on every single render pass regardless of whether anything changed, adding real per-frame overhead for output no longer needed. Build + clippy + test (378 passing) all still green.
2025-02-15Checkpoint: preserve all uncommitted rust-rewrite worktree worksrdusr1-12/+130
Safety commit before reconciling this worktree with main, which has diverged with its own separate fixes today. Nothing here is reviewed or curated yet - this exists purely so none of this work can be lost to a git operation, disk issue, or worktree cleanup while that reconciliation happens.
2024-11-01Add Snap-Layouts flyout (Windows 11-style maximize-button hover menu)srdusr1-3/+36
Right-clicking (or hovering) the maximize button opens a flyout of fixed half/quarter positions (snap_flyout.rs renders it); picking one applies that zone via WindowManager::apply_snap_zone, the click-driven equivalent of dragging a window to that edge and releasing.
2024-08-23Round the bottom border strip's corners to match the topsrdusr1-0/+10
MISSING.md listed the border frame's bottom/left/right strips as staying square while the top one (and the titlebar above it) rounds -- "unrelated to client content rounding... not attempted." The left/ right strips genuinely can't participate (border_strips' geometry has them span only the height between the top and bottom strips, no corner to round), but the bottom strip is exactly the same shape as the top one and had no reason left to stay square. decoration::render_border_bottom mirrors render_border_top exactly (round_bottom_corners mirrors round_top_corners), cached the same way in a new border_bottom_decorations map, and drawn in both render loops via the same all-or-nothing occlusion check the top strip already uses - pulled out of the left/right strips' per-fragment occlusion splitting into its own dedicated bitmap path, matching top's existing trade-off (cropping a rounded bitmap's source rect per fragment is real extra work for a strip this thin) rather than inventing a new one. One real bug caught before it shipped: round_bottom_corners' corner- centre math (height - r - 1) panics on unsigned underflow whenever the radius clamp lands on the strip's own full height (a real, common case - a 2px-thick test strip hits it immediately). Fixed by computing the centre as a signed offset instead, mirroring how the existing dx/dy distance math already avoids the same class of issue.
2024-07-30Split crates/wayland/src/state.rs (1276 lines) into state/srdusr1-0/+175
Pure reorganization, no behavior change - verified by diffing the function-name and struct-name sets before/after (both identical) plus a full cargo test pass. mod.rs keeps ClientState/OutputEntry/CompState/ WindowAnim/RepeatState's definitions, the key-repeat impl, and the output-lookup impl (all small and tightly coupled to the type definitions), plus mod declarations. The one large impl CompState block (previously ~600 lines) splits by concern: - lifecycle.rs: new_managed_window, set_decorated_from_mode, redraw_decoration_buffer, remove_window. - layers.rs: ensure_layer_initial_configure. - focus.rs: set_keyboard_focus, set_window_activated. - menu.rs: open/close/run_context_menu_action, is_double_click. - geometry.rs: raise_pinned, sync_geometry. - tick.rs: tick_dirty_broadcasts, tick_animations, resync_stacking_order. - toplevel.rs: the with_toplevel_title/app_id/sync_toplevel_metadata free functions. - tests.rs: unsplit, same reasoning as every other split this pass. CompState's fields were already pub(crate) (this crate's existing convention, unlike core's/config's plain-private), so no field- visibility changes were needed - only resync_stacking_order (called from geometry.rs, defined in tick.rs) needed bumping from private to pub(crate), matching that same convention.