← Back to team overview

lightdm-gtk-greeter-team team mailing list archive

[Merge] lp:~kalgasnik/lightdm-gtk-greeter/focus_fix into lp:lightdm-gtk-greeter

 

Andrew P. has proposed merging lp:~kalgasnik/lightdm-gtk-greeter/focus_fix into lp:lightdm-gtk-greeter.

Requested reviews:
  LightDM Gtk+ Greeter Development Team (lightdm-gtk-greeter-team)

For more details, see:
https://code.launchpad.net/~kalgasnik/lightdm-gtk-greeter/focus_fix/+merge/199652

Switching focus between greeter windows is not handled correctly .
Open/close shutdown dialog to reproduce it - only window under cursor can have focus (and catch keys press, so you can close this dialog using "escape" key only when dialog is under cursor).
The solution for this problem is taken (copy/paste) from unity-greeter.
-- 
https://code.launchpad.net/~kalgasnik/lightdm-gtk-greeter/focus_fix/+merge/199652
Your team LightDM Gtk+ Greeter Development Team is requested to review the proposed merge of lp:~kalgasnik/lightdm-gtk-greeter/focus_fix into lp:lightdm-gtk-greeter.
=== modified file 'src/lightdm-gtk-greeter.c'
--- src/lightdm-gtk-greeter.c	2013-12-13 02:56:06 +0000
+++ src/lightdm-gtk-greeter.c	2013-12-19 12:01:59 +0000
@@ -1748,6 +1748,51 @@
     return x != NULL;
 }
 
+static GdkFilterReturn
+focus_upon_map (GdkXEvent *gxevent, GdkEvent *event, gpointer  data)
+{
+    XEvent* xevent = (XEvent*)gxevent;
+    if (xevent->type == MapNotify)
+    {
+        Window xwin = xevent->xmap.window;
+        Window keyboard_xid = 0;
+        GdkDisplay* display = gdk_x11_lookup_xdisplay (xevent->xmap.display);
+        GdkWindow* win = gdk_x11_window_foreign_new_for_display (display, xwin);
+        GdkWindow* keyboard_win = onboard_window ? gtk_widget_get_window (GTK_WIDGET (onboard_window)) : NULL;
+
+        /* Check to see if this window is our onboard window, since we don't want to focus it. */
+        if (keyboard_win)
+#if GTK_CHECK_VERSION (3, 0, 0)
+                keyboard_xid = gdk_x11_window_get_xid (keyboard_win);
+#else
+                keyboard_xid = gdk_x11_drawable_get_xid (keyboard_win);
+#endif
+            
+        if (xwin != keyboard_xid && gdk_window_get_type_hint (win) != GDK_WINDOW_TYPE_HINT_NOTIFICATION)
+        {
+            gdk_window_focus (win, GDK_CURRENT_TIME);
+            /* Make sure to keep keyboard above */
+            if (onboard_window)
+                gdk_window_raise (keyboard_win);
+        }
+    }
+    else if (xevent->type == UnmapNotify)
+    {
+        Window xwin;
+        int revert_to;
+        XGetInputFocus (xevent->xunmap.display, &xwin, &revert_to);
+
+        if (revert_to == RevertToNone)
+        {
+            gdk_window_focus (gtk_widget_get_window (GTK_WIDGET (login_window)), GDK_CURRENT_TIME);
+            /* Make sure to keep keyboard above */
+            if (onboard_window)
+                gdk_window_raise (gtk_widget_get_window (GTK_WIDGET (onboard_window)));
+        }
+    }
+    return GDK_FILTER_CONTINUE;
+}
+
 int
 main (int argc, char **argv)
 {
@@ -2221,6 +2266,11 @@
     
     gdk_threads_add_timeout( 100, (GSourceFunc) clock_timeout_thread, NULL );
 
+    /* focus fix (source: unity-greeter) */
+    GdkWindow* root_window = gdk_get_default_root_window ();
+    gdk_window_set_events (root_window, gdk_window_get_events (root_window) | GDK_SUBSTRUCTURE_MASK);
+    gdk_window_add_filter (root_window, focus_upon_map, NULL);
+
 #if GTK_CHECK_VERSION (3, 0, 0)
 #else
     gdk_threads_enter();


Follow ups