widget: Return an array from list_devices

To forther reduce the GList usage in the code base.
This commit is contained in:
Timm Bäder 2020-04-10 09:55:18 +02:00
parent e583349956
commit ca47e96d35
3 changed files with 46 additions and 31 deletions

View File

@ -1798,15 +1798,18 @@ typedef struct
} GrabNotifyInfo;
static void
synth_crossing_for_grab_notify (GtkWidget *from,
GtkWidget *to,
GrabNotifyInfo *info,
GList *devices,
GdkCrossingMode mode)
synth_crossing_for_grab_notify (GtkWidget *from,
GtkWidget *to,
GrabNotifyInfo *info,
GdkDevice **devices,
guint n_devices,
GdkCrossingMode mode)
{
while (devices)
guint i;
for (i = 0; i < n_devices; i++)
{
GdkDevice *device = devices->data;
GdkDevice *device = devices[i];
GdkSurface *from_surface, *to_surface;
/* Do not propagate events more than once to
@ -1848,8 +1851,6 @@ synth_crossing_for_grab_notify (GtkWidget *from,
if (to_surface)
info->notified_surfaces = g_list_prepend (info->notified_surfaces, to_surface);
}
devices = devices->next;
}
}
@ -1859,7 +1860,8 @@ gtk_grab_notify_foreach (GtkWidget *child,
{
GrabNotifyInfo *info = data;
gboolean was_grabbed, is_grabbed, was_shadowed, is_shadowed;
GList *devices;
GdkDevice **devices;
guint n_devices;
was_grabbed = info->was_grabbed;
is_grabbed = info->is_grabbed;
@ -1888,10 +1890,12 @@ gtk_grab_notify_foreach (GtkWidget *child,
_gtk_widget_get_device_surface (child, info->device))
{
/* Device specified and is on widget */
devices = g_list_prepend (NULL, info->device);
devices = g_new (GdkDevice *, 1);
devices[0] = info->device;
n_devices = 1;
}
else
devices = _gtk_widget_list_devices (child);
devices = _gtk_widget_list_devices (child, &n_devices);
if (is_shadowed)
{
@ -1899,7 +1903,7 @@ gtk_grab_notify_foreach (GtkWidget *child,
if (!was_shadowed && devices &&
gtk_widget_is_sensitive (child))
synth_crossing_for_grab_notify (child, info->new_grab_widget,
info, devices,
info, devices, n_devices,
GDK_CROSSING_GTK_GRAB);
}
else
@ -1908,7 +1912,7 @@ gtk_grab_notify_foreach (GtkWidget *child,
if (was_shadowed && devices &&
gtk_widget_is_sensitive (child))
synth_crossing_for_grab_notify (info->old_grab_widget, child,
info, devices,
info, devices, n_devices,
info->from_grab ? GDK_CROSSING_GTK_GRAB :
GDK_CROSSING_GTK_UNGRAB);
}
@ -1917,7 +1921,7 @@ gtk_grab_notify_foreach (GtkWidget *child,
_gtk_widget_grab_notify (child, was_shadowed);
g_object_unref (child);
g_list_free (devices);
g_free (devices);
info->was_grabbed = was_grabbed;
info->is_grabbed = is_grabbed;

View File

@ -7619,38 +7619,47 @@ _gtk_widget_get_device_surface (GtkWidget *widget,
*
* Returns the list of pointer #GdkDevices that are currently
* on top of any surface belonging to @widget. Free the list
* with g_list_free(), the elements are owned by GTK+ and must
* with g_free(), the elements are owned by GTK+ and must
* not be freed.
*/
GList *
_gtk_widget_list_devices (GtkWidget *widget)
GdkDevice **
_gtk_widget_list_devices (GtkWidget *widget,
guint *out_n_devices)
{
GPtrArray *result;
GdkSeat *seat;
GList *result = NULL;
GList *devices;
GList *l;
GdkDevice *device;
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
g_assert (out_n_devices);
if (!_gtk_widget_get_mapped (widget))
return NULL;
{
*out_n_devices = 0;
return NULL;
}
result = g_ptr_array_new ();
seat = gdk_display_get_default_seat (_gtk_widget_get_display (widget));
device = gdk_seat_get_pointer (seat);
if (is_my_surface (widget, gdk_device_get_last_event_surface (device)))
result = g_list_prepend (result, device);
{
g_ptr_array_add (result, device);
}
devices = gdk_seat_get_slaves (seat, GDK_SEAT_CAPABILITY_ALL_POINTING);
for (l = devices; l; l = l->next)
{
device = l->data;
if (is_my_surface (widget, gdk_device_get_last_event_surface (device)))
result = g_list_prepend (result, device);
g_ptr_array_add (result, device);
}
g_list_free (devices);
return result;
*out_n_devices = result->len;
return (GdkDevice **)g_ptr_array_free (result, FALSE);
}
/*
@ -7741,17 +7750,18 @@ gtk_widget_propagate_state (GtkWidget *widget,
if (!priv->shadowed &&
(new_flags & GTK_STATE_FLAG_INSENSITIVE) != (old_flags & GTK_STATE_FLAG_INSENSITIVE))
{
guint i, n_devices;
GdkDevice **devices;
GList *event_surfaces = NULL;
GList *devices, *d;
devices = _gtk_widget_list_devices (widget);
devices = _gtk_widget_list_devices (widget, &n_devices);
for (d = devices; d; d = d->next)
for (i = 0; i < n_devices; i++)
{
GdkSurface *surface;
GdkDevice *device;
device = d->data;
device = devices[i];
surface = _gtk_widget_get_device_surface (widget, device);
/* Do not propagate more than once to the
@ -7762,17 +7772,17 @@ gtk_widget_propagate_state (GtkWidget *widget,
continue;
if (!gtk_widget_is_sensitive (widget))
_gtk_widget_synthesize_crossing (widget, NULL, d->data,
_gtk_widget_synthesize_crossing (widget, NULL, device,
GDK_CROSSING_STATE_CHANGED);
else
_gtk_widget_synthesize_crossing (NULL, widget, d->data,
_gtk_widget_synthesize_crossing (NULL, widget, device,
GDK_CROSSING_STATE_CHANGED);
event_surfaces = g_list_prepend (event_surfaces, surface);
}
g_list_free (event_surfaces);
g_list_free (devices);
g_free (devices);
}
if (!gtk_widget_is_sensitive (widget))

View File

@ -266,7 +266,8 @@ void _gtk_widget_set_device_surface (GtkWidget *widget,
GdkSurface *pointer_window);
GdkSurface * _gtk_widget_get_device_surface (GtkWidget *widget,
GdkDevice *device);
GList * _gtk_widget_list_devices (GtkWidget *widget);
GdkDevice ** _gtk_widget_list_devices (GtkWidget *widget,
guint *out_n_devices);
void _gtk_widget_synthesize_crossing (GtkWidget *from,
GtkWidget *to,