Blame SOURCES/0006-properties-window-Keep-alive-properties-window-if-ca.patch

1e3c33
From 965a1fb9dcd468b9fc0b87279f3a4a33b6bd635c Mon Sep 17 00:00:00 2001
1e3c33
From: Carlos Soriano <csoriano@redhat.com>
1e3c33
Date: Tue, 7 Aug 2018 12:40:42 +0200
1e3c33
Subject: [PATCH 06/11] properties-window: Keep alive properties window if
1e3c33
 called through DBus
1e3c33
1e3c33
The properties window can be used from within Nautilus, and therefore a
1e3c33
dialog window makes sense, or from outside Nautilus, such as the
1e3c33
FileManager dbus free desktop standard.
1e3c33
1e3c33
In the later, used for integration with things like desktop icons
1e3c33
extensions, we need to keep the application alive since GApplication
1e3c33
would close the application if no application window is alive after a
1e3c33
timeout.
1e3c33
1e3c33
To fix this, this work makes the window hint a regular window if used
1e3c33
from those cases.
1e3c33
---
1e3c33
 src/nautilus-files-view.c        |   6 +-
1e3c33
 src/nautilus-freedesktop-dbus.c  |  10 ++-
1e3c33
 src/nautilus-pathbar.c           |   3 +-
1e3c33
 src/nautilus-properties-window.c | 106 ++++++++++++++++++++++---------
1e3c33
 src/nautilus-properties-window.h |  10 ++-
1e3c33
 src/nautilus-window.c            |   3 +-
1e3c33
 6 files changed, 101 insertions(+), 37 deletions(-)
1e3c33
1e3c33
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
1e3c33
index 8aff33e25..5395390e7 100644
1e3c33
--- a/src/nautilus-files-view.c
1e3c33
+++ b/src/nautilus-files-view.c
1e3c33
@@ -2435,14 +2435,16 @@ action_properties (GSimpleAction *action,
1e3c33
         {
1e3c33
             files = g_list_append (NULL, nautilus_file_ref (priv->directory_as_file));
1e3c33
 
1e3c33
-            nautilus_properties_window_present (files, GTK_WIDGET (view), NULL);
1e3c33
+            nautilus_properties_window_present (files, GTK_WIDGET (view), NULL,
1e3c33
+                                                NULL, NULL);
1e3c33
 
1e3c33
             nautilus_file_list_free (files);
1e3c33
         }
1e3c33
     }
1e3c33
     else
1e3c33
     {
1e3c33
-        nautilus_properties_window_present (selection, GTK_WIDGET (view), NULL);
1e3c33
+        nautilus_properties_window_present (selection, GTK_WIDGET (view), NULL,
1e3c33
+                                            NULL, NULL);
1e3c33
     }
1e3c33
 }
1e3c33
 
1e3c33
diff --git a/src/nautilus-freedesktop-dbus.c b/src/nautilus-freedesktop-dbus.c
1e3c33
index c4657aba3..b88809908 100644
1e3c33
--- a/src/nautilus-freedesktop-dbus.c
1e3c33
+++ b/src/nautilus-freedesktop-dbus.c
1e3c33
@@ -114,6 +114,12 @@ skeleton_handle_show_folders_cb (NautilusFreedesktopFileManager1 *object,
1e3c33
     return TRUE;
1e3c33
 }
1e3c33
 
1e3c33
+static void
1e3c33
+properties_window_on_finished (gpointer user_data)
1e3c33
+{
1e3c33
+    g_application_release (g_application_get_default ());
1e3c33
+}
1e3c33
+
1e3c33
 static gboolean
1e3c33
 skeleton_handle_show_item_properties_cb (NautilusFreedesktopFileManager1 *object,
1e3c33
                                          GDBusMethodInvocation           *invocation,
1e3c33
@@ -133,7 +139,9 @@ skeleton_handle_show_item_properties_cb (NautilusFreedesktopFileManager1 *object
1e3c33
 
1e3c33
     files = g_list_reverse (files);
1e3c33
 
1e3c33
-    nautilus_properties_window_present (files, NULL, startup_id);
1e3c33
+    g_application_hold (g_application_get_default ());
1e3c33
+    nautilus_properties_window_present (files, NULL, startup_id,
1e3c33
+                                        properties_window_on_finished, NULL);
1e3c33
 
1e3c33
     nautilus_file_list_free (files);
1e3c33
 
1e3c33
diff --git a/src/nautilus-pathbar.c b/src/nautilus-pathbar.c
1e3c33
index 630b8ed33..ea3d2b53f 100644
1e3c33
--- a/src/nautilus-pathbar.c
1e3c33
+++ b/src/nautilus-pathbar.c
1e3c33
@@ -211,7 +211,8 @@ action_pathbar_properties (GSimpleAction *action,
1e3c33
 
1e3c33
     files = g_list_append (NULL, nautilus_file_ref (priv->context_menu_file));
1e3c33
 
1e3c33
-    nautilus_properties_window_present (files, GTK_WIDGET (self), NULL);
1e3c33
+    nautilus_properties_window_present (files, GTK_WIDGET (self), NULL, NULL,
1e3c33
+                                        NULL);
1e3c33
 
1e3c33
     nautilus_file_list_free (files);
1e3c33
 }
1e3c33
diff --git a/src/nautilus-properties-window.c b/src/nautilus-properties-window.c
1e3c33
index 8bd335a07..5405435cd 100644
1e3c33
--- a/src/nautilus-properties-window.c
1e3c33
+++ b/src/nautilus-properties-window.c
1e3c33
@@ -152,6 +152,9 @@ typedef struct
1e3c33
     char *startup_id;
1e3c33
     char *pending_key;
1e3c33
     GHashTable *pending_files;
1e3c33
+    NautilusPropertiesWindowCallback callback;
1e3c33
+    gpointer callback_data;
1e3c33
+    NautilusPropertiesWindow *window;
1e3c33
 } StartupData;
1e3c33
 
1e3c33
 /* drag and drop definitions */
1e3c33
@@ -197,8 +200,6 @@ static void is_directory_ready_callback (NautilusFile *file,
1e3c33
                                          gpointer      data);
1e3c33
 static void cancel_group_change_callback (GroupChange *change);
1e3c33
 static void cancel_owner_change_callback (OwnerChange *change);
1e3c33
-static void parent_widget_destroyed_callback (GtkWidget *widget,
1e3c33
-                                              gpointer   callback_data);
1e3c33
 static void select_image_button_callback (GtkWidget                *widget,
1e3c33
                                           NautilusPropertiesWindow *properties_window);
1e3c33
 static void set_icon (const char               *icon_path,
1e3c33
@@ -4811,12 +4812,15 @@ get_pending_key (GList *file_list)
1e3c33
 }
1e3c33
 
1e3c33
 static StartupData *
1e3c33
-startup_data_new (GList      *original_files,
1e3c33
-                  GList      *target_files,
1e3c33
-                  const char *pending_key,
1e3c33
-                  GtkWidget  *parent_widget,
1e3c33
-                  GtkWindow  *parent_window,
1e3c33
-                  const char *startup_id)
1e3c33
+startup_data_new (GList                            *original_files,
1e3c33
+                  GList                            *target_files,
1e3c33
+                  const char                       *pending_key,
1e3c33
+                  GtkWidget                        *parent_widget,
1e3c33
+                  GtkWindow                        *parent_window,
1e3c33
+                  const char                       *startup_id,
1e3c33
+                  NautilusPropertiesWindowCallback  callback,
1e3c33
+                  gpointer                          callback_data,
1e3c33
+                  NautilusPropertiesWindow         *window)
1e3c33
 {
1e3c33
     StartupData *data;
1e3c33
     GList *l;
1e3c33
@@ -4830,6 +4834,9 @@ startup_data_new (GList      *original_files,
1e3c33
     data->pending_key = g_strdup (pending_key);
1e3c33
     data->pending_files = g_hash_table_new (g_direct_hash,
1e3c33
                                             g_direct_equal);
1e3c33
+    data->callback = callback;
1e3c33
+    data->callback_data = callback_data;
1e3c33
+    data->window = window;
1e3c33
 
1e3c33
     for (l = data->target_files; l != NULL; l = l->next)
1e3c33
     {
1e3c33
@@ -5149,7 +5156,7 @@ remove_window (NautilusPropertiesWindow *window)
1e3c33
     }
1e3c33
 }
1e3c33
 
1e3c33
-static GtkWindow *
1e3c33
+static NautilusPropertiesWindow *
1e3c33
 get_existing_window (GList *file_list)
1e3c33
 {
1e3c33
     if (!file_list->next)
1e3c33
@@ -5160,10 +5167,28 @@ get_existing_window (GList *file_list)
1e3c33
     return NULL;
1e3c33
 }
1e3c33
 
1e3c33
+static void
1e3c33
+properties_window_finish (StartupData *data)
1e3c33
+{
1e3c33
+    if (data->parent_widget != NULL)
1e3c33
+    {
1e3c33
+        g_signal_handlers_disconnect_by_data (data->parent_widget,
1e3c33
+                                              data);
1e3c33
+    }
1e3c33
+    if (data->window != NULL)
1e3c33
+    {
1e3c33
+        g_signal_handlers_disconnect_by_data (data->window,
1e3c33
+                                              data);
1e3c33
+    }
1e3c33
+
1e3c33
+    remove_pending (data, TRUE, TRUE, FALSE);
1e3c33
+    startup_data_free (data);
1e3c33
+}
1e3c33
+
1e3c33
 static void
1e3c33
 cancel_create_properties_window_callback (gpointer callback_data)
1e3c33
 {
1e3c33
-    remove_pending ((StartupData *) callback_data, TRUE, FALSE, TRUE);
1e3c33
+    properties_window_finish ((StartupData *) callback_data);
1e3c33
 }
1e3c33
 
1e3c33
 static void
1e3c33
@@ -5172,7 +5197,7 @@ parent_widget_destroyed_callback (GtkWidget *widget,
1e3c33
 {
1e3c33
     g_assert (widget == ((StartupData *) callback_data)->parent_widget);
1e3c33
 
1e3c33
-    remove_pending ((StartupData *) callback_data, TRUE, TRUE, FALSE);
1e3c33
+    properties_window_finish ((StartupData *) callback_data);
1e3c33
 }
1e3c33
 
1e3c33
 static void
1e3c33
@@ -5203,16 +5228,24 @@ remove_pending (StartupData *startup_data,
1e3c33
         eel_timed_wait_stop
1e3c33
             (cancel_create_properties_window_callback, startup_data);
1e3c33
     }
1e3c33
-    if (cancel_destroy_handler && startup_data->parent_widget)
1e3c33
+    g_hash_table_remove (pending_lists, startup_data->pending_key);
1e3c33
+}
1e3c33
+
1e3c33
+static gboolean
1e3c33
+widget_on_destroy (GtkWidget *widget,
1e3c33
+                   gpointer   user_data)
1e3c33
+{
1e3c33
+    StartupData *data = (StartupData *) user_data;
1e3c33
+
1e3c33
+
1e3c33
+    if (data->callback != NULL)
1e3c33
     {
1e3c33
-        g_signal_handlers_disconnect_by_func (startup_data->parent_widget,
1e3c33
-                                              G_CALLBACK (parent_widget_destroyed_callback),
1e3c33
-                                              startup_data);
1e3c33
+        data->callback (data->callback_data);
1e3c33
     }
1e3c33
 
1e3c33
-    g_hash_table_remove (pending_lists, startup_data->pending_key);
1e3c33
+    properties_window_finish (data);
1e3c33
 
1e3c33
-    startup_data_free (startup_data);
1e3c33
+    return GDK_EVENT_PROPAGATE;
1e3c33
 }
1e3c33
 
1e3c33
 static void
1e3c33
@@ -5232,29 +5265,34 @@ is_directory_ready_callback (NautilusFile *file,
1e3c33
         new_window = create_properties_window (startup_data);
1e3c33
 
1e3c33
         add_window (new_window);
1e3c33
+        startup_data->window = new_window;
1e3c33
 
1e3c33
         remove_pending (startup_data, FALSE, TRUE, TRUE);
1e3c33
 
1e3c33
         gtk_window_present (GTK_WINDOW (new_window));
1e3c33
+        g_signal_connect(GTK_WIDGET (new_window), "destroy",
1e3c33
+                         G_CALLBACK (widget_on_destroy), startup_data);
1e3c33
     }
1e3c33
 }
1e3c33
 
1e3c33
-
1e3c33
 void
1e3c33
-nautilus_properties_window_present (GList       *original_files,
1e3c33
-                                    GtkWidget   *parent_widget,
1e3c33
-                                    const gchar *startup_id)
1e3c33
+nautilus_properties_window_present (GList                            *original_files,
1e3c33
+                                    GtkWidget                        *parent_widget,
1e3c33
+                                    const gchar                      *startup_id,
1e3c33
+                                    NautilusPropertiesWindowCallback  callback,
1e3c33
+                                    gpointer                          callback_data)
1e3c33
 {
1e3c33
     GList *l, *next;
1e3c33
-    GtkWidget *parent_window;
1e3c33
+    GtkWindow *parent_window;
1e3c33
     StartupData *startup_data;
1e3c33
     GList *target_files;
1e3c33
-    GtkWindow *existing_window;
1e3c33
+    NautilusPropertiesWindow *existing_window;
1e3c33
     char *pending_key;
1e3c33
 
1e3c33
     g_return_if_fail (original_files != NULL);
1e3c33
     g_return_if_fail (parent_widget == NULL || GTK_IS_WIDGET (parent_widget));
1e3c33
 
1e3c33
+
1e3c33
     /* Create the hash tables first time through. */
1e3c33
     if (windows == NULL)
1e3c33
     {
1e3c33
@@ -5272,15 +5310,19 @@ nautilus_properties_window_present (GList       *original_files,
1e3c33
     {
1e3c33
         if (parent_widget)
1e3c33
         {
1e3c33
-            gtk_window_set_screen (existing_window,
1e3c33
+            gtk_window_set_screen (GTK_WINDOW (existing_window),
1e3c33
                                    gtk_widget_get_screen (parent_widget));
1e3c33
         }
1e3c33
         else if (startup_id)
1e3c33
         {
1e3c33
-            gtk_window_set_startup_id (existing_window, startup_id);
1e3c33
+            gtk_window_set_startup_id (GTK_WINDOW (existing_window), startup_id);
1e3c33
         }
1e3c33
 
1e3c33
-        gtk_window_present (existing_window);
1e3c33
+        gtk_window_present (GTK_WINDOW (existing_window));
1e3c33
+        startup_data = startup_data_new (NULL, NULL, NULL, NULL, NULL, NULL,
1e3c33
+                                         callback, callback_data, existing_window);
1e3c33
+        g_signal_connect(GTK_WIDGET (existing_window), "destroy",
1e3c33
+                         G_CALLBACK (widget_on_destroy), startup_data);
1e3c33
         return;
1e3c33
     }
1e3c33
 
1e3c33
@@ -5290,6 +5332,9 @@ nautilus_properties_window_present (GList       *original_files,
1e3c33
     /* Look to see if we're already waiting for a window for this file. */
1e3c33
     if (g_hash_table_lookup (pending_lists, pending_key) != NULL)
1e3c33
     {
1e3c33
+        /* FIXME: No callback is done if this happen. In practice, it's a quite
1e3c33
+         * corner case
1e3c33
+         */
1e3c33
         return;
1e3c33
     }
1e3c33
 
1e3c33
@@ -5297,7 +5342,7 @@ nautilus_properties_window_present (GList       *original_files,
1e3c33
 
1e3c33
     if (parent_widget)
1e3c33
     {
1e3c33
-        parent_window = gtk_widget_get_ancestor (parent_widget, GTK_TYPE_WINDOW);
1e3c33
+        parent_window = GTK_WINDOW (gtk_widget_get_ancestor (parent_widget, GTK_TYPE_WINDOW));
1e3c33
     }
1e3c33
     else
1e3c33
     {
1e3c33
@@ -5308,8 +5353,11 @@ nautilus_properties_window_present (GList       *original_files,
1e3c33
                                      target_files,
1e3c33
                                      pending_key,
1e3c33
                                      parent_widget,
1e3c33
-                                     GTK_WINDOW (parent_window),
1e3c33
-                                     startup_id);
1e3c33
+                                     parent_window,
1e3c33
+                                     startup_id,
1e3c33
+                                     callback,
1e3c33
+                                     callback_data,
1e3c33
+                                     NULL);
1e3c33
 
1e3c33
     nautilus_file_list_free (target_files);
1e3c33
     g_free (pending_key);
1e3c33
diff --git a/src/nautilus-properties-window.h b/src/nautilus-properties-window.h
1e3c33
index 9eff54c4e..e8d6a90e9 100644
1e3c33
--- a/src/nautilus-properties-window.h
1e3c33
+++ b/src/nautilus-properties-window.h
1e3c33
@@ -59,8 +59,12 @@ typedef struct NautilusPropertiesWindowClass NautilusPropertiesWindowClass;
1e3c33
 
1e3c33
 GType   nautilus_properties_window_get_type   (void);
1e3c33
 
1e3c33
-void 	nautilus_properties_window_present    (GList       *files,
1e3c33
-					       GtkWidget   *parent_widget,
1e3c33
-					       const gchar *startup_id);
1e3c33
+typedef void (* NautilusPropertiesWindowCallback) (gpointer    callback_data);
1e3c33
+
1e3c33
+void nautilus_properties_window_present (GList                            *files,
1e3c33
+                                         GtkWidget                        *parent_widget,
1e3c33
+                                         const gchar                      *startup_id,
1e3c33
+                                         NautilusPropertiesWindowCallback  callback,
1e3c33
+                                         gpointer                          callback_data);
1e3c33
 
1e3c33
 #endif /* NAUTILUS_PROPERTIES_WINDOW_H */
1e3c33
diff --git a/src/nautilus-window.c b/src/nautilus-window.c
1e3c33
index 41c4623be..a6ee4d489 100644
1e3c33
--- a/src/nautilus-window.c
1e3c33
+++ b/src/nautilus-window.c
1e3c33
@@ -1309,7 +1309,8 @@ action_properties (GSimpleAction *action,
1e3c33
     file = nautilus_file_get (priv->selected_file);
1e3c33
 
1e3c33
     list = g_list_append (NULL, file);
1e3c33
-    nautilus_properties_window_present (list, GTK_WIDGET (window), NULL);
1e3c33
+    nautilus_properties_window_present (list, GTK_WIDGET (window), NULL, NULL,
1e3c33
+                                        NULL);
1e3c33
     nautilus_file_list_free (list);
1e3c33
 
1e3c33
     g_clear_object (&priv->selected_file);
1e3c33
-- 
1e3c33
2.17.1
1e3c33