Xlib EnterNotify event not generated when expected (dwm)

61 Views Asked by At

I am running the 'dwm' tiling window manager. In another virtual terminal I have attached gdb to dwm using sudo gdb -p $(pidof dwm) and I have set a breakpoint on the enternotify function (b enternotify). The enternotify function is called every time a EnterNotify event is received so by setting a breakpoint here I am able to detect when dwm receives an EnterNotify event.

As expected, when I move my mouse onto a different window, the breakpoint is hit and I must tell gdb to continue program execution. The breakpoint is also hit when the mouse is on an empty monitor and I move a window onto that monitor.

The problem is in the following scenario: I have two windows open 'A' and 'B' each occupying half the monitor. The pointer is over the 'A' window at the top right of the screen (see first image). Then I use a keyboard shortcut to open another window, this appears on the left side of the screen and dwm moves 'A' to the bottom right and 'B' to the top right. Now the pointer is over window 'B' (see second image). The pointer is now over a different window than it was before but the breakpoint was NOT hit, meaning that no EnterNotify event was generated. How can this be? The docs say that 'If a pointer motion or a window hierarchy change causes the pointer to be in a different window than before, the X server reports EnterNotify or LeaveNotify events to clients who have selected for these events.'. In this case, clearly the window hierarchy has changed and caused the pointer to be in a different window than before so surely a EnterNotify event should have been produced.

Edit: If I do the same except instead of creating a new window I move an existing window from a different monitor onto the one with the pointer then the breakpoint IS hit?!

Edit2: Closing the focused window under the pointer will not hit the breakpoint if there is another window on the same monitor that expands to reach under the pointer.

Edit3: If the pointer is over a different window due to a setmfact keybinding, then the breakpoint is NOT hit.

before

after

All windows are subscribed to EnterNotify events:

...
/* called after MapRequest */
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
...
...
/* on setup, the root window is subscribed */
wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
    |ButtonPressMask|PointerMotionMask|EnterWindowMask
    |LeaveWindowMask|StructureNotifyMask|PropertyChangeMask;
XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
XSelectInput(dpy, root, wa.event_mask);
...

Full dwm source available at git://git.suckless.org/dwm

1

There are 1 best solutions below

0
On

The last line of the restack function is:

while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));

docs explain that this will discard the EnterNotify event.