[gnome-builder] grep: replace search if already running



commit de0011caacc79ded327c489b78e7a810cebb3cc9
Author: vanadiae <vanadiae35 gmail com>
Date:   Tue Dec 21 17:18:23 2021 +0100

    grep: replace search if already running
    
    Currently if one makes a search that will definitely take ages to
    complete ([:alnum:] regex is a good example), then there's no way of
    launching a more efficient or better search to replace the previous one.
    The current behavior makes the "Find" button insensitive while a search
    is running, but even that part is broken as typing new characters in the
    entry will trigger gbp_grep_panel_find_entry_text_changed_cb() and make
    the button sensitive again…
    
    So instead, just make it simpler and allow making searches even when
    there's already one running, cancelling the previous one.

 src/plugins/grep/gbp-grep-panel.c | 33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)
---
diff --git a/src/plugins/grep/gbp-grep-panel.c b/src/plugins/grep/gbp-grep-panel.c
index 25fbdcb98..aedd5ad88 100644
--- a/src/plugins/grep/gbp-grep-panel.c
+++ b/src/plugins/grep/gbp-grep-panel.c
@@ -421,12 +421,24 @@ gbp_grep_panel_scan_cb (GObject      *object,
   g_assert (GBP_IS_GREP_PANEL (self));
 
   if (!gbp_grep_model_scan_finish (model, result, &error))
-    /* TODO: For now we warn in the not-very-noticeable messages panel, but when we start
-     * depending on libadwaita we'll be able to use a status page here as an error page,
-     * in the stack.
-     */
-    ide_object_warning (ide_widget_get_context (GTK_WIDGET (self)),
-                        "Failed to find files: %s", error->message);
+    {
+      /* When it's been cancelled, it means a new search has been launched when the previous
+       * one was still running. In that case, we don't want to update the UI like we would
+       * if the search did end correctly, since that would show back the old search results
+       * and hide the spinner, which is confusing because it will be replaced by the new
+       * search results later when they arrive. So instead, don't do any of this and just
+       * let the next pending search results update the UI accordingly when we get them.
+       */
+      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+        return;
+      else
+        /* TODO: For now we warn in the not-very-noticeable messages panel, but when we start
+         * depending on libadwaita we'll be able to use a status page here as an error page,
+         * in the stack.
+         */
+        ide_object_warning (ide_widget_get_context (GTK_WIDGET (self)),
+                            "Failed to find files: %s", error->message);
+    }
   else
     gbp_grep_panel_set_model (self, model);
 
@@ -434,7 +446,6 @@ gbp_grep_panel_scan_cb (GObject      *object,
 
   gtk_spinner_stop (self->spinner);
   gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->scrolled_window));
-  gtk_widget_set_sensitive (GTK_WIDGET (self->find_button), TRUE);
 
   /* The model defaults to selecting all items, so if the "Select all" header check box was
    * unselected, then we'll end up in an inconsistent state where toggling the header check
@@ -483,12 +494,18 @@ gbp_grep_panel_launch_search (GbpGrepPanel *self)
 
   gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->spinner));
   gtk_spinner_start (self->spinner);
-  gtk_widget_set_sensitive (GTK_WIDGET (self->find_button), FALSE);
   gtk_widget_set_sensitive (GTK_WIDGET (self->replace_button), FALSE);
   gtk_widget_set_sensitive (GTK_WIDGET (self->replace_entry), FALSE);
 
   ide_widget_reveal_and_grab (GTK_WIDGET (self));
 
+  /* We allow making a new search even if there's already one running, but cancel the previous
+   * one to make sure it doesn't needlessly use resources for the grep process that's still
+   * running. Useful for example when you realize that your regex is going to match almost
+   * every single lines of the source tree and so it will never end…
+   */
+  g_cancellable_cancel (self->cancellable);
+  g_clear_object (&self->cancellable);
   self->cancellable = g_cancellable_new ();
   gbp_grep_model_scan_async (model,
                              self->cancellable,


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