[gtk+/wip/carlosg/event-delivery: 56/71] gtkwindow: Revoke implicit grabs when activating an explicit one



commit f4c45a06d4b14c3a5a9351ce33b1da6a1fd7d4a3
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sat Apr 1 22:38:02 2017 +0200

    gtkwindow: Revoke implicit grabs when activating an explicit one
    
    Only if they fall outside the grab widget, in that case the widget holding
    the implicit grab won't be receiving events anymore, so we can just undo
    it.

 gtk/gtkwindow.c        |   28 ++++++++++++++++++++++++++++
 gtk/gtkwindowgroup.c   |   23 +++++++++++++++++++++++
 gtk/gtkwindowprivate.h |    4 ++++
 3 files changed, 55 insertions(+), 0 deletions(-)
---
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 0b0a15f..de5ba11 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -11556,6 +11556,34 @@ gtk_window_update_pointer_focus_on_state_change (GtkWindow *window,
 }
 
 void
+gtk_window_maybe_revoke_implicit_grab (GtkWindow *window,
+                                       GdkDevice *device,
+                                       GtkWidget *grab_widget)
+{
+  GList *l = window->priv->foci, *cur;
+
+  while (l)
+    {
+      GtkPointerFocus *focus = l->data;
+
+      cur = l;
+      focus = cur->data;
+      l = cur->next;
+
+      if (focus->toplevel != window)
+        continue;
+
+      if (device && focus->device == device &&
+          focus->target != grab_widget &&
+          !gtk_widget_is_ancestor (focus->target, grab_widget))
+        gtk_window_set_pointer_focus_grab (window,
+                                           focus->device,
+                                           focus->sequence,
+                                           NULL);
+    }
+}
+
+void
 gtk_window_set_pointer_focus_grab (GtkWindow        *window,
                                    GdkDevice        *device,
                                    GdkEventSequence *sequence,
diff --git a/gtk/gtkwindowgroup.c b/gtk/gtkwindowgroup.c
index bb12650..38befc5 100644
--- a/gtk/gtkwindowgroup.c
+++ b/gtk/gtkwindowgroup.c
@@ -253,6 +253,25 @@ gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
   return NULL;
 }
 
+static void
+revoke_implicit_grabs (GtkWindowGroup *window_group,
+                       GdkDevice      *device,
+                       GtkWidget      *grab_widget)
+{
+  GList *windows, *l;
+
+  windows = gtk_window_group_list_windows (window_group);
+
+  for (l = windows; l; l = l->next)
+    {
+      gtk_window_maybe_revoke_implicit_grab (l->data,
+                                             device,
+                                             grab_widget);
+    }
+
+  g_list_free (windows);
+}
+
 void
 _gtk_window_group_add_grab (GtkWindowGroup *window_group,
                             GtkWidget      *widget)
@@ -261,6 +280,8 @@ _gtk_window_group_add_grab (GtkWindowGroup *window_group,
 
   priv = window_group->priv;
   priv->grabs = g_slist_prepend (priv->grabs, widget);
+
+  revoke_implicit_grabs (window_group, NULL, widget);
 }
 
 void
@@ -290,6 +311,8 @@ _gtk_window_group_add_device_grab (GtkWindowGroup *window_group,
   info->block_others = block_others;
 
   priv->device_grabs = g_slist_prepend (priv->device_grabs, info);
+
+  revoke_implicit_grabs (window_group, device, widget);
 }
 
 void
diff --git a/gtk/gtkwindowprivate.h b/gtk/gtkwindowprivate.h
index 7d8d189..8571219 100644
--- a/gtk/gtkwindowprivate.h
+++ b/gtk/gtkwindowprivate.h
@@ -161,6 +161,10 @@ void             gtk_window_set_pointer_focus_grab (GtkWindow        *window,
 void             gtk_window_update_pointer_focus_on_state_change (GtkWindow *window,
                                                                   GtkWidget *widget);
 
+void             gtk_window_maybe_revoke_implicit_grab (GtkWindow *window,
+                                                        GdkDevice *device,
+                                                        GtkWidget *grab_widget);
+
 G_END_DECLS
 
 #endif /* __GTK_WINDOW_PRIVATE_H__ */


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