[gtk: 1/2] GtkFileChooserWidget: Propagate keys from external entry to fcwidget at the BUBBLE phase




commit e1159dab93abbedd59f76f67690a37783b4252af
Author: Luca Bacci <luca bacci982 gmail com>
Date:   Fri May 13 12:28:25 2022 +0200

    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 1fb075dbca911d4a61e7ebbf9fc040cd697f4d83
     * commit 686116ba615f989610a6b78e84870555dbf5106b

 gtk/gtkfilechooserwidget.c | 38 ++++++++++++++++++++++++++++----------
 1 file changed, 28 insertions(+), 10 deletions(-)
---
diff --git a/gtk/gtkfilechooserwidget.c b/gtk/gtkfilechooserwidget.c
index dfe796847c..6e212f5ab2 100644
--- a/gtk/gtkfilechooserwidget.c
+++ b/gtk/gtkfilechooserwidget.c
@@ -236,6 +236,7 @@ struct _GtkFileChooserWidget
   LocationMode location_mode;
 
   GtkWidget *external_entry;
+  GtkEventController *external_entry_controller;
 
   GtkWidget *choice_box;
   GHashTable *choices;
@@ -2302,6 +2303,28 @@ forward_key (GtkEventControllerKey *key,
   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 */
 static void
 save_widgets_create (GtkFileChooserWidget *impl)
@@ -2323,10 +2346,7 @@ save_widgets_create (GtkFileChooserWidget *impl)
       impl->location_entry = impl->external_entry;
       g_object_add_weak_pointer (G_OBJECT (impl->external_entry), (gpointer *)&impl->location_entry);
       location_entry_setup (impl);
-
-      g_signal_connect_after (gtk_entry_get_key_controller (GTK_ENTRY (impl->external_entry)),
-                              "key-pressed",
-                              G_CALLBACK (forward_key), impl);
+      external_entry_setup (impl);
       return;
     }
 
@@ -2363,9 +2383,7 @@ save_widgets_destroy (GtkFileChooserWidget *impl)
 {
   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)),
-                                            forward_key, impl);
-
+      external_entry_disconnect (impl);
       location_entry_disconnect (impl);
       impl->location_entry = NULL;
     }
@@ -3104,7 +3122,6 @@ gtk_file_chooser_widget_dispose (GObject *object)
   GtkFileChooserWidget *impl = (GtkFileChooserWidget *) object;
 
   cancel_all_operations (impl);
-
   g_clear_pointer (&impl->rename_file_popover, gtk_widget_unparent);
   g_clear_pointer (&impl->browse_files_popover, gtk_widget_unparent);
   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)
     {
+      external_entry_disconnect (impl);
       location_entry_disconnect (impl);
       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 (entry == NULL || GTK_IS_FILE_CHOOSER_ENTRY (entry));
 
-  impl->external_entry = entry;
-
   if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
     {
       save_widgets_destroy (impl);
+
+      impl->external_entry = entry;
       save_widgets_create (impl);
     }
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]