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