Merge branch 'kill-grabs-2' into 'master'

Kill grabs

See merge request GNOME/gtk!1492
This commit is contained in:
Matthias Clasen 2020-02-29 01:19:48 +00:00
commit c9d3f87e43
8 changed files with 17 additions and 304 deletions

View File

@ -4368,8 +4368,7 @@ gtk_window_group_new
gtk_window_group_add_window
gtk_window_group_remove_window
gtk_window_group_list_windows
gtk_window_group_get_current_grab
gtk_window_group_get_current_device_grab
<SUBSECTION Standard>
GTK_IS_WINDOW_GROUP
GTK_IS_WINDOW_GROUP_CLASS
@ -4391,13 +4390,6 @@ gtk_get_locale_direction
gtk_init
gtk_init_check
<SUBSECTION>
gtk_grab_add
gtk_grab_get_current
gtk_grab_remove
gtk_device_grab_add
gtk_device_grab_remove
<SUBSECTION>
GTK_PRIORITY_RESIZE

View File

@ -1657,7 +1657,6 @@ gtk_main_do_event (GdkEvent *event)
GtkWidget *grab_widget = NULL;
GtkWindowGroup *window_group;
GdkEvent *rewritten_event = NULL;
GdkDevice *device;
GList *tmp_list;
if (gtk_inspector_handle_event (event))
@ -1712,14 +1711,9 @@ gtk_main_do_event (GdkEvent *event)
goto cleanup;
window_group = gtk_main_get_window_group (target_widget);
device = gdk_event_get_device (event);
/* check whether there is a (device) grab in effect... */
if (device)
grab_widget = gtk_window_group_get_current_device_grab (window_group, device);
if (!grab_widget)
grab_widget = gtk_window_group_get_current_grab (window_group);
/* check whether there is a grab in effect... */
grab_widget = gtk_window_group_get_current_grab (window_group);
/* If the grab widget is an ancestor of the event widget
* then we send the event to the original event widget.
@ -1738,13 +1732,6 @@ gtk_main_do_event (GdkEvent *event)
if (check_event_in_child_popover (target_widget, grab_widget))
grab_widget = target_widget;
/* If the widget receiving events is actually blocked by another
* device GTK grab
*/
if (device &&
_gtk_window_group_widget_is_blocked_for_device (window_group, grab_widget, device))
goto cleanup;
/* Not all events get sent to the grabbing widget.
* The delete, destroy, expose, focus change and resize
* events still get sent to the event widget because
@ -2058,24 +2045,6 @@ gtk_grab_add (GtkWidget *widget)
}
}
/**
* gtk_grab_get_current:
*
* Queries the current grab of the default window group.
*
* Returns: (transfer none) (nullable): The widget which currently
* has the grab or %NULL if no grab is active
*/
GtkWidget*
gtk_grab_get_current (void)
{
GtkWindowGroup *group;
group = gtk_main_get_window_group (NULL);
return gtk_window_group_get_current_grab (group);
}
/**
* gtk_grab_remove: (method)
* @widget: The widget which gives up the grab
@ -2108,64 +2077,6 @@ gtk_grab_remove (GtkWidget *widget)
}
}
/**
* gtk_device_grab_add:
* @widget: a #GtkWidget
* @device: a #GdkDevice to grab on.
* @block_others: %TRUE to prevent other devices to interact with @widget.
*
* Adds a GTK grab on @device, so all the events on @device and its
* associated pointer or keyboard (if any) are delivered to @widget.
* If the @block_others parameter is %TRUE, any other devices will be
* unable to interact with @widget during the grab.
*/
void
gtk_device_grab_add (GtkWidget *widget,
GdkDevice *device,
gboolean block_others)
{
GtkWindowGroup *group;
GtkWidget *old_grab_widget;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (GDK_IS_DEVICE (device));
group = gtk_main_get_window_group (widget);
old_grab_widget = gtk_window_group_get_current_device_grab (group, device);
if (old_grab_widget != widget)
_gtk_window_group_add_device_grab (group, widget, device, block_others);
gtk_grab_notify (group, device, old_grab_widget, widget, TRUE);
}
/**
* gtk_device_grab_remove:
* @widget: a #GtkWidget
* @device: a #GdkDevice
*
* Removes a device grab from the given widget.
*
* You have to pair calls to gtk_device_grab_add() and
* gtk_device_grab_remove().
*/
void
gtk_device_grab_remove (GtkWidget *widget,
GdkDevice *device)
{
GtkWindowGroup *group;
GtkWidget *new_grab_widget;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (GDK_IS_DEVICE (device));
group = gtk_main_get_window_group (widget);
_gtk_window_group_remove_device_grab (group, widget, device);
new_grab_widget = gtk_window_group_get_current_device_grab (group, device);
gtk_grab_notify (group, device, widget, new_grab_widget, FALSE);
}
/**
* gtk_get_current_event:
*
@ -2408,20 +2319,15 @@ gtk_propagate_event (GtkWidget *widget,
{
GtkWindowGroup *window_group;
GtkWidget *event_widget, *topmost = NULL;
GdkDevice *device;
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
event_widget = gtk_get_event_widget (event);
window_group = gtk_main_get_window_group (event_widget);
device = gdk_event_get_device (event);
/* check whether there is a (device) grab in effect... */
if (device)
topmost = gtk_window_group_get_current_device_grab (window_group, device);
if (!topmost)
topmost = gtk_window_group_get_current_grab (window_group);
/* check whether there is a grab in effect... */
topmost = gtk_window_group_get_current_grab (window_group);
return gtk_propagate_event_internal (widget, event, topmost);
}

View File

@ -107,21 +107,6 @@ PangoLanguage *gtk_get_default_language (void);
GDK_AVAILABLE_IN_ALL
GtkTextDirection gtk_get_locale_direction (void);
GDK_AVAILABLE_IN_ALL
void gtk_grab_add (GtkWidget *widget);
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_grab_get_current (void);
GDK_AVAILABLE_IN_ALL
void gtk_grab_remove (GtkWidget *widget);
GDK_AVAILABLE_IN_ALL
void gtk_device_grab_add (GtkWidget *widget,
GdkDevice *device,
gboolean block_others);
GDK_AVAILABLE_IN_ALL
void gtk_device_grab_remove (GtkWidget *widget,
GdkDevice *device);
GDK_AVAILABLE_IN_ALL
GdkEvent * gtk_get_current_event (void);
GDK_AVAILABLE_IN_ALL

View File

@ -32,6 +32,7 @@
#include "gtkcsstypesprivate.h"
#include "gtktexthandleprivate.h"
#include "gtkeventcontrollerprivate.h"
#include "gtkwindowgroup.h"
G_BEGIN_DECLS
@ -67,6 +68,10 @@ void _gtk_ensure_resources (void);
void gtk_main_sync (void);
GtkWidget * gtk_window_group_get_current_grab (GtkWindowGroup *window_group);
void gtk_grab_add (GtkWidget *widget);
void gtk_grab_remove (GtkWidget *widget);
gboolean _gtk_boolean_handled_accumulator (GSignalInvocationHint *ihint,
GValue *return_accu,
const GValue *handler_return,

View File

@ -5526,7 +5526,6 @@ gtk_widget_device_is_shadowed (GtkWidget *widget,
GtkRoot *root;
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
if (!_gtk_widget_get_realized (widget))
return TRUE;
@ -5538,14 +5537,6 @@ gtk_widget_device_is_shadowed (GtkWidget *widget,
else
group = gtk_window_get_group (NULL);
grab_widget = gtk_window_group_get_current_device_grab (group, device);
/* Widget not inside the hierarchy of grab_widget */
if (grab_widget &&
widget != grab_widget &&
!gtk_widget_is_ancestor (widget, grab_widget))
return TRUE;
grab_widget = gtk_window_group_get_current_grab (group);
if (grab_widget && widget != grab_widget &&
!gtk_widget_is_ancestor (widget, grab_widget))

View File

@ -9494,10 +9494,8 @@ gtk_window_maybe_update_cursor (GtkWindow *window,
continue;
group = gtk_window_get_group (window);
grab_widget = gtk_window_group_get_current_device_grab (group,
focus->device);
if (!grab_widget)
grab_widget = gtk_window_group_get_current_grab (group);
grab_widget = gtk_window_group_get_current_grab (group);
if (!grab_widget)
grab_widget = gtk_pointer_focus_get_implicit_grab (focus);

View File

@ -27,6 +27,7 @@
#include "gtkmain.h"
#include "gtkwindowprivate.h"
#include "gtkwindowgroup.h"
#include "gtkprivate.h"
/**
@ -62,7 +63,6 @@ struct _GtkDeviceGrabInfo
struct _GtkWindowGroupPrivate
{
GSList *grabs;
GSList *device_grabs;
};
G_DEFINE_TYPE_WITH_PRIVATE (GtkWindowGroup, gtk_window_group, G_TYPE_OBJECT)
@ -82,8 +82,10 @@ gtk_window_group_class_init (GtkWindowGroupClass *klass)
/**
* gtk_window_group_new:
*
* Creates a new #GtkWindowGroup object. Grabs added with
* gtk_grab_add() only affect windows within the same #GtkWindowGroup.
* Creates a new #GtkWindowGroup object.
*
* Modality of windows only affects windows
* within the same #GtkWindowGroup.
*
* Returns: a new #GtkWindowGroup.
**/
@ -98,7 +100,6 @@ window_group_cleanup_grabs (GtkWindowGroup *group,
GtkWindow *window)
{
GtkWindowGroupPrivate *priv;
GtkDeviceGrabInfo *info;
GSList *tmp_list;
GSList *to_remove = NULL;
@ -118,26 +119,6 @@ window_group_cleanup_grabs (GtkWindowGroup *group,
g_object_unref (to_remove->data);
to_remove = g_slist_delete_link (to_remove, to_remove);
}
tmp_list = priv->device_grabs;
while (tmp_list)
{
info = tmp_list->data;
if (gtk_widget_get_root (info->widget) == (GtkRoot *) window)
to_remove = g_slist_prepend (to_remove, info);
tmp_list = tmp_list->next;
}
while (to_remove)
{
info = to_remove->data;
gtk_device_grab_remove (info->widget, info->device);
to_remove = g_slist_delete_link (to_remove, to_remove);
}
}
/**
@ -230,15 +211,6 @@ gtk_window_group_list_windows (GtkWindowGroup *window_group)
return g_list_reverse (group_windows);
}
/**
* gtk_window_group_get_current_grab:
* @window_group: a #GtkWindowGroup
*
* Gets the current grab widget of the given group,
* see gtk_grab_add().
*
* Returns: (transfer none): the current grab widget of the group
*/
GtkWidget *
gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
{
@ -289,133 +261,3 @@ _gtk_window_group_remove_grab (GtkWindowGroup *window_group,
priv = window_group->priv;
priv->grabs = g_slist_remove (priv->grabs, widget);
}
void
_gtk_window_group_add_device_grab (GtkWindowGroup *window_group,
GtkWidget *widget,
GdkDevice *device,
gboolean block_others)
{
GtkWindowGroupPrivate *priv;
GtkDeviceGrabInfo *info;
priv = window_group->priv;
info = g_slice_new0 (GtkDeviceGrabInfo);
info->widget = widget;
info->device = device;
info->block_others = block_others;
priv->device_grabs = g_slist_prepend (priv->device_grabs, info);
revoke_implicit_grabs (window_group, device, widget);
}
void
_gtk_window_group_remove_device_grab (GtkWindowGroup *window_group,
GtkWidget *widget,
GdkDevice *device)
{
GtkWindowGroupPrivate *priv;
GtkDeviceGrabInfo *info;
GSList *list, *node = NULL;
GdkDevice *other_device;
priv = window_group->priv;
other_device = gdk_device_get_associated_device (device);
list = priv->device_grabs;
while (list)
{
info = list->data;
if (info->widget == widget &&
(info->device == device ||
info->device == other_device))
{
node = list;
break;
}
list = list->next;
}
if (node)
{
info = node->data;
priv->device_grabs = g_slist_delete_link (priv->device_grabs, node);
g_slice_free (GtkDeviceGrabInfo, info);
}
}
/**
* gtk_window_group_get_current_device_grab:
* @window_group: a #GtkWindowGroup
* @device: a #GdkDevice
*
* Returns the current grab widget for @device, or %NULL if none.
*
* Returns: (nullable) (transfer none): The grab widget, or %NULL
*/
GtkWidget *
gtk_window_group_get_current_device_grab (GtkWindowGroup *window_group,
GdkDevice *device)
{
GtkWindowGroupPrivate *priv;
GtkDeviceGrabInfo *info;
GdkDevice *other_device;
GSList *list;
g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
priv = window_group->priv;
list = priv->device_grabs;
other_device = gdk_device_get_associated_device (device);
while (list)
{
info = list->data;
list = list->next;
if (info->device == device ||
info->device == other_device)
return info->widget;
}
return NULL;
}
gboolean
_gtk_window_group_widget_is_blocked_for_device (GtkWindowGroup *window_group,
GtkWidget *widget,
GdkDevice *device)
{
GtkWindowGroupPrivate *priv;
GtkDeviceGrabInfo *info;
GdkDevice *other_device;
GSList *list;
priv = window_group->priv;
other_device = gdk_device_get_associated_device (device);
list = priv->device_grabs;
while (list)
{
info = list->data;
list = list->next;
/* Look for blocking grabs on other device pairs
* that have the passed widget within the GTK+ grab.
*/
if (info->block_others &&
info->device != device &&
info->device != other_device &&
(info->widget == widget ||
gtk_widget_is_ancestor (widget, info->widget)))
return TRUE;
}
return FALSE;
}

View File

@ -76,12 +76,6 @@ void gtk_window_group_remove_window (GtkWindowGroup *window_grou
GDK_AVAILABLE_IN_ALL
GList * gtk_window_group_list_windows (GtkWindowGroup *window_group);
GDK_AVAILABLE_IN_ALL
GtkWidget * gtk_window_group_get_current_grab (GtkWindowGroup *window_group);
GDK_AVAILABLE_IN_ALL
GtkWidget * gtk_window_group_get_current_device_grab (GtkWindowGroup *window_group,
GdkDevice *device);
G_END_DECLS