[nautilus] application: refactor desktop construction



commit 3eeda743a42fe10f0e31743c3fb2ba8907fc8883
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Mon Apr 28 17:55:14 2014 -0700

    application: refactor desktop construction
    
    Move it to be completely contained within NautilusDesktopWindow,
    considerably simplifying the code in NautilusApplication to handle that.

 src/nautilus-application-actions.c |   22 ++++-
 src/nautilus-application.c         |  158 +++++---------------------------
 src/nautilus-application.h         |    2 -
 src/nautilus-desktop-window.c      |  175 ++++++++++++++++++++++++++++++------
 src/nautilus-desktop-window.h      |    4 +-
 5 files changed, 192 insertions(+), 169 deletions(-)
---
diff --git a/src/nautilus-application-actions.c b/src/nautilus-application-actions.c
index 5ffd835..e346d61 100644
--- a/src/nautilus-application-actions.c
+++ b/src/nautilus-application-actions.c
@@ -20,6 +20,8 @@
  */
 
 #include "nautilus-application-actions.h"
+
+#include "nautilus-desktop-window.h"
 #include "nautilus-file-management-properties.h"
 
 #include <glib/gi18n.h>
@@ -135,13 +137,24 @@ action_help (GSimpleAction *action,
 }
 
 static void
-action_force_desktop (GSimpleAction *action,
+action_open_desktop (GSimpleAction *action,
+                     GVariant *parameter,
+                     gpointer user_data)
+{
+       nautilus_desktop_window_ensure ();
+}
+
+static void
+action_close_desktop (GSimpleAction *action,
                      GVariant *parameter,
                      gpointer user_data)
 {
-       NautilusApplication *self = user_data;
+       GtkWidget *desktop_window;
 
-       nautilus_application_open_desktop (self);
+       desktop_window = nautilus_desktop_window_get ();
+       if (desktop_window != NULL) {
+               gtk_widget_destroy (desktop_window);
+       }
 }
 
 static void
@@ -231,7 +244,8 @@ static GActionEntry app_entries[] = {
        { "help", action_help, NULL, NULL, NULL },
        { "quit", action_quit, NULL, NULL, NULL },
        { "kill", action_kill, NULL, NULL, NULL },
-       { "force-desktop", action_force_desktop, NULL, NULL, NULL },
+       { "open-desktop", action_open_desktop, NULL, NULL, NULL },
+       { "close-desktop", action_close_desktop, NULL, NULL, NULL },
 };
 
 void
diff --git a/src/nautilus-application.c b/src/nautilus-application.c
index 46cb372..936be40 100644
--- a/src/nautilus-application.c
+++ b/src/nautilus-application.c
@@ -44,7 +44,6 @@
 #include "nautilus-window-slot.h"
 
 #include <libnautilus-private/nautilus-dbus-manager.h>
-#include <libnautilus-private/nautilus-desktop-link-monitor.h>
 #include <libnautilus-private/nautilus-directory-private.h>
 #include <libnautilus-private/nautilus-file-utilities.h>
 #include <libnautilus-private/nautilus-file-operations.h>
@@ -73,9 +72,6 @@
 
 #define NAUTILUS_ACCEL_MAP_SAVE_DELAY 30
 
-/* Keeps track of all the desktop windows. */
-static GList *nautilus_application_desktop_windows;
-
 /* The saving of the accelerator map was requested  */
 static gboolean save_of_accel_map_requested = FALSE;
 
@@ -379,107 +375,6 @@ do_upgrades_once (NautilusApplication *self)
        g_free (xdg_dir);
 }
 
-static void 
-selection_get_cb (GtkWidget          *widget,
-                 GtkSelectionData   *selection_data,
-                 guint               info,
-                 guint               time)
-{
-       /* No extra targets atm */
-}
-
-static GtkWidget *
-get_desktop_manager_selection (GdkScreen *screen)
-{
-       char selection_name[32];
-       GdkAtom selection_atom;
-       Window selection_owner;
-       GdkDisplay *display;
-       GtkWidget *selection_widget;
-
-       g_snprintf (selection_name, sizeof (selection_name),
-                   "_NET_DESKTOP_MANAGER_S%d", gdk_screen_get_number (screen));
-       selection_atom = gdk_atom_intern (selection_name, FALSE);
-       display = gdk_screen_get_display (screen);
-
-       selection_owner = XGetSelectionOwner (GDK_DISPLAY_XDISPLAY (display),
-                                             gdk_x11_atom_to_xatom_for_display (display, 
-                                                                                selection_atom));
-       if (selection_owner != None) {
-               return NULL;
-       }
-       
-       selection_widget = gtk_invisible_new_for_screen (screen);
-       /* We need this for gdk_x11_get_server_time() */
-       gtk_widget_add_events (selection_widget, GDK_PROPERTY_CHANGE_MASK);
-
-       if (gtk_selection_owner_set_for_display (display,
-                                                selection_widget,
-                                                selection_atom,
-                                                gdk_x11_get_server_time (gtk_widget_get_window 
(selection_widget)))) {
-               
-               g_signal_connect (selection_widget, "selection-get",
-                                 G_CALLBACK (selection_get_cb), NULL);
-               return selection_widget;
-       }
-
-       gtk_widget_destroy (selection_widget);
-       
-       return NULL;
-}
-
-static void
-desktop_unrealize_cb (GtkWidget        *widget,
-                     GtkWidget        *selection_widget)
-{
-       gtk_widget_destroy (selection_widget);
-}
-
-static gboolean
-selection_clear_event_cb (GtkWidget            *widget,
-                         GdkEventSelection     *event,
-                         NautilusDesktopWindow *window)
-{
-       gtk_widget_destroy (GTK_WIDGET (window));
-       
-       nautilus_application_desktop_windows =
-               g_list_remove (nautilus_application_desktop_windows, window);
-
-       return TRUE;
-}
-
-static void
-nautilus_application_create_desktop_windows (NautilusApplication *application)
-{
-       GdkScreen *screen;
-       NautilusDesktopWindow *window;
-       GtkWidget *selection_widget;
-
-       screen = gdk_screen_get_default ();
-
-       DEBUG ("Creating desktop window");
-               
-       selection_widget = get_desktop_manager_selection (screen);
-       if (selection_widget != NULL) {
-               window = nautilus_desktop_window_new (GTK_APPLICATION (application), screen);
-
-               g_signal_connect (selection_widget, "selection-clear-event",
-                                 G_CALLBACK (selection_clear_event_cb), window);
-
-               g_signal_connect (window, "unrealize",
-                                 G_CALLBACK (desktop_unrealize_cb), selection_widget);
-
-               /* We realize it immediately so that the NAUTILUS_DESKTOP_WINDOW_ID
-                  property is set so gnome-settings-daemon doesn't try to set the
-                  background. And we do a gdk_flush() to be sure X gets it. */
-               gtk_widget_realize (GTK_WIDGET (window));
-               gdk_flush ();
-
-               nautilus_application_desktop_windows =
-                       g_list_prepend (nautilus_application_desktop_windows, window);
-       }
-}
-
 static gboolean
 another_navigation_window_already_showing (NautilusApplication *application,
                                           NautilusWindow *the_window)
@@ -1040,7 +935,14 @@ nautilus_application_local_command_line (GApplication *application,
        if (self->priv->force_desktop) {
                DEBUG ("Forcing desktop, as requested");
                g_action_group_activate_action (G_ACTION_GROUP (application),
-                                               "force-desktop", NULL);
+                                               "open-desktop", NULL);
+                /* fall through */
+       }
+
+       if (self->priv->no_desktop) {
+               DEBUG ("Forcing desktop off, as requested");
+               g_action_group_activate_action (G_ACTION_GROUP (application),
+                                               "close-desktop", NULL);
                 /* fall through */
        }
 
@@ -1109,26 +1011,6 @@ init_icons_and_styles (void)
                                           NAUTILUS_DATADIR G_DIR_SEPARATOR_S "icons");
 }
 
-void
-nautilus_application_open_desktop (NautilusApplication *application)
-{
-       /* Initialize the desktop link monitor singleton */
-       nautilus_desktop_link_monitor_get ();
-
-       nautilus_application_create_desktop_windows (application);
-}
-
-static void
-nautilus_application_close_desktop (void)
-{
-       g_list_foreach (nautilus_application_desktop_windows,
-                       (GFunc) gtk_widget_destroy, NULL);
-       g_list_free (nautilus_application_desktop_windows);
-       nautilus_application_desktop_windows = NULL;
-
-       nautilus_desktop_link_monitor_shutdown ();
-}
-
 /* callback for showing or hiding the desktop based on the user's preference */
 static void
 desktop_changed_callback (gpointer user_data)
@@ -1137,9 +1019,11 @@ desktop_changed_callback (gpointer user_data)
 
        application = NAUTILUS_APPLICATION (user_data);
        if (g_settings_get_boolean (gnome_background_preferences, NAUTILUS_PREFERENCES_SHOW_DESKTOP)) {
-               nautilus_application_open_desktop (application);
+               g_action_group_activate_action (G_ACTION_GROUP (application),
+                                               "open-desktop", NULL);
        } else {
-               nautilus_application_close_desktop ();
+               g_action_group_activate_action (G_ACTION_GROUP (application),
+                                               "close-desktop", NULL);
        }
 }
 
@@ -1160,13 +1044,21 @@ init_desktop (NautilusApplication *self)
        }
 
        if (should_show) {
-               nautilus_application_open_desktop (self);
+               g_action_group_activate_action (G_ACTION_GROUP (self),
+                                               "open-desktop", NULL);
+       } else {
+               g_action_group_activate_action (G_ACTION_GROUP (self),
+                                               "close-desktop", NULL);
        }
 
-       /* Monitor the preference to show or hide the desktop */
-       g_signal_connect_swapped (gnome_background_preferences, "changed::" NAUTILUS_PREFERENCES_SHOW_DESKTOP,
-                                 G_CALLBACK (desktop_changed_callback),
-                                 self);
+       /* Monitor the preference to show or hide the desktop, if no other
+        * command line option was specified.
+        */
+       if (!self->priv->no_desktop && !self->priv->force_desktop) {
+               g_signal_connect_swapped (gnome_background_preferences, "changed::" 
NAUTILUS_PREFERENCES_SHOW_DESKTOP,
+                                         G_CALLBACK (desktop_changed_callback),
+                                         self);
+       }
 }
 
 static gboolean 
diff --git a/src/nautilus-application.h b/src/nautilus-application.h
index 31ead47..75679a4 100644
--- a/src/nautilus-application.h
+++ b/src/nautilus-application.h
@@ -67,8 +67,6 @@ void nautilus_application_open_location (NautilusApplication *application,
                                         GFile *selection,
                                         const char *startup_id);
 
-void nautilus_application_open_desktop  (NautilusApplication *application);
-
 void nautilus_application_notify_unmount_show (NautilusApplication *application,
                                               const gchar *message);
 
diff --git a/src/nautilus-desktop-window.c b/src/nautilus-desktop-window.c
index 4d78a05..399fb9f 100644
--- a/src/nautilus-desktop-window.c
+++ b/src/nautilus-desktop-window.c
@@ -33,6 +33,7 @@
 #include <glib/gi18n.h>
 
 #include <eel/eel-vfs-extensions.h>
+#include <libnautilus-private/nautilus-desktop-link-monitor.h>
 #include <libnautilus-private/nautilus-file-utilities.h>
 #include <libnautilus-private/nautilus-icon-names.h>
 #include <libnautilus-private/nautilus-global-preferences.h>
@@ -41,6 +42,8 @@ struct NautilusDesktopWindowDetails {
        gulong size_changed_id;
 
        gboolean loaded;
+
+       GtkWidget *desktop_selection;
 };
 
 G_DEFINE_TYPE (NautilusDesktopWindow, nautilus_desktop_window, 
@@ -62,17 +65,20 @@ nautilus_desktop_window_update_directory (NautilusDesktopWindow *window)
 }
 
 static void
-nautilus_desktop_window_constructed (GObject *obj)
+nautilus_desktop_window_finalize (GObject *obj)
 {
-       GtkActionGroup *action_group;
-       GtkAction *action;
-       AtkObject *accessible;
-       NautilusDesktopWindow *window = NAUTILUS_DESKTOP_WINDOW (obj);
-       NautilusWindow *nwindow = NAUTILUS_WINDOW (obj);
+       nautilus_desktop_link_monitor_shutdown ();
 
-       G_OBJECT_CLASS (nautilus_desktop_window_parent_class)->constructed (obj);
+       G_OBJECT_CLASS (nautilus_desktop_window_parent_class)->finalize (obj);
+}
+
+static void
+nautilus_desktop_window_init_actions (NautilusDesktopWindow *window)
+{
+       GtkAction *action;
+       GtkActionGroup *action_group;
 
-       action_group = nautilus_window_get_main_action_group (nwindow);
+       action_group = nautilus_window_get_main_action_group (NAUTILUS_WINDOW (window));
 
        /* Don't allow close action on desktop */
        action = gtk_action_group_get_action (action_group,
@@ -88,20 +94,85 @@ nautilus_desktop_window_constructed (GObject *obj)
        action = gtk_action_group_get_action (action_group,
                                              NAUTILUS_ACTION_SEARCH);
        gtk_action_set_sensitive (action, FALSE);
+}
 
-       /* Set the accessible name so that it doesn't inherit the cryptic desktop URI. */
-       accessible = gtk_widget_get_accessible (GTK_WIDGET (window));
+static void
+selection_get_cb (GtkWidget          *widget,
+                 GtkSelectionData   *selection_data,
+                 guint               info,
+                 guint               time)
+{
+       /* No extra targets atm */
+}
 
-       if (accessible) {
-               atk_object_set_name (accessible, _("Desktop"));
+static gboolean
+selection_clear_event_cb (GtkWidget            *widget,
+                         GdkEventSelection     *event,
+                         NautilusDesktopWindow *window)
+{
+       gtk_widget_destroy (GTK_WIDGET (window));
+
+       return TRUE;
+}
+
+static void
+nautilus_desktop_window_init_selection (NautilusDesktopWindow *window)
+{
+       char selection_name[32];
+       GdkAtom selection_atom;
+       Window selection_owner;
+       GdkDisplay *display;
+       GtkWidget *selection_widget;
+       GdkScreen *screen;
+
+       screen = gdk_screen_get_default ();
+
+       g_snprintf (selection_name, sizeof (selection_name),
+                   "_NET_DESKTOP_MANAGER_S%d", gdk_screen_get_number (screen));
+       selection_atom = gdk_atom_intern (selection_name, FALSE);
+       display = gdk_screen_get_display (screen);
+
+       selection_owner = XGetSelectionOwner (GDK_DISPLAY_XDISPLAY (display),
+                                             gdk_x11_atom_to_xatom_for_display (display,
+                                                                                selection_atom));
+       if (selection_owner != None) {
+               g_critical ("Another desktop manager in use; desktop window won't be created");
+               return;
+       }
+
+       selection_widget = gtk_invisible_new_for_screen (screen);
+       /* We need this for gdk_x11_get_server_time() */
+       gtk_widget_add_events (selection_widget, GDK_PROPERTY_CHANGE_MASK);
+
+       if (!gtk_selection_owner_set_for_display (display,
+                                                 selection_widget,
+                                                 selection_atom,
+                                                 gdk_x11_get_server_time (gtk_widget_get_window 
(selection_widget)))) {
+               gtk_widget_destroy (selection_widget);
+               g_critical ("Can't set ourselves as selection owner for desktop manager; "
+                           "desktop window won't be created");
+               return;
        }
+
+       g_signal_connect (selection_widget, "selection-get",
+                         G_CALLBACK (selection_get_cb), window);
+       g_signal_connect (selection_widget, "selection-clear-event",
+                         G_CALLBACK (selection_clear_event_cb), window);
+
+       window->details->desktop_selection = selection_widget;
 }
 
 static void
-nautilus_desktop_window_init (NautilusDesktopWindow *window)
+nautilus_desktop_window_constructed (GObject *obj)
 {
-       window->details = G_TYPE_INSTANCE_GET_PRIVATE (window, NAUTILUS_TYPE_DESKTOP_WINDOW,
-                                                      NautilusDesktopWindowDetails);
+       AtkObject *accessible;
+       NautilusDesktopWindow *window = NAUTILUS_DESKTOP_WINDOW (obj);
+        GdkRGBA transparent = {0, 0, 0, 0};
+
+       G_OBJECT_CLASS (nautilus_desktop_window_parent_class)->constructed (obj);
+
+       /* Initialize the desktop link monitor singleton */
+       nautilus_desktop_link_monitor_get ();
 
        gtk_window_move (GTK_WINDOW (window), 0, 0);
 
@@ -115,6 +186,40 @@ nautilus_desktop_window_init (NautilusDesktopWindow *window)
 
        g_object_set_data (G_OBJECT (window), "is_desktop_window", 
                           GINT_TO_POINTER (1));
+
+       nautilus_desktop_window_init_selection (window);
+       nautilus_desktop_window_init_actions (window);
+
+       /* Set the accessible name so that it doesn't inherit the cryptic desktop URI. */
+       accessible = gtk_widget_get_accessible (GTK_WIDGET (window));
+
+       if (accessible) {
+               atk_object_set_name (accessible, _("Desktop"));
+       }
+
+       /* Special sawmill setting */
+       gtk_window_set_wmclass (GTK_WINDOW (window), "desktop_window", "Nautilus");
+
+       /* Point window at the desktop folder.
+        * Note that nautilus_desktop_window_init is too early to do this.
+        */
+       nautilus_desktop_window_update_directory (window);
+        gtk_widget_override_background_color (GTK_WIDGET (window), 0, &transparent);
+
+       /* We realize it immediately so that the NAUTILUS_DESKTOP_WINDOW_ID
+        * property is set so gnome-settings-daemon doesn't try to set
+        * background. And we do a gdk_flush() to be sure X gets it.
+        */
+       gtk_widget_realize (GTK_WIDGET (window));
+       gdk_flush ();
+
+}
+
+static void
+nautilus_desktop_window_init (NautilusDesktopWindow *window)
+{
+       window->details = G_TYPE_INSTANCE_GET_PRIVATE (window, NAUTILUS_TYPE_DESKTOP_WINDOW,
+                                                      NautilusDesktopWindowDetails);
 }
 
 static void
@@ -132,14 +237,16 @@ nautilus_desktop_window_screen_size_changed (GdkScreen             *screen,
                      NULL);
 }
 
-NautilusDesktopWindow *
-nautilus_desktop_window_new (GtkApplication *application,
-                            GdkScreen      *screen)
+static NautilusDesktopWindow *
+nautilus_desktop_window_new (void)
 {
+       GdkScreen *screen;
+       GApplication *application;
        NautilusDesktopWindow *window;
        int width_request, height_request;
-        GdkRGBA transparent = {0, 0, 0, 0};
 
+       application = g_application_get_default ();
+       screen = gdk_screen_get_default ();
        width_request = gdk_screen_get_width (screen);
        height_request = gdk_screen_get_height (screen);
 
@@ -148,20 +255,29 @@ nautilus_desktop_window_new (GtkApplication *application,
                               "disable-chrome", TRUE,
                               "width_request", width_request,
                               "height_request", height_request,
-                              "screen", screen,
                               NULL);
 
-       /* Special sawmill setting*/
-       gtk_window_set_wmclass (GTK_WINDOW (window), "desktop_window", "Nautilus");
+       return window;
+}
 
-       /* Point window at the desktop folder.
-        * Note that nautilus_desktop_window_init is too early to do this.
-        */
-       nautilus_desktop_window_update_directory (window);
-        gtk_widget_override_background_color (GTK_WIDGET (window), 0, &transparent);
+static NautilusDesktopWindow *the_desktop_window = NULL;
 
+void
+nautilus_desktop_window_ensure (void)
+{
+       NautilusDesktopWindow *window;
 
-       return window;
+       if (!the_desktop_window) {
+               window = nautilus_desktop_window_new ();
+               g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &the_desktop_window);
+               the_desktop_window = window;
+       }
+}
+
+GtkWidget *
+nautilus_desktop_window_get (void)
+{
+       return GTK_WIDGET (the_desktop_window);
 }
 
 static gboolean
@@ -195,6 +311,8 @@ unrealize (GtkWidget *widget)
                details->size_changed_id = 0;
        }
 
+       gtk_widget_destroy (details->desktop_selection);
+
        GTK_WIDGET_CLASS (nautilus_desktop_window_parent_class)->unrealize (widget);
 }
 
@@ -264,6 +382,7 @@ nautilus_desktop_window_class_init (NautilusDesktopWindowClass *klass)
        GObjectClass *oclass = G_OBJECT_CLASS (klass);
 
        oclass->constructed = nautilus_desktop_window_constructed;
+       oclass->finalize = nautilus_desktop_window_finalize;
 
        wclass->realize = realize;
        wclass->unrealize = unrealize;
diff --git a/src/nautilus-desktop-window.h b/src/nautilus-desktop-window.h
index 48b1981..506dd62 100644
--- a/src/nautilus-desktop-window.h
+++ b/src/nautilus-desktop-window.h
@@ -53,8 +53,8 @@ typedef struct {
 } NautilusDesktopWindowClass;
 
 GType                  nautilus_desktop_window_get_type            (void);
-NautilusDesktopWindow *nautilus_desktop_window_new                 (GtkApplication        *application,
-                                                                   GdkScreen             *screen);
+GtkWidget *            nautilus_desktop_window_get                 (void);
+void                   nautilus_desktop_window_ensure              (void);
 gboolean               nautilus_desktop_window_loaded              (NautilusDesktopWindow *window);
 
 #endif /* NAUTILUS_DESKTOP_WINDOW_H */


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