diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c index 0c7380a..477935a 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 c4657ab..b888099 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 630b8ed..ea3d2b5 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 8bd335a..5405435 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) @@ -5161,9 +5168,27 @@ get_existing_window (GList *file_list) } 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 9eff54c..e8d6a90 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 1f8d520..46eb741 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);