GNOME Bugzilla – Bug 762756
keyboard focus problem on dismiss of menus under wayland
Last modified: 2016-05-18 07:56:33 UTC
Created attachment 322494 [details] [review] gtk-demo patch to demo this A patch to gtk3-demo to demo an apparent keyboard focus problem on deactivation of a menu belonging to a menubar a) in gtk3-demo activate the menus example b) click in the gtkentry, cursor is visible c) activate a menu in the menubar d) press esc e) cursor remains unshown in gtkentry, but typing will add text to it alt tab to another app and back and it regains its focus this also affects glade and LibreOffice (with experimental native gtk3 menubar enabled) Maybe a missing focus-in-event to the toplevel after the menu window is dismissed ?
Yes, same with gnome-terminal, very visible if using the block shaped cursor.
Seems this is a regression introduced with the GdkSeat implementation but a more precise git bisect is not really possible because the tree doesn't always build for each commit. Adding Carlos in CC.
Created attachment 326834 [details] Simple reproducer for testing purpose. This simple reproducer demonstrates that the bug is related to a focus-out event which is received in Wayland and not in X11. 1. Build and run the probgram in X11 2. Open the menu, dismiss, no focus out. Now redo the same in Wayland: 3. Open the menu, a focus-out event is received and the cursor stops. I could not use git bisect, but simply reverting commit d54f208d on master fixes the issue so this is really gdk_seat_grab() with GtkMenu causing the issue.
Ok, could be because the Wayland and X11 backend differ wrt focus handling. The X server will emit FocusIn and FocusOut events on grab/ungrab and the X11 backend handles that in _gdk_device_manager_core_handle_focus() taking into account things like the mode and detail given by the XEvent. The X11 backend will not necessarily emit the focus change GdkEvent. The Wayland backend tries to emulate that but emits the focus change GdkEvent quite unconditionally, and I reckon this could be the problem. Relevant code: For X11: https://git.gnome.org/browse/gtk+/tree/gdk/x11/gdkdevicemanager-core-x11.c#n811 For Wayland: gdk_wayland_device_grab() https://git.gnome.org/browse/gtk+/tree/gdk/wayland/gdkdevice-wayland.c#n642 and device_emit_grab_crossing() https://git.gnome.org/browse/gtk+/tree/gdk/wayland/gdkdevice-wayland.c#n600
In the X11 case, when opening the menu, we have: Gdk-Message: focus out: window: 46137347, detail: NotifyAncestor, mode: NotifyGrab Gdk-Message: focus out: window: 46137347, detail: NotifyInferior, mode: NotifyGrab And then for that window, HAS_FOCUS (toplevel) == true, had_focus == true, therefore (HAS_FOCUS (toplevel) != had_focus) is false, the GDK_FOCUS_CHANGE event is not emitted.
Created attachment 326851 [details] [review] wayland: Perform seat grab focus checks on native windows We don't care about the specific (possibly client-side) window that requested the focus here, only the toplevel. Fixes mistakenly sent focus events when the grab happens inside the current focus window.
Attachment 326851 [details] pushed as 14967d8 - wayland: Perform seat grab focus checks on native windows
*** Bug 765477 has been marked as a duplicate of this bug. ***
The patch has been also backported to gtk-3-20
*** Bug 766594 has been marked as a duplicate of this bug. ***