diff options
author | Matthias Clasen <mclasen@redhat.com> | 2019-03-06 23:40:29 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2019-03-16 21:24:45 -0400 |
commit | 4238a04c7be9717ae8efc1debd709b10a82f9268 (patch) | |
tree | 07c87b0385d164981f0d2f805d4a9dd1e0a5168d /gtk/gtkwindow.c | |
parent | adb547a1478738828c09595f848b6105328df5bc (diff) | |
download | gtk+-4238a04c7be9717ae8efc1debd709b10a82f9268.tar.gz |
window: Use gtk_synthesize_crossing_events
Emit focus change events in the same way as crossing events.
Also change the code to only emit focus change events for
the master keyboard - we only maintain a single focus location,
so sending multiple focus change events for different devices
seems confusing.
Diffstat (limited to 'gtk/gtkwindow.c')
-rw-r--r-- | gtk/gtkwindow.c | 119 |
1 files changed, 51 insertions, 68 deletions
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index bf6eeeb6da..85a965c169 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -6911,40 +6911,28 @@ do_focus_change (GtkWidget *widget, gboolean in) { GdkSeat *seat; - GList *devices, *d; - - g_object_ref (widget); + GdkDevice *device; + GdkEvent *event; seat = gdk_display_get_default_seat (gtk_widget_get_display (widget)); - devices = gdk_seat_get_slaves (seat, GDK_SEAT_CAPABILITY_KEYBOARD); - devices = g_list_prepend (devices, gdk_seat_get_keyboard (seat)); - - for (d = devices; d; d = d->next) - { - GdkDevice *dev = d->data; - GdkEvent *fevent; - GdkSurface *surface; - - surface = _gtk_widget_get_surface (widget); + device = gdk_seat_get_keyboard (seat); - fevent = gdk_event_new (GDK_FOCUS_CHANGE); - gdk_event_set_display (fevent, gtk_widget_get_display (widget)); + event = gdk_event_new (GDK_FOCUS_CHANGE); + gdk_event_set_display (event, gtk_widget_get_display (widget)); + gdk_event_set_device (event, device); - fevent->any.type = GDK_FOCUS_CHANGE; - fevent->any.surface = surface; - if (surface) - g_object_ref (surface); - fevent->focus_change.in = in; - gdk_event_set_device (fevent, dev); + event->any.type = GDK_FOCUS_CHANGE; + event->any.surface = _gtk_widget_get_surface (widget); + if (event->any.surface) + g_object_ref (event->any.surface); + event->focus_change.in = in; + event->focus_change.mode = GDK_CROSSING_STATE_CHANGED; + event->focus_change.detail = GDK_NOTIFY_ANCESTOR; - gtk_widget_set_has_focus (widget, in); - gtk_widget_event (widget, fevent); + gtk_widget_set_has_focus (widget, in); + gtk_widget_event (widget, event); - g_object_unref (fevent); - } - - g_list_free (devices); - g_object_unref (widget); + g_object_unref (event); } static gboolean @@ -7162,44 +7150,6 @@ gtk_window_move_focus (GtkWidget *widget, gtk_window_set_focus (GTK_WINDOW (widget), NULL); } -static void -unset_focus_widget (GtkWindow *window) -{ - GtkWindowPrivate *priv = gtk_window_get_instance_private (window); - GtkWidget *f; - - for (f = priv->focus_widget; f; f = gtk_widget_get_parent (f)) - gtk_widget_unset_state_flags (f, GTK_STATE_FLAG_FOCUSED|GTK_STATE_FLAG_FOCUS_VISIBLE); - - if (priv->focus_widget) - do_focus_change (priv->focus_widget, FALSE); - g_set_object (&priv->focus_widget, NULL); -} - -static void -set_focus_widget (GtkWindow *window, - GtkWidget *focus) -{ - GtkWindowPrivate *priv = gtk_window_get_instance_private (window); - GtkWidget *f; - GtkStateFlags flags = GTK_STATE_FLAG_FOCUSED; - - if (gtk_window_get_focus_visible (window)) - flags |= GTK_STATE_FLAG_FOCUS_VISIBLE; - - for (f = focus; f; f = gtk_widget_get_parent (f)) - { - GtkWidget *parent = gtk_widget_get_parent (f); - gtk_widget_set_state_flags (f, flags, FALSE); - if (parent) - gtk_widget_set_focus_child (parent, f); - } - - g_set_object (&priv->focus_widget, focus); - if (priv->focus_widget) - do_focus_change (priv->focus_widget, TRUE); -} - /** * gtk_window_set_focus: * @window: a #GtkWindow @@ -7216,13 +7166,46 @@ void gtk_window_set_focus (GtkWindow *window, GtkWidget *focus) { + GtkWindowPrivate *priv = gtk_window_get_instance_private (window); + GtkWidget *old_focus = NULL; + GtkWidget *f; + GdkSeat *seat; + GdkDevice *device; + GdkEvent *event; + g_return_if_fail (GTK_IS_WINDOW (window)); if (focus && !gtk_widget_is_sensitive (focus)) return; - unset_focus_widget (window); - set_focus_widget (window, focus); + if (priv->focus_widget) + old_focus = g_object_ref (priv->focus_widget); + g_set_object (&priv->focus_widget, NULL); + + seat = gdk_display_get_default_seat (gtk_widget_get_display (GTK_WIDGET (window))); + device = gdk_seat_get_keyboard (seat); + + event = gdk_event_new (GDK_FOCUS_CHANGE); + gdk_event_set_display (event, gtk_widget_get_display (GTK_WIDGET (window))); + gdk_event_set_device (event, device); + event->any.surface = _gtk_widget_get_surface (GTK_WIDGET (window)); + if (event->any.surface) + g_object_ref (event->any.surface); + + gtk_synthesize_crossing_events (window, old_focus, focus, event, GDK_CROSSING_NORMAL); + + g_object_unref (event); + + g_set_object (&priv->focus_widget, focus); + + g_clear_object (&old_focus); + + for (f = focus; f; f = gtk_widget_get_parent (f)) + { + GtkWidget *parent = gtk_widget_get_parent (f); + if (parent) + gtk_widget_set_focus_child (parent, f); + } g_object_notify (G_OBJECT (window), "focus-widget"); } |