[nautilus] file-operations: Delay dialog activation



commit 3647c7473a0c5cb851e2cc500acfb6ffd11bdfc3
Author: Álvaro Costa <alvaroc dev gmail com>
Date:   Fri Nov 26 18:33:06 2021 -0300

    file-operations: Delay dialog activation
    
    Warning, error and question dialogs may pop up unexpectedly during
    lengthier operations and the user may end up selecting an unwanted
    action.
    
    This patch introduces a delay of 2s for dialog activation when
    the total elapsed time of the job that created the dialog is
    greater than 2s.
    
    Fixes https://gitlab.gnome.org/GNOME/nautilus/-/issues/1988

 src/nautilus-file-operations.c       | 26 ++++++++++++++++++++++++++
 src/nautilus-operations-ui-manager.h |  2 ++
 2 files changed, 28 insertions(+)
---
diff --git a/src/nautilus-file-operations.c b/src/nautilus-file-operations.c
index 2951af898..73ccaf487 100644
--- a/src/nautilus-file-operations.c
+++ b/src/nautilus-file-operations.c
@@ -250,6 +250,7 @@ G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (SourceInfo, source_info_clear)
 #define SECONDS_NEEDED_FOR_RELIABLE_TRANSFER_RATE 8
 #define NSEC_PER_MICROSEC 1000
 #define PROGRESS_NOTIFY_INTERVAL 100 * NSEC_PER_MICROSEC
+#define LONG_JOB_THRESHOLD_IN_SECONDS 2
 
 #define MAXIMUM_DISPLAYED_FILE_NAME_LENGTH 50
 
@@ -1231,6 +1232,7 @@ typedef struct
     const char *details_text;
     const char **button_titles;
     gboolean show_all;
+    gboolean should_start_inactive;
     int result;
     /* Dialogs are ran from operation threads, which need to be blocked until
      * the user gives a valid response
@@ -1299,6 +1301,20 @@ dialog_realize_cb (GtkWidget *widget,
     set_transient_for (gtk_widget_get_window (widget), parent_handle);
 }
 
+static gboolean
+is_long_job (CommonJob *job)
+{
+    double elapsed = nautilus_progress_info_get_total_elapsed_time (job->progress);
+    return elapsed > LONG_JOB_THRESHOLD_IN_SECONDS ? TRUE : FALSE;
+}
+
+static gboolean
+simple_dialog_button_activate (GtkWidget *button)
+{
+    gtk_widget_set_sensitive (button, TRUE);
+    return G_SOURCE_REMOVE;
+}
+
 static gboolean
 do_run_simple_dialog (gpointer _data)
 {
@@ -1343,6 +1359,14 @@ do_run_simple_dialog (gpointer _data)
             gtk_style_context_add_class (gtk_widget_get_style_context (button),
                                          "destructive-action");
         }
+
+        if (data->should_start_inactive)
+        {
+            gtk_widget_set_sensitive (button, FALSE);
+            g_timeout_add_seconds (BUTTON_ACTIVATION_DELAY_IN_SECONDS,
+                                   G_SOURCE_FUNC (simple_dialog_button_activate),
+                                   button);
+        }
     }
 
     if (data->details_text)
@@ -1454,6 +1478,8 @@ run_simple_dialog_va (CommonJob      *job,
 
     nautilus_progress_info_pause (job->progress);
 
+    data->should_start_inactive = is_long_job (job);
+
     g_mutex_lock (&data->mutex);
 
     g_main_context_invoke (NULL,
diff --git a/src/nautilus-operations-ui-manager.h b/src/nautilus-operations-ui-manager.h
index 06fa3ba3d..052a0da92 100644
--- a/src/nautilus-operations-ui-manager.h
+++ b/src/nautilus-operations-ui-manager.h
@@ -3,6 +3,8 @@
 #include <gio/gio.h>
 #include <gtk/gtk.h>
 
+#define BUTTON_ACTIVATION_DELAY_IN_SECONDS 2
+
 typedef struct {
     int id;
     char *new_name;


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