[nautilus/wip/antoniof/gtk4-preparation-step-event-controllers: 9/21] location-entry: Track text changes through GtkEditable




commit 6c10a85bab39eba295d8385b93c6df4668e91688
Author: António Fernandes <antoniof gnome org>
Date:   Sat Aug 7 12:57:05 2021 +0100

    location-entry: Track text changes through GtkEditable
    
    We have been keeping a copy of GtkEntry code to guess whether a key
    event would insert text into the entry.
    
    Not only is this a hack, it also relies on overriding the ::event signal
    and chaining it up, which won't be possible in GTK4 where the ::event
    signal is gone.
    
    Instead of guessing, we can know for sure whether characters have been
    inserted or deleted by listening to GtkEditable::insert-text and
    GtkEditable::delete-text.

 src/nautilus-location-entry.c | 104 ++++++++++++++++--------------------------
 1 file changed, 40 insertions(+), 64 deletions(-)
---
diff --git a/src/nautilus-location-entry.c b/src/nautilus-location-entry.c
index 260767044..3d1bbe997 100644
--- a/src/nautilus-location-entry.c
+++ b/src/nautilus-location-entry.c
@@ -495,68 +495,6 @@ update_completions_store (gpointer callback_data)
     return FALSE;
 }
 
-/* Until we have a more elegant solution, this is how we figure out if
- * the GtkEntry inserted characters, assuming that the return value is
- * TRUE indicating that the GtkEntry consumed the key event for some
- * reason. This is a clone of code from GtkEntry.
- */
-static gboolean
-entry_would_have_inserted_characters (const GdkEvent *event)
-{
-    guint keyval;
-    GdkModifierType state;
-
-    if (G_UNLIKELY (!gdk_event_get_keyval (event, &keyval)))
-    {
-        g_return_val_if_reached (GDK_EVENT_PROPAGATE);
-    }
-    if (G_UNLIKELY (!gdk_event_get_state (event, &state)))
-    {
-        g_return_val_if_reached (GDK_EVENT_PROPAGATE);
-    }
-
-    switch (keyval)
-    {
-        case GDK_KEY_BackSpace:
-        case GDK_KEY_Clear:
-        case GDK_KEY_Insert:
-        case GDK_KEY_Delete:
-        case GDK_KEY_Home:
-        case GDK_KEY_End:
-        case GDK_KEY_KP_Home:
-        case GDK_KEY_KP_End:
-        case GDK_KEY_Left:
-        case GDK_KEY_Right:
-        case GDK_KEY_KP_Left:
-        case GDK_KEY_KP_Right:
-        case GDK_KEY_Return:
-        /* For when the entry is set to be always visible.
-         */
-        case GDK_KEY_Escape:
-        {
-            return FALSE;
-        }
-
-        default:
-        {
-            if (keyval >= 0x20 && keyval <= 0xFF)
-            {
-                if ((state & GDK_CONTROL_MASK) != 0)
-                {
-                    return FALSE;
-                }
-                if ((state & GDK_MOD1_MASK) != 0)
-                {
-                    return FALSE;
-                }
-            }
-        }
-    }
-
-    /* GTK+ 4 TODO: gdk_event_get_string () and check if length > 0. */
-    return ((const GdkEventKey *) event)->length;
-}
-
 static void
 got_completion_data_callback (GFilenameCompleter    *completer,
                               NautilusLocationEntry *entry)
@@ -772,11 +710,19 @@ nautilus_location_entry_on_event (GtkWidget *widget,
         return GDK_EVENT_PROPAGATE;
     }
 
+    return GDK_EVENT_PROPAGATE;
+}
+
+static void
+after_text_change (NautilusLocationEntry *self,
+                   gboolean               insert)
+{
+    NautilusLocationEntryPrivate *priv = nautilus_location_entry_get_instance_private (self);
 
     /* Only insert a completion if a character was typed. Otherwise,
      * update the completions store (i.e. in case backspace was pressed)
      * but don't insert the completion into the entry. */
-    priv->idle_insert_completion = entry_would_have_inserted_characters (event);
+    priv->idle_insert_completion = insert;
 
     /* Do the expand at idle time to avoid slowing down typing when the
      * directory is large. */
@@ -784,8 +730,29 @@ nautilus_location_entry_on_event (GtkWidget *widget,
     {
         priv->idle_id = g_idle_add (update_completions_store, self);
     }
+}
+
+static void
+on_after_insert_text (GtkEditable *editable,
+                      const gchar *text,
+                      gint         length,
+                      gint        *position,
+                      gpointer     data)
+{
+    NautilusLocationEntry *self = NAUTILUS_LOCATION_ENTRY (editable);
+
+    after_text_change (self, TRUE);
+}
 
-    return handled;
+static void
+on_after_delete_text (GtkEditable *editable,
+                      gint         start_pos,
+                      gint         end_pos,
+                      gpointer     data)
+{
+    NautilusLocationEntry *self = NAUTILUS_LOCATION_ENTRY (editable);
+
+    after_text_change (self, FALSE);
 }
 
 static void
@@ -982,6 +949,15 @@ nautilus_location_entry_init (NautilusLocationEntry *entry)
     g_signal_connect_object (entry, "changed",
                              G_CALLBACK (editable_changed_callback), entry, 0);
 
+    g_signal_connect_after (entry,
+                            "insert-text",
+                            G_CALLBACK (on_after_insert_text),
+                            NULL);
+    g_signal_connect_after (entry,
+                            "delete-text",
+                            G_CALLBACK (on_after_delete_text),
+                            NULL);
+
     priv->completion = gtk_entry_completion_new ();
     priv->completions_store = gtk_list_store_new (1, G_TYPE_STRING);
     gtk_entry_completion_set_model (priv->completion, GTK_TREE_MODEL (priv->completions_store));


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