GNOME Bugzilla – Bug 137551
grab can block first focus-in-event on new windows
Last modified: 2011-02-04 16:16:24 UTC
Just trying out gtk+-2.4.0 on win32 using gtk-demo, and I noticed a bug in opening the "Entry Completion" demo. The new dialog that pops up doesn't get its first focus-in-event, so the caret and/or focus indication is never displayed. I have tracked the problem to gdkevents-win32.c, near line 2823, where it checks for some sort of grab state before sending focus events. The grab seems to be caused by still having the mouse button pressed after double-clicking on the demo list treeview in gtk-demo. I tried changing gtk-demo to open the new dialog 500ms later, giving me a chance to release the mouse button. This then worked correctly. If I then tried holding the mouse button down for more than that half second it failed again, so it definately seems to be related to the mouse button being down.
The test for pointer grab in the handling of WM_SETFOCUS and WM_KILLFOCUS was added recently, as a fix for bug #129242. I'm afraid it won't be straightforward to fix the issue in this bug without recreating the problems described in bug #129242. I wonder how this stuff works on X11. Will have to run some tests with event debugging printout on X11.
I'm attaching a patch that fixes the specific problem for me. When the set focus is blocked, it calls SetFocus(wParam) to pass focus back to the previously focused window. This keeps GTK's and win32's ideas of the currently focused window consistent.
Created attachment 25862 [details] [review] Patch against gtk+-2.4.0. A bit of a kludge.
Mass changing gtk+ bugs with target milestone of 2.4.2 to target 2.4.4, as Matthias said he was trying to do himself on IRC and was asking for help with. If you see this message, it means I was successful at fixing the borken-ness in bugzilla :) Sorry for the spam; just query on this message and delete all emails you get with this message, since there will probably be a lot.
*** Bug 149449 has been marked as a duplicate of this bug. ***
*** Bug 143174 has been marked as a duplicate of this bug. ***
*** Bug 148389 has been marked as a duplicate of this bug. ***
Isn't the problem here that gdk_display_keyboard_ungrab (and gdk_keyboard_grab) in gdk/win32/gdkevents-win32.c don't generate GDK_FOCUS_CHANGE events to simulate what the X server does on X11? At least that is what I think should happen, for example the manpage for XGrabKeyboard mentions that it can generate FocusIn and FocusOut: http://tronche.com/gui/x/xlib/input/XGrabKeyboard.html I slapped together the following code and put it last in gdk_display_keyboard_ungrab and it seems to solve the problems with disappearing carets and GIMP rotate tool not behaving correctly (bug #148389), but of course one should then also generate a focus out event for the grab window and do the reverse in gdk_keyboard_grab, maybe only do it if the focused window is not the same as the grab window etc. window = gdk_win32_handle_table_lookup ((GdkNativeWindow) GetFocus ()); if (window && !GDK_WINDOW_DESTROYED (window) && (((GdkWindowObject *) window)->event_mask & GDK_FOCUS_CHANGE_MASK)) { event = gdk_event_new (GDK_FOCUS_CHANGE); event->focus_change.window = window; event->focus_change.in = TRUE; append_event (display, event); } Related question: shouldn't the code in gdk_event_translate that blocks FOCUS_CHANGE when input is grabbed look at keyboard grab instead of pointer grab? Could someone with more X11 knowledge than me please comment on this?
*** Bug 151368 has been marked as a duplicate of this bug. ***
*** Bug 150279 has been marked as a duplicate of this bug. ***
These pages look relevant too: http://tronche.com/gui/x/xlib/events/input-focus/normal-and-grabbed.html http://tronche.com/gui/x/xlib/events/input-focus/grab.html I've created a patch for the gtk-2-4 source that does the following things: - Changes gdk_event_translate to check for keyboard grab instead of pointer grab. I don't see anywhere in the manpage for XGrabPointer that it can affect FocusIn/Out. - Simulates a focus change to the grabber when grabbing the keyboard and from the grabber back to the window that really has focus when ungrabbing the keyboard. By looking at the source for the X11 backend I deduced that focus change events should only be sent to toplevel windows, and it seems to work much better that way. Is this correct? I am not sure if it does the right thing when grabbing with owner_events==TRUE. A grab with owner_events==TRUE doesn't affect focus events after the patch (it didn't before either I think). As far as I can see the patch does not reopen bug #129242, and it seems to fix the problem with new windows not getting focus correctly (this bug). It definitely needs more testing, and any comments are welcome, even if they point out that I've totally misunderstood how this stuff should work :)
Created attachment 31341 [details] [review] Possible patch Against gtk-2-4 (CVS) source. Probably needs more work, or at least more testing. (Taking the liberty of marking Tim's patch as obsolete to avoid confusion. I think my solution is better ;)
I tested your solution and it does fix the issue I was having and reported in Bug 151368. I am interested though if this bug is not also related to the problem I just reported in Bug 152566.
Yes, bug #152566 seems to be related in the sense that both have to do with grabbing. For that bug I think the problem is that gdk_pointer_grab and gdk_display_pointer_ungrab in gdk/win32/gdkevents-win32.c do not generate GDK_ENTER_NOTIFY/GDK_LEAVE_NOTIFY as they should. There are even comments hinting at this in those functions: /* FIXME: Generate GDK_CROSSING_GRAB events */ Thanks for testing by the way.
Created attachment 31670 [details] [review] implement GDK_CROSS_GRAB/UNGRAB in gdk_pointer_grab/ungrab I created a patch that sends an event for the GDK_CROSSING_GRAB and GDK_CROSSING_UNGRAB case. At least for gtkcombobox there is no longer an issue with buttons becoming non-clickable after opening a combobox, Bug 152566. The patch includes Patch 31341. Also, I'm not sure I did this correctly as I am not entirely sure why it works. It also does not appear to fix Bug 152035. I have made some other changes in gdkevents_win32.c that involved a flickering issue when resizing windows in win32. These changes should be ignored as they're unrelated to this bug.
By sending a GDK_ENTER_NOTIFY and GTK_LEAVE_NOTIFY it appears Tree Store test in gtk-demo is broken. The tree doesn't appear to get the correct coordinates of the mouse clicks.
I'm just guessing, but that could be because your implementation is incomplete, you might want to try to send an ENTER_NOTIFY to the window under the cursor in gdk_display_pointer_ungrab, and the reverse in gdk_pointer_grab. The synthesize_enter_or_leave_event function looks useful. But, this has nothing to do with this bug (#137551) which is about missing focus events. I suggest you attach patches in bug #152566 where it is relevant instead. Also please remove all irrelevant stuff from your patch including the patch for this bug.
*** Bug 150931 has been marked as a duplicate of this bug. ***
*** Bug 155931 has been marked as a duplicate of this bug. ***
Patch 31341 appears to be working. I've been using it since Robert posted it here and have not run into a case where it did not work or had something else break as a result. It could of course, just be that I have not tested in enough ways. I have patched my gtk+ upto the latest cvs as of today and tested with gtk-demo testgtk and numerous other gtk+ programs I've been working in win32. I can't say, whether or not this patch is optimial, but I can say that on my p2 450 celeron I had no noticable slow downs. So, if it is not optimal, then it certainly is not hurting performance. What needs to happen to get this patch commited?
> What needs to happen to get this patch commited? Robert's reminder in bug #152035 was enough ;-) Committing it in a moment.
Patch applied to HEAD and gtk-2-4.
*** Bug 158755 has been marked as a duplicate of this bug. ***