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

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