<feed xmlns='http://www.w3.org/2005/Atom'>
<title>srdwm/crates/core/src/event.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-04T22:55:00+00:00</updated>
<entry>
<title>Show a keybinding the way a person writes it, and let bind_repeat be described</title>
<updated>2026-08-04T22:55:00+00:00</updated>
<author>
<name>srdusr</name>
<email>99972264+srdusr@users.noreply.github.com</email>
</author>
<published>2026-08-04T22:55:00+00:00</published>
<link rel='alternate' type='text/html' href='https://srdusr.com/git/srdwm/commit/?id=9c1673fa73bb49433370a60a7b4bb16abee98a9b'/>
<id>urn:sha1:9c1673fa73bb49433370a60a7b4bb16abee98a9b</id>
<content type='text'>
Measured with dotfiles-1a, who own the launcher that displays these: `srd
keybindings` returned 84 bindings and 84 empty descriptions - 100% - so
every entry their launcher showed was a bare key combo with nothing to say
what it does. Two causes, one on each side of the boundary.

`srd.bind_repeat` never accepted a description. `srd.bind` has taken an
optional third argument all along, but its repeating sibling took only two,
and mlua drops a surplus argument silently rather than raising - so a
config that documented its repeat bindings got no error and no description.
It now takes one exactly like `bind`.

The combos themselves were reported in their internal dispatch form:
`Shift+Mod4+h`. `Mod4` is the X11 modifier's name, not a key's; nothing on
a keyboard is labelled Mod4, and the canonical Ctrl/Shift/Alt/Mod4 ordering
renders the owner's own `Super+Shift+h` binding back to them inside out.
`srd keybindings` now reports a display form - Super, and the order people
write - while everything internal keeps the canonical form it dispatches
on. The display form parses back to the same binding, so it can be pasted
into a config, and a test pins that round trip rather than trusting it.

The owner's own config now describes all 84 bindings; verified through the
real path, in a nested compositor running that config: 84 of 84 described,
zero occurrences of "Mod4".
</content>
</entry>
<entry>
<title>Accumulate core-crate additions: capture requests, focus/workspace fixes, test coverage</title>
<updated>2024-11-30T21:03:00+00:00</updated>
<author>
<name>srdusr</name>
<email>99972264+srdusr@users.noreply.github.com</email>
</author>
<published>2024-11-30T21:03:00+00:00</published>
<link rel='alternate' type='text/html' href='https://srdusr.com/git/srdwm/commit/?id=583063c3094ca0cf9f6cceba92d710b238547f6b'/>
<id>urn:sha1:583063c3094ca0cf9f6cceba92d710b238547f6b</id>
<content type='text'>
Bundles several related changes to crates/core built up over this
session rather than committed incrementally:
- WindowManager::request_capture_workspace/drain_capture_requests (new
  manager/capture.rs) - backend-agnostic queuing for an off-screen
  workspace render, see the wayland-side commit for why this exists.
- focus_window now switches workspace as a side effect when the target
  isn't on the current one, matching Hyprland's focuswindow convention
  (manager/focus.rs).
- Assorted window/rules/theme field additions and their test coverage.

Left less granular than the repo's usual one-purpose-per-commit
convention deliberately: these accumulated across a long session
without being committed as they landed, and are too entangled
line-by-line to safely split apart now without risking mis-attributing
changes to the wrong commit message.
</content>
</entry>
<entry>
<title>Fix keybindings silently never firing when a named key is lowercase</title>
<updated>2024-07-13T23:02:00+00:00</updated>
<author>
<name>srdusr</name>
<email>99972264+srdusr@users.noreply.github.com</email>
</author>
<published>2024-07-13T23:02:00+00:00</published>
<link rel='alternate' type='text/html' href='https://srdusr.com/git/srdwm/commit/?id=2994f622b2998dc6aebbd38f52a6e6612ed8e7c8'/>
<id>urn:sha1:2994f622b2998dc6aebbd38f52a6e6612ed8e7c8</id>
<content type='text'>
canonicalize_key_combo already reordered multi-modifier combos into
dispatch's canonical Ctrl/Shift/Alt/Mod4 order, but passed the key
name through verbatim. keysyms::keysym_to_name capitalizes every
named key ("Space", "Return", "Escape", "BackSpace", ...) while
leaving letters/digits alone, so srd.bind("Super+space", ...) stored
"Mod4+space" while a real Space keypress dispatches as "Mod4+Space" --
never matching. Accepted silently at config-load time, so the only
live symptom was the bind's own callback never running at all.

Root-caused live: keybindings.lua's Super+space bind had a temporary
diagnostic added (logs to /tmp/superspace.log before spawning ags) to
tell "key never fired" apart from "key fired but ags failed" - the
log file never existed, meaning the callback itself never ran.

Fix: round-trip the key name through name_to_keysym (already case-
insensitive) and back through keysym_to_name before storing, so any
case the config writes normalizes to dispatch's canonical form.
</content>
</entry>
<entry>
<title>Fix decoration drift during animated transitions; checkpoint IPC/global-menu/output-management work</title>
<updated>2024-05-30T14:10:00+00:00</updated>
<author>
<name>srdusr</name>
<email>99972264+srdusr@users.noreply.github.com</email>
</author>
<published>2024-05-30T14:10:00+00:00</published>
<link rel='alternate' type='text/html' href='https://srdusr.com/git/srdwm/commit/?id=1c175642d073689ca11b9252411ea5f8446007d0'/>
<id>urn:sha1:1c175642d073689ca11b9252411ea5f8446007d0</id>
<content type='text'>
Border/titlebar decoration was built from Window.geometry (the animation's
final target) in both wayland backends' render loops, while sync_geometry
already draws a window's actual content at window_anims' interpolated rect
during any maximize/fullscreen/open-slide tween. Border and content read two
different rectangles for the whole transition, so the border visibly
detached from the window it was outlining - reported as "borders aren't
flush." Both udev.rs and winit.rs now read the same animated rect for
titlebar placement, border-strip placement, and the occlusion test against
later windows in stacking order. Verified: cargo build --workspace, cargo
clippy (0 new warnings), cargo test -p srdwm-core (111/111).

Also checkpoints substantial protocol/IPC work from prior sessions that had
accumulated uncommitted: gtk-shell1 support (gtk_shell.rs, the vendored
gtk-shell.xml, xwayland.rs's X11-side mirror) backing the global app menu;
zwlr_foreign_toplevel_manager_v1 (foreign_toplevel.rs) broadcasting distinct
maximized/minimized/fullscreen/activated state per window; output_management
(ext-output-management + layer-shell exclusive-zone reservation tracking);
workspace.rs and context_menu.rs; a Unix-socket IPC crate (platform/src/
ipc.rs) and a `srd` control-CLI crate (crates/ctl); xkb_config.rs; and a
theme module (core/src/theme.rs). A peer session working the AGS shell
concurrently verified several of these live against a running srdwm: the
global menu rendering a real app's File/Edit menu over gtk-shell1, and
foreign-toplevel correctly reporting maximized and fullscreen as independent,
non-simultaneous states with the geometry each implies (maximize stops at a
reserved top bar and past a dock; fullscreen reaches the true monitor edge).
</content>
</entry>
<entry>
<title>Draw a cursor, handle the lid, and everything a real config needs</title>
<updated>2024-05-13T22:42:00+00:00</updated>
<author>
<name>srdusr</name>
<email>99972264+srdusr@users.noreply.github.com</email>
</author>
<published>2024-05-13T22:42:00+00:00</published>
<link rel='alternate' type='text/html' href='https://srdusr.com/git/srdwm/commit/?id=dd31bf5ac2a692617d478478d36c733586b93cf8'/>
<id>urn:sha1:dd31bf5ac2a692617d478478d36c733586b93cf8</id>
<content type='text'>
Groundwork for actually daily-driving this: porting the user's Hyprland
config exposed what srdwm couldn't yet express, and testing on a bare TTY
exposed something worse.

A visible mouse cursor. Nothing drew a pointer at all - on a bare TTY the
mouse was simply invisible. It hid because the nested backend runs inside
another compositor, which draws a cursor over srdwm's window; only the DRM
backend, i.e. the actual session path, was affected. A built-in arrow is now
composited above everything on the output the pointer is on. It's a
reviewable ASCII bitmap rather than an XCursor theme: a cursor that is always
present beats a prettier one that sometimes isn't, the same reasoning as
decoration.rs's font fallback. Client-set cursor surfaces and named shapes
are still not rendered, so an app asking for an I-beam gets the arrow.

Lid switch. libinput switch events are handled and surfaced to config as
srd.on("lid_closed"/"lid_open", fn), so closing the lid can lock and suspend
instead of doing nothing.

Config-driven additions, each needed by a binding in the ported config and
none of which existed: fullscreen (Window.fullscreen was a dead field --
declared, never read or written), directional window move that swaps with
the neighbour and reorders the stack so tiling follows, focus cycling,
modifier+drag to move/resize anywhere in a window rather than only by the
titlebar, modifier+scroll to change workspace, and 8 XF86 media/power
keysyms taken from the system's own XF86keysym.h. The keysym tables are
hand-maintained in both directions and a key missing from either fails
silently, so a round-trip test now covers every one the configs bind.

Verified in the QEMU VM: a bare-TTY screendump shows a recognisable arrow at
the pointer position (113 white fill + 58 black outline pixels at screen
centre, where the pointer starts).
</content>
</entry>
<entry>
<title>Rewrite srdwm in Rust: working X11 and Wayland backends, Lua config</title>
<updated>2024-04-01T22:58:00+00:00</updated>
<author>
<name>srdusr</name>
<email>99972264+srdusr@users.noreply.github.com</email>
</author>
<published>2024-04-01T22:58:00+00:00</published>
<link rel='alternate' type='text/html' href='https://srdusr.com/git/srdwm/commit/?id=8110bb2773b6c841029a51eca7971f42a36f480c'/>
<id>urn:sha1:8110bb2773b6c841029a51eca7971f42a36f480c</id>
<content type='text'>
The C++ prototype (moved to legacy-cpp/) was mostly a design skeleton:
X11 and Windows backends were partially real, Wayland created the
wlroots object graph but never wired a single event listener, macOS
was stub except monitor enumeration, and the Lua engine's srd.bind()
stored a key-combo string but never the actual closure. See
docs/PRIOR_ART.md for the full audit.

This replaces it with a Cargo workspace:

- srdwm-core: platform-independent window/workspace/monitor state,
  a real master-stack tiling layout, and SmartPlacement grid/cascade/
  snap-to-edge placement - fixing several bugs in the C++ version
  (hardcoded 2-column grid, cascade that never cascaded, snap-to-edge
  that always returned a fixed rect). 35 unit tests.
- srdwm-config: the srd Lua API via mlua, implementing the surface
  docs/DEFAULTS.md always documented but the C++ engine never actually
  built (srd.window.close()/focus(direction), srd.workspace.next(),
  real keybinding closures, require("srd") support). 10 unit tests.
- srdwm-x11: a real reparenting WM with a drawn title bar (buttons,
  drag, resize), verified live under Xephyr - frame placement and
  client offset match srdwm-core's computed geometry exactly, and the
  decoration renders correctly on screen.
- srdwm-wayland: a from-scratch smithay compositor (the C++ version
  had nothing working to port from) - runs via the winit backend,
  tracks xdg-shell toplevels through the same WindowManager and
  hit-testing code X11 uses, verified to start/render/run without
  crashing. Decorations are solid-color (no text yet); see
  docs/IMPLEMENTATION_STATUS.md for exact scope.
- srdwm-windows / srdwm-macos: structured, cfg-gated designs informed
  by komorebi/glazewm and yabai/AeroSpace respectively (see
  docs/PRIOR_ART.md), honestly marked as unbuilt/unverified since this
  sandbox has no Windows or macOS target.
</content>
</entry>
</feed>
