feat(windowing): generic X11/EWMH window backend#41
Conversation
Generic wmctrl/xprop backend for list/focus/activate/move/resize on any EWMH-compliant X11 window manager without a dedicated backend (Cinnamon, MATE, Xfce, Openbox, …). Registered last in the backend order so a session-native backend always wins first. Also dispatch move_window/resize_window by the resolved window's backend instead of hardcoding the GNOME Shell extension, so geometry ops work on X11 too. doctor now reports window listing/focus available on plain X11 sessions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces a generic X11/EWMH window backend using wmctrl and xprop to support window listing, activation, moving, and resizing on standards-compliant X11 window managers. The move_window and resize_window tools are refactored to delegate to the registry, enabling support for both GNOME and X11 backends. Feedback suggests adding an X11 session check to list_windows to avoid executing commands on Wayland, handling the coordinate -1 in wmctrl move commands to prevent it from being ignored as a "preserve" instruction, and making the "N/A" check in the clean helper case-insensitive.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
- list_windows: bail on non-X11 sessions so it never returns XWayland-only windows when a Wayland session falls through to this backend. - move_window: map a -1 x/y target to -2, since wmctrl -e reads -1 as "preserve current value" and would otherwise drop the move. - clean: compare "N/A" case-insensitively. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Thanks for the review — all three points addressed in 75a3e65:
Added unit tests for the coordinate mapping and the |
probe(): the focused flag (and thus focused_window/activate verification) comes from _NET_ACTIVE_WINDOW via xprop, so advertise can_focus_apps/can_focus_windows only when xprop is on PATH. Listing still works with wmctrl alone. diagnostics: capabilities.window_control hard-coded the named backend fields and omitted i3 and x11, so it was empty on X11-only sessions even though the registry uses the x11 backend. Read i3/x11 from windowing.backends (tried last). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…focus unavailable resize_window: reject width<=0 || height<=0 before wmctrl -e, where a non-positive value is the "preserve current value" sentinel and would report success while leaving a dimension unchanged. windowing note: when a backend can list windows but cannot verify focus (e.g. wmctrl present but xprop missing on X11, so can_focus_windows=false), say listing-only instead of claiming focused_window and targeted-input verification are available. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Thanks @devthejo, nice work. I pushed a small formatting-only commit on top and merged it. |
What
Adds a generic X11 / EWMH window backend so
list_windows,focused_window,activate_window,move_window, andresize_windowwork on X11 window managers that don't have a dedicated backend — Cinnamon/Muffin, MATE/Marco, Xfce/xfwm4, Openbox, etc.Today window targeting only covers GNOME Shell, KWin, Hyprland, i3, and COSMIC, so on e.g. Cinnamon
doctorreportscan_list_windows: falseand targeted window ops are unavailable even though the session is fully scriptable over EWMH. The README already advertises "X11 best-effort", but there is currently no generic X11 backend.How
src/windowing/backends/x11.rs— talks plain EWMH/ICCCM viawmctrl+xprop(same shell-out style as the i3/hyprland backends):list_windows:wmctrl -l -p -G -x→ id / pid / geometry /WM_CLASS/ title, focused flag from_NET_ACTIVE_WINDOW, terminal enrichment like the other backends.activate_window:wmctrl -i -a(EWMH_NET_ACTIVE_WINDOW).move_window/resize_window:wmctrl -i -r -eafter dropping the maximized state.parse_wmctrl_windows/parse_active_window_idhelpers with unit tests.BACKEND_ORDER/DESCRIPTORS/probe_backends, so any session-native backend still wins first; the probe is gated to real X11 sessions so it won't hijack XWayland under a Wayland compositor.move_window/resize_windownow dispatch by the resolved window's backend (registry::move_window/resize_window) instead of being hardcoded to the GNOME Shell extension, andwindow_geometry_opreports the actual backend.Testing
cargo testgreen (adds x11 parser tests);cargo clippyclean.doctor→readiness.blockers: [](window listing/focus now available).list_windowsreturns the live window list with the correct focused window.activate_windowflips_NET_ACTIVE_WINDOWto the target (verifiedexact_window_focused: true).move_window/resize_windowchange the window geometry.Notes / limitations
move/resizefinal position is best-effort —wmctrl -eis subject to WM frame-gravity offsets; the size is exact. Could be tightened later using_NET_FRAME_EXTENTS.wmctrl+xpropat runtime (the backend probe fails gracefully if they're absent), consistent with the i3 (i3-msg+xprop) and Hyprland (hyprctl) backends.🤖 Generated with Claude Code