diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index a7ad9fcf3e..e1ec1a994d 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -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; diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 91527f8d28..307f516f14 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -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)) diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h index 1b104e77d9..db969f4cb2 100644 --- a/gtk/gtkwidgetprivate.h +++ b/gtk/gtkwidgetprivate.h @@ -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,