GNOME Bugzilla – Bug 158038
Mozilla X focus problems / handling NotifyPointer focus events
Last modified: 2005-04-20 01:35:39 UTC
I'm debugging a reproducible X focus problem with gtk2 builds of Mozilla variants using the Ion window manager. The problem details are in Mozilla bug #230097 (https://bugzilla.mozilla.org/show_bug.cgi?id=230097). Debug traces (see comment #12 in the above bug report) seem to indicate that the problem might lie in the gtk+ library. My limited understanding of the Mozilla code is that it's relying on the gtk+ focus events to keep track of which of its windows has the keyboard focus. The problem seems to be that these events are not dispatched under certain conditions although the focus window has changed. These conditions depend on the mouse pointer, and are connected to X focus events with detail NotifyPointer. Tuomo Valkonen, the author of the Ion window manager, says in the Mozilla bug report that the NotifyPointer X focus events don't contain actual focus information but Mozilla seems to be taking them for normal focus events. This seems to actually take place in gtk+: see below. Is this the intended behaviour or a bug in gtk+ ? The gtk+ source code (version 2.4.13), file gdk/x11/gdkevents-x11.c, looks to me as the focus_in_event and focus_out_event events are dispatched from gdk_event_translate() based on the received X focus events, when the HAS_FOCUS state of the window changes. The HAS_FOCUS macro is defined as #define HAS_FOCUS(toplevel) \ ((toplevel)->has_focus || (toplevel)->has_pointer_focus) Now gdk_event_translate() sets/clears 'has_focus' by these X focus event details: case NotifyAncestor: case NotifyNonlinear: case NotifyVirtual: case NotifyNonlinearVirtual: and 'has_pointer_focus' just by this: case NotifyPointer: In the problematic case the NotifyPointer X focus events are unpaired, ie. the window gets a NotifyPointer FocusIn event, but not a NotifyPointer FocusOut one. This leads to the HAS_FOCUS state remaining true after the WM has set the focus to another window (has_focus is false but has_pointer is still true). Thus a focus_out_event is not dispatched. When the WM sets the focus back the HAS_FOCUS still remains true (only has_focus changes), and no focus_in_event is dispatched. I hope I'm making myself clear; if you need traces or anything else, I'll be happy to provide them.
Probably a dup of bug 109246. *** This bug has been marked as a duplicate of 109246 ***