diff --git a/gtk/gtkeditablelabel.c b/gtk/gtkeditablelabel.c index e107121ad9..a4690960fb 100644 --- a/gtk/gtkeditablelabel.c +++ b/gtk/gtkeditablelabel.c @@ -192,11 +192,23 @@ gtk_editable_label_prepare_drag (GtkDragSource *source, gtk_label_get_label (GTK_LABEL (self->label))); } +static gboolean +stop_editing_soon (gpointer data) +{ + GtkEventController *controller = data; + GtkWidget *widget = gtk_event_controller_get_widget (controller); + + if (!gtk_event_controller_focus_contains_focus (GTK_EVENT_CONTROLLER_FOCUS (controller))) + gtk_editable_label_stop_editing (GTK_EDITABLE_LABEL (widget), TRUE); + + return FALSE; +} + static void gtk_editable_label_focus_out (GtkEventController *controller, GtkEditableLabel *self) { - gtk_editable_label_stop_editing (self, TRUE); + g_timeout_add (100, stop_editing_soon, controller); } static void diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 21e0ac3036..6b4e2d77a7 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -184,6 +184,7 @@ typedef struct GtkWidget *default_widget; GtkWidget *focus_widget; + GtkWidget *move_focus_widget; GtkWindow *transient_parent; GtkWindowGeometryInfo *geometry_info; GtkWindowGroup *group; @@ -2003,7 +2004,12 @@ gtk_window_root_set_focus (GtkRoot *root, if (focus == priv->focus_widget) { - priv->move_focus = FALSE; + if (priv->move_focus && + focus && gtk_widget_is_visible (focus)) + { + priv->move_focus = FALSE; + g_clear_object (&priv->move_focus_widget); + } return; } @@ -2023,7 +2029,12 @@ gtk_window_root_set_focus (GtkRoot *root, g_clear_object (&old_focus); - priv->move_focus = FALSE; + if (priv->move_focus && + focus && gtk_widget_is_visible (focus)) + { + priv->move_focus = FALSE; + g_clear_object (&priv->move_focus_widget); + } g_object_notify (G_OBJECT (self), "focus-widget"); } @@ -2547,6 +2558,7 @@ gtk_window_dispose (GObject *object) g_list_free_full (priv->foci, (GDestroyNotify) gtk_pointer_focus_unref); priv->foci = NULL; + g_clear_object (&priv->move_focus_widget); gtk_window_set_focus (window, NULL); gtk_window_set_default_widget (window, NULL); @@ -4675,7 +4687,25 @@ maybe_unset_focus_and_default (GtkWindow *window) GtkWindowPrivate *priv = gtk_window_get_instance_private (window); if (priv->move_focus) - gtk_widget_child_focus (GTK_WIDGET (window), GTK_DIR_TAB_FORWARD); + { + GtkWidget *parent; + + parent = _gtk_widget_get_parent (priv->move_focus_widget); + + while (parent) + { + if (_gtk_widget_get_visible (parent)) + { + if (gtk_widget_grab_focus (parent)) + break; + } + + parent = _gtk_widget_get_parent (parent); + } + + priv->move_focus = FALSE; + g_clear_object (&priv->move_focus_widget); + } if (priv->unset_default) gtk_window_set_default_widget (window, NULL); @@ -5134,7 +5164,10 @@ _gtk_window_unset_focus_and_default (GtkWindow *window, child = priv->focus_widget; if (child && (child == widget || gtk_widget_is_ancestor (child, widget))) - priv->move_focus = TRUE; + { + priv->move_focus_widget = g_object_ref (widget); + priv->move_focus = TRUE; + } child = priv->default_widget; if (child && (child == widget || gtk_widget_is_ancestor (child, widget)))