GtkFileChooserWidget: Propagate keys from external entry to fcwidget at the BUBBLE phase

Now that we use event controllers we can forward keybindings from the
external entry to the filechooserwidget at the bubble phase.

Fixes #4905

References:
 * commit 1fb075dbca
 * commit 686116ba61
This commit is contained in:
Luca Bacci 2022-05-13 12:28:25 +02:00
parent c4f423694f
commit e1159dab93

View File

@ -236,6 +236,7 @@ struct _GtkFileChooserWidget
LocationMode location_mode; LocationMode location_mode;
GtkWidget *external_entry; GtkWidget *external_entry;
GtkEventController *external_entry_controller;
GtkWidget *choice_box; GtkWidget *choice_box;
GHashTable *choices; GHashTable *choices;
@ -2302,6 +2303,28 @@ forward_key (GtkEventControllerKey *key,
return gtk_event_controller_key_forward (key, GTK_WIDGET (impl)); return gtk_event_controller_key_forward (key, GTK_WIDGET (impl));
} }
static void
external_entry_setup (GtkFileChooserWidget *impl)
{
/* Make keybindings (for example, Ctrl+H to toggle showing hidden files)
* work even when the focus is on the external entry (which is outside
* the hierarchy of GtkFileChooserWidget) */
impl->external_entry_controller = gtk_event_controller_key_new ();
gtk_event_controller_set_propagation_phase (impl->external_entry_controller,
GTK_PHASE_BUBBLE);
g_signal_connect (impl->external_entry_controller, "key-pressed",
G_CALLBACK (forward_key), impl);
gtk_widget_add_controller (impl->external_entry, impl->external_entry_controller);
}
static void
external_entry_disconnect (GtkFileChooserWidget *impl)
{
gtk_widget_remove_controller (impl->external_entry, impl->external_entry_controller);
impl->external_entry_controller = NULL;
}
/* Creates the widgets specific to Save mode */ /* Creates the widgets specific to Save mode */
static void static void
save_widgets_create (GtkFileChooserWidget *impl) save_widgets_create (GtkFileChooserWidget *impl)
@ -2323,10 +2346,7 @@ save_widgets_create (GtkFileChooserWidget *impl)
impl->location_entry = impl->external_entry; impl->location_entry = impl->external_entry;
g_object_add_weak_pointer (G_OBJECT (impl->external_entry), (gpointer *)&impl->location_entry); g_object_add_weak_pointer (G_OBJECT (impl->external_entry), (gpointer *)&impl->location_entry);
location_entry_setup (impl); location_entry_setup (impl);
external_entry_setup (impl);
g_signal_connect_after (gtk_entry_get_key_controller (GTK_ENTRY (impl->external_entry)),
"key-pressed",
G_CALLBACK (forward_key), impl);
return; return;
} }
@ -2363,9 +2383,7 @@ save_widgets_destroy (GtkFileChooserWidget *impl)
{ {
if (impl->external_entry && impl->external_entry == impl->location_entry) if (impl->external_entry && impl->external_entry == impl->location_entry)
{ {
g_signal_handlers_disconnect_by_func (gtk_entry_get_key_controller (GTK_ENTRY (impl->external_entry)), external_entry_disconnect (impl);
forward_key, impl);
location_entry_disconnect (impl); location_entry_disconnect (impl);
impl->location_entry = NULL; impl->location_entry = NULL;
} }
@ -3104,7 +3122,6 @@ gtk_file_chooser_widget_dispose (GObject *object)
GtkFileChooserWidget *impl = (GtkFileChooserWidget *) object; GtkFileChooserWidget *impl = (GtkFileChooserWidget *) object;
cancel_all_operations (impl); cancel_all_operations (impl);
g_clear_pointer (&impl->rename_file_popover, gtk_widget_unparent); g_clear_pointer (&impl->rename_file_popover, gtk_widget_unparent);
g_clear_pointer (&impl->browse_files_popover, gtk_widget_unparent); g_clear_pointer (&impl->browse_files_popover, gtk_widget_unparent);
g_clear_object (&impl->extra_widget); g_clear_object (&impl->extra_widget);
@ -3112,6 +3129,7 @@ gtk_file_chooser_widget_dispose (GObject *object)
if (impl->external_entry && impl->location_entry == impl->external_entry) if (impl->external_entry && impl->location_entry == impl->external_entry)
{ {
external_entry_disconnect (impl);
location_entry_disconnect (impl); location_entry_disconnect (impl);
impl->external_entry = NULL; impl->external_entry = NULL;
} }
@ -7850,11 +7868,11 @@ gtk_file_chooser_widget_set_save_entry (GtkFileChooserWidget *impl,
g_return_if_fail (GTK_IS_FILE_CHOOSER_WIDGET (impl)); g_return_if_fail (GTK_IS_FILE_CHOOSER_WIDGET (impl));
g_return_if_fail (entry == NULL || GTK_IS_FILE_CHOOSER_ENTRY (entry)); g_return_if_fail (entry == NULL || GTK_IS_FILE_CHOOSER_ENTRY (entry));
impl->external_entry = entry;
if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
{ {
save_widgets_destroy (impl); save_widgets_destroy (impl);
impl->external_entry = entry;
save_widgets_create (impl); save_widgets_create (impl);
} }
} }