diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c index 2f11068e94..1ae575880e 100644 --- a/gtk/gtkfilechooserdefault.c +++ b/gtk/gtkfilechooserdefault.c @@ -2306,6 +2306,19 @@ new_folder_button_clicked (GtkButton *button, gtk_tree_path_free (path); } +static GSource * +add_idle_while_impl_is_alive (GtkFileChooserDefault *impl, GCallback callback) +{ + GSource *source; + + source = g_idle_source_new (); + g_source_set_closure (source, + g_cclosure_new_object (callback, G_OBJECT (impl))); + g_source_attach (source, NULL); + + return source; +} + /* Idle handler for creating a new folder after editing its name cell, or for * canceling the editing. */ @@ -2364,13 +2377,7 @@ queue_edited_idle (GtkFileChooserDefault *impl, */ if (!impl->edited_idle) - { - impl->edited_idle = g_idle_source_new (); - g_source_set_closure (impl->edited_idle, - g_cclosure_new_object (G_CALLBACK (edited_idle_cb), - G_OBJECT (impl))); - g_source_attach (impl->edited_idle, NULL); - } + impl->edited_idle = add_idle_while_impl_is_alive (impl, G_CALLBACK (edited_idle_cb)); g_free (impl->edited_new_text); impl->edited_new_text = g_strdup (new_text); @@ -2966,11 +2973,7 @@ shortcuts_drag_leave_cb (GtkWidget *widget, #if 0 if (gtk_drag_get_source_widget (context) == widget && !impl->shortcuts_drag_outside_idle) { - impl->shortcuts_drag_outside_idle = g_idle_source_new (); - g_source_set_closure (impl->shortcuts_drag_outside_idle, - g_cclosure_new_object (G_CALLBACK (shortcuts_drag_outside_idle_cb), - G_OBJECT (impl))); - g_source_attach (impl->shortcuts_drag_outside_idle, NULL); + impl->shortcuts_drag_outside_idle = add_idle_while_impl_is_alive (impl, G_CALLBACK (shortcuts_drag_outside_idle_cb)); } #endif @@ -8934,6 +8937,37 @@ search_entry_activate_cb (GtkEntry *entry, search_start_query (impl, text); } +static gboolean +focus_entry_idle_cb (GtkFileChooserDefault *impl) +{ + GDK_THREADS_ENTER (); + + g_source_destroy (impl->focus_entry_idle); + impl->focus_entry_idle = NULL; + + if (impl->search_entry) + gtk_widget_grab_focus (impl->search_entry); + + GDK_THREADS_LEAVE (); + + return FALSE; +} + +static void +focus_search_entry_in_idle (GtkFileChooserDefault *impl) +{ + /* bgo#634558 - When the user clicks on the Search entry in the shortcuts + * pane, we get a selection-changed signal and we set up the search widgets. + * However, gtk_tree_view_button_press() focuses the treeview *after* making + * the change to the selection. So, we need to re-focus the search entry + * after the treeview has finished doing its work; we'll do that in an idle + * handler. + */ + + if (!impl->focus_entry_idle) + impl->focus_entry_idle = add_idle_while_impl_is_alive (impl, G_CALLBACK (focus_entry_idle_cb)); +} + /* Hides the path bar and creates the search entry */ static void search_setup_widgets (GtkFileChooserDefault *impl) @@ -9002,7 +9036,7 @@ search_setup_widgets (GtkFileChooserDefault *impl) gtk_widget_hide (impl->location_entry_box); } - gtk_widget_grab_focus (impl->search_entry); + focus_search_entry_in_idle (impl); /* FMQ: hide the filter combo? */ } @@ -9046,7 +9080,7 @@ search_activate (GtkFileChooserDefault *impl) if (impl->operation_mode == OPERATION_MODE_SEARCH) { - gtk_widget_grab_focus (impl->search_entry); + focus_search_entry_in_idle (impl); return; } diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h index 7fc8ec7f06..e414e43d2d 100644 --- a/gtk/gtkfilechooserprivate.h +++ b/gtk/gtkfilechooserprivate.h @@ -272,6 +272,8 @@ struct _GtkFileChooserDefault gulong settings_signal_id; int icon_size; + GSource *focus_entry_idle; + gulong toplevel_set_focus_id; GtkWidget *toplevel_last_focus_widget;