<feed xmlns='http://www.w3.org/2005/Atom'>
<title>srdwm/crates/wayland/src/virtual_pointer.rs, branch main</title>
<subtitle>Cross-platform window manager written in Rust.
</subtitle>
<id>https://srdusr.com/git/srdwm/atom?h=main</id>
<link rel='self' href='https://srdusr.com/git/srdwm/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://srdusr.com/git/srdwm/'/>
<updated>2026-08-30T18:41:00+00:00</updated>
<entry>
<title>Indent doc list continuations</title>
<updated>2026-08-30T18:41:00+00:00</updated>
<author>
<name>srdusr</name>
<email>99972264+srdusr@users.noreply.github.com</email>
</author>
<published>2026-08-30T18:41:00+00:00</published>
<link rel='alternate' type='text/html' href='https://srdusr.com/git/srdwm/commit/?id=f2f9ed1b3f9c49b323ce591eb72a406058d324a4'/>
<id>urn:sha1:f2f9ed1b3f9c49b323ce591eb72a406058d324a4</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Confirm Nemo's popup works; fix the two bugs that hid it, and shadow bleed across a monitor seam</title>
<updated>2026-04-19T22:48:00+00:00</updated>
<author>
<name>srdusr</name>
<email>99972264+srdusr@users.noreply.github.com</email>
</author>
<published>2026-04-19T22:48:00+00:00</published>
<link rel='alternate' type='text/html' href='https://srdusr.com/git/srdwm/commit/?id=436d42da6ef61a5ea20d5102c4baed7bf0993606'/>
<id>urn:sha1:436d42da6ef61a5ea20d5102c4baed7bf0993606</id>
<content type='text'>
Nemo's right-click context menu was the last open punch-list item, parked
twice as untestable. It works: verified end to end in a throwaway nested
compositor, menu and submenu both, at the correct position and stacking.
The popup path itself needed no fix, so the POPUP-GEOM-DIAG/POPUP-GRAB-DIAG
diagnostics are removed.

Two real bugs turned up in the way of testing it.

zwlr_virtual_pointer was a silent no-op on the winit backend. Every
Motion/MotionAbsolute handler read UdevState::bounds() behind an early
return when state.udev was None, and that field is Some only for the DRM
backend. The protocol advertised its global, accepted create_virtual_pointer
and accepted every request, then discarded all motion with no error and no
log. That is the backend a nested instance runs on, so the only safe way to
drive a throwaway compositor - a Wayland client of that compositor, which
cannot reach any other session, unlike ydotool's /dev/uinput writes - did
not work at all. Bounds now come from WindowManager::monitors() when udev is
absent; both backends fill that list from Platform::monitors().

The winit backend's screencopy pass rendered no popups and no shadows. It
re-renders the scene offscreen, and that second scene was missing tiers, so
grim on a nested instance reported the opposite of the truth: a menu drawing
perfectly on screen photographed as absent. The DRM backend never had this,
since it serves screencopy from the on-screen frame it just drew. Border
strips are still missing from that pass, called out in the code rather than
left silent.

Also fixed, from the "windows show a bit in the other monitor" report:
shadow_rect expanded by SHADOW_SIZE on every side with no monitor-boundary
awareness, so a window flush against a seam put its 24px shadow strip on the
neighbouring screen. shadow_rect_clipped clips to the bounding box of the
monitors the window's geometry actually touches - not just its assigned
one, since a window straddling a seam really does occupy both and clipping
there would cut its shadow off mid-body. The bitmap's own extent stays
unclipped, because the src rectangle indexes into it; only the fragment list
is clipped. Six tests on the incident's own numbers. Not confirmed on
screen: the nested backend cannot produce a second monitor.

New tool: tools/virtual-pointer-click, a scriptable virtual-pointer driver
that acknowledges each command after its round-trip, so a test script can
put a screenshot between a move and the click that follows it.

489 tests pass, clippy clean.
</content>
</entry>
<entry>
<title>Make tiling's master/stack ratio live, add settings readback everywhere</title>
<updated>2025-11-07T12:04:00+00:00</updated>
<author>
<name>srdusr</name>
<email>99972264+srdusr@users.noreply.github.com</email>
</author>
<published>2025-11-07T12:04:00+00:00</published>
<link rel='alternate' type='text/html' href='https://srdusr.com/git/srdwm/commit/?id=ea78f94027ecd2c690904a6d7729e9e3cc190a20'/>
<id>urn:sha1:ea78f94027ecd2c690904a6d7729e9e3cc190a20</id>
<content type='text'>
Investigated the "tiling needs a lot of work" report directly. The
MasterStackLayout algorithm itself was already correct; the real gap was
that dragging or resizing a tiled window did nothing durable (raw
geometry that the next arrange_workspace silently discarded), and
master_ratio/master_count had no live path at all (config-file only).

A resize-drag on the shared master/stack boundary now live-adjusts
TilingConfig::master_ratio and re-arranges the group immediately; srd set
master_ratio/master_count do the same for a keybind or script. Found and
fixed a real bug while building this: start_resize's own focus_window
call re-stacks its target in self.order before the ratio-drag decision
used to be made, silently misclassifying real master-column grabs.
Fixed by deciding ratio-drag status (and freezing the membership
snapshot it depends on) before that raise happens, applying
MasterStackLayout directly against the frozen snapshot rather than
re-deriving membership from the by-then-reordered live order. Live-
verified in a nested compositor, not just unit-tested.

Also closes the readback gaps flagged directly by the AGS peer session:
border_width/border_color/corner_radius/decoration_mode/gap_inner/
gap_outer/master_ratio/master_count were all live-settable via srd set
with no way to read the current value back, and pin_input had no
readback at all. SettingsResponse now reports all of them; a new
pinned_inputs query (srd pinned inputs) lists every currently pinned
pid/window.
</content>
</entry>
<entry>
<title>Wayland backend: desktop icons v2, menu rebuild, layer-shell/scale fixes,</title>
<updated>2025-09-10T09:24:00+00:00</updated>
<author>
<name>srdusr</name>
<email>99972264+srdusr@users.noreply.github.com</email>
</author>
<published>2025-09-10T09:24:00+00:00</published>
<link rel='alternate' type='text/html' href='https://srdusr.com/git/srdwm/commit/?id=5ee627928d0cb017e59d796c71793c35d5b65d33'/>
<id>urn:sha1:5ee627928d0cb017e59d796c71793c35d5b65d33</id>
<content type='text'>
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.
</content>
</entry>
</feed>
