From 38547120b2ea2cb1c525a2d015051b09489ba099 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 1 Oct 2020 16:54:10 +0200 Subject: [PATCH 1/2] gtkwindow: Ensure to revert focus to a parent on hide() When a widget is hidden, check harder for the keyboard focus being contained in that widget, in order to reset it. Portions of the focus child hierarchy may be outdated at the time, so it is more reliable to check GtkRoot::focus (i.e. the property we intend to update here). Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3214 --- gtk/gtkwindow.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 947b178f76..6bdb06931b 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -5206,28 +5206,24 @@ _gtk_window_unset_focus_and_default (GtkWindow *window, GtkWindowPrivate *priv = gtk_window_get_instance_private (window); GtkWidget *child; GtkWidget *parent; + GtkWidget *focus; g_object_ref (window); g_object_ref (widget); parent = _gtk_widget_get_parent (widget); - if (gtk_widget_get_focus_child (parent) == widget) + focus = gtk_root_get_focus (GTK_ROOT (window)); + if (focus && (focus == widget || gtk_widget_is_ancestor (focus, widget))) { - child = priv->focus_widget; - - while (child && child != widget) - child = _gtk_widget_get_parent (child); - - if (child == widget) + while (parent) { - GtkWidget *new_focus; + if (_gtk_widget_get_visible (parent)) + { + gtk_widget_grab_focus (parent); + break; + } - if (GTK_IS_NATIVE (widget)) - new_focus = gtk_widget_get_parent (widget); - else - new_focus = NULL; - - gtk_window_set_focus (GTK_WINDOW (window), new_focus); + parent = gtk_widget_get_parent (parent); } } From ac164d240b0dcd37b84207094f00606cb1c353ac Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 5 Oct 2020 21:53:05 -0400 Subject: [PATCH 2/2] Cosmetic Don't call gtk_root_get_focus when we already have the GtkWindowPrivate struct at hand. And use gtk_window_set_focus to update the focus, like the old code did. --- gtk/gtkwindow.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 6bdb06931b..046079f56f 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -5190,17 +5190,17 @@ gtk_window_css_changed (GtkWidget *widget, } } -/** +/* * _gtk_window_unset_focus_and_default: * @window: a #GtkWindow * @widget: a widget inside of @window - * + * * Checks whether the focus and default widgets of @window are * @widget or a descendent of @widget, and if so, unset them. - **/ + */ void _gtk_window_unset_focus_and_default (GtkWindow *window, - GtkWidget *widget) + GtkWidget *widget) { GtkWindowPrivate *priv = gtk_window_get_instance_private (window); @@ -5211,30 +5211,31 @@ _gtk_window_unset_focus_and_default (GtkWindow *window, g_object_ref (window); g_object_ref (widget); - parent = _gtk_widget_get_parent (widget); - focus = gtk_root_get_focus (GTK_ROOT (window)); + focus = priv->focus_widget; if (focus && (focus == widget || gtk_widget_is_ancestor (focus, widget))) { + parent = _gtk_widget_get_parent (widget); + while (parent) { if (_gtk_widget_get_visible (parent)) { - gtk_widget_grab_focus (parent); + gtk_window_set_focus (window, parent); break; } parent = gtk_widget_get_parent (parent); } } - + child = priv->default_widget; - + while (child && child != widget) child = _gtk_widget_get_parent (child); if (child == widget) gtk_window_set_default_widget (window, NULL); - + g_object_unref (widget); g_object_unref (window); }