dwm-fixmultimon-6.4.diff - sites - public wiki contents of suckless.org | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
Refs | |
--- | |
dwm-fixmultimon-6.4.diff (3227B) | |
--- | |
1 From e8f792e8a482e461f9512ac8057d630284a47014 Mon Sep 17 00:00:00 2001 | |
2 From: Christopher Lang <[email protected]> | |
3 Date: Wed, 2 Aug 2023 16:02:15 +0100 | |
4 Subject: [dwm][patch] Stop input focus on pointers unselected monitor | |
5 | |
6 When the pointer is on an unselected monitor and is not moving, it | |
7 should not interfere what window is selected/focused. | |
8 | |
9 1: | |
10 | |
11 From https://tronche.com/gui/x/xlib/events/input-focus/normal-and-grabb… | |
12 When the focus moves from window A to window B, A is an inferior of B, | |
13 and the pointer is in window P, the X server does the following: | |
14 It generates a FocusOut event on window A... | |
15 It generates a FocusOut event on each win... | |
16 It generates a FocusIn event on window B,... | |
17 If window P is an inferior of window B but window P is not window A or | |
18 an inferior or ancestor of window A, it generates a FocusIn event on | |
19 each window below window B, down to and including window P, with the | |
20 detail member of each XFocusInEvent structure set to NotifyPointer. | |
21 | |
22 If focusmon selects a monitor with no clients then XSetInputFocus is | |
23 called on the root window. Due to the above rules, an FocusIn event is s… | |
24 to the window under the pointer which may be on another monitor. Now a | |
25 window on one monitor is getting our keyboard input but another monitor | |
26 is selected. In this undesirable state, a killclient shortcut (for | |
27 example) will not destroy the window that is accepting input. | |
28 | |
29 We fix this by focusing on the bar window instead of root when an empty | |
30 monitor is selected. Windows on other monitors are not a children of the | |
31 bar window so they will not be focused by a NotifyPointer event. | |
32 | |
33 2: | |
34 | |
35 If a window is moved from the selected monitor to the monitor under the | |
36 pointer and the rearrangement of windows on the second monitor causes a | |
37 different window to be under the pointer, then an enternotify event is | |
38 sent for that window. This causes that window to be focused and the | |
39 second monitor to be selected. If the arrangement on the second monitor | |
40 did not cause the pointer to be under a different window then the | |
41 selected monitor would not change (very unpredictable behaviour!). | |
42 | |
43 We fix this by suppressing all enternotify events at the end of an | |
44 arrange(NULL) call. | |
45 --- | |
46 dwm.c | 11 ++++++++--- | |
47 1 file changed, 8 insertions(+), 3 deletions(-) | |
48 | |
49 diff --git a/dwm.c b/dwm.c | |
50 index f1d86b2..5b71b33 100644 | |
51 --- a/dwm.c | |
52 +++ b/dwm.c | |
53 @@ -382,6 +382,7 @@ applysizehints(Client *c, int *x, int *y, int *w, in… | |
54 void | |
55 arrange(Monitor *m) | |
56 { | |
57 + XEvent ev; | |
58 if (m) | |
59 showhide(m->stack); | |
60 else for (m = mons; m; m = m->next) | |
61 @@ -389,8 +390,12 @@ arrange(Monitor *m) | |
62 if (m) { | |
63 arrangemon(m); | |
64 restack(m); | |
65 - } else for (m = mons; m; m = m->next) | |
66 - arrangemon(m); | |
67 + } else { | |
68 + for (m = mons; m; m = m->next) | |
69 + arrangemon(m); | |
70 + XSync(dpy, False); | |
71 + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); | |
72 + } | |
73 } | |
74 | |
75 void | |
76 @@ -804,7 +809,7 @@ focus(Client *c) | |
77 XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBord… | |
78 setfocus(c); | |
79 } else { | |
80 - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentT… | |
81 + XSetInputFocus(dpy, selmon->barwin, RevertToPointerRoot… | |
82 XDeleteProperty(dpy, root, netatom[NetActiveWindow]); | |
83 } | |
84 selmon->sel = c; | |
85 -- | |
86 2.41.0 | |
87 |