[mutter/wayland] wayland: Set/unset wayland focus on mutter grab/ungrab operations



commit 1b29113150a91b1b889047988f860ee58fe6c61d
Author: Rui Matos <tiagomatos gmail com>
Date:   Tue Mar 11 18:45:39 2014 +0100

    wayland: Set/unset wayland focus on mutter grab/ungrab operations
    
    This ensures that we send the proper leave and enter events to wayland
    clients.
    
    Particularly, this solves a bug in SSD xwayland windows where clicking
    and dragging on the title bar to move the window only works on the odd
    turn (unless the pointer moves away from the title bar between
    tries). This happens because xwayland gets a button press but doesn't
    see the release so when it gets the next button press it discards it
    because its pointer button tracking logic says that the button is
    already pressed. Sending the proper wayland pointer leave event fixes
    it since wayland clients must forget about button state at that point.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=726123

 src/compositor/compositor.c |   26 +++++++++++++++-----------
 src/core/display-private.h  |    2 ++
 src/core/display.c          |   42 ++++++++++++++++++++++++++++++------------
 3 files changed, 47 insertions(+), 23 deletions(-)
---
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 6a49043..6a5fb46 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -426,11 +426,8 @@ meta_begin_modal_for_plugin (MetaScreen       *screen,
   if (is_modal (display) || display->grab_op != META_GRAB_OP_NONE)
     return FALSE;
 
-  if (meta_is_wayland_compositor ())
-    ok = TRUE;
-  else
-    ok = begin_modal_x11 (screen, plugin, options, timestamp);
-  if (!ok)
+  if (!meta_is_wayland_compositor () &&
+      !begin_modal_x11 (screen, plugin, options, timestamp))
     return FALSE;
 
   display->grab_op = META_GRAB_OP_COMPOSITOR;
@@ -439,6 +436,9 @@ meta_begin_modal_for_plugin (MetaScreen       *screen,
   display->grab_have_pointer = TRUE;
   display->grab_have_keyboard = TRUE;
 
+  if (meta_is_wayland_compositor ())
+    meta_display_sync_wayland_input_focus (display);
+
   return TRUE;
 }
 
@@ -452,17 +452,21 @@ meta_end_modal_for_plugin (MetaScreen     *screen,
 
   g_return_if_fail (is_modal (display));
 
-  if (!meta_is_wayland_compositor ())
-    {
-      XIUngrabDevice (xdpy, META_VIRTUAL_CORE_POINTER_ID, timestamp);
-      XIUngrabDevice (xdpy, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);
-    }
-
   display->grab_op = META_GRAB_OP_NONE;
   display->grab_window = NULL;
   display->grab_screen = NULL;
   display->grab_have_pointer = FALSE;
   display->grab_have_keyboard = FALSE;
+
+  if (meta_is_wayland_compositor ())
+    {
+      meta_display_sync_wayland_input_focus (display);
+    }
+  else
+    {
+      XIUngrabDevice (xdpy, META_VIRTUAL_CORE_POINTER_ID, timestamp);
+      XIUngrabDevice (xdpy, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);
+    }
 }
 
 static void
diff --git a/src/core/display-private.h b/src/core/display-private.h
index 096304f..14725c1 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -486,4 +486,6 @@ void meta_display_set_input_focus_xwindow (MetaDisplay *display,
                                            Window       window,
                                            guint32      timestamp);
 
+void meta_display_sync_wayland_input_focus (MetaDisplay *display);
+
 #endif
diff --git a/src/core/display.c b/src/core/display.c
index 489ca9f..58dede3 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -1742,6 +1742,29 @@ get_input_event (MetaDisplay *display,
   return NULL;
 }
 
+void
+meta_display_sync_wayland_input_focus (MetaDisplay *display)
+{
+  MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
+  MetaWindow *focus_window;
+
+  if (display->grab_op != META_GRAB_OP_NONE)
+    focus_window = NULL;
+  else if (meta_display_xwindow_is_a_no_focus_window (display, display->focus_xwindow))
+    focus_window = NULL;
+  else if (display->focus_window && display->focus_window->surface)
+    focus_window = display->focus_window;
+  else
+    meta_topic (META_DEBUG_FOCUS, "Focus change has no effect, because there is no matching wayland 
surface");
+
+  meta_wayland_compositor_set_input_focus (compositor, focus_window);
+
+  if (display->grab_op != META_GRAB_OP_NONE)
+    meta_wayland_pointer_set_focus (&compositor->seat->pointer, NULL);
+  else
+    meta_wayland_seat_repick (compositor->seat, NULL);
+}
+
 static void
 update_focus_window (MetaDisplay *display,
                      MetaWindow  *window,
@@ -1749,8 +1772,6 @@ update_focus_window (MetaDisplay *display,
                      gulong       serial,
                      gboolean     focused_by_us)
 {
-  MetaWaylandCompositor *compositor;
-
   display->focus_serial = serial;
   display->focused_by_us = focused_by_us;
 
@@ -1790,16 +1811,7 @@ update_focus_window (MetaDisplay *display,
     meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL with serial %lu\n", serial);
 
   if (meta_is_wayland_compositor ())
-    {
-      compositor = meta_wayland_compositor_get_default ();
-
-      if (meta_display_xwindow_is_a_no_focus_window (display, xwindow))
-        meta_wayland_compositor_set_input_focus (compositor, NULL);
-      else if (window && window->surface)
-        meta_wayland_compositor_set_input_focus (compositor, window);
-      else
-        meta_topic (META_DEBUG_FOCUS, "Focus change has no effect, because there is no matching wayland 
surface");
-     }
+    meta_display_sync_wayland_input_focus (display);
 
   g_object_notify (G_OBJECT (display), "focus-window");
   meta_display_update_active_window_hint (display);
@@ -4070,6 +4082,9 @@ meta_display_begin_grab_op (MetaDisplay *display,
       meta_window_refresh_resize_popup (display->grab_window);
     }
 
+  if (meta_is_wayland_compositor ())
+    meta_display_sync_wayland_input_focus (display);
+
   g_signal_emit (display, display_signals[GRAB_OP_BEGIN], 0,
                  screen, display->grab_window, display->grab_op);
   
@@ -4163,6 +4178,9 @@ meta_display_end_grab_op (MetaDisplay *display,
       g_source_remove (display->grab_resize_timeout_id);
       display->grab_resize_timeout_id = 0;
     }
+
+  if (meta_is_wayland_compositor ())
+    meta_display_sync_wayland_input_focus (display);
 }
 
 /**


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]