diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index d6efac75ee..f0e8f07125 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -11470,6 +11470,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, diff --git a/gtk/gtkwindowgroup.c b/gtk/gtkwindowgroup.c index bb1265065f..38befc5a4c 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 7d8d18965d..857121985e 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__ */