srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland/src/winit
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2025-09-10 11:24:00 +0200
committersrdusr <[email protected]>2025-09-10 11:24:00 +0200
commit5ee627928d0cb017e59d796c71793c35d5b65d33 (patch)
tree3285a7df82a04b178fb41fae220d60fe1dd38bd7 /crates/wayland/src/winit
parent4a55182ce17fd4474f8be1e8819a41b7ccd11045 (diff)
downloadsrdwm-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/winit')
-rw-r--r--crates/wayland/src/winit/connect.rs14
-rw-r--r--crates/wayland/src/winit/nested_platform.rs10
2 files changed, 24 insertions, 0 deletions
diff --git a/crates/wayland/src/winit/connect.rs b/crates/wayland/src/winit/connect.rs
index 140dc58..39eda5a 100644
--- a/crates/wayland/src/winit/connect.rs
+++ b/crates/wayland/src/winit/connect.rs
@@ -111,6 +111,7 @@ impl WaylandPlatform {
data_control_state,
session_lock_state: SessionLockManagerState::new::<CompState, _>(&dh, |_| true),
_screencopy_state: screencopy::ScreencopyState::new::<CompState>(&dh),
+ _virtual_pointer_state: crate::virtual_pointer::VirtualPointerState::new::<CompState>(&dh),
screencopy_pending: Vec::new(),
_appmenu_state: crate::appmenu::AppmenuManagerState::new::<CompState>(&dh),
_virtual_keyboard_state: smithay::wayland::virtual_keyboard::VirtualKeyboardManagerState::new::<CompState, _>(&dh, |_client| true),
@@ -154,6 +155,8 @@ impl WaylandPlatform {
desktop_icons: None,
desktop_icon_buffers: HashMap::new(),
desktop_icon_drag: None,
+ desktop_marquee: None,
+ marquee_buffers: Default::default(),
desktop_menu: None,
desktop_menu_buffer: None,
last_icon_click: None,
@@ -161,6 +164,7 @@ impl WaylandPlatform {
wm: wm.clone(),
surface_to_id: HashMap::new(),
id_to_window: HashMap::new(),
+ virtual_pointers: Vec::new(),
dead_layer_surfaces: HashSet::new(),
hidden_layer_surfaces: HashMap::new(),
layer_surfaces_shown_once: HashSet::new(),
@@ -192,6 +196,16 @@ impl WaylandPlatform {
appmenu_registrar: None,
};
+ // Same per-app remembered position/size seeding as the udev
+ // backend's own `connect()` - see that call site's own comment
+ // and `window_memory.rs` for what/why. The nested backend has no
+ // daily-driver use case of its own, but a window mapped while
+ // testing under it should still honor whatever a real session
+ // already remembered, not silently ignore the same store.
+ for (app_id, g) in crate::window_memory::load() {
+ wm.borrow_mut().set_remembered_geometry(app_id, (g.x, g.y, g.width, g.height));
+ }
+
let listener = ListeningSocket::bind_auto("wayland", 0..32).map_err(err)?;
if let Some(name) = listener.socket_name() {
std::env::set_var("WAYLAND_DISPLAY", name);
diff --git a/crates/wayland/src/winit/nested_platform.rs b/crates/wayland/src/winit/nested_platform.rs
index 316b1b5..40d03ff 100644
--- a/crates/wayland/src/winit/nested_platform.rs
+++ b/crates/wayland/src/winit/nested_platform.rs
@@ -69,6 +69,16 @@ impl Platform for WaylandPlatform {
self.state.begin_native_lock();
}
self.state.poll_native_lock_auth();
+ // Same pin-input draining as `udev/platform.rs`'s matching block --
+ // see its own comment and `virtual_pointer.rs`'s module doc
+ // comment for the full Phase 2 design. Pinned virtual-pointer
+ // delivery never touches `udev`/`bounds()` at all (unlike this
+ // backend's own unpinned motion, which is a documented no-op
+ // here), so this is exercised here too - genuinely the way to
+ // validate it in a nested instance rather than the live session.
+ for (pid, window) in self.wm.borrow_mut().drain_pin_input_requests() {
+ self.state.set_virtual_pointer_pin(pid, window);
+ }
let wait = TARGET_FRAME_TIME.saturating_sub(self.last_frame.elapsed());
let _ = self.idle_event_loop.dispatch(Some(wait), &mut self.state);
self.last_frame = Instant::now();