commit a558b5b0970da906924722ea2df282cbbbca2425
parent c690081873592d6067ca72ae1ec40d761b304a9d
Author: Lukasz Kasprzak <lukas@labunix.xyz>
Date: Fri, 17 Jul 2026 20:35:00 +0200
[dwm][keychord] correct recoverability note
My previous commit overstated the freeze as leaving dwm "frozen permanently"
with the loop unable to "ever exit". That is wrong: XSendEvent is only
discarded when it carries an event_mask. A synthetic KeyPress sent with
event_mask=0 to the _NET_SUPPORTING_WM_CHECK window reaches dwm's creator
regardless of selected masks, breaks the wait loop, and (followed by a
ButtonPress so buttonpress() runs XAllowEvents) recovers the session without
killing dwm. Verified on Xephyr. The bug and the fix are unchanged; only the
recoverability wording is corrected.
Diffstat:
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/dwm.suckless.org/patches/keychord/index.md b/dwm.suckless.org/patches/keychord/index.md
@@ -15,11 +15,16 @@ changed grabkeys function to match the changes made in dwm-6.4.
rebased onto dwm 6.8 and fixed event loss in the chord wait loop. While
waiting for the next key of a chord, every event that was not a KeyPress was
discarded. Discarding a ButtonPress that activated the GrabModeSync passive
-grab from grabbuttons() left the pointer and keyboard frozen permanently: only
-buttonpress()'s XAllowEvents can release that grab, and the loop could never
-exit because a frozen keyboard cannot deliver the KeyPress it waits for. A
-MapRequest arriving mid-chord was dropped the same way, leaving the window
-unmanaged. Events are now dispatched through handler[] as run() does.
+grab from grabbuttons() left pointer and keyboard frozen: only buttonpress()'s
+XAllowEvents can release that grab, and the loop cannot exit on its own, because
+the frozen keyboard delivers no further KeyPress. Ordinary input, XTEST and
+xdotool cannot break it; recovery needs a synthetic KeyPress sent with
+XSendEvent event_mask=0 to the _NET_SUPPORTING_WM_CHECK window (event_mask=0
+delivers to the window's creator, bypassing the fact that dwm selects no
+KeyPressMask), followed by a synthetic ButtonPress to make buttonpress() run
+XAllowEvents. Absent such a tool the session is lost. A MapRequest arriving
+mid-chord was dropped the same way, leaving the window unmanaged. Events are now
+dispatched through handler[] as run() does.
Download