diff options
| author | srdusr <[email protected]> | 2025-09-10 11:24:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2025-09-10 11:24:00 +0200 |
| commit | 5ee627928d0cb017e59d796c71793c35d5b65d33 (patch) | |
| tree | 3285a7df82a04b178fb41fae220d60fe1dd38bd7 /crates/wayland/src/state/mod.rs | |
| parent | 4a55182ce17fd4474f8be1e8819a41b7ccd11045 (diff) | |
| download | srdwm-5ee627928d0cb017e59d796c71793c35d5b65d33.tar.gz srdwm-5ee627928d0cb017e59d796c71793c35d5b65d33.zip | |
Wayland backend: desktop icons v2, menu rebuild, layer-shell/scale fixes,
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.
Diffstat (limited to 'crates/wayland/src/state/mod.rs')
| -rw-r--r-- | crates/wayland/src/state/mod.rs | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/crates/wayland/src/state/mod.rs b/crates/wayland/src/state/mod.rs index 0fb303e..3519297 100644 --- a/crates/wayland/src/state/mod.rs +++ b/crates/wayland/src/state/mod.rs @@ -39,6 +39,7 @@ use smithay::wayland::shell::xdg::decoration::XdgDecorationState; use smithay::wayland::dmabuf::DmabufState; use smithay::wayland::shm::ShmState; use smithay::wayland::xdg_activation::XdgActivationState; +use wayland_protocols_wlr::virtual_pointer::v1::server::zwlr_virtual_pointer_v1::ZwlrVirtualPointerV1; use srdwm_core::{Event as CoreEvent, SnapZoneKind, Window as CoreWindow, WindowId, WindowManager, TITLEBAR_HEIGHT}; @@ -217,6 +218,7 @@ pub(crate) struct CompState { pub(crate) _fractional_scale_state: smithay::wayland::fractional_scale::FractionalScaleManagerState, pub(crate) _cursor_shape_state: smithay::wayland::cursor_shape::CursorShapeManagerState, pub(crate) _screencopy_state: screencopy::ScreencopyState, + pub(crate) _virtual_pointer_state: crate::virtual_pointer::VirtualPointerState, /// Captures requested via `wlr-screencopy` but not yet serviced; drained /// inside the render pass (see `screencopy::service_pending`). pub(crate) screencopy_pending: Vec<screencopy::PendingCapture>, @@ -362,6 +364,20 @@ pub(crate) struct CompState { /// drag is active. #[allow(clippy::type_complexity)] pub(crate) desktop_icon_drag: Option<(String, (i32, i32), (i32, i32))>, + /// An active rubber-band/marquee selection drag on bare desktop -- + /// `(start, current)`, both global-space pointer positions. The one + /// "click and drag" desktop interaction this compositor never had at + /// all (only single-icon click-select existed) - reported live next + /// to "missing click and drag stuff like from windows". `None` + /// whenever no marquee is active. See `start_desktop_marquee`/ + /// `update_desktop_marquee`/`end_desktop_marquee`. + pub(crate) desktop_marquee: Option<((i32, i32), (i32, i32))>, + /// Four thin solid-color strips forming the marquee's own rectangle + /// outline (top/bottom/left/right) - same "keep a persistent `Solid + /// ColorBuffer` per strip, update it in place every frame" pattern + /// `border_side_buffers` already uses for window borders, reused here + /// rather than allocating a fresh buffer on every motion tick. + pub(crate) marquee_buffers: [SolidColorBuffer; 4], /// The right-click desktop-icon/bare-desktop menu, if one is currently /// open - see `desktop_menu.rs`. Same lifecycle/mutual-exclusion /// story as `context_menu`/`snap_flyout` above. @@ -383,6 +399,17 @@ pub(crate) struct CompState { pub(crate) wm: Rc<RefCell<WindowManager>>, pub(crate) surface_to_id: HashMap<WlSurface, WindowId>, pub(crate) id_to_window: HashMap<WindowId, DWindow>, + /// Every live `zwlr_virtual_pointer_v1` object, so `set_virtual_pointer_ + /// pin` (`virtual_pointer.rs`) can find every pointer a given client + /// (identified by pid, via `Client::get_credentials`) owns without a + /// second, redundant per-client map - see that module's own doc + /// comment for why pid, not an opaque per-object id nothing outside + /// this compositor could otherwise learn, is the pinning handle. Pruned + /// lazily (a destroyed resource's own methods become no-ops, and dead + /// entries are filtered out the next time this is walked) rather than + /// on every single destroy - this list is only ever touched by an + /// infrequent pin/unpin request, never a hot path. + pub(crate) virtual_pointers: Vec<ZwlrVirtualPointerV1>, /// Surfaces whose `zwlr_layer_surface_v1` role has been destroyed -- /// consulted by the pre-commit hook `CompositorHandler::new_surface` /// registers (see its doc comment) to work around a real smithay bug |