From ce8a88d786eeb4617e1760f656484e5fdf5630ec Mon Sep 17 00:00:00 2001 From: Carlos Soriano Date: Fri, 15 Apr 2016 10:35:34 +0200 Subject: desktop: move to a different folder For a better structured hierarchy. --- Makefile.am | 1 + configure.ac | 1 + libnautilus-private/Makefile.am | 12 - .../nautilus-desktop-directory-file.c | 556 --------------- .../nautilus-desktop-directory-file.h | 53 -- libnautilus-private/nautilus-desktop-directory.c | 571 ---------------- libnautilus-private/nautilus-desktop-directory.h | 58 -- libnautilus-private/nautilus-desktop-icon-file.c | 519 -------------- libnautilus-private/nautilus-desktop-icon-file.h | 59 -- .../nautilus-desktop-link-monitor.c | 430 ------------ .../nautilus-desktop-link-monitor.h | 60 -- libnautilus-private/nautilus-desktop-link.c | 432 ------------ libnautilus-private/nautilus-desktop-link.h | 77 --- libnautilus-private/nautilus-desktop-metadata.c | 90 --- libnautilus-private/nautilus-desktop-metadata.h | 43 -- nautilus-desktop/Makefile.am | 58 ++ nautilus-desktop/main-desktop.c | 38 ++ nautilus-desktop/nautilus-desktop-application.c | 243 +++++++ nautilus-desktop/nautilus-desktop-application.h | 36 + .../nautilus-desktop-canvas-view-container.c | 199 ++++++ .../nautilus-desktop-canvas-view-container.h | 35 + nautilus-desktop/nautilus-desktop-canvas-view.c | 744 ++++++++++++++++++++ nautilus-desktop/nautilus-desktop-canvas-view.h | 54 ++ nautilus-desktop/nautilus-desktop-directory-file.c | 557 +++++++++++++++ nautilus-desktop/nautilus-desktop-directory-file.h | 53 ++ nautilus-desktop/nautilus-desktop-directory.c | 571 ++++++++++++++++ nautilus-desktop/nautilus-desktop-directory.h | 58 ++ nautilus-desktop/nautilus-desktop-icon-file.c | 520 ++++++++++++++ nautilus-desktop/nautilus-desktop-icon-file.h | 60 ++ nautilus-desktop/nautilus-desktop-link-monitor.c | 432 ++++++++++++ nautilus-desktop/nautilus-desktop-link-monitor.h | 60 ++ nautilus-desktop/nautilus-desktop-link.c | 436 ++++++++++++ nautilus-desktop/nautilus-desktop-link.h | 77 +++ nautilus-desktop/nautilus-desktop-metadata.c | 90 +++ nautilus-desktop/nautilus-desktop-metadata.h | 43 ++ nautilus-desktop/nautilus-desktop-window-slot.c | 67 ++ nautilus-desktop/nautilus-desktop-window-slot.h | 36 + nautilus-desktop/nautilus-desktop-window.c | 416 ++++++++++++ nautilus-desktop/nautilus-desktop-window.h | 59 ++ src/Makefile.am | 40 +- src/main-desktop.c | 36 - src/nautilus-desktop-application.c | 243 ------- src/nautilus-desktop-application.h | 36 - src/nautilus-desktop-canvas-view-container.c | 199 ------ src/nautilus-desktop-canvas-view-container.h | 35 - src/nautilus-desktop-canvas-view.c | 745 --------------------- src/nautilus-desktop-canvas-view.h | 54 -- src/nautilus-desktop-window-slot.c | 67 -- src/nautilus-desktop-window-slot.h | 36 - src/nautilus-desktop-window.c | 415 ------------ src/nautilus-desktop-window.h | 59 -- src/nautilus-main.c | 3 +- 52 files changed, 4960 insertions(+), 4912 deletions(-) delete mode 100644 libnautilus-private/nautilus-desktop-directory-file.c delete mode 100644 libnautilus-private/nautilus-desktop-directory-file.h delete mode 100644 libnautilus-private/nautilus-desktop-directory.c delete mode 100644 libnautilus-private/nautilus-desktop-directory.h delete mode 100644 libnautilus-private/nautilus-desktop-icon-file.c delete mode 100644 libnautilus-private/nautilus-desktop-icon-file.h delete mode 100644 libnautilus-private/nautilus-desktop-link-monitor.c delete mode 100644 libnautilus-private/nautilus-desktop-link-monitor.h delete mode 100644 libnautilus-private/nautilus-desktop-link.c delete mode 100644 libnautilus-private/nautilus-desktop-link.h delete mode 100644 libnautilus-private/nautilus-desktop-metadata.c delete mode 100644 libnautilus-private/nautilus-desktop-metadata.h create mode 100644 nautilus-desktop/Makefile.am create mode 100644 nautilus-desktop/main-desktop.c create mode 100644 nautilus-desktop/nautilus-desktop-application.c create mode 100644 nautilus-desktop/nautilus-desktop-application.h create mode 100644 nautilus-desktop/nautilus-desktop-canvas-view-container.c create mode 100644 nautilus-desktop/nautilus-desktop-canvas-view-container.h create mode 100644 nautilus-desktop/nautilus-desktop-canvas-view.c create mode 100644 nautilus-desktop/nautilus-desktop-canvas-view.h create mode 100644 nautilus-desktop/nautilus-desktop-directory-file.c create mode 100644 nautilus-desktop/nautilus-desktop-directory-file.h create mode 100644 nautilus-desktop/nautilus-desktop-directory.c create mode 100644 nautilus-desktop/nautilus-desktop-directory.h create mode 100644 nautilus-desktop/nautilus-desktop-icon-file.c create mode 100644 nautilus-desktop/nautilus-desktop-icon-file.h create mode 100644 nautilus-desktop/nautilus-desktop-link-monitor.c create mode 100644 nautilus-desktop/nautilus-desktop-link-monitor.h create mode 100644 nautilus-desktop/nautilus-desktop-link.c create mode 100644 nautilus-desktop/nautilus-desktop-link.h create mode 100644 nautilus-desktop/nautilus-desktop-metadata.c create mode 100644 nautilus-desktop/nautilus-desktop-metadata.h create mode 100644 nautilus-desktop/nautilus-desktop-window-slot.c create mode 100644 nautilus-desktop/nautilus-desktop-window-slot.h create mode 100644 nautilus-desktop/nautilus-desktop-window.c create mode 100644 nautilus-desktop/nautilus-desktop-window.h delete mode 100644 src/main-desktop.c delete mode 100644 src/nautilus-desktop-application.c delete mode 100644 src/nautilus-desktop-application.h delete mode 100644 src/nautilus-desktop-canvas-view-container.c delete mode 100644 src/nautilus-desktop-canvas-view-container.h delete mode 100644 src/nautilus-desktop-canvas-view.c delete mode 100644 src/nautilus-desktop-canvas-view.h delete mode 100644 src/nautilus-desktop-window-slot.c delete mode 100644 src/nautilus-desktop-window-slot.h delete mode 100644 src/nautilus-desktop-window.c delete mode 100644 src/nautilus-desktop-window.h diff --git a/Makefile.am b/Makefile.am index ee62eca68..b75140f34 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,6 +6,7 @@ DIRS = \ libgd \ libnautilus-private \ src \ + nautilus-desktop \ test \ po \ data \ diff --git a/configure.ac b/configure.ac index ae2ffecdf..955a6bdba 100644 --- a/configure.ac +++ b/configure.ac @@ -318,6 +318,7 @@ libnautilus-extension/libnautilus-extension-uninstalled.pc libgd/Makefile po/Makefile.in src/Makefile +nautilus-desktop/Makefile nautilus-sendto-extension/Makefile test/Makefile ]) diff --git a/libnautilus-private/Makefile.am b/libnautilus-private/Makefile.am index 8c37d4db7..7e0718fb7 100644 --- a/libnautilus-private/Makefile.am +++ b/libnautilus-private/Makefile.am @@ -80,18 +80,6 @@ libnautilus_private_la_SOURCES = \ nautilus-debug.h \ nautilus-default-file-icon.c \ nautilus-default-file-icon.h \ - nautilus-desktop-directory-file.c \ - nautilus-desktop-directory-file.h \ - nautilus-desktop-directory.c \ - nautilus-desktop-directory.h \ - nautilus-desktop-icon-file.c \ - nautilus-desktop-icon-file.h \ - nautilus-desktop-link-monitor.c \ - nautilus-desktop-link-monitor.h \ - nautilus-desktop-link.c \ - nautilus-desktop-link.h \ - nautilus-desktop-metadata.c \ - nautilus-desktop-metadata.h \ nautilus-directory-async.c \ nautilus-directory-notify.h \ nautilus-directory-private.h \ diff --git a/libnautilus-private/nautilus-desktop-directory-file.c b/libnautilus-private/nautilus-desktop-directory-file.c deleted file mode 100644 index 2a43bdf98..000000000 --- a/libnautilus-private/nautilus-desktop-directory-file.c +++ /dev/null @@ -1,556 +0,0 @@ -/* - nautilus-desktop-directory-file.c: Subclass of NautilusFile to help implement the - virtual desktop. - - Copyright (C) 2003 Red Hat, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, see . - - Author: Alexander Larsson -*/ - -#include -#include "nautilus-desktop-directory-file.h" - -#include "nautilus-desktop-metadata.h" -#include "nautilus-directory-notify.h" -#include "nautilus-directory-private.h" -#include "nautilus-file-attributes.h" -#include "nautilus-file-private.h" -#include "nautilus-file-utilities.h" -#include -#include "nautilus-desktop-directory.h" -#include "nautilus-metadata.h" -#include -#include -#include - -struct NautilusDesktopDirectoryFileDetails { - NautilusDesktopDirectory *desktop_directory; - - NautilusFile *real_dir_file; - - GHashTable *callbacks; - GHashTable *monitors; -}; - -typedef struct { - NautilusDesktopDirectoryFile *desktop_file; - NautilusFileCallback callback; - gpointer callback_data; - - NautilusFileAttributes delegated_attributes; - NautilusFileAttributes non_delegated_attributes; - - GList *non_ready_files; - - gboolean initializing; -} DesktopCallback; - -typedef struct { - NautilusDesktopDirectoryFile *desktop_file; - - NautilusFileAttributes delegated_attributes; - NautilusFileAttributes non_delegated_attributes; -} DesktopMonitor; - -G_DEFINE_TYPE (NautilusDesktopDirectoryFile, nautilus_desktop_directory_file, - NAUTILUS_TYPE_FILE); - -static guint -desktop_callback_hash (gconstpointer desktop_callback_as_pointer) -{ - const DesktopCallback *desktop_callback; - - desktop_callback = desktop_callback_as_pointer; - return GPOINTER_TO_UINT (desktop_callback->callback) - ^ GPOINTER_TO_UINT (desktop_callback->callback_data); -} - -static gboolean -desktop_callback_equal (gconstpointer desktop_callback_as_pointer, - gconstpointer desktop_callback_as_pointer_2) -{ - const DesktopCallback *desktop_callback, *desktop_callback_2; - - desktop_callback = desktop_callback_as_pointer; - desktop_callback_2 = desktop_callback_as_pointer_2; - - return desktop_callback->callback == desktop_callback_2->callback - && desktop_callback->callback_data == desktop_callback_2->callback_data; -} - - -static void -real_file_changed_callback (NautilusFile *real_file, - gpointer callback_data) -{ - NautilusDesktopDirectoryFile *desktop_file; - - desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (callback_data); - nautilus_file_changed (NAUTILUS_FILE (desktop_file)); -} - -static NautilusFileAttributes -get_delegated_attributes_mask (void) -{ - return NAUTILUS_FILE_ATTRIBUTE_DEEP_COUNTS | - NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT | - NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_MIME_TYPES | - NAUTILUS_FILE_ATTRIBUTE_INFO; -} - -static void -partition_attributes (NautilusFileAttributes attributes, - NautilusFileAttributes *delegated_attributes, - NautilusFileAttributes *non_delegated_attributes) -{ - NautilusFileAttributes mask; - - mask = get_delegated_attributes_mask (); - - *delegated_attributes = attributes & mask; - *non_delegated_attributes = attributes & ~mask; -} - -static void -desktop_directory_file_monitor_add (NautilusFile *file, - gconstpointer client, - NautilusFileAttributes attributes) -{ - NautilusDesktopDirectoryFile *desktop_file; - DesktopMonitor *monitor; - - desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); - - /* Map the client to a unique value so this doesn't interfere - * with direct monitoring of the file by the same client. - */ - monitor = g_hash_table_lookup (desktop_file->details->monitors, client); - if (monitor != NULL) { - g_assert (monitor->desktop_file == desktop_file); - } else { - monitor = g_new0 (DesktopMonitor, 1); - monitor->desktop_file = desktop_file; - g_hash_table_insert (desktop_file->details->monitors, - (gpointer) client, monitor); - } - - partition_attributes (attributes, - &monitor->delegated_attributes, - &monitor->non_delegated_attributes); - - /* Pawn off partioned attributes to real dir file */ - nautilus_file_monitor_add (desktop_file->details->real_dir_file, - monitor, monitor->delegated_attributes); - - /* Do the rest ourself */ - nautilus_directory_monitor_add_internal - (file->details->directory, file, - client, TRUE, - monitor->non_delegated_attributes, - NULL, NULL); -} - -static void -desktop_directory_file_monitor_remove (NautilusFile *file, - gconstpointer client) -{ - NautilusDesktopDirectoryFile *desktop_file; - DesktopMonitor *monitor; - - desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); - - /* Map the client to the value used by the earlier add call. */ - monitor = g_hash_table_lookup (desktop_file->details->monitors, client); - if (monitor == NULL) { - return; - } - - /* Call through to the real file remove calls. */ - g_hash_table_remove (desktop_file->details->monitors, client); - - /* Remove the locally handled parts */ - nautilus_directory_monitor_remove_internal - (file->details->directory, file, client); -} - -static void -desktop_callback_destroy (DesktopCallback *desktop_callback) -{ - g_assert (desktop_callback != NULL); - g_assert (NAUTILUS_IS_DESKTOP_DIRECTORY_FILE (desktop_callback->desktop_file)); - - nautilus_file_unref (NAUTILUS_FILE (desktop_callback->desktop_file)); - g_list_free (desktop_callback->non_ready_files); - g_free (desktop_callback); -} - -static void -desktop_callback_check_done (DesktopCallback *desktop_callback) -{ - /* Check if we are ready. */ - if (desktop_callback->initializing || - desktop_callback->non_ready_files != NULL) { - return; - } - - /* Ensure our metadata is updated before calling back */ - nautilus_desktop_update_metadata_from_keyfile (NAUTILUS_FILE (desktop_callback->desktop_file), "directory"); - - /* Remove from the hash table before sending it. */ - g_hash_table_remove (desktop_callback->desktop_file->details->callbacks, - desktop_callback); - - /* We are ready, so do the real callback. */ - (* desktop_callback->callback) (NAUTILUS_FILE (desktop_callback->desktop_file), - desktop_callback->callback_data); - - /* And we are done. */ - desktop_callback_destroy (desktop_callback); -} - -static void -desktop_callback_remove_file (DesktopCallback *desktop_callback, - NautilusFile *file) -{ - desktop_callback->non_ready_files = g_list_remove - (desktop_callback->non_ready_files, file); - desktop_callback_check_done (desktop_callback); -} - -static void -ready_callback (NautilusFile *file, - gpointer callback_data) -{ - DesktopCallback *desktop_callback; - - g_assert (NAUTILUS_IS_FILE (file)); - g_assert (callback_data != NULL); - - desktop_callback = callback_data; - g_assert (g_list_find (desktop_callback->non_ready_files, file) != NULL); - - desktop_callback_remove_file (desktop_callback, file); -} - -static void -desktop_directory_file_call_when_ready (NautilusFile *file, - NautilusFileAttributes attributes, - NautilusFileCallback callback, - gpointer callback_data) - -{ - NautilusDesktopDirectoryFile *desktop_file; - DesktopCallback search_key, *desktop_callback; - - desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); - - /* Check to be sure we aren't overwriting. */ - search_key.callback = callback; - search_key.callback_data = callback_data; - if (g_hash_table_lookup (desktop_file->details->callbacks, &search_key) != NULL) { - g_warning ("tried to add a new callback while an old one was pending"); - return; - } - - /* Create a desktop_callback record. */ - desktop_callback = g_new0 (DesktopCallback, 1); - nautilus_file_ref (file); - desktop_callback->desktop_file = desktop_file; - desktop_callback->callback = callback; - desktop_callback->callback_data = callback_data; - desktop_callback->initializing = TRUE; - - partition_attributes (attributes, - &desktop_callback->delegated_attributes, - &desktop_callback->non_delegated_attributes); - - desktop_callback->non_ready_files = g_list_prepend - (desktop_callback->non_ready_files, file); - desktop_callback->non_ready_files = g_list_prepend - (desktop_callback->non_ready_files, desktop_file->details->real_dir_file); - - /* Put it in the hash table. */ - g_hash_table_insert (desktop_file->details->callbacks, - desktop_callback, desktop_callback); - - /* Now connect to each file's call_when_ready. */ - nautilus_directory_call_when_ready_internal - (file->details->directory, file, - desktop_callback->non_delegated_attributes, - FALSE, NULL, ready_callback, desktop_callback); - nautilus_file_call_when_ready - (desktop_file->details->real_dir_file, - desktop_callback->delegated_attributes, - ready_callback, desktop_callback); - - desktop_callback->initializing = FALSE; - - /* Check if any files became read while we were connecting up - * the call_when_ready callbacks (also handles the pathological - * case where there are no files at all). - */ - desktop_callback_check_done (desktop_callback); - -} - -static void -desktop_directory_file_cancel_call_when_ready (NautilusFile *file, - NautilusFileCallback callback, - gpointer callback_data) -{ - NautilusDesktopDirectoryFile *desktop_file; - DesktopCallback search_key, *desktop_callback; - - desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); - - /* Find the entry in the table. */ - search_key.callback = callback; - search_key.callback_data = callback_data; - desktop_callback = g_hash_table_lookup (desktop_file->details->callbacks, &search_key); - if (desktop_callback == NULL) { - return; - } - - /* Remove from the hash table before working with it. */ - g_hash_table_remove (desktop_callback->desktop_file->details->callbacks, desktop_callback); - - /* Tell the real directory to cancel the call. */ - nautilus_directory_cancel_callback_internal - (file->details->directory, file, - NULL, ready_callback, desktop_callback); - - nautilus_file_cancel_call_when_ready - (desktop_file->details->real_dir_file, - ready_callback, desktop_callback); - - desktop_callback_destroy (desktop_callback); -} - -static gboolean -real_check_if_ready (NautilusFile *file, - NautilusFileAttributes attributes) -{ - return nautilus_directory_check_if_ready_internal - (file->details->directory, file, - attributes); -} - -static gboolean -desktop_directory_file_check_if_ready (NautilusFile *file, - NautilusFileAttributes attributes) -{ - NautilusFileAttributes delegated_attributes, non_delegated_attributes; - NautilusDesktopDirectoryFile *desktop_file; - - desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); - - partition_attributes (attributes, - &delegated_attributes, - &non_delegated_attributes); - - return real_check_if_ready (file, non_delegated_attributes) && - nautilus_file_check_if_ready (desktop_file->details->real_dir_file, - delegated_attributes); -} - -static gboolean -desktop_directory_file_get_item_count (NautilusFile *file, - guint *count, - gboolean *count_unreadable) -{ - NautilusDesktopDirectoryFile *desktop_file; - gboolean got_count; - - desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); - - got_count = nautilus_file_get_directory_item_count (desktop_file->details->real_dir_file, - count, - count_unreadable); - - if (count) { - *count += g_list_length (file->details->directory->details->file_list); - } - - return got_count; -} - -static NautilusRequestStatus -desktop_directory_file_get_deep_counts (NautilusFile *file, - guint *directory_count, - guint *file_count, - guint *unreadable_directory_count, - goffset *total_size) -{ - NautilusDesktopDirectoryFile *desktop_file; - NautilusRequestStatus status; - - desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); - - status = nautilus_file_get_deep_counts (desktop_file->details->real_dir_file, - directory_count, - file_count, - unreadable_directory_count, - total_size, - TRUE); - - if (file_count) { - *file_count += g_list_length (file->details->directory->details->file_list); - } - - return status; -} - -static gboolean -desktop_directory_file_get_date (NautilusFile *file, - NautilusDateType date_type, - time_t *date) -{ - NautilusDesktopDirectoryFile *desktop_file; - - desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); - - return nautilus_file_get_date (desktop_file->details->real_dir_file, - date_type, - date); -} - -static char * -desktop_directory_file_get_where_string (NautilusFile *file) -{ - return g_strdup (_("on the desktop")); -} - - -static void -monitor_destroy (gpointer data) -{ - DesktopMonitor *monitor = data; - - nautilus_file_monitor_remove - (NAUTILUS_FILE (monitor->desktop_file->details->real_dir_file), monitor); - g_free (monitor); -} - -static void -nautilus_desktop_directory_file_set_metadata (NautilusFile *file, - const char *key, - const char *value) -{ - nautilus_desktop_set_metadata_string (file, "directory", key, value); -} - -static void -nautilus_desktop_directory_file_set_metadata_as_list (NautilusFile *file, - const char *key, - char **value) -{ - nautilus_desktop_set_metadata_stringv (file, "directory", key, (const gchar **) value); -} - -static void -nautilus_desktop_directory_file_init (NautilusDesktopDirectoryFile *desktop_file) -{ - NautilusDesktopDirectory *desktop_directory; - NautilusDirectory *real_dir; - NautilusFile *real_dir_file; - - desktop_file->details = G_TYPE_INSTANCE_GET_PRIVATE (desktop_file, - NAUTILUS_TYPE_DESKTOP_DIRECTORY_FILE, - NautilusDesktopDirectoryFileDetails); - - desktop_directory = NAUTILUS_DESKTOP_DIRECTORY (nautilus_directory_get_by_uri (EEL_DESKTOP_URI)); - desktop_file->details->desktop_directory = desktop_directory; - - desktop_file->details->callbacks = g_hash_table_new - (desktop_callback_hash, desktop_callback_equal); - desktop_file->details->monitors = g_hash_table_new_full (NULL, NULL, - NULL, monitor_destroy); - - real_dir = nautilus_desktop_directory_get_real_directory (desktop_directory); - real_dir_file = nautilus_directory_get_corresponding_file (real_dir); - nautilus_directory_unref (real_dir); - - desktop_file->details->real_dir_file = real_dir_file; - g_signal_connect_object (real_dir_file, "changed", - G_CALLBACK (real_file_changed_callback), desktop_file, 0); -} - - -static void -desktop_callback_remove_file_cover (gpointer key, - gpointer value, - gpointer callback_data) -{ - desktop_callback_remove_file - (value, NAUTILUS_FILE (callback_data)); -} - - -static void -desktop_finalize (GObject *object) -{ - NautilusDesktopDirectoryFile *desktop_file; - NautilusDesktopDirectory *desktop_directory; - - desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (object); - desktop_directory = desktop_file->details->desktop_directory; - - /* Todo: ghash now safe? */ - eel_g_hash_table_safe_for_each - (desktop_file->details->callbacks, - desktop_callback_remove_file_cover, - desktop_file->details->real_dir_file); - - if (g_hash_table_size (desktop_file->details->callbacks) != 0) { - g_warning ("call_when_ready still pending when desktop virtual file is destroyed"); - } - - g_hash_table_destroy (desktop_file->details->callbacks); - g_hash_table_destroy (desktop_file->details->monitors); - - nautilus_file_unref (desktop_file->details->real_dir_file); - nautilus_directory_unref (NAUTILUS_DIRECTORY (desktop_directory)); - - G_OBJECT_CLASS (nautilus_desktop_directory_file_parent_class)->finalize (object); -} - -static void -nautilus_desktop_directory_file_class_init (NautilusDesktopDirectoryFileClass *klass) -{ - GObjectClass *object_class; - NautilusFileClass *file_class; - - object_class = G_OBJECT_CLASS (klass); - file_class = NAUTILUS_FILE_CLASS (klass); - - object_class->finalize = desktop_finalize; - - file_class->default_file_type = G_FILE_TYPE_DIRECTORY; - - file_class->monitor_add = desktop_directory_file_monitor_add; - file_class->monitor_remove = desktop_directory_file_monitor_remove; - file_class->call_when_ready = desktop_directory_file_call_when_ready; - file_class->cancel_call_when_ready = desktop_directory_file_cancel_call_when_ready; - file_class->check_if_ready = desktop_directory_file_check_if_ready; - file_class->get_item_count = desktop_directory_file_get_item_count; - file_class->get_deep_counts = desktop_directory_file_get_deep_counts; - file_class->get_date = desktop_directory_file_get_date; - file_class->get_where_string = desktop_directory_file_get_where_string; - file_class->set_metadata = nautilus_desktop_directory_file_set_metadata; - file_class->set_metadata_as_list = nautilus_desktop_directory_file_set_metadata_as_list; - - g_type_class_add_private (klass, sizeof (NautilusDesktopDirectoryFileDetails)); -} diff --git a/libnautilus-private/nautilus-desktop-directory-file.h b/libnautilus-private/nautilus-desktop-directory-file.h deleted file mode 100644 index 2a5097980..000000000 --- a/libnautilus-private/nautilus-desktop-directory-file.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - nautilus-desktop-directory-file.h: Subclass of NautilusFile to implement the - the case of the desktop directory - - Copyright (C) 2003 Red Hat, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, see . - - Author: Alexander Larsson -*/ - -#ifndef NAUTILUS_DESKTOP_DIRECTORY_FILE_H -#define NAUTILUS_DESKTOP_DIRECTORY_FILE_H - -#include - -#define NAUTILUS_TYPE_DESKTOP_DIRECTORY_FILE nautilus_desktop_directory_file_get_type() -#define NAUTILUS_DESKTOP_DIRECTORY_FILE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_DESKTOP_DIRECTORY_FILE, NautilusDesktopDirectoryFile)) -#define NAUTILUS_DESKTOP_DIRECTORY_FILE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DESKTOP_DIRECTORY_FILE, NautilusDesktopDirectoryFileClass)) -#define NAUTILUS_IS_DESKTOP_DIRECTORY_FILE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_DESKTOP_DIRECTORY_FILE)) -#define NAUTILUS_IS_DESKTOP_DIRECTORY_FILE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DESKTOP_DIRECTORY_FILE)) -#define NAUTILUS_DESKTOP_DIRECTORY_FILE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_DESKTOP_DIRECTORY_FILE, NautilusDesktopDirectoryFileClass)) - -typedef struct NautilusDesktopDirectoryFileDetails NautilusDesktopDirectoryFileDetails; - -typedef struct { - NautilusFile parent_slot; - NautilusDesktopDirectoryFileDetails *details; -} NautilusDesktopDirectoryFile; - -typedef struct { - NautilusFileClass parent_slot; -} NautilusDesktopDirectoryFileClass; - -GType nautilus_desktop_directory_file_get_type (void); - -#endif /* NAUTILUS_DESKTOP_DIRECTORY_FILE_H */ diff --git a/libnautilus-private/nautilus-desktop-directory.c b/libnautilus-private/nautilus-desktop-directory.c deleted file mode 100644 index 9f97baaa9..000000000 --- a/libnautilus-private/nautilus-desktop-directory.c +++ /dev/null @@ -1,571 +0,0 @@ -/* - nautilus-desktop-directory.c: Subclass of NautilusDirectory to implement - a virtual directory consisting of the desktop directory and the desktop - icons - - Copyright (C) 2003 Red Hat, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, see . - - Author: Alexander Larsson -*/ - -#include -#include "nautilus-desktop-directory.h" -#include "nautilus-desktop-directory-file.h" - -#include "nautilus-directory-private.h" -#include "nautilus-file.h" -#include "nautilus-file-private.h" -#include "nautilus-file-utilities.h" -#include "nautilus-global-preferences.h" -#include - -struct NautilusDesktopDirectoryDetails { - NautilusDirectory *real_directory; - GHashTable *callbacks; - GHashTable *monitors; -}; - -typedef struct { - NautilusDesktopDirectory *desktop_dir; - NautilusDirectoryCallback callback; - gpointer callback_data; - - NautilusFileAttributes wait_for_attributes; - gboolean wait_for_file_list; - - GList *non_ready_directories; - GList *merged_file_list; -} MergedCallback; - - -typedef struct { - NautilusDesktopDirectory *desktop_dir; - - gboolean monitor_hidden_files; - NautilusFileAttributes monitor_attributes; -} MergedMonitor; - -static void desktop_directory_changed_callback (gpointer data); - -G_DEFINE_TYPE_WITH_CODE (NautilusDesktopDirectory, nautilus_desktop_directory, NAUTILUS_TYPE_DIRECTORY, - nautilus_ensure_extension_points (); - g_io_extension_point_implement (NAUTILUS_DIRECTORY_PROVIDER_EXTENSION_POINT_NAME, - g_define_type_id, - NAUTILUS_DESKTOP_DIRECTORY_PROVIDER_NAME, - 0)); -static gboolean -desktop_contains_file (NautilusDirectory *directory, - NautilusFile *file) -{ - NautilusDesktopDirectory *desktop; - - desktop = NAUTILUS_DESKTOP_DIRECTORY (directory); - - if (nautilus_directory_contains_file (desktop->details->real_directory, file)) { - return TRUE; - } - - return file->details->directory == directory; -} - -static guint -merged_callback_hash (gconstpointer merged_callback_as_pointer) -{ - const MergedCallback *merged_callback; - - merged_callback = merged_callback_as_pointer; - return GPOINTER_TO_UINT (merged_callback->callback) - ^ GPOINTER_TO_UINT (merged_callback->callback_data); -} - -static gboolean -merged_callback_equal (gconstpointer merged_callback_as_pointer, - gconstpointer merged_callback_as_pointer_2) -{ - const MergedCallback *merged_callback, *merged_callback_2; - - merged_callback = merged_callback_as_pointer; - merged_callback_2 = merged_callback_as_pointer_2; - - return merged_callback->callback == merged_callback_2->callback - && merged_callback->callback_data == merged_callback_2->callback_data; -} - -static void -merged_callback_destroy (MergedCallback *merged_callback) -{ - g_assert (merged_callback != NULL); - g_assert (NAUTILUS_IS_DESKTOP_DIRECTORY (merged_callback->desktop_dir)); - - g_list_free (merged_callback->non_ready_directories); - nautilus_file_list_free (merged_callback->merged_file_list); - g_free (merged_callback); -} - -static void -merged_callback_check_done (MergedCallback *merged_callback) -{ - /* Check if we are ready. */ - if (merged_callback->non_ready_directories != NULL) { - return; - } - - /* Remove from the hash table before sending it. */ - g_hash_table_steal (merged_callback->desktop_dir->details->callbacks, merged_callback); - - /* We are ready, so do the real callback. */ - (* merged_callback->callback) (NAUTILUS_DIRECTORY (merged_callback->desktop_dir), - merged_callback->merged_file_list, - merged_callback->callback_data); - - /* And we are done. */ - merged_callback_destroy (merged_callback); -} - -static void -merged_callback_remove_directory (MergedCallback *merged_callback, - NautilusDirectory *directory) -{ - merged_callback->non_ready_directories = g_list_remove - (merged_callback->non_ready_directories, directory); - merged_callback_check_done (merged_callback); -} - -static void -directory_ready_callback (NautilusDirectory *directory, - GList *files, - gpointer callback_data) -{ - MergedCallback *merged_callback; - - g_assert (NAUTILUS_IS_DIRECTORY (directory)); - g_assert (callback_data != NULL); - - merged_callback = callback_data; - g_assert (g_list_find (merged_callback->non_ready_directories, directory) != NULL); - - /* Update based on this call. */ - merged_callback->merged_file_list = g_list_concat - (merged_callback->merged_file_list, - nautilus_file_list_copy (files)); - - /* Check if we are ready. */ - merged_callback_remove_directory (merged_callback, directory); -} - -static void -desktop_call_when_ready (NautilusDirectory *directory, - NautilusFileAttributes file_attributes, - gboolean wait_for_file_list, - NautilusDirectoryCallback callback, - gpointer callback_data) -{ - NautilusDesktopDirectory *desktop; - MergedCallback search_key, *merged_callback; - - desktop = NAUTILUS_DESKTOP_DIRECTORY (directory); - - /* Check to be sure we aren't overwriting. */ - search_key.callback = callback; - search_key.callback_data = callback_data; - if (g_hash_table_lookup (desktop->details->callbacks, &search_key) != NULL) { - g_warning ("tried to add a new callback while an old one was pending"); - return; - } - - /* Create a merged_callback record. */ - merged_callback = g_new0 (MergedCallback, 1); - merged_callback->desktop_dir = desktop; - merged_callback->callback = callback; - merged_callback->callback_data = callback_data; - merged_callback->wait_for_attributes = file_attributes; - merged_callback->wait_for_file_list = wait_for_file_list; - merged_callback->non_ready_directories = g_list_prepend - (merged_callback->non_ready_directories, directory); - merged_callback->non_ready_directories = g_list_prepend - (merged_callback->non_ready_directories, desktop->details->real_directory); - - - merged_callback->merged_file_list = g_list_concat (NULL, - nautilus_file_list_copy (directory->details->file_list)); - - /* Put it in the hash table. */ - g_hash_table_insert (desktop->details->callbacks, - merged_callback, merged_callback); - - /* Now tell all the directories about it. */ - nautilus_directory_call_when_ready - (desktop->details->real_directory, - merged_callback->wait_for_attributes, - merged_callback->wait_for_file_list, - directory_ready_callback, merged_callback); - nautilus_directory_call_when_ready_internal - (directory, - NULL, - merged_callback->wait_for_attributes, - merged_callback->wait_for_file_list, - directory_ready_callback, - NULL, - merged_callback); - -} - -static void -desktop_cancel_callback (NautilusDirectory *directory, - NautilusDirectoryCallback callback, - gpointer callback_data) -{ - NautilusDesktopDirectory *desktop; - MergedCallback search_key, *merged_callback; - GList *node; - - desktop = NAUTILUS_DESKTOP_DIRECTORY (directory); - - /* Find the entry in the table. */ - search_key.callback = callback; - search_key.callback_data = callback_data; - merged_callback = g_hash_table_lookup (desktop->details->callbacks, &search_key); - if (merged_callback == NULL) { - return; - } - - /* Remove from the hash table before working with it. */ - g_hash_table_steal (merged_callback->desktop_dir->details->callbacks, merged_callback); - - /* Tell all the directories to cancel the call. */ - for (node = merged_callback->non_ready_directories; node != NULL; node = node->next) { - nautilus_directory_cancel_callback - (node->data, - directory_ready_callback, merged_callback); - } - merged_callback_destroy (merged_callback); -} - -static void -merged_monitor_destroy (MergedMonitor *monitor) -{ - NautilusDesktopDirectory *desktop; - - desktop = monitor->desktop_dir; - - /* Call through to the real directory remove calls. */ - nautilus_directory_file_monitor_remove (desktop->details->real_directory, monitor); - - nautilus_directory_monitor_remove_internal (NAUTILUS_DIRECTORY (desktop), NULL, monitor); - - g_free (monitor); -} - -static void -build_merged_callback_list (NautilusDirectory *directory, - GList *file_list, - gpointer callback_data) -{ - GList **merged_list; - - merged_list = callback_data; - *merged_list = g_list_concat (*merged_list, - nautilus_file_list_copy (file_list)); -} - -static void -desktop_monitor_add (NautilusDirectory *directory, - gconstpointer client, - gboolean monitor_hidden_files, - NautilusFileAttributes file_attributes, - NautilusDirectoryCallback callback, - gpointer callback_data) -{ - NautilusDesktopDirectory *desktop; - MergedMonitor *monitor; - GList *merged_callback_list; - - desktop = NAUTILUS_DESKTOP_DIRECTORY (directory); - - /* Map the client to a unique value so this doesn't interfere - * with direct monitoring of the directory by the same client. - */ - monitor = g_hash_table_lookup (desktop->details->monitors, client); - if (monitor != NULL) { - g_assert (monitor->desktop_dir == desktop); - } else { - monitor = g_new0 (MergedMonitor, 1); - monitor->desktop_dir = desktop; - g_hash_table_insert (desktop->details->monitors, - (gpointer) client, monitor); - } - monitor->monitor_hidden_files = monitor_hidden_files; - monitor->monitor_attributes = file_attributes; - - /* Call through to the real directory add calls. */ - merged_callback_list = NULL; - - /* Call up to real dir */ - nautilus_directory_file_monitor_add - (desktop->details->real_directory, monitor, - monitor_hidden_files, - file_attributes, - build_merged_callback_list, &merged_callback_list); - - /* Handle the desktop part */ - merged_callback_list = g_list_concat (merged_callback_list, - nautilus_file_list_copy (directory->details->file_list)); - - - if (callback != NULL) { - (* callback) (directory, merged_callback_list, callback_data); - } - nautilus_file_list_free (merged_callback_list); -} - -static void -desktop_monitor_remove (NautilusDirectory *directory, - gconstpointer client) -{ - NautilusDesktopDirectory *desktop; - MergedMonitor *monitor; - - desktop = NAUTILUS_DESKTOP_DIRECTORY (directory); - - monitor = g_hash_table_lookup (desktop->details->monitors, client); - if (monitor == NULL) { - return; - } - - g_hash_table_remove (desktop->details->monitors, client); -} - -static void -desktop_force_reload (NautilusDirectory *directory) -{ - NautilusDesktopDirectory *desktop; - - desktop = NAUTILUS_DESKTOP_DIRECTORY (directory); - - nautilus_directory_force_reload (desktop->details->real_directory); - - /* We don't invalidate the files in desktop, since they are always - up to date. (And we don't ever want to mark them invalid.) */ -} - -static gboolean -desktop_are_all_files_seen (NautilusDirectory *directory) -{ - NautilusDesktopDirectory *desktop; - - desktop = NAUTILUS_DESKTOP_DIRECTORY (directory); - - if (!nautilus_directory_are_all_files_seen (desktop->details->real_directory)) { - return FALSE; - } - - return TRUE; -} - -static gboolean -desktop_is_not_empty (NautilusDirectory *directory) -{ - NautilusDesktopDirectory *desktop; - - desktop = NAUTILUS_DESKTOP_DIRECTORY (directory); - - if (nautilus_directory_is_not_empty (desktop->details->real_directory)) { - return TRUE; - } - - return directory->details->file_list != NULL; -} - -static GList * -desktop_get_file_list (NautilusDirectory *directory) -{ - GList *real_dir_file_list, *desktop_dir_file_list = NULL; - - real_dir_file_list = nautilus_directory_get_file_list - (NAUTILUS_DESKTOP_DIRECTORY (directory)->details->real_directory); - desktop_dir_file_list = NAUTILUS_DIRECTORY_CLASS (nautilus_desktop_directory_parent_class)->get_file_list (directory); - - return g_list_concat (real_dir_file_list, desktop_dir_file_list); -} - -NautilusDirectory * -nautilus_desktop_directory_get_real_directory (NautilusDesktopDirectory *desktop) -{ - nautilus_directory_ref (desktop->details->real_directory); - return desktop->details->real_directory; -} - - -static void -desktop_finalize (GObject *object) -{ - NautilusDesktopDirectory *desktop; - - desktop = NAUTILUS_DESKTOP_DIRECTORY (object); - - nautilus_directory_unref (desktop->details->real_directory); - - g_hash_table_destroy (desktop->details->callbacks); - g_hash_table_destroy (desktop->details->monitors); - g_free (desktop->details); - - g_signal_handlers_disconnect_by_func (nautilus_preferences, - desktop_directory_changed_callback, - desktop); - - G_OBJECT_CLASS (nautilus_desktop_directory_parent_class)->finalize (object); -} - -static void -done_loading_callback (NautilusDirectory *real_directory, - NautilusDesktopDirectory *desktop) -{ - nautilus_directory_emit_done_loading (NAUTILUS_DIRECTORY (desktop)); -} - - -static void -forward_files_added_cover (NautilusDirectory *real_directory, - GList *files, - gpointer callback_data) -{ - nautilus_directory_emit_files_added (NAUTILUS_DIRECTORY (callback_data), files); -} - -static void -forward_files_changed_cover (NautilusDirectory *real_directory, - GList *files, - gpointer callback_data) -{ - nautilus_directory_emit_files_changed (NAUTILUS_DIRECTORY (callback_data), files); -} - -static void -update_desktop_directory (NautilusDesktopDirectory *desktop) -{ - char *desktop_path; - char *desktop_uri; - NautilusDirectory *real_directory; - - real_directory = desktop->details->real_directory; - if (real_directory != NULL) { - g_hash_table_foreach_remove (desktop->details->callbacks, (GHRFunc) gtk_true, NULL); - g_hash_table_foreach_remove (desktop->details->monitors, (GHRFunc) gtk_true, NULL); - - g_signal_handlers_disconnect_by_func (real_directory, done_loading_callback, desktop); - g_signal_handlers_disconnect_by_func (real_directory, forward_files_added_cover, desktop); - g_signal_handlers_disconnect_by_func (real_directory, forward_files_changed_cover, desktop); - - nautilus_directory_unref (real_directory); - } - - desktop_path = nautilus_get_desktop_directory (); - desktop_uri = g_filename_to_uri (desktop_path, NULL, NULL); - real_directory = nautilus_directory_get_by_uri (desktop_uri); - g_free (desktop_uri); - g_free (desktop_path); - - g_signal_connect_object (real_directory, "done-loading", - G_CALLBACK (done_loading_callback), desktop, 0); - g_signal_connect_object (real_directory, "files-added", - G_CALLBACK (forward_files_added_cover), desktop, 0); - g_signal_connect_object (real_directory, "files-changed", - G_CALLBACK (forward_files_changed_cover), desktop, 0); - - desktop->details->real_directory = real_directory; -} - -static NautilusFile * -real_new_file_from_filename (NautilusDirectory *directory, - const char *filename, - gboolean self_owned) -{ - NautilusFile *file; - - g_assert (NAUTILUS_IS_DIRECTORY (directory)); - g_assert (filename != NULL); - g_assert (filename[0] != '\0'); - - if (self_owned) { - file = NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_DESKTOP_DIRECTORY_FILE, NULL)); - } else { - g_critical ("Accessing desktop uris directly is not supported."); - - return NULL; - } - - nautilus_file_set_directory (file, directory); - - return file; -} - -static gboolean -real_handles_location (GFile *location) -{ - g_autofree gchar *uri; - - uri = g_file_get_uri (location); - - return eel_uri_is_desktop (uri); -} - -static void -desktop_directory_changed_callback (gpointer data) -{ - update_desktop_directory (NAUTILUS_DESKTOP_DIRECTORY (data)); - nautilus_directory_force_reload (NAUTILUS_DIRECTORY (data)); -} - -static void -nautilus_desktop_directory_init (NautilusDesktopDirectory *desktop) -{ - desktop->details = g_new0 (NautilusDesktopDirectoryDetails, 1); - - desktop->details->callbacks = g_hash_table_new_full - (merged_callback_hash, merged_callback_equal, - NULL, (GDestroyNotify)merged_callback_destroy); - desktop->details->monitors = g_hash_table_new_full (NULL, NULL, - NULL, (GDestroyNotify)merged_monitor_destroy); - - update_desktop_directory (NAUTILUS_DESKTOP_DIRECTORY (desktop)); -} - -static void -nautilus_desktop_directory_class_init (NautilusDesktopDirectoryClass *class) -{ - NautilusDirectoryClass *directory_class; - - directory_class = NAUTILUS_DIRECTORY_CLASS (class); - - G_OBJECT_CLASS (class)->finalize = desktop_finalize; - - directory_class->contains_file = desktop_contains_file; - directory_class->call_when_ready = desktop_call_when_ready; - directory_class->cancel_callback = desktop_cancel_callback; - directory_class->file_monitor_add = desktop_monitor_add; - directory_class->file_monitor_remove = desktop_monitor_remove; - directory_class->force_reload = desktop_force_reload; - directory_class->are_all_files_seen = desktop_are_all_files_seen; - directory_class->is_not_empty = desktop_is_not_empty; - directory_class->new_file_from_filename = real_new_file_from_filename; - directory_class->handles_location = real_handles_location; - /* Override get_file_list so that we can return the list of files - * in NautilusDesktopDirectory->details->real_directory, - * in addition to the list of standard desktop icons on the desktop. - */ - directory_class->get_file_list = desktop_get_file_list; -} - diff --git a/libnautilus-private/nautilus-desktop-directory.h b/libnautilus-private/nautilus-desktop-directory.h deleted file mode 100644 index 9e9dc4949..000000000 --- a/libnautilus-private/nautilus-desktop-directory.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - nautilus-desktop-directory.h: Subclass of NautilusDirectory to implement - a virtual directory consisting of the desktop directory and the desktop - icons - - Copyright (C) 2003 Red Hat, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, see . - - Author: Alexander Larsson -*/ - -#ifndef NAUTILUS_DESKTOP_DIRECTORY_H -#define NAUTILUS_DESKTOP_DIRECTORY_H - -#include - -#define NAUTILUS_TYPE_DESKTOP_DIRECTORY nautilus_desktop_directory_get_type() -#define NAUTILUS_DESKTOP_DIRECTORY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_DESKTOP_DIRECTORY, NautilusDesktopDirectory)) -#define NAUTILUS_DESKTOP_DIRECTORY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DESKTOP_DIRECTORY, NautilusDesktopDirectoryClass)) -#define NAUTILUS_IS_DESKTOP_DIRECTORY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_DESKTOP_DIRECTORY)) -#define NAUTILUS_IS_DESKTOP_DIRECTORY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DESKTOP_DIRECTORY)) -#define NAUTILUS_DESKTOP_DIRECTORY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_DESKTOP_DIRECTORY, NautilusDesktopDirectoryClass)) - -#define NAUTILUS_DESKTOP_DIRECTORY_PROVIDER_NAME "desktop-directory-provider" - -typedef struct NautilusDesktopDirectoryDetails NautilusDesktopDirectoryDetails; - -typedef struct { - NautilusDirectory parent_slot; - NautilusDesktopDirectoryDetails *details; -} NautilusDesktopDirectory; - -typedef struct { - NautilusDirectoryClass parent_slot; - -} NautilusDesktopDirectoryClass; - -GType nautilus_desktop_directory_get_type (void); -NautilusDirectory * nautilus_desktop_directory_get_real_directory (NautilusDesktopDirectory *desktop_directory); - -#endif /* NAUTILUS_DESKTOP_DIRECTORY_H */ diff --git a/libnautilus-private/nautilus-desktop-icon-file.c b/libnautilus-private/nautilus-desktop-icon-file.c deleted file mode 100644 index 3519d0476..000000000 --- a/libnautilus-private/nautilus-desktop-icon-file.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - nautilus-desktop-icon-file.c: Subclass of NautilusFile to help implement the - virtual desktop icons. - - Copyright (C) 2003 Red Hat, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, see . - - Author: Alexander Larsson -*/ - -#include -#include "nautilus-desktop-icon-file.h" - -#include "nautilus-desktop-metadata.h" -#include "nautilus-desktop-directory-file.h" -#include "nautilus-directory-notify.h" -#include "nautilus-directory-private.h" -#include "nautilus-file-attributes.h" -#include "nautilus-file-private.h" -#include "nautilus-file-utilities.h" -#include "nautilus-file-operations.h" -#include "nautilus-link.h" -#include "nautilus-file-undo-manager.h" -#include -#include "nautilus-desktop-directory.h" -#include -#include -#include - -struct NautilusDesktopIconFileDetails { - NautilusDesktopLink *link; -}; - -G_DEFINE_TYPE(NautilusDesktopIconFile, nautilus_desktop_icon_file, NAUTILUS_TYPE_FILE) - - -static void -desktop_icon_file_monitor_add (NautilusFile *file, - gconstpointer client, - NautilusFileAttributes attributes) -{ - nautilus_directory_monitor_add_internal - (file->details->directory, file, - client, TRUE, attributes, NULL, NULL); -} - -static void -desktop_icon_file_monitor_remove (NautilusFile *file, - gconstpointer client) -{ - nautilus_directory_monitor_remove_internal - (file->details->directory, file, client); -} - -static void -desktop_icon_file_call_when_ready (NautilusFile *file, - NautilusFileAttributes attributes, - NautilusFileCallback callback, - gpointer callback_data) -{ - nautilus_directory_call_when_ready_internal - (file->details->directory, file, - attributes, FALSE, NULL, callback, callback_data); -} - -static void -desktop_icon_file_cancel_call_when_ready (NautilusFile *file, - NautilusFileCallback callback, - gpointer callback_data) -{ - nautilus_directory_cancel_callback_internal - (file->details->directory, file, - NULL, callback, callback_data); -} - -static gboolean -desktop_icon_file_check_if_ready (NautilusFile *file, - NautilusFileAttributes attributes) -{ - return nautilus_directory_check_if_ready_internal - (file->details->directory, file, - attributes); -} - -static gboolean -desktop_icon_file_get_item_count (NautilusFile *file, - guint *count, - gboolean *count_unreadable) -{ - if (count != NULL) { - *count = 0; - } - if (count_unreadable != NULL) { - *count_unreadable = FALSE; - } - return TRUE; -} - -static NautilusRequestStatus -desktop_icon_file_get_deep_counts (NautilusFile *file, - guint *directory_count, - guint *file_count, - guint *unreadable_directory_count, - goffset *total_size) -{ - if (directory_count != NULL) { - *directory_count = 0; - } - if (file_count != NULL) { - *file_count = 0; - } - if (unreadable_directory_count != NULL) { - *unreadable_directory_count = 0; - } - if (total_size != NULL) { - *total_size = 0; - } - - return NAUTILUS_REQUEST_DONE; -} - -static gboolean -desktop_icon_file_get_date (NautilusFile *file, - NautilusDateType date_type, - time_t *date) -{ - NautilusDesktopIconFile *desktop_file; - - desktop_file = NAUTILUS_DESKTOP_ICON_FILE (file); - - return nautilus_desktop_link_get_date (desktop_file->details->link, - date_type, date); -} - -static char * -desktop_icon_file_get_where_string (NautilusFile *file) -{ - return g_strdup (_("on the desktop")); -} - -static void -nautilus_desktop_icon_file_init (NautilusDesktopIconFile *desktop_file) -{ - desktop_file->details = G_TYPE_INSTANCE_GET_PRIVATE (desktop_file, - NAUTILUS_TYPE_DESKTOP_ICON_FILE, - NautilusDesktopIconFileDetails); -} - -static void -update_info_from_link (NautilusDesktopIconFile *icon_file) -{ - NautilusFile *file; - NautilusDesktopLink *link; - char *display_name; - GMount *mount; - - file = NAUTILUS_FILE (icon_file); - - link = icon_file->details->link; - - if (link == NULL) { - return; - } - - eel_ref_str_unref (file->details->mime_type); - file->details->mime_type = eel_ref_str_get_unique ("application/x-nautilus-link"); - file->details->type = G_FILE_TYPE_SHORTCUT; - file->details->size = 0; - file->details->has_permissions = FALSE; - file->details->can_read = TRUE; - file->details->can_write = TRUE; - - file->details->can_mount = FALSE; - file->details->can_unmount = FALSE; - file->details->can_eject = FALSE; - if (file->details->mount) { - g_object_unref (file->details->mount); - } - mount = nautilus_desktop_link_get_mount (link); - file->details->mount = mount; - if (mount) { - file->details->can_unmount = g_mount_can_unmount (mount); - file->details->can_eject = g_mount_can_eject (mount); - } - - file->details->file_info_is_up_to_date = TRUE; - - display_name = nautilus_desktop_link_get_display_name (link); - nautilus_file_set_display_name (file, - display_name, NULL, TRUE); - g_free (display_name); - - if (file->details->icon != NULL) { - g_object_unref (file->details->icon); - } - file->details->icon = nautilus_desktop_link_get_icon (link); - g_free (file->details->activation_uri); - file->details->activation_uri = nautilus_desktop_link_get_activation_uri (link); - file->details->got_link_info = TRUE; - file->details->link_info_is_up_to_date = TRUE; - - file->details->directory_count = 0; - file->details->got_directory_count = TRUE; - file->details->directory_count_is_up_to_date = TRUE; -} - -void -nautilus_desktop_icon_file_update (NautilusDesktopIconFile *icon_file) -{ - NautilusFile *file; - - update_info_from_link (icon_file); - file = NAUTILUS_FILE (icon_file); - nautilus_file_changed (file); -} - -void -nautilus_desktop_icon_file_remove (NautilusDesktopIconFile *icon_file) -{ - NautilusFile *file; - GList list; - - icon_file->details->link = NULL; - - file = NAUTILUS_FILE (icon_file); - - /* ref here because we might be removing the last ref when we - * mark the file gone below, but we need to keep a ref at - * least long enough to send the change notification. - */ - nautilus_file_ref (file); - - file->details->is_gone = TRUE; - - list.data = file; - list.next = NULL; - list.prev = NULL; - - nautilus_directory_remove_file (file->details->directory, file); - nautilus_directory_emit_change_signals (file->details->directory, &list); - - nautilus_file_unref (file); -} - -NautilusDesktopIconFile * -nautilus_desktop_icon_file_new (NautilusDesktopLink *link) -{ - NautilusFile *file; - NautilusDirectory *directory; - NautilusDesktopIconFile *icon_file; - GList list; - char *name; - - directory = nautilus_directory_get_by_uri (EEL_DESKTOP_URI); - - file = NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_DESKTOP_ICON_FILE, NULL)); - -#ifdef NAUTILUS_FILE_DEBUG_REF - printf("%10p ref'd\n", file); - eazel_dump_stack_trace ("\t", 10); -#endif - - nautilus_file_set_directory (file, directory); - - icon_file = NAUTILUS_DESKTOP_ICON_FILE (file); - icon_file->details->link = link; - - name = nautilus_desktop_link_get_file_name (link); - file->details->name = eel_ref_str_new (name); - g_free (name); - - update_info_from_link (icon_file); - - nautilus_desktop_update_metadata_from_keyfile (file, file->details->name); - - nautilus_directory_add_file (directory, file); - - list.data = file; - list.next = NULL; - list.prev = NULL; - nautilus_directory_emit_files_added (directory, &list); - - return icon_file; -} - -/* Note: This can return NULL if the link was recently removed (i.e. unmounted) */ -NautilusDesktopLink * -nautilus_desktop_icon_file_get_link (NautilusDesktopIconFile *icon_file) -{ - if (icon_file->details->link) - return g_object_ref (icon_file->details->link); - else - return NULL; -} - -static void -nautilus_desktop_icon_file_unmount (NautilusFile *file, - GMountOperation *mount_op, - GCancellable *cancellable, - NautilusFileOperationCallback callback, - gpointer callback_data) -{ - NautilusDesktopIconFile *desktop_file; - GMount *mount; - - desktop_file = NAUTILUS_DESKTOP_ICON_FILE (file); - if (desktop_file) { - mount = nautilus_desktop_link_get_mount (desktop_file->details->link); - if (mount != NULL) { - nautilus_file_operations_unmount_mount (NULL, mount, FALSE, TRUE); - } - } - -} - -static void -nautilus_desktop_icon_file_eject (NautilusFile *file, - GMountOperation *mount_op, - GCancellable *cancellable, - NautilusFileOperationCallback callback, - gpointer callback_data) -{ - NautilusDesktopIconFile *desktop_file; - GMount *mount; - - desktop_file = NAUTILUS_DESKTOP_ICON_FILE (file); - if (desktop_file) { - mount = nautilus_desktop_link_get_mount (desktop_file->details->link); - if (mount != NULL) { - nautilus_file_operations_unmount_mount (NULL, mount, TRUE, TRUE); - } - } -} - -static char* -real_get_target_uri (NautilusFile *file) -{ - char *uri = NULL; - GFile *location; - NautilusDesktopLink *link; - - g_return_val_if_fail (NAUTILUS_IS_DESKTOP_ICON_FILE (file), NULL); - - link = nautilus_desktop_icon_file_get_link (NAUTILUS_DESKTOP_ICON_FILE (file)); - - if (link != NULL) { - location = nautilus_desktop_link_get_activation_location (link); - g_object_unref (link); - if (location != NULL) { - uri = g_file_get_uri (location); - g_object_unref (location); - - return uri; - } - } - - return NAUTILUS_FILE_CLASS (nautilus_desktop_icon_file_parent_class)->get_target_uri (file); -} - -static void -real_rename (NautilusFile *file, - const char *new_name, - NautilusFileOperationCallback callback, - gpointer callback_data) -{ - NautilusDesktopLink *link; - char *old_name; - gboolean success; - GError *error; - - g_return_if_fail (NAUTILUS_IS_FILE (file)); - g_return_if_fail (new_name != NULL); - g_return_if_fail (callback != NULL); - - /* Can't rename a file that's already gone. - * We need to check this here because there may be a new - * file with the same name. - */ - if (nautilus_file_rename_handle_file_gone (file, callback, callback_data)) { - return; - } - - link = nautilus_desktop_icon_file_get_link (NAUTILUS_DESKTOP_ICON_FILE (file)); - old_name = nautilus_file_get_display_name (file); - - if ((old_name != NULL && strcmp (new_name, old_name) == 0)) { - success = TRUE; - } else { - success = (link != NULL && nautilus_desktop_link_rename (link, new_name)); - } - - if (success) { - (* callback) (file, NULL, NULL, callback_data); - } else { - error = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, - _("Unable to rename desktop icon")); - (* callback) (file, NULL, error, callback_data); - g_error_free (error); - } - - g_free (old_name); - g_object_unref (link); - - return; -} - -static gboolean -real_can_rename (NautilusFile *file) -{ - NautilusDesktopLink *link; - gboolean can_rename; - - can_rename = NAUTILUS_FILE_CLASS (nautilus_desktop_icon_file_parent_class)->can_rename (file); - - if (!can_rename) - return FALSE; - - link = nautilus_desktop_icon_file_get_link (NAUTILUS_DESKTOP_ICON_FILE (file)); - - /* Certain types of links can't be renamed */ - if (link != NULL) { - can_rename = nautilus_desktop_link_can_rename (link); - g_object_unref (link); - } - - return can_rename; -} - -static gboolean -real_drag_can_accept_files (NautilusFile *drop_target_item) -{ - return TRUE; -} - -static void -real_invalidate_attributes_internal (NautilusFile *file, - NautilusFileAttributes attributes) -{ - /* Desktop icon files are always up to date. - * If we invalidate their attributes they - * will lose data, so we just ignore them. - */ - return; -} - -static gboolean -real_opens_in_view (NautilusFile *file) -{ - return TRUE; -} - -static gboolean -real_is_special_link (NautilusFile *file) -{ - return TRUE; -} - -static void -nautilus_desktop_icon_file_set_metadata (NautilusFile *file, - const char *key, - const char *value) -{ - nautilus_desktop_set_metadata_string (file, file->details->name, key, value); -} - -static void -nautilus_desktop_icon_file_set_metadata_as_list (NautilusFile *file, - const char *key, - char **value) -{ - nautilus_desktop_set_metadata_stringv (file, file->details->name, key, (const gchar **) value); -} - -static void -nautilus_desktop_icon_file_class_init (NautilusDesktopIconFileClass *klass) -{ - GObjectClass *object_class; - NautilusFileClass *file_class; - - object_class = G_OBJECT_CLASS (klass); - file_class = NAUTILUS_FILE_CLASS (klass); - - file_class->default_file_type = G_FILE_TYPE_DIRECTORY; - - file_class->monitor_add = desktop_icon_file_monitor_add; - file_class->monitor_remove = desktop_icon_file_monitor_remove; - file_class->call_when_ready = desktop_icon_file_call_when_ready; - file_class->cancel_call_when_ready = desktop_icon_file_cancel_call_when_ready; - file_class->check_if_ready = desktop_icon_file_check_if_ready; - file_class->get_item_count = desktop_icon_file_get_item_count; - file_class->get_deep_counts = desktop_icon_file_get_deep_counts; - file_class->get_date = desktop_icon_file_get_date; - file_class->get_where_string = desktop_icon_file_get_where_string; - file_class->set_metadata = nautilus_desktop_icon_file_set_metadata; - file_class->set_metadata_as_list = nautilus_desktop_icon_file_set_metadata_as_list; - file_class->unmount = nautilus_desktop_icon_file_unmount; - file_class->eject = nautilus_desktop_icon_file_eject; - file_class->can_rename = real_can_rename; - file_class->rename = real_rename; - file_class->get_target_uri = real_get_target_uri; - file_class->drag_can_accept_files = real_drag_can_accept_files; - file_class->invalidate_attributes_internal = real_invalidate_attributes_internal; - file_class->opens_in_view = real_opens_in_view; - file_class->is_special_link = real_is_special_link; - - g_type_class_add_private (object_class, sizeof(NautilusDesktopIconFileDetails)); -} diff --git a/libnautilus-private/nautilus-desktop-icon-file.h b/libnautilus-private/nautilus-desktop-icon-file.h deleted file mode 100644 index 8fe802796..000000000 --- a/libnautilus-private/nautilus-desktop-icon-file.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - nautilus-desktop-file.h: Subclass of NautilusFile to implement the - the case of a desktop icon file - - Copyright (C) 2003 Red Hat, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, see . - - Author: Alexander Larsson -*/ - -#ifndef NAUTILUS_DESKTOP_ICON_FILE_H -#define NAUTILUS_DESKTOP_ICON_FILE_H - -#include -#include - -#define NAUTILUS_TYPE_DESKTOP_ICON_FILE nautilus_desktop_icon_file_get_type() -#define NAUTILUS_DESKTOP_ICON_FILE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_DESKTOP_ICON_FILE, NautilusDesktopIconFile)) -#define NAUTILUS_DESKTOP_ICON_FILE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DESKTOP_ICON_FILE, NautilusDesktopIconFileClass)) -#define NAUTILUS_IS_DESKTOP_ICON_FILE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_DESKTOP_ICON_FILE)) -#define NAUTILUS_IS_DESKTOP_ICON_FILE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DESKTOP_ICON_FILE)) -#define NAUTILUS_DESKTOP_ICON_FILE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_DESKTOP_ICON_FILE, NautilusDesktopIconFileClass)) - -typedef struct NautilusDesktopIconFileDetails NautilusDesktopIconFileDetails; - -typedef struct { - NautilusFile parent_slot; - NautilusDesktopIconFileDetails *details; -} NautilusDesktopIconFile; - -typedef struct { - NautilusFileClass parent_slot; -} NautilusDesktopIconFileClass; - -GType nautilus_desktop_icon_file_get_type (void); - -NautilusDesktopIconFile *nautilus_desktop_icon_file_new (NautilusDesktopLink *link); -void nautilus_desktop_icon_file_update (NautilusDesktopIconFile *icon_file); -void nautilus_desktop_icon_file_remove (NautilusDesktopIconFile *icon_file); -NautilusDesktopLink *nautilus_desktop_icon_file_get_link (NautilusDesktopIconFile *icon_file); - -#endif /* NAUTILUS_DESKTOP_ICON_FILE_H */ diff --git a/libnautilus-private/nautilus-desktop-link-monitor.c b/libnautilus-private/nautilus-desktop-link-monitor.c deleted file mode 100644 index 21b0cd69f..000000000 --- a/libnautilus-private/nautilus-desktop-link-monitor.c +++ /dev/null @@ -1,430 +0,0 @@ -/* - nautilus-desktop-link-monitor.c: singleton thatn manages the links - - Copyright (C) 2003 Red Hat, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, see . - - Author: Alexander Larsson -*/ - -#include -#include "nautilus-desktop-link-monitor.h" -#include "nautilus-desktop-link.h" -#include "nautilus-desktop-icon-file.h" -#include "nautilus-directory.h" -#include "nautilus-desktop-directory.h" -#include "nautilus-global-preferences.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -struct NautilusDesktopLinkMonitorDetails { - GVolumeMonitor *volume_monitor; - NautilusDirectory *desktop_dir; - - NautilusDesktopLink *home_link; - NautilusDesktopLink *trash_link; - NautilusDesktopLink *network_link; - - GList *mount_links; -}; - -G_DEFINE_TYPE (NautilusDesktopLinkMonitor, nautilus_desktop_link_monitor, G_TYPE_OBJECT); - -static NautilusDesktopLinkMonitor *the_link_monitor = NULL; - -void -nautilus_desktop_link_monitor_shutdown (void) -{ - g_clear_object (&the_link_monitor); -} - -NautilusDesktopLinkMonitor * -nautilus_desktop_link_monitor_get (void) -{ - if (the_link_monitor == NULL) { - g_object_new (NAUTILUS_TYPE_DESKTOP_LINK_MONITOR, NULL); - eel_debug_call_at_shutdown (nautilus_desktop_link_monitor_shutdown); - } - return the_link_monitor; -} - -static gboolean -volume_file_name_used (NautilusDesktopLinkMonitor *monitor, - const char *name) -{ - GList *l; - char *other_name; - gboolean same; - - for (l = monitor->details->mount_links; l != NULL; l = l->next) { - other_name = nautilus_desktop_link_get_file_name (l->data); - same = strcmp (name, other_name) == 0; - g_free (other_name); - - if (same) { - return TRUE; - } - } - - return FALSE; -} - -char * -nautilus_desktop_link_monitor_make_filename_unique (NautilusDesktopLinkMonitor *monitor, - const char *filename) -{ - char *unique_name; - int i; - - i = 2; - unique_name = g_strdup (filename); - while (volume_file_name_used (monitor, unique_name)) { - g_free (unique_name); - unique_name = g_strdup_printf ("%s.%d", filename, i++); - } - return unique_name; -} - -static gboolean -has_mount (NautilusDesktopLinkMonitor *monitor, - GMount *mount) -{ - gboolean ret; - GMount *other_mount; - GList *l; - - ret = FALSE; - - for (l = monitor->details->mount_links; l != NULL; l = l->next) { - other_mount = nautilus_desktop_link_get_mount (l->data); - if (mount == other_mount) { - g_object_unref (other_mount); - ret = TRUE; - break; - } - g_object_unref (other_mount); - } - - return ret; -} - -static void -create_mount_link (NautilusDesktopLinkMonitor *monitor, - GMount *mount) -{ - NautilusDesktopLink *link; - - if (has_mount (monitor, mount)) - return; - - if ((!g_mount_is_shadowed (mount)) && - g_settings_get_boolean (nautilus_desktop_preferences, - NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE)) { - link = nautilus_desktop_link_new_from_mount (mount); - monitor->details->mount_links = g_list_prepend (monitor->details->mount_links, link); - } -} - -static void -remove_mount_link (NautilusDesktopLinkMonitor *monitor, - GMount *mount) -{ - GList *l; - NautilusDesktopLink *link; - GMount *other_mount; - - link = NULL; - for (l = monitor->details->mount_links; l != NULL; l = l->next) { - other_mount = nautilus_desktop_link_get_mount (l->data); - if (mount == other_mount) { - g_object_unref (other_mount); - link = l->data; - break; - } - g_object_unref (other_mount); - } - - if (link) { - monitor->details->mount_links = g_list_remove (monitor->details->mount_links, link); - g_object_unref (link); - } -} - - - -static void -mount_added_callback (GVolumeMonitor *volume_monitor, - GMount *mount, - NautilusDesktopLinkMonitor *monitor) -{ - create_mount_link (monitor, mount); -} - - -static void -mount_removed_callback (GVolumeMonitor *volume_monitor, - GMount *mount, - NautilusDesktopLinkMonitor *monitor) -{ - remove_mount_link (monitor, mount); -} - -static void -mount_changed_callback (GVolumeMonitor *volume_monitor, - GMount *mount, - NautilusDesktopLinkMonitor *monitor) -{ - /* TODO: update the mount with other details */ - - /* remove a mount if it goes into the shadows */ - if (g_mount_is_shadowed (mount) && has_mount (monitor, mount)) { - remove_mount_link (monitor, mount); - }} - -static void -update_link_visibility (NautilusDesktopLinkMonitor *monitor, - NautilusDesktopLink **link_ref, - NautilusDesktopLinkType link_type, - const char *preference_key) -{ - if (g_settings_get_boolean (nautilus_desktop_preferences, preference_key)) { - if (*link_ref == NULL) { - *link_ref = nautilus_desktop_link_new (link_type); - } - } else { - if (*link_ref != NULL) { - g_object_unref (*link_ref); - *link_ref = NULL; - } - } -} - -static void -desktop_home_visible_changed (gpointer callback_data) -{ - NautilusDesktopLinkMonitor *monitor; - - monitor = NAUTILUS_DESKTOP_LINK_MONITOR (callback_data); - - update_link_visibility (NAUTILUS_DESKTOP_LINK_MONITOR (monitor), - &monitor->details->home_link, - NAUTILUS_DESKTOP_LINK_HOME, - NAUTILUS_PREFERENCES_DESKTOP_HOME_VISIBLE); -} - -static void -desktop_trash_visible_changed (gpointer callback_data) -{ - NautilusDesktopLinkMonitor *monitor; - - monitor = NAUTILUS_DESKTOP_LINK_MONITOR (callback_data); - - update_link_visibility (NAUTILUS_DESKTOP_LINK_MONITOR (callback_data), - &monitor->details->trash_link, - NAUTILUS_DESKTOP_LINK_TRASH, - NAUTILUS_PREFERENCES_DESKTOP_TRASH_VISIBLE); -} - -static void -desktop_network_visible_changed (gpointer callback_data) -{ - NautilusDesktopLinkMonitor *monitor; - - monitor = NAUTILUS_DESKTOP_LINK_MONITOR (callback_data); - - update_link_visibility (NAUTILUS_DESKTOP_LINK_MONITOR (callback_data), - &monitor->details->network_link, - NAUTILUS_DESKTOP_LINK_NETWORK, - NAUTILUS_PREFERENCES_DESKTOP_NETWORK_VISIBLE); -} - -static void -desktop_volumes_visible_changed (gpointer callback_data) -{ - NautilusDesktopLinkMonitor *monitor; - GList *l, *mounts; - - monitor = NAUTILUS_DESKTOP_LINK_MONITOR (callback_data); - - if (g_settings_get_boolean (nautilus_desktop_preferences, - NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE)) { - if (monitor->details->mount_links == NULL) { - mounts = g_volume_monitor_get_mounts (monitor->details->volume_monitor); - for (l = mounts; l != NULL; l = l->next) { - create_mount_link (monitor, l->data); - g_object_unref (l->data); - } - g_list_free (mounts); - } - } else { - g_list_foreach (monitor->details->mount_links, (GFunc)g_object_unref, NULL); - g_list_free (monitor->details->mount_links); - monitor->details->mount_links = NULL; - } -} - -static void -create_link_and_add_preference (NautilusDesktopLink **link_ref, - NautilusDesktopLinkType link_type, - const char *preference_key, - GCallback callback, - gpointer callback_data) -{ - char *detailed_signal; - - if (g_settings_get_boolean (nautilus_desktop_preferences, preference_key)) { - *link_ref = nautilus_desktop_link_new (link_type); - } - - detailed_signal = g_strconcat ("changed::", preference_key, NULL); - g_signal_connect_swapped (nautilus_desktop_preferences, - detailed_signal, - callback, callback_data); - - g_free (detailed_signal); -} - -static void -nautilus_desktop_link_monitor_init (NautilusDesktopLinkMonitor *monitor) -{ - GList *l, *mounts; - GMount *mount; - - monitor->details = G_TYPE_INSTANCE_GET_PRIVATE (monitor, NAUTILUS_TYPE_DESKTOP_LINK_MONITOR, - NautilusDesktopLinkMonitorDetails); - - the_link_monitor = monitor; - monitor->details->volume_monitor = g_volume_monitor_get (); - - /* We keep around a ref to the desktop dir */ - monitor->details->desktop_dir = nautilus_directory_get_by_uri (EEL_DESKTOP_URI); - - /* Default links */ - - create_link_and_add_preference (&monitor->details->home_link, - NAUTILUS_DESKTOP_LINK_HOME, - NAUTILUS_PREFERENCES_DESKTOP_HOME_VISIBLE, - G_CALLBACK (desktop_home_visible_changed), - monitor); - - create_link_and_add_preference (&monitor->details->trash_link, - NAUTILUS_DESKTOP_LINK_TRASH, - NAUTILUS_PREFERENCES_DESKTOP_TRASH_VISIBLE, - G_CALLBACK (desktop_trash_visible_changed), - monitor); - - create_link_and_add_preference (&monitor->details->network_link, - NAUTILUS_DESKTOP_LINK_NETWORK, - NAUTILUS_PREFERENCES_DESKTOP_NETWORK_VISIBLE, - G_CALLBACK (desktop_network_visible_changed), - monitor); - - /* Mount links */ - - mounts = g_volume_monitor_get_mounts (monitor->details->volume_monitor); - for (l = mounts; l != NULL; l = l->next) { - mount = l->data; - create_mount_link (monitor, mount); - g_object_unref (mount); - } - g_list_free (mounts); - - g_signal_connect_swapped (nautilus_desktop_preferences, - "changed::" NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE, - G_CALLBACK (desktop_volumes_visible_changed), - monitor); - - g_signal_connect_object (monitor->details->volume_monitor, "mount-added", - G_CALLBACK (mount_added_callback), monitor, 0); - g_signal_connect_object (monitor->details->volume_monitor, "mount-removed", - G_CALLBACK (mount_removed_callback), monitor, 0); - g_signal_connect_object (monitor->details->volume_monitor, "mount-changed", - G_CALLBACK (mount_changed_callback), monitor, 0); -} - -static void -remove_link_and_preference (NautilusDesktopLink **link_ref, - const char *preference_key, - GCallback callback, - gpointer callback_data) -{ - if (*link_ref != NULL) { - g_object_unref (*link_ref); - *link_ref = NULL; - } - - g_signal_handlers_disconnect_by_func (nautilus_desktop_preferences, - callback, callback_data); -} - -static void -desktop_link_monitor_finalize (GObject *object) -{ - NautilusDesktopLinkMonitor *monitor; - - monitor = NAUTILUS_DESKTOP_LINK_MONITOR (object); - - /* Default links */ - - remove_link_and_preference (&monitor->details->home_link, - NAUTILUS_PREFERENCES_DESKTOP_HOME_VISIBLE, - G_CALLBACK (desktop_home_visible_changed), - monitor); - - remove_link_and_preference (&monitor->details->trash_link, - NAUTILUS_PREFERENCES_DESKTOP_TRASH_VISIBLE, - G_CALLBACK (desktop_trash_visible_changed), - monitor); - - remove_link_and_preference (&monitor->details->network_link, - NAUTILUS_PREFERENCES_DESKTOP_NETWORK_VISIBLE, - G_CALLBACK (desktop_network_visible_changed), - monitor); - - /* Mounts */ - - g_list_foreach (monitor->details->mount_links, (GFunc)g_object_unref, NULL); - g_list_free (monitor->details->mount_links); - monitor->details->mount_links = NULL; - - nautilus_directory_unref (monitor->details->desktop_dir); - monitor->details->desktop_dir = NULL; - - g_signal_handlers_disconnect_by_func (nautilus_desktop_preferences, - desktop_volumes_visible_changed, - monitor); - - g_object_unref (monitor->details->volume_monitor); - - G_OBJECT_CLASS (nautilus_desktop_link_monitor_parent_class)->finalize (object); -} - -static void -nautilus_desktop_link_monitor_class_init (NautilusDesktopLinkMonitorClass *klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - object_class->finalize = desktop_link_monitor_finalize; - - g_type_class_add_private (klass, sizeof (NautilusDesktopLinkMonitorDetails)); -} diff --git a/libnautilus-private/nautilus-desktop-link-monitor.h b/libnautilus-private/nautilus-desktop-link-monitor.h deleted file mode 100644 index dc47aea0c..000000000 --- a/libnautilus-private/nautilus-desktop-link-monitor.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - nautilus-desktop-link-monitor.h: singleton that manages the desktop links - - Copyright (C) 2003 Red Hat, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, see . - - Author: Alexander Larsson -*/ - -#ifndef NAUTILUS_DESKTOP_LINK_MONITOR_H -#define NAUTILUS_DESKTOP_LINK_MONITOR_H - -#include -#include - -#define NAUTILUS_TYPE_DESKTOP_LINK_MONITOR nautilus_desktop_link_monitor_get_type() -#define NAUTILUS_DESKTOP_LINK_MONITOR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_DESKTOP_LINK_MONITOR, NautilusDesktopLinkMonitor)) -#define NAUTILUS_DESKTOP_LINK_MONITOR_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DESKTOP_LINK_MONITOR, NautilusDesktopLinkMonitorClass)) -#define NAUTILUS_IS_DESKTOP_LINK_MONITOR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_DESKTOP_LINK_MONITOR)) -#define NAUTILUS_IS_DESKTOP_LINK_MONITOR_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DESKTOP_LINK_MONITOR)) -#define NAUTILUS_DESKTOP_LINK_MONITOR_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_DESKTOP_LINK_MONITOR, NautilusDesktopLinkMonitorClass)) - -typedef struct NautilusDesktopLinkMonitorDetails NautilusDesktopLinkMonitorDetails; - -typedef struct { - GObject parent_slot; - NautilusDesktopLinkMonitorDetails *details; -} NautilusDesktopLinkMonitor; - -typedef struct { - GObjectClass parent_slot; -} NautilusDesktopLinkMonitorClass; - -GType nautilus_desktop_link_monitor_get_type (void); - -NautilusDesktopLinkMonitor * nautilus_desktop_link_monitor_get (void); -void nautilus_desktop_link_monitor_shutdown (void); - -/* Used by nautilus-desktop-link.c */ -char * nautilus_desktop_link_monitor_make_filename_unique (NautilusDesktopLinkMonitor *monitor, - const char *filename); - -#endif /* NAUTILUS_DESKTOP_LINK_MONITOR_H */ diff --git a/libnautilus-private/nautilus-desktop-link.c b/libnautilus-private/nautilus-desktop-link.c deleted file mode 100644 index f6decb6f9..000000000 --- a/libnautilus-private/nautilus-desktop-link.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - nautilus-desktop-link.c: Class that handles the links on the desktop - - Copyright (C) 2003 Red Hat, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, see . - - Author: Alexander Larsson -*/ - -#include -#include "nautilus-desktop-link.h" -#include "nautilus-desktop-link-monitor.h" -#include "nautilus-desktop-icon-file.h" -#include "nautilus-directory-private.h" -#include "nautilus-desktop-directory.h" -#include "nautilus-icon-names.h" -#include -#include -#include -#include -#include -#include - -struct NautilusDesktopLinkDetails { - NautilusDesktopLinkType type; - char *filename; - char *display_name; - GFile *activation_location; - GIcon *icon; - - NautilusDesktopIconFile *icon_file; - - /* Just for mount icons: */ - GMount *mount; -}; - -G_DEFINE_TYPE(NautilusDesktopLink, nautilus_desktop_link, G_TYPE_OBJECT) - -static void -create_icon_file (NautilusDesktopLink *link) -{ - link->details->icon_file = nautilus_desktop_icon_file_new (link); -} - -static void -nautilus_desktop_link_changed (NautilusDesktopLink *link) -{ - if (link->details->icon_file != NULL) { - nautilus_desktop_icon_file_update (link->details->icon_file); - } -} - -static void -mount_changed_callback (GMount *mount, NautilusDesktopLink *link) -{ - g_free (link->details->display_name); - if (link->details->activation_location) { - g_object_unref (link->details->activation_location); - } - if (link->details->icon) { - g_object_unref (link->details->icon); - } - - link->details->display_name = g_mount_get_name (mount); - link->details->activation_location = g_mount_get_default_location (mount); - link->details->icon = g_mount_get_icon (mount); - - nautilus_desktop_link_changed (link); -} - -static GIcon * -get_desktop_trash_icon (void) -{ - const gchar *icon_name; - - if (nautilus_trash_monitor_is_empty ()) { - icon_name = NAUTILUS_DESKTOP_ICON_TRASH; - } else { - icon_name = NAUTILUS_DESKTOP_ICON_TRASH_FULL; - } - - return g_themed_icon_new (icon_name); -} - -static void -trash_state_changed_callback (NautilusTrashMonitor *trash_monitor, - gboolean state, - gpointer callback_data) -{ - NautilusDesktopLink *link; - - link = NAUTILUS_DESKTOP_LINK (callback_data); - g_assert (link->details->type == NAUTILUS_DESKTOP_LINK_TRASH); - - if (link->details->icon) { - g_object_unref (link->details->icon); - } - link->details->icon = get_desktop_trash_icon (); - - nautilus_desktop_link_changed (link); -} - -static void -home_name_changed (gpointer callback_data) -{ - NautilusDesktopLink *link; - - link = NAUTILUS_DESKTOP_LINK (callback_data); - g_assert (link->details->type == NAUTILUS_DESKTOP_LINK_HOME); - - g_free (link->details->display_name); - link->details->display_name = g_settings_get_string (nautilus_desktop_preferences, - NAUTILUS_PREFERENCES_DESKTOP_HOME_NAME); - if (link->details->display_name[0] == 0) { - g_free (link->details->display_name); - link->details->display_name = g_strdup (_("Home")); - } - - nautilus_desktop_link_changed (link); -} - -static void -trash_name_changed (gpointer callback_data) -{ - NautilusDesktopLink *link; - - link = NAUTILUS_DESKTOP_LINK (callback_data); - g_assert (link->details->type == NAUTILUS_DESKTOP_LINK_TRASH); - - g_free (link->details->display_name); - link->details->display_name = g_settings_get_string (nautilus_desktop_preferences, - NAUTILUS_PREFERENCES_DESKTOP_TRASH_NAME); - nautilus_desktop_link_changed (link); -} - -static void -network_name_changed (gpointer callback_data) -{ - NautilusDesktopLink *link; - - link = NAUTILUS_DESKTOP_LINK (callback_data); - g_assert (link->details->type == NAUTILUS_DESKTOP_LINK_NETWORK); - - g_free (link->details->display_name); - link->details->display_name = g_settings_get_string (nautilus_desktop_preferences, - NAUTILUS_PREFERENCES_DESKTOP_NETWORK_NAME); - nautilus_desktop_link_changed (link); -} - -NautilusDesktopLink * -nautilus_desktop_link_new (NautilusDesktopLinkType type) -{ - NautilusDesktopLink *link; - - link = NAUTILUS_DESKTOP_LINK (g_object_new (NAUTILUS_TYPE_DESKTOP_LINK, NULL)); - - link->details->type = type; - switch (type) { - case NAUTILUS_DESKTOP_LINK_HOME: - link->details->filename = g_strdup ("home"); - link->details->display_name = g_settings_get_string (nautilus_desktop_preferences, - NAUTILUS_PREFERENCES_DESKTOP_HOME_NAME); - link->details->activation_location = g_file_new_for_path (g_get_home_dir ()); - link->details->icon = g_themed_icon_new (NAUTILUS_DESKTOP_ICON_HOME); - - g_signal_connect_swapped (nautilus_desktop_preferences, - "changed::" NAUTILUS_PREFERENCES_DESKTOP_HOME_NAME, - G_CALLBACK (home_name_changed), - link); - break; - - case NAUTILUS_DESKTOP_LINK_TRASH: - link->details->filename = g_strdup ("trash"); - link->details->display_name = g_settings_get_string (nautilus_desktop_preferences, - NAUTILUS_PREFERENCES_DESKTOP_TRASH_NAME); - link->details->activation_location = g_file_new_for_uri (EEL_TRASH_URI); - link->details->icon = get_desktop_trash_icon (); - - g_signal_connect_swapped (nautilus_desktop_preferences, - "changed::" NAUTILUS_PREFERENCES_DESKTOP_TRASH_NAME, - G_CALLBACK (trash_name_changed), - link); - g_signal_connect_object (nautilus_trash_monitor_get (), "trash-state-changed", - G_CALLBACK (trash_state_changed_callback), link, 0); - break; - - case NAUTILUS_DESKTOP_LINK_NETWORK: - link->details->filename = g_strdup ("network"); - link->details->display_name = g_settings_get_string (nautilus_desktop_preferences, - NAUTILUS_PREFERENCES_DESKTOP_NETWORK_NAME); - link->details->activation_location = g_file_new_for_uri ("network:///"); - link->details->icon = g_themed_icon_new (NAUTILUS_DESKTOP_ICON_NETWORK); - - g_signal_connect_swapped (nautilus_desktop_preferences, - "changed::" NAUTILUS_PREFERENCES_DESKTOP_NETWORK_NAME, - G_CALLBACK (network_name_changed), - link); - break; - - default: - case NAUTILUS_DESKTOP_LINK_MOUNT: - g_assert_not_reached(); - } - - create_icon_file (link); - - return link; -} - -NautilusDesktopLink * -nautilus_desktop_link_new_from_mount (GMount *mount) -{ - NautilusDesktopLink *link; - GVolume *volume; - char *name, *filename; - - link = NAUTILUS_DESKTOP_LINK (g_object_new (NAUTILUS_TYPE_DESKTOP_LINK, NULL)); - - link->details->type = NAUTILUS_DESKTOP_LINK_MOUNT; - - link->details->mount = g_object_ref (mount); - - /* We try to use the drive name to get somewhat stable filenames - for metadata */ - volume = g_mount_get_volume (mount); - if (volume != NULL) { - name = g_volume_get_name (volume); - g_object_unref (volume); - } else { - name = g_mount_get_name (mount); - } - - /* Replace slashes in name */ - filename = g_strconcat (g_strdelimit (name, "/", '-'), ".volume", NULL); - link->details->filename = - nautilus_desktop_link_monitor_make_filename_unique (nautilus_desktop_link_monitor_get (), - filename); - g_free (filename); - g_free (name); - - link->details->display_name = g_mount_get_name (mount); - - link->details->activation_location = g_mount_get_default_location (mount); - link->details->icon = g_mount_get_icon (mount); - - g_signal_connect_object (mount, "changed", - G_CALLBACK (mount_changed_callback), link, 0); - - create_icon_file (link); - - return link; -} - -GMount * -nautilus_desktop_link_get_mount (NautilusDesktopLink *link) -{ - if (link->details->mount) { - return g_object_ref (link->details->mount); - } - return NULL; -} - -NautilusDesktopLinkType -nautilus_desktop_link_get_link_type (NautilusDesktopLink *link) -{ - return link->details->type; -} - -char * -nautilus_desktop_link_get_file_name (NautilusDesktopLink *link) -{ - return g_strdup (link->details->filename); -} - -char * -nautilus_desktop_link_get_display_name (NautilusDesktopLink *link) -{ - return g_strdup (link->details->display_name); -} - -GIcon * -nautilus_desktop_link_get_icon (NautilusDesktopLink *link) -{ - if (link->details->icon != NULL) { - return g_object_ref (link->details->icon); - } - return NULL; -} - -GFile * -nautilus_desktop_link_get_activation_location (NautilusDesktopLink *link) -{ - if (link->details->activation_location) { - return g_object_ref (link->details->activation_location); - } - return NULL; -} - -char * -nautilus_desktop_link_get_activation_uri (NautilusDesktopLink *link) -{ - if (link->details->activation_location) { - return g_file_get_uri (link->details->activation_location); - } - return NULL; -} - - -gboolean -nautilus_desktop_link_get_date (NautilusDesktopLink *link, - NautilusDateType date_type, - time_t *date) -{ - return FALSE; -} - -gboolean -nautilus_desktop_link_can_rename (NautilusDesktopLink *link) -{ - return (link->details->type == NAUTILUS_DESKTOP_LINK_HOME || - link->details->type == NAUTILUS_DESKTOP_LINK_TRASH || - link->details->type == NAUTILUS_DESKTOP_LINK_NETWORK); -} - -gboolean -nautilus_desktop_link_rename (NautilusDesktopLink *link, - const char *name) -{ - switch (link->details->type) { - case NAUTILUS_DESKTOP_LINK_HOME: - g_settings_set_string (nautilus_desktop_preferences, - NAUTILUS_PREFERENCES_DESKTOP_HOME_NAME, - name); - break; - case NAUTILUS_DESKTOP_LINK_TRASH: - g_settings_set_string (nautilus_desktop_preferences, - NAUTILUS_PREFERENCES_DESKTOP_TRASH_NAME, - name); - break; - case NAUTILUS_DESKTOP_LINK_NETWORK: - g_settings_set_string (nautilus_desktop_preferences, - NAUTILUS_PREFERENCES_DESKTOP_NETWORK_NAME, - name); - break; - default: - g_assert_not_reached (); - /* FIXME: Do we want volume renaming? - * We didn't support that before. */ - break; - } - - return TRUE; -} - -static void -nautilus_desktop_link_init (NautilusDesktopLink *link) -{ - link->details = G_TYPE_INSTANCE_GET_PRIVATE (link, - NAUTILUS_TYPE_DESKTOP_LINK, - NautilusDesktopLinkDetails); -} - -static void -desktop_link_finalize (GObject *object) -{ - NautilusDesktopLink *link; - - link = NAUTILUS_DESKTOP_LINK (object); - - if (link->details->icon_file != NULL) { - nautilus_desktop_icon_file_remove (link->details->icon_file); - nautilus_file_unref (NAUTILUS_FILE (link->details->icon_file)); - link->details->icon_file = NULL; - } - - if (link->details->type == NAUTILUS_DESKTOP_LINK_HOME) { - g_signal_handlers_disconnect_by_func (nautilus_desktop_preferences, - home_name_changed, - link); - } - - if (link->details->type == NAUTILUS_DESKTOP_LINK_TRASH) { - g_signal_handlers_disconnect_by_func (nautilus_desktop_preferences, - trash_name_changed, - link); - } - - if (link->details->type == NAUTILUS_DESKTOP_LINK_NETWORK) { - g_signal_handlers_disconnect_by_func (nautilus_desktop_preferences, - network_name_changed, - link); - } - - if (link->details->type == NAUTILUS_DESKTOP_LINK_MOUNT) { - g_object_unref (link->details->mount); - } - - g_free (link->details->filename); - g_free (link->details->display_name); - if (link->details->activation_location) { - g_object_unref (link->details->activation_location); - } - if (link->details->icon) { - g_object_unref (link->details->icon); - } - - G_OBJECT_CLASS (nautilus_desktop_link_parent_class)->finalize (object); -} - -static void -nautilus_desktop_link_class_init (NautilusDesktopLinkClass *klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = desktop_link_finalize; - - g_type_class_add_private (object_class, sizeof(NautilusDesktopLinkDetails)); -} diff --git a/libnautilus-private/nautilus-desktop-link.h b/libnautilus-private/nautilus-desktop-link.h deleted file mode 100644 index 7c1025b40..000000000 --- a/libnautilus-private/nautilus-desktop-link.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - nautilus-desktop-link.h: Class that handles the links on the desktop - - Copyright (C) 2003 Red Hat, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, see . - - Author: Alexander Larsson -*/ - -#ifndef NAUTILUS_DESKTOP_LINK_H -#define NAUTILUS_DESKTOP_LINK_H - -#include -#include - -#define NAUTILUS_TYPE_DESKTOP_LINK nautilus_desktop_link_get_type() -#define NAUTILUS_DESKTOP_LINK(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_DESKTOP_LINK, NautilusDesktopLink)) -#define NAUTILUS_DESKTOP_LINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DESKTOP_LINK, NautilusDesktopLinkClass)) -#define NAUTILUS_IS_DESKTOP_LINK(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_DESKTOP_LINK)) -#define NAUTILUS_IS_DESKTOP_LINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DESKTOP_LINK)) -#define NAUTILUS_DESKTOP_LINK_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_DESKTOP_LINK, NautilusDesktopLinkClass)) - -typedef struct NautilusDesktopLinkDetails NautilusDesktopLinkDetails; - -typedef struct { - GObject parent_slot; - NautilusDesktopLinkDetails *details; -} NautilusDesktopLink; - -typedef struct { - GObjectClass parent_slot; -} NautilusDesktopLinkClass; - -typedef enum { - NAUTILUS_DESKTOP_LINK_HOME, - NAUTILUS_DESKTOP_LINK_TRASH, - NAUTILUS_DESKTOP_LINK_MOUNT, - NAUTILUS_DESKTOP_LINK_NETWORK -} NautilusDesktopLinkType; - -GType nautilus_desktop_link_get_type (void); - -NautilusDesktopLink * nautilus_desktop_link_new (NautilusDesktopLinkType type); -NautilusDesktopLink * nautilus_desktop_link_new_from_mount (GMount *mount); -NautilusDesktopLinkType nautilus_desktop_link_get_link_type (NautilusDesktopLink *link); -char * nautilus_desktop_link_get_file_name (NautilusDesktopLink *link); -char * nautilus_desktop_link_get_display_name (NautilusDesktopLink *link); -GIcon * nautilus_desktop_link_get_icon (NautilusDesktopLink *link); -GFile * nautilus_desktop_link_get_activation_location (NautilusDesktopLink *link); -char * nautilus_desktop_link_get_activation_uri (NautilusDesktopLink *link); -gboolean nautilus_desktop_link_get_date (NautilusDesktopLink *link, - NautilusDateType date_type, - time_t *date); -GMount * nautilus_desktop_link_get_mount (NautilusDesktopLink *link); -gboolean nautilus_desktop_link_can_rename (NautilusDesktopLink *link); -gboolean nautilus_desktop_link_rename (NautilusDesktopLink *link, - const char *name); - - -#endif /* NAUTILUS_DESKTOP_LINK_H */ diff --git a/libnautilus-private/nautilus-desktop-metadata.c b/libnautilus-private/nautilus-desktop-metadata.c deleted file mode 100644 index e9ef2d6b5..000000000 --- a/libnautilus-private/nautilus-desktop-metadata.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Nautilus - * - * Copyright (C) 2011 Red Hat, Inc. - * - * Nautilus is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * Nautilus is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; see the file COPYING. If not, - * see . - * - * Authors: Cosimo Cecchi - */ - -#include - -#include "nautilus-desktop-metadata.h" - -#include "nautilus-file-utilities.h" -#include "nautilus-keyfile-metadata.h" - -static gchar * -get_keyfile_path (void) -{ - gchar *xdg_dir, *retval; - - xdg_dir = nautilus_get_user_directory (); - retval = g_build_filename (xdg_dir, "desktop-metadata", NULL); - - g_free (xdg_dir); - - return retval; -} - -void -nautilus_desktop_set_metadata_string (NautilusFile *file, - const gchar *name, - const gchar *key, - const gchar *string) -{ - gchar *keyfile_filename; - - keyfile_filename = get_keyfile_path (); - - nautilus_keyfile_metadata_set_string (file, keyfile_filename, - name, key, string); - - g_free (keyfile_filename); -} - -void -nautilus_desktop_set_metadata_stringv (NautilusFile *file, - const char *name, - const char *key, - const char * const *stringv) -{ - gchar *keyfile_filename; - - keyfile_filename = get_keyfile_path (); - - nautilus_keyfile_metadata_set_stringv (file, keyfile_filename, - name, key, stringv); - - g_free (keyfile_filename); -} - -gboolean -nautilus_desktop_update_metadata_from_keyfile (NautilusFile *file, - const gchar *name) -{ - gchar *keyfile_filename; - gboolean result; - - keyfile_filename = get_keyfile_path (); - - result = nautilus_keyfile_metadata_update_from_keyfile (file, - keyfile_filename, - name); - - g_free (keyfile_filename); - return result; -} diff --git a/libnautilus-private/nautilus-desktop-metadata.h b/libnautilus-private/nautilus-desktop-metadata.h deleted file mode 100644 index f8c67d3cf..000000000 --- a/libnautilus-private/nautilus-desktop-metadata.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Nautilus - * - * Copyright (C) 2011 Red Hat, Inc. - * - * Nautilus is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * Nautilus is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; see the file COPYING. If not, - * see . - * - * Authors: Cosimo Cecchi - */ - -#ifndef __NAUTILUS_DESKTOP_METADATA_H__ -#define __NAUTILUS_DESKTOP_METADATA_H__ - -#include - -#include - -void nautilus_desktop_set_metadata_string (NautilusFile *file, - const gchar *name, - const gchar *key, - const gchar *string); - -void nautilus_desktop_set_metadata_stringv (NautilusFile *file, - const char *name, - const char *key, - const char * const *stringv); - -gboolean nautilus_desktop_update_metadata_from_keyfile (NautilusFile *file, - const gchar *name); - -#endif /* __NAUTILUS_DESKTOP_METADATA_H__ */ diff --git a/nautilus-desktop/Makefile.am b/nautilus-desktop/Makefile.am new file mode 100644 index 000000000..524146e8f --- /dev/null +++ b/nautilus-desktop/Makefile.am @@ -0,0 +1,58 @@ +include $(top_srcdir)/Makefile.shared + +bin_PROGRAMS= \ + nautilus-desktop \ + $(NULL) + +AM_CPPFLAGS = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/libnautilus-private \ + -I$(top_builddir)/libnautilus-private \ + -I$(top_srcdir)/libgd \ + -I$(top_srcdir)/src \ + -I$(top_builddir)/src \ + $(BASE_CFLAGS) \ + $(COMMON_CFLAGS) \ + $(NAUTILUS_CFLAGS) \ + $(WARNING_CFLAGS) \ + $(EXIF_CFLAGS) \ + $(EXEMPI_CFLAGS) \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DNAUTILUS_DATADIR=\""$(datadir)/nautilus"\" \ + -DPREFIX=\""$(prefix)"\" \ + -DVERSION="\"$(VERSION)\"" \ + $(DISABLE_DEPRECATED) \ + $(NULL) + +LDADD =\ + $(top_builddir)/src/libnautilus.la \ + $(NULL) + +nautilus_desktop_SOURCES= \ + main-desktop.c \ + nautilus-desktop-application.c \ + nautilus-desktop-application.h \ + nautilus-desktop-canvas-view.c \ + nautilus-desktop-canvas-view.h \ + nautilus-desktop-canvas-view-container.c \ + nautilus-desktop-canvas-view-container.h \ + nautilus-desktop-directory.c \ + nautilus-desktop-directory.h \ + nautilus-desktop-directory-file.c \ + nautilus-desktop-directory-file.h \ + nautilus-desktop-icon-file.c \ + nautilus-desktop-icon-file.h \ + nautilus-desktop-link.c \ + nautilus-desktop-link.h \ + nautilus-desktop-link-monitor.c \ + nautilus-desktop-link-monitor.h \ + nautilus-desktop-metadata.c \ + nautilus-desktop-metadata.h \ + nautilus-desktop-window.c \ + nautilus-desktop-window.h \ + nautilus-desktop-window-slot.c \ + nautilus-desktop-window-slot.h \ + $(NULL) + +-include $(top_srcdir)/git.mk diff --git a/nautilus-desktop/main-desktop.c b/nautilus-desktop/main-desktop.c new file mode 100644 index 000000000..b2e151b57 --- /dev/null +++ b/nautilus-desktop/main-desktop.c @@ -0,0 +1,38 @@ +#include + +#include "nautilus-desktop-application.h" +#include + +#include +#include + +#ifdef HAVE_LOCALE_H +#include +#endif +#include +#include +#include + +int +main (int argc, char *argv[]) +{ + NautilusDesktopApplication *application; + int retval; + + /* Initialize gettext support */ + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + g_set_prgname ("nautilus-desktop"); + + nautilus_register_resource (); + application = nautilus_desktop_application_new (); + + retval = g_application_run (G_APPLICATION (application), + argc, argv); + + g_object_unref (application); + + return retval; +} diff --git a/nautilus-desktop/nautilus-desktop-application.c b/nautilus-desktop/nautilus-desktop-application.c new file mode 100644 index 000000000..31ff6e603 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-application.c @@ -0,0 +1,243 @@ +/* nautilus-desktop-application.c + * + * Copyright (C) 2016 Carlos Soriano + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include "nautilus-desktop-application.h" +#include "nautilus-desktop-window.h" +#include "nautilus-desktop-directory.h" +#include "nautilus-file-utilities.h" + +#include "nautilus-freedesktop-generated.h" + +#include +#include +#include + +static NautilusFreedesktopFileManager1 *freedesktop_proxy = NULL; + +struct _NautilusDesktopApplication +{ + NautilusApplication parent_instance; + + GCancellable *freedesktop_cancellable; +}; + +G_DEFINE_TYPE (NautilusDesktopApplication, nautilus_desktop_application, NAUTILUS_TYPE_APPLICATION) + +static void +on_show_folders (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GError *error = NULL; + + nautilus_freedesktop_file_manager1_call_show_items_finish (freedesktop_proxy, + res, + &error); + if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + { + g_warning ("Unable to show items with File Manager freedesktop proxy: %s", error->message); + } + + g_clear_error (&error); +} + +static void +open_location_on_dbus (NautilusDesktopApplication *self, + const gchar *uri) +{ + const gchar *uris[] = { uri, NULL }; + + nautilus_freedesktop_file_manager1_call_show_folders (freedesktop_proxy, + uris, + "", + self->freedesktop_cancellable, + on_show_folders, + self); +} + +static void +open_location_full (NautilusApplication *app, + GFile *location, + NautilusWindowOpenFlags flags, + GList *selection, + NautilusWindow *target_window, + NautilusWindowSlot *target_slot) +{ + NautilusDesktopApplication *self = NAUTILUS_DESKTOP_APPLICATION (app); + gchar *uri; + + uri = g_file_get_uri (location); + if (eel_uri_is_desktop (uri) && target_window && + NAUTILUS_IS_DESKTOP_WINDOW (target_window)) + { + nautilus_window_open_location_full (target_window, location, flags, selection, NULL); + } + else + { + if (freedesktop_proxy) + { + open_location_on_dbus (self, uri); + } + else + { + g_warning ("cannot open folder on desktop, freedesktop bus not ready\n"); + } + } + + g_free (uri); +} + +static void +nautilus_application_set_desktop_visible (NautilusDesktopApplication *self, + gboolean visible) +{ + GtkWidget *desktop_window; + + if (visible) + { + nautilus_desktop_window_ensure (); + } + else + { + desktop_window = nautilus_desktop_window_get (); + if (desktop_window != NULL) + { + gtk_widget_destroy (desktop_window); + } + } +} + +static void +update_desktop_from_gsettings (NautilusDesktopApplication *self) +{ + GdkDisplay *display; + gboolean visible; + +#ifdef GDK_WINDOWING_X11 + display = gdk_display_get_default (); + visible = g_settings_get_boolean (gnome_background_preferences, + NAUTILUS_PREFERENCES_SHOW_DESKTOP); + if (!GDK_IS_X11_DISPLAY (display)) + { + if (visible) + { + g_warning ("Desktop icons only supported on X11. Desktop not created"); + } + + return; + } + + nautilus_application_set_desktop_visible (self, visible); + + return; +#endif + + g_warning ("Desktop icons only supported on X11. Desktop not created"); +} + +static void +init_desktop (NautilusDesktopApplication *self) +{ + g_signal_connect_swapped (gnome_background_preferences, "changed::" NAUTILUS_PREFERENCES_SHOW_DESKTOP, + G_CALLBACK (update_desktop_from_gsettings), + self); + update_desktop_from_gsettings (self); +} + +static void +nautilus_desktop_application_activate (GApplication *app) +{ + /* Do nothing */ +} + +static void +nautilus_desktop_application_startup (GApplication *app) +{ + NautilusDesktopApplication *self = NAUTILUS_DESKTOP_APPLICATION (app); + GError *error = NULL; + + nautilus_application_startup_common (NAUTILUS_APPLICATION (app)); + self->freedesktop_cancellable = g_cancellable_new (); + freedesktop_proxy = nautilus_freedesktop_file_manager1_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.FileManager1", + "/org/freedesktop/FileManager1", + self->freedesktop_cancellable, + &error); + + if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + { + g_warning ("Unable to create File Manager freedesktop proxy: %s", error->message); + } + + g_clear_error (&error); + + init_desktop (self); +} + +static void +nautilus_desktop_application_dispose (GObject *object) +{ + NautilusDesktopApplication *self = NAUTILUS_DESKTOP_APPLICATION (object); + + g_clear_object (&self->freedesktop_cancellable); + + + G_OBJECT_CLASS (nautilus_desktop_application_parent_class)->dispose (object); +} + +static void +nautilus_desktop_application_class_init (NautilusDesktopApplicationClass *klass) +{ + GApplicationClass *application_class = G_APPLICATION_CLASS (klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + NautilusApplicationClass *parent_class = NAUTILUS_APPLICATION_CLASS (klass); + + parent_class->open_location_full = open_location_full; + + application_class->startup = nautilus_desktop_application_startup; + application_class->activate = nautilus_desktop_application_activate; + + gobject_class->dispose = nautilus_desktop_application_dispose; +} + +static void +nautilus_desktop_ensure_builtins (void) +{ + /* Ensure the type so it can be registered early as a directory extension provider*/ + g_type_ensure (NAUTILUS_TYPE_DESKTOP_DIRECTORY); +} + +static void +nautilus_desktop_application_init (NautilusDesktopApplication *self) +{ + nautilus_ensure_extension_points (); + nautilus_ensure_extension_builtins (); + nautilus_desktop_ensure_builtins (); +} + +NautilusDesktopApplication * +nautilus_desktop_application_new (void) +{ + return g_object_new (NAUTILUS_TYPE_DESKTOP_APPLICATION, + "application-id", "org.gnome.NautilusDesktop", + NULL); +} + diff --git a/nautilus-desktop/nautilus-desktop-application.h b/nautilus-desktop/nautilus-desktop-application.h new file mode 100644 index 000000000..4f4c62c47 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-application.h @@ -0,0 +1,36 @@ +/* nautilus-desktop-application.h + * + * Copyright (C) 2016 Carlos Soriano + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NAUTILUS_DESKTOP_APPLICATION_H +#define NAUTILUS_DESKTOP_APPLICATION_H + +#include +#include "nautilus-application.h" + +G_BEGIN_DECLS + +#define NAUTILUS_TYPE_DESKTOP_APPLICATION (nautilus_desktop_application_get_type()) + +G_DECLARE_FINAL_TYPE (NautilusDesktopApplication, nautilus_desktop_application, NAUTILUS, DESKTOP_APPLICATION, NautilusApplication) + +NautilusDesktopApplication *nautilus_desktop_application_new (void); + +G_END_DECLS + +#endif /* NAUTILUS_DESKTOP_APPLICATION_H */ + diff --git a/nautilus-desktop/nautilus-desktop-canvas-view-container.c b/nautilus-desktop/nautilus-desktop-canvas-view-container.c new file mode 100644 index 000000000..23db902d2 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-canvas-view-container.c @@ -0,0 +1,199 @@ +/* nautilus-desktop-canvas-view-container.c + * + * Copyright (C) 2016 Carlos Soriano + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "nautilus-desktop-canvas-view-container.h" +#include "nautilus-desktop-icon-file.h" + +struct _NautilusDesktopCanvasViewContainer +{ + NautilusCanvasViewContainer parent_instance; +}; + +G_DEFINE_TYPE (NautilusDesktopCanvasViewContainer, nautilus_desktop_canvas_view_container, NAUTILUS_TYPE_CANVAS_VIEW_CONTAINER) + +/* Sort as follows: + * 0) home link + * 1) network link + * 2) mount links + * 3) other + * 4) trash link + */ +typedef enum { + SORT_HOME_LINK, + SORT_NETWORK_LINK, + SORT_MOUNT_LINK, + SORT_OTHER, + SORT_TRASH_LINK +} SortCategory; + +static SortCategory +get_sort_category (NautilusFile *file) +{ + NautilusDesktopLink *link; + SortCategory category; + + category = SORT_OTHER; + + if (NAUTILUS_IS_DESKTOP_ICON_FILE (file)) + { + link = nautilus_desktop_icon_file_get_link (NAUTILUS_DESKTOP_ICON_FILE (file)); + if (link != NULL) + { + switch (nautilus_desktop_link_get_link_type (link)) + { + case NAUTILUS_DESKTOP_LINK_HOME: + category = SORT_HOME_LINK; + break; + case NAUTILUS_DESKTOP_LINK_MOUNT: + category = SORT_MOUNT_LINK; + break; + case NAUTILUS_DESKTOP_LINK_TRASH: + category = SORT_TRASH_LINK; + break; + case NAUTILUS_DESKTOP_LINK_NETWORK: + category = SORT_NETWORK_LINK; + break; + default: + category = SORT_OTHER; + break; + } + g_object_unref (link); + } + } + + return category; +} + +static int +real_compare_icons (NautilusCanvasContainer *container, + NautilusCanvasIconData *data_a, + NautilusCanvasIconData *data_b) +{ + NautilusFile *file_a; + NautilusFile *file_b; + NautilusFilesView *directory_view; + SortCategory category_a, category_b; + + file_a = (NautilusFile *) data_a; + file_b = (NautilusFile *) data_b; + + directory_view = NAUTILUS_FILES_VIEW (NAUTILUS_CANVAS_VIEW_CONTAINER (container)->view); + g_return_val_if_fail (directory_view != NULL, 0); + + category_a = get_sort_category (file_a); + category_b = get_sort_category (file_b); + + if (category_a == category_b) + { + return nautilus_file_compare_for_sort (file_a, + file_b, + NAUTILUS_FILE_SORT_BY_DISPLAY_NAME, + nautilus_files_view_should_sort_directories_first (directory_view), + FALSE); + } + + if (category_a < category_b) + { + return -1; + } + else + { + return +1; + } +} + +static void +real_get_icon_text (NautilusCanvasContainer *container, + NautilusCanvasIconData *data, + char **editable_text, + char **additional_text, + gboolean include_invisible) +{ + NautilusFile *file; + gboolean use_additional; + + file = NAUTILUS_FILE (data); + + g_assert (NAUTILUS_IS_FILE (file)); + g_assert (editable_text != NULL); + + use_additional = (additional_text != NULL); + + /* Strip the suffix for nautilus object xml files. */ + *editable_text = nautilus_file_get_display_name (file); + + if (!use_additional) { + return; + } + + if (NAUTILUS_IS_DESKTOP_ICON_FILE (file) || + nautilus_file_is_nautilus_link (file)) + { + /* Don't show the normal extra information for desktop icons, + * or desktop files, it doesn't make sense. + */ + *additional_text = NULL; + + return; + } + + return NAUTILUS_CANVAS_CONTAINER_CLASS (nautilus_desktop_canvas_view_container_parent_class)->get_icon_text (container, + data, + editable_text, + additional_text, + include_invisible); +} + +static char * +real_get_icon_description (NautilusCanvasContainer *container, + NautilusCanvasIconData *data) +{ + NautilusFile *file; + + file = NAUTILUS_FILE (data); + g_assert (NAUTILUS_IS_FILE (file)); + + if (NAUTILUS_IS_DESKTOP_ICON_FILE (file)) + { + return NULL; + } + + return NAUTILUS_CANVAS_CONTAINER_CLASS (nautilus_desktop_canvas_view_container_parent_class)->get_icon_description (container, + data); +} + +NautilusDesktopCanvasViewContainer * +nautilus_desktop_canvas_view_container_new (void) +{ + return g_object_new (NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW_CONTAINER, NULL); +} + +static void +nautilus_desktop_canvas_view_container_class_init (NautilusDesktopCanvasViewContainerClass *klass) +{ + NautilusCanvasContainerClass *container_class = NAUTILUS_CANVAS_CONTAINER_CLASS (klass); + + container_class->get_icon_description = real_get_icon_description; + container_class->get_icon_text = real_get_icon_text; + container_class->compare_icons = real_compare_icons; +} + +static void +nautilus_desktop_canvas_view_container_init (NautilusDesktopCanvasViewContainer *self) +{ +} diff --git a/nautilus-desktop/nautilus-desktop-canvas-view-container.h b/nautilus-desktop/nautilus-desktop-canvas-view-container.h new file mode 100644 index 000000000..018062b7d --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-canvas-view-container.h @@ -0,0 +1,35 @@ +/* nautilus-desktop-canvas-view-container.h + * + * Copyright (C) 2016 Carlos Soriano + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef NAUTILUS_DESKTOP_CANVAS_VIEW_CONTAINER_H +#define NAUTILUS_DESKTOP_CANVAS_VIEW_CONTAINER_H + +#include +#include "nautilus-canvas-view-container.h" + +G_BEGIN_DECLS + +#define NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW_CONTAINER (nautilus_desktop_canvas_view_container_get_type()) + +G_DECLARE_FINAL_TYPE (NautilusDesktopCanvasViewContainer, nautilus_desktop_canvas_view_container, NAUTILUS, DESKTOP_CANVAS_VIEW_CONTAINER, NautilusCanvasViewContainer) + +NautilusDesktopCanvasViewContainer *nautilus_desktop_canvas_view_container_new (void); + +G_END_DECLS + +#endif /* NAUTILUS_DESKTOP_CANVAS_VIEW_CONTAINER_H */ + diff --git a/nautilus-desktop/nautilus-desktop-canvas-view.c b/nautilus-desktop/nautilus-desktop-canvas-view.c new file mode 100644 index 000000000..04731d96e --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-canvas-view.c @@ -0,0 +1,744 @@ + +/* nautilus-desktop-canvas-view.c - implementation of canvas view for managing the desktop. + + Copyright (C) 2000, 2001 Eazel, Inc.mou + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + see . + + Authors: Mike Engber + Gene Z. Ragan + Miguel de Icaza +*/ + +#include +#include + +#include "nautilus-desktop-canvas-view.h" + +#include "nautilus-desktop-canvas-view-container.h" +#include "nautilus-desktop-icon-file.h" +#include "nautilus-desktop-directory.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct NautilusDesktopCanvasViewDetails +{ + GdkWindow *root_window; +}; + +static void default_zoom_level_changed (gpointer user_data); +static void real_update_context_menus (NautilusFilesView *view); +static char* real_get_backing_uri (NautilusFilesView *view); +static void real_check_empty_states (NautilusFilesView *view); +static char * real_get_file_paths_or_uris_as_newline_delimited_string (NautilusFilesView *view, + GList *selection, + gboolean get_paths); +static void nautilus_desktop_canvas_view_update_canvas_container_fonts (NautilusDesktopCanvasView *view); +static void font_changed_callback (gpointer callback_data); + +G_DEFINE_TYPE (NautilusDesktopCanvasView, nautilus_desktop_canvas_view, NAUTILUS_TYPE_CANVAS_VIEW) + +static char *desktop_directory; + +#define get_canvas_container(w) nautilus_canvas_view_get_canvas_container(NAUTILUS_CANVAS_VIEW (w)) + +#define POPUP_PATH_CANVAS_APPEARANCE "/selection/Canvas Appearance Items" + +static void +canvas_container_set_workarea (NautilusCanvasContainer *canvas_container, + GdkScreen *screen, + long *workareas, + int n_items) +{ + int left, right, top, bottom; + int screen_width, screen_height; + int i; + + left = right = top = bottom = 0; + + screen_width = gdk_screen_get_width (screen); + screen_height = gdk_screen_get_height (screen); + + for (i = 0; i < n_items; i += 4) { + int x = workareas [i]; + int y = workareas [i + 1]; + int width = workareas [i + 2]; + int height = workareas [i + 3]; + + if ((x + width) > screen_width || (y + height) > screen_height) + continue; + + left = MAX (left, x); + right = MAX (right, screen_width - width - x); + top = MAX (top, y); + bottom = MAX (bottom, screen_height - height - y); + } + + nautilus_canvas_container_set_margins (canvas_container, + left, right, top, bottom); +} + +static void +net_workarea_changed (NautilusDesktopCanvasView *canvas_view, + GdkWindow *window) +{ + long *nworkareas = NULL; + long *workareas = NULL; + GdkAtom type_returned; + int format_returned; + int length_returned; + NautilusCanvasContainer *canvas_container; + GdkScreen *screen; + + g_return_if_fail (NAUTILUS_IS_DESKTOP_CANVAS_VIEW (canvas_view)); + + canvas_container = get_canvas_container (canvas_view); + + /* Find the number of desktops so we know how long the + * workareas array is going to be (each desktop will have four + * elements in the workareas array describing + * x,y,width,height) */ + gdk_error_trap_push (); + if (!gdk_property_get (window, + gdk_atom_intern ("_NET_NUMBER_OF_DESKTOPS", FALSE), + gdk_x11_xatom_to_atom (XA_CARDINAL), + 0, 4, FALSE, + &type_returned, + &format_returned, + &length_returned, + (guchar **) &nworkareas)) { + g_warning("Can not calculate _NET_NUMBER_OF_DESKTOPS"); + } + if (gdk_error_trap_pop() + || nworkareas == NULL + || type_returned != gdk_x11_xatom_to_atom (XA_CARDINAL) + || format_returned != 32) + g_warning("Can not calculate _NET_NUMBER_OF_DESKTOPS"); + + /* Note : gdk_property_get() is broken (API documents admit + * this). As a length argument, it expects the number of + * _bytes_ of data you require. Internally, gdk_property_get + * converts that value to a count of 32 bit (4 byte) elements. + * However, the length returned is in bytes, but is calculated + * via the count of returned elements * sizeof(long). This + * means on a 64 bit system, the number of bytes you have to + * request does not correspond to the number of bytes you get + * back, and is the reason for the workaround below. + */ + gdk_error_trap_push (); + if (nworkareas == NULL || (*nworkareas < 1) + || !gdk_property_get (window, + gdk_atom_intern ("_NET_WORKAREA", FALSE), + gdk_x11_xatom_to_atom (XA_CARDINAL), + 0, ((*nworkareas) * 4 * 4), FALSE, + &type_returned, + &format_returned, + &length_returned, + (guchar **) &workareas)) { + g_warning("Can not get _NET_WORKAREA"); + workareas = NULL; + } + + if (gdk_error_trap_pop () + || workareas == NULL + || type_returned != gdk_x11_xatom_to_atom (XA_CARDINAL) + || ((*nworkareas) * 4 * sizeof(long)) != length_returned + || format_returned != 32) { + g_warning("Can not determine workarea, guessing at layout"); + nautilus_canvas_container_set_margins (canvas_container, + 0, 0, 0, 0); + } else { + screen = gdk_window_get_screen (window); + + canvas_container_set_workarea + (canvas_container, screen, workareas, length_returned / sizeof (long)); + } + + if (nworkareas != NULL) + g_free (nworkareas); + + if (workareas != NULL) + g_free (workareas); +} + +static GdkFilterReturn +desktop_canvas_view_property_filter (GdkXEvent *gdk_xevent, + GdkEvent *event, + gpointer data) +{ + XEvent *xevent = gdk_xevent; + NautilusDesktopCanvasView *canvas_view; + + canvas_view = NAUTILUS_DESKTOP_CANVAS_VIEW (data); + + switch (xevent->type) { + case PropertyNotify: + if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name ("_NET_WORKAREA")) + net_workarea_changed (canvas_view, event->any.window); + break; + default: + break; + } + + return GDK_FILTER_CONTINUE; +} + +static guint +real_get_id (NautilusFilesView *view) +{ + return NAUTILUS_VIEW_DESKTOP_ID; +} + +static void +nautilus_desktop_canvas_view_dispose (GObject *object) +{ + NautilusDesktopCanvasView *canvas_view; + + canvas_view = NAUTILUS_DESKTOP_CANVAS_VIEW (object); + + g_signal_handlers_disconnect_by_func (nautilus_icon_view_preferences, + default_zoom_level_changed, + canvas_view); + g_signal_handlers_disconnect_by_func (nautilus_preferences, + font_changed_callback, + canvas_view); + g_signal_handlers_disconnect_by_func (gnome_lockdown_preferences, + nautilus_files_view_update_context_menus, + canvas_view); + + G_OBJECT_CLASS (nautilus_desktop_canvas_view_parent_class)->dispose (object); +} + +static void +nautilus_desktop_canvas_view_end_loading (NautilusFilesView *view, + gboolean all_files_seen) +{ + gboolean needs_reorganization; + gchar *stored_size_icon; + guint current_zoom; + guint current_icon_size; + gchar *current_icon_size_string; + NautilusFile *file; + + NAUTILUS_FILES_VIEW_CLASS (nautilus_desktop_canvas_view_parent_class)->end_loading (view, all_files_seen); + + if (!all_files_seen) + return; + + file = nautilus_files_view_get_directory_as_file (view); + g_return_if_fail (file != NULL); + + stored_size_icon = nautilus_file_get_metadata (file, NAUTILUS_METADATA_KEY_DESKTOP_ICON_SIZE, NULL); + current_zoom = nautilus_canvas_container_get_zoom_level (get_canvas_container (view)); + current_icon_size = nautilus_canvas_container_get_icon_size_for_zoom_level (current_zoom); + needs_reorganization = stored_size_icon == NULL || atoi (stored_size_icon) != current_icon_size; + + if (needs_reorganization) { + current_icon_size_string = g_strdup_printf ("%d", current_icon_size); + nautilus_canvas_view_clean_up_by_name (NAUTILUS_CANVAS_VIEW (view)); + nautilus_file_set_metadata (file, NAUTILUS_METADATA_KEY_DESKTOP_ICON_SIZE, + NULL, current_icon_size_string); + + g_free (current_icon_size_string); + } + + g_free (stored_size_icon); +} + +static NautilusCanvasContainer * +real_create_canvas_container (NautilusCanvasView *canvas_view) +{ + return NAUTILUS_CANVAS_CONTAINER (nautilus_desktop_canvas_view_container_new ()); +} + +static void +nautilus_desktop_canvas_view_class_init (NautilusDesktopCanvasViewClass *class) +{ + NautilusFilesViewClass *vclass; + NautilusCanvasViewClass *canvas_class; + + vclass = NAUTILUS_FILES_VIEW_CLASS (class); + canvas_class = NAUTILUS_CANVAS_VIEW_CLASS (class); + + + G_OBJECT_CLASS (class)->dispose = nautilus_desktop_canvas_view_dispose; + + canvas_class->create_canvas_container = real_create_canvas_container; + + vclass->update_context_menus = real_update_context_menus; + vclass->get_view_id = real_get_id; + vclass->end_loading = nautilus_desktop_canvas_view_end_loading; + vclass->get_backing_uri = real_get_backing_uri; + vclass->check_empty_states = real_check_empty_states; + + g_type_class_add_private (class, sizeof (NautilusDesktopCanvasViewDetails)); +} + +static void +unrealized_callback (GtkWidget *widget, NautilusDesktopCanvasView *desktop_canvas_view) +{ + g_return_if_fail (desktop_canvas_view->details->root_window != NULL); + + /* Remove the property filter */ + gdk_window_remove_filter (desktop_canvas_view->details->root_window, + desktop_canvas_view_property_filter, + desktop_canvas_view); + desktop_canvas_view->details->root_window = NULL; +} + +static void +realized_callback (GtkWidget *widget, NautilusDesktopCanvasView *desktop_canvas_view) +{ + GdkWindow *root_window; + GdkScreen *screen; + + g_return_if_fail (desktop_canvas_view->details->root_window == NULL); + + screen = gtk_widget_get_screen (widget); + root_window = gdk_screen_get_root_window (screen); + + desktop_canvas_view->details->root_window = root_window; + + /* Read out the workarea geometry and update the icon container accordingly */ + net_workarea_changed (desktop_canvas_view, root_window); + + /* Setup the property filter */ + gdk_window_set_events (root_window, GDK_PROPERTY_CHANGE_MASK); + gdk_window_add_filter (root_window, + desktop_canvas_view_property_filter, + desktop_canvas_view); +} + +static void +desktop_canvas_container_realize (GtkWidget *widget, + NautilusDesktopCanvasView *desktop_canvas_view) +{ + GdkWindow *bin_window; + GdkRGBA transparent = { 0, 0, 0, 0 }; + + bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (widget)); + gdk_window_set_background_rgba (bin_window, &transparent); +} + +static NautilusCanvasZoomLevel +get_default_zoom_level (void) +{ + NautilusCanvasZoomLevel default_zoom_level; + + default_zoom_level = g_settings_get_enum (nautilus_icon_view_preferences, + NAUTILUS_PREFERENCES_ICON_VIEW_DEFAULT_ZOOM_LEVEL); + + return CLAMP (default_zoom_level, NAUTILUS_CANVAS_ZOOM_LEVEL_SMALL, NAUTILUS_CANVAS_ZOOM_LEVEL_LARGE); +} + +static void +set_up_zoom_level (NautilusDesktopCanvasView *desktop_canvas_view) +{ + NautilusCanvasZoomLevel new_level; + + new_level = get_default_zoom_level (); + nautilus_canvas_container_set_zoom_level (get_canvas_container (desktop_canvas_view), + new_level); +} + +static void +default_zoom_level_changed (gpointer user_data) +{ + NautilusCanvasZoomLevel new_level; + NautilusDesktopCanvasView *desktop_canvas_view; + gint new_icon_size; + NautilusFile *file; + gchar *new_icon_size_string; + + desktop_canvas_view = NAUTILUS_DESKTOP_CANVAS_VIEW (user_data); + file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (user_data)); + new_level = get_default_zoom_level (); + new_icon_size = nautilus_canvas_container_get_icon_size_for_zoom_level (new_level); + new_icon_size_string = g_strdup_printf ("%d", new_icon_size); + + nautilus_file_set_metadata (file, NAUTILUS_METADATA_KEY_DESKTOP_ICON_SIZE, + NULL, new_icon_size_string); + set_up_zoom_level (desktop_canvas_view); + + g_free (new_icon_size_string); +} + +static void +font_changed_callback (gpointer callback_data) +{ + g_return_if_fail (NAUTILUS_IS_DESKTOP_CANVAS_VIEW (callback_data)); + + nautilus_desktop_canvas_view_update_canvas_container_fonts (NAUTILUS_DESKTOP_CANVAS_VIEW (callback_data)); +} + +static void +nautilus_desktop_canvas_view_update_canvas_container_fonts (NautilusDesktopCanvasView *canvas_view) +{ + NautilusCanvasContainer *canvas_container; + char *font; + + canvas_container = get_canvas_container (canvas_view); + g_assert (canvas_container != NULL); + + font = g_settings_get_string (nautilus_desktop_preferences, + NAUTILUS_PREFERENCES_DESKTOP_FONT); + + nautilus_canvas_container_set_font (canvas_container, font); + + g_free (font); +} + +static const gchar * +get_control_center_command (const gchar ** params_out) +{ + gchar *path; + const gchar *retval; + const gchar *params; + const gchar *xdg_current_desktop; + gchar **desktop_names; + gboolean is_unity; + int i; + + path = NULL; + retval = NULL; + params = NULL; + + xdg_current_desktop = g_getenv ("XDG_CURRENT_DESKTOP"); + + /* Detect the Unity-based environments */ + is_unity = FALSE; + if (xdg_current_desktop != NULL) { + desktop_names = g_strsplit (xdg_current_desktop, ":", 0); + for (i = 0; desktop_names[i]; ++i) { + if (!g_strcmp0 (desktop_names[i], "Unity")) { + is_unity = TRUE; + break; + } + } + g_strfreev (desktop_names); + } + + /* In Unity look for unity-control-center */ + if (is_unity) { + path = g_find_program_in_path ("unity-control-center"); + if (path != NULL) { + retval = "unity-control-center"; + params = "appearance"; + goto out; + } + } + + /* Otherwise look for gnome-control-center */ + path = g_find_program_in_path ("gnome-control-center"); + if (path != NULL) { + retval = "gnome-control-center"; + params = "background"; + } + + out: + g_free (path); + if (params_out != NULL) { + *params_out = params; + } + + return retval; +} + +static void +action_change_background (GSimpleAction *action, + GVariant *state, + gpointer user_data) +{ + const gchar *control_center_cmd, *params; + + g_assert (NAUTILUS_FILES_VIEW (user_data)); + + control_center_cmd = get_control_center_command (¶ms); + if (control_center_cmd == NULL) { + return; + } + + nautilus_launch_application_from_command (gtk_widget_get_screen (GTK_WIDGET (user_data)), + control_center_cmd, + FALSE, + params, NULL); +} + +static void +action_empty_trash (GSimpleAction *action, + GVariant *state, + gpointer user_data) +{ + g_assert (NAUTILUS_IS_FILES_VIEW (user_data)); + + nautilus_file_operations_empty_trash (GTK_WIDGET (user_data)); +} + +static void +action_stretch (GSimpleAction *action, + GVariant *state, + gpointer user_data) +{ + nautilus_canvas_container_show_stretch_handles + (get_canvas_container (user_data)); +} + +static void +action_unstretch (GSimpleAction *action, + GVariant *state, + gpointer user_data) +{ + nautilus_canvas_container_unstretch (get_canvas_container (user_data)); +} + +static void +action_organize_desktop_by_name (GSimpleAction *action, + GVariant *state, + gpointer user_data) +{ + nautilus_canvas_view_clean_up_by_name (NAUTILUS_CANVAS_VIEW (user_data)); +} + +static gboolean +trash_link_is_selection (NautilusFilesView *view) +{ + GList *selection; + NautilusDesktopLink *link; + gboolean result; + + result = FALSE; + + selection = nautilus_view_get_selection (NAUTILUS_VIEW (view)); + + if ((g_list_length (selection) == 1) && + NAUTILUS_IS_DESKTOP_ICON_FILE (selection->data)) { + link = nautilus_desktop_icon_file_get_link (NAUTILUS_DESKTOP_ICON_FILE (selection->data)); + /* link may be NULL if the link was recently removed (unmounted) */ + if (link != NULL && + nautilus_desktop_link_get_link_type (link) == NAUTILUS_DESKTOP_LINK_TRASH) { + result = TRUE; + } + if (link) { + g_object_unref (link); + } + } + + nautilus_file_list_free (selection); + + return result; +} + +const GActionEntry desktop_view_entries[] = { + { "change-background", action_change_background }, + { "organize-desktop-by-name", action_organize_desktop_by_name }, + { "empty-trash", action_empty_trash }, + { "stretch", action_stretch }, + { "unstretch", action_unstretch }, +}; + +static void +real_check_empty_states (NautilusFilesView *view) +{ + /* Do nothing */ +} + +static char* +real_get_backing_uri (NautilusFilesView *view) +{ + gchar *uri; + NautilusDirectory *directory; + NautilusDirectory *model; + + g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL); + + model = nautilus_files_view_get_model (view); + + if (model == NULL) { + return NULL; + } + + directory = nautilus_desktop_directory_get_real_directory (NAUTILUS_DESKTOP_DIRECTORY (model)); + + uri = nautilus_directory_get_uri (directory); + + nautilus_directory_unref (directory); + + return uri; +} + +static void +real_update_context_menus (NautilusFilesView *view) +{ + NautilusCanvasContainer *canvas_container; + NautilusDesktopCanvasView *desktop_view; + GAction *action; + GActionGroup *view_action_group; + GList *selection; + int selection_count; + + g_assert (NAUTILUS_IS_DESKTOP_CANVAS_VIEW (view)); + + NAUTILUS_FILES_VIEW_CLASS (nautilus_desktop_canvas_view_parent_class)->update_context_menus (view); + + view_action_group = nautilus_files_view_get_action_group (view); + desktop_view = NAUTILUS_DESKTOP_CANVAS_VIEW (view); + selection = nautilus_view_get_selection (NAUTILUS_VIEW (view)); + selection_count = g_list_length (selection); + + action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "empty-trash"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), trash_link_is_selection (view)); + + action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "keep-aligned"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), TRUE); + + action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "organize-desktop-by-name"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), TRUE); + + action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "change-background"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), TRUE); + + action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "properties"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), selection_count > 0); + + /* Stretch */ + canvas_container = get_canvas_container (desktop_view); + + action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "stretch"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), selection_count == 1 && + canvas_container != NULL && + !nautilus_canvas_container_has_stretch_handles (canvas_container)); + + nautilus_file_list_free (selection); + + /* Unstretch */ + action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "unstretch"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), canvas_container != NULL && + nautilus_canvas_container_is_stretched (canvas_container)); +} + +static void +nautilus_desktop_canvas_view_init (NautilusDesktopCanvasView *desktop_canvas_view) +{ + NautilusCanvasContainer *canvas_container; + GtkAllocation allocation; + GActionGroup *view_action_group; + GtkAdjustment *hadj, *vadj; + + desktop_canvas_view->details = G_TYPE_INSTANCE_GET_PRIVATE (desktop_canvas_view, + NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW, + NautilusDesktopCanvasViewDetails); + + if (desktop_directory == NULL) { + desktop_directory = nautilus_get_desktop_directory (); + } + + canvas_container = get_canvas_container (desktop_canvas_view); + + nautilus_canvas_container_set_is_fixed_size (canvas_container, TRUE); + nautilus_canvas_container_set_is_desktop (canvas_container, TRUE); + nautilus_canvas_container_set_store_layout_timestamps (canvas_container, TRUE); + + /* Set allocation to be at 0, 0 */ + gtk_widget_get_allocation (GTK_WIDGET (canvas_container), &allocation); + allocation.x = 0; + allocation.y = 0; + gtk_widget_set_allocation (GTK_WIDGET (canvas_container), &allocation); + + gtk_widget_queue_resize (GTK_WIDGET (canvas_container)); + + hadj = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (canvas_container)); + vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (canvas_container)); + + gtk_adjustment_set_value (hadj, 0); + gtk_adjustment_set_value (vadj, 0); + + nautilus_files_view_ignore_hidden_file_preferences + (NAUTILUS_FILES_VIEW (desktop_canvas_view)); + + nautilus_files_view_set_show_foreign (NAUTILUS_FILES_VIEW (desktop_canvas_view), + FALSE); + + g_signal_connect_object (canvas_container, "realize", + G_CALLBACK (desktop_canvas_container_realize), desktop_canvas_view, 0); + + g_signal_connect_object (desktop_canvas_view, "realize", + G_CALLBACK (realized_callback), desktop_canvas_view, 0); + g_signal_connect_object (desktop_canvas_view, "unrealize", + G_CALLBACK (unrealized_callback), desktop_canvas_view, 0); + + g_signal_connect_swapped (nautilus_icon_view_preferences, + "changed::" NAUTILUS_PREFERENCES_ICON_VIEW_DEFAULT_ZOOM_LEVEL, + G_CALLBACK (default_zoom_level_changed), + desktop_canvas_view); + + g_signal_connect_swapped (nautilus_desktop_preferences, + "changed::" NAUTILUS_PREFERENCES_DESKTOP_FONT, + G_CALLBACK (font_changed_callback), + desktop_canvas_view); + + set_up_zoom_level (desktop_canvas_view); + nautilus_desktop_canvas_view_update_canvas_container_fonts (desktop_canvas_view); + + g_signal_connect_swapped (gnome_lockdown_preferences, + "changed::" NAUTILUS_PREFERENCES_LOCKDOWN_COMMAND_LINE, + G_CALLBACK (nautilus_files_view_update_context_menus), + desktop_canvas_view); + + view_action_group = nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (desktop_canvas_view)); + + g_action_map_add_action_entries (G_ACTION_MAP (view_action_group), + desktop_view_entries, + G_N_ELEMENTS (desktop_view_entries), + NAUTILUS_FILES_VIEW (desktop_canvas_view)); +} + +NautilusFilesView * +nautilus_desktop_canvas_view_new (NautilusWindowSlot *slot) +{ + return g_object_new (NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW, + "window-slot", slot, + "supports-zooming", FALSE, + "supports-auto-layout", FALSE, + "supports-manual-layout", TRUE, + "supports-scaling", TRUE, + "supports-keep-aligned", TRUE, + NULL); +} diff --git a/nautilus-desktop/nautilus-desktop-canvas-view.h b/nautilus-desktop/nautilus-desktop-canvas-view.h new file mode 100644 index 000000000..e40d80ff4 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-canvas-view.h @@ -0,0 +1,54 @@ + +/* fm-icon-view.h - interface for icon view of directory. + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + see . + + Authors: Mike Engber +*/ + +#ifndef NAUTILUS_DESKTOP_CANVAS_VIEW_H +#define NAUTILUS_DESKTOP_CANVAS_VIEW_H + +#include "nautilus-canvas-view.h" + +#define NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW nautilus_desktop_canvas_view_get_type() +#define NAUTILUS_DESKTOP_CANVAS_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW, NautilusDesktopCanvasView)) +#define NAUTILUS_DESKTOP_CANVAS_VIEW_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW, NautilusDesktopCanvasViewClass)) +#define NAUTILUS_IS_DESKTOP_CANVAS_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW)) +#define NAUTILUS_IS_DESKTOP_CANVAS_VIEW_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW)) +#define NAUTILUS_DESKTOP_CANVAS_VIEW_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW, NautilusDesktopCanvasViewClass)) + +typedef struct NautilusDesktopCanvasViewDetails NautilusDesktopCanvasViewDetails; +typedef struct { + NautilusCanvasView parent; + NautilusDesktopCanvasViewDetails *details; +} NautilusDesktopCanvasView; + +typedef struct { + NautilusCanvasViewClass parent_class; +} NautilusDesktopCanvasViewClass; + +/* GObject support */ +GType nautilus_desktop_canvas_view_get_type (void); +NautilusFilesView * nautilus_desktop_canvas_view_new (NautilusWindowSlot *slot); + +#endif /* NAUTILUS_DESKTOP_CANVAS_VIEW_H */ diff --git a/nautilus-desktop/nautilus-desktop-directory-file.c b/nautilus-desktop/nautilus-desktop-directory-file.c new file mode 100644 index 000000000..ba3cd136c --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-directory-file.c @@ -0,0 +1,557 @@ +/* + nautilus-desktop-directory-file.c: Subclass of NautilusFile to help implement the + virtual desktop. + + Copyright (C) 2003 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, see . + + Author: Alexander Larsson +*/ + +#include +#include "nautilus-desktop-directory-file.h" +#include "nautilus-desktop-metadata.h" +#include "nautilus-desktop-directory.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +struct NautilusDesktopDirectoryFileDetails { + NautilusDesktopDirectory *desktop_directory; + + NautilusFile *real_dir_file; + + GHashTable *callbacks; + GHashTable *monitors; +}; + +typedef struct { + NautilusDesktopDirectoryFile *desktop_file; + NautilusFileCallback callback; + gpointer callback_data; + + NautilusFileAttributes delegated_attributes; + NautilusFileAttributes non_delegated_attributes; + + GList *non_ready_files; + + gboolean initializing; +} DesktopCallback; + +typedef struct { + NautilusDesktopDirectoryFile *desktop_file; + + NautilusFileAttributes delegated_attributes; + NautilusFileAttributes non_delegated_attributes; +} DesktopMonitor; + +G_DEFINE_TYPE (NautilusDesktopDirectoryFile, nautilus_desktop_directory_file, + NAUTILUS_TYPE_FILE); + +static guint +desktop_callback_hash (gconstpointer desktop_callback_as_pointer) +{ + const DesktopCallback *desktop_callback; + + desktop_callback = desktop_callback_as_pointer; + return GPOINTER_TO_UINT (desktop_callback->callback) + ^ GPOINTER_TO_UINT (desktop_callback->callback_data); +} + +static gboolean +desktop_callback_equal (gconstpointer desktop_callback_as_pointer, + gconstpointer desktop_callback_as_pointer_2) +{ + const DesktopCallback *desktop_callback, *desktop_callback_2; + + desktop_callback = desktop_callback_as_pointer; + desktop_callback_2 = desktop_callback_as_pointer_2; + + return desktop_callback->callback == desktop_callback_2->callback + && desktop_callback->callback_data == desktop_callback_2->callback_data; +} + + +static void +real_file_changed_callback (NautilusFile *real_file, + gpointer callback_data) +{ + NautilusDesktopDirectoryFile *desktop_file; + + desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (callback_data); + nautilus_file_changed (NAUTILUS_FILE (desktop_file)); +} + +static NautilusFileAttributes +get_delegated_attributes_mask (void) +{ + return NAUTILUS_FILE_ATTRIBUTE_DEEP_COUNTS | + NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT | + NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_MIME_TYPES | + NAUTILUS_FILE_ATTRIBUTE_INFO; +} + +static void +partition_attributes (NautilusFileAttributes attributes, + NautilusFileAttributes *delegated_attributes, + NautilusFileAttributes *non_delegated_attributes) +{ + NautilusFileAttributes mask; + + mask = get_delegated_attributes_mask (); + + *delegated_attributes = attributes & mask; + *non_delegated_attributes = attributes & ~mask; +} + +static void +desktop_directory_file_monitor_add (NautilusFile *file, + gconstpointer client, + NautilusFileAttributes attributes) +{ + NautilusDesktopDirectoryFile *desktop_file; + DesktopMonitor *monitor; + + desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); + + /* Map the client to a unique value so this doesn't interfere + * with direct monitoring of the file by the same client. + */ + monitor = g_hash_table_lookup (desktop_file->details->monitors, client); + if (monitor != NULL) { + g_assert (monitor->desktop_file == desktop_file); + } else { + monitor = g_new0 (DesktopMonitor, 1); + monitor->desktop_file = desktop_file; + g_hash_table_insert (desktop_file->details->monitors, + (gpointer) client, monitor); + } + + partition_attributes (attributes, + &monitor->delegated_attributes, + &monitor->non_delegated_attributes); + + /* Pawn off partioned attributes to real dir file */ + nautilus_file_monitor_add (desktop_file->details->real_dir_file, + monitor, monitor->delegated_attributes); + + /* Do the rest ourself */ + nautilus_directory_monitor_add_internal + (file->details->directory, file, + client, TRUE, + monitor->non_delegated_attributes, + NULL, NULL); +} + +static void +desktop_directory_file_monitor_remove (NautilusFile *file, + gconstpointer client) +{ + NautilusDesktopDirectoryFile *desktop_file; + DesktopMonitor *monitor; + + desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); + + /* Map the client to the value used by the earlier add call. */ + monitor = g_hash_table_lookup (desktop_file->details->monitors, client); + if (monitor == NULL) { + return; + } + + /* Call through to the real file remove calls. */ + g_hash_table_remove (desktop_file->details->monitors, client); + + /* Remove the locally handled parts */ + nautilus_directory_monitor_remove_internal + (file->details->directory, file, client); +} + +static void +desktop_callback_destroy (DesktopCallback *desktop_callback) +{ + g_assert (desktop_callback != NULL); + g_assert (NAUTILUS_IS_DESKTOP_DIRECTORY_FILE (desktop_callback->desktop_file)); + + nautilus_file_unref (NAUTILUS_FILE (desktop_callback->desktop_file)); + g_list_free (desktop_callback->non_ready_files); + g_free (desktop_callback); +} + +static void +desktop_callback_check_done (DesktopCallback *desktop_callback) +{ + /* Check if we are ready. */ + if (desktop_callback->initializing || + desktop_callback->non_ready_files != NULL) { + return; + } + + /* Ensure our metadata is updated before calling back */ + nautilus_desktop_update_metadata_from_keyfile (NAUTILUS_FILE (desktop_callback->desktop_file), "directory"); + + /* Remove from the hash table before sending it. */ + g_hash_table_remove (desktop_callback->desktop_file->details->callbacks, + desktop_callback); + + /* We are ready, so do the real callback. */ + (* desktop_callback->callback) (NAUTILUS_FILE (desktop_callback->desktop_file), + desktop_callback->callback_data); + + /* And we are done. */ + desktop_callback_destroy (desktop_callback); +} + +static void +desktop_callback_remove_file (DesktopCallback *desktop_callback, + NautilusFile *file) +{ + desktop_callback->non_ready_files = g_list_remove + (desktop_callback->non_ready_files, file); + desktop_callback_check_done (desktop_callback); +} + +static void +ready_callback (NautilusFile *file, + gpointer callback_data) +{ + DesktopCallback *desktop_callback; + + g_assert (NAUTILUS_IS_FILE (file)); + g_assert (callback_data != NULL); + + desktop_callback = callback_data; + g_assert (g_list_find (desktop_callback->non_ready_files, file) != NULL); + + desktop_callback_remove_file (desktop_callback, file); +} + +static void +desktop_directory_file_call_when_ready (NautilusFile *file, + NautilusFileAttributes attributes, + NautilusFileCallback callback, + gpointer callback_data) + +{ + NautilusDesktopDirectoryFile *desktop_file; + DesktopCallback search_key, *desktop_callback; + + desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); + + /* Check to be sure we aren't overwriting. */ + search_key.callback = callback; + search_key.callback_data = callback_data; + if (g_hash_table_lookup (desktop_file->details->callbacks, &search_key) != NULL) { + g_warning ("tried to add a new callback while an old one was pending"); + return; + } + + /* Create a desktop_callback record. */ + desktop_callback = g_new0 (DesktopCallback, 1); + nautilus_file_ref (file); + desktop_callback->desktop_file = desktop_file; + desktop_callback->callback = callback; + desktop_callback->callback_data = callback_data; + desktop_callback->initializing = TRUE; + + partition_attributes (attributes, + &desktop_callback->delegated_attributes, + &desktop_callback->non_delegated_attributes); + + desktop_callback->non_ready_files = g_list_prepend + (desktop_callback->non_ready_files, file); + desktop_callback->non_ready_files = g_list_prepend + (desktop_callback->non_ready_files, desktop_file->details->real_dir_file); + + /* Put it in the hash table. */ + g_hash_table_insert (desktop_file->details->callbacks, + desktop_callback, desktop_callback); + + /* Now connect to each file's call_when_ready. */ + nautilus_directory_call_when_ready_internal + (file->details->directory, file, + desktop_callback->non_delegated_attributes, + FALSE, NULL, ready_callback, desktop_callback); + nautilus_file_call_when_ready + (desktop_file->details->real_dir_file, + desktop_callback->delegated_attributes, + ready_callback, desktop_callback); + + desktop_callback->initializing = FALSE; + + /* Check if any files became read while we were connecting up + * the call_when_ready callbacks (also handles the pathological + * case where there are no files at all). + */ + desktop_callback_check_done (desktop_callback); + +} + +static void +desktop_directory_file_cancel_call_when_ready (NautilusFile *file, + NautilusFileCallback callback, + gpointer callback_data) +{ + NautilusDesktopDirectoryFile *desktop_file; + DesktopCallback search_key, *desktop_callback; + + desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); + + /* Find the entry in the table. */ + search_key.callback = callback; + search_key.callback_data = callback_data; + desktop_callback = g_hash_table_lookup (desktop_file->details->callbacks, &search_key); + if (desktop_callback == NULL) { + return; + } + + /* Remove from the hash table before working with it. */ + g_hash_table_remove (desktop_callback->desktop_file->details->callbacks, desktop_callback); + + /* Tell the real directory to cancel the call. */ + nautilus_directory_cancel_callback_internal + (file->details->directory, file, + NULL, ready_callback, desktop_callback); + + nautilus_file_cancel_call_when_ready + (desktop_file->details->real_dir_file, + ready_callback, desktop_callback); + + desktop_callback_destroy (desktop_callback); +} + +static gboolean +real_check_if_ready (NautilusFile *file, + NautilusFileAttributes attributes) +{ + return nautilus_directory_check_if_ready_internal + (file->details->directory, file, + attributes); +} + +static gboolean +desktop_directory_file_check_if_ready (NautilusFile *file, + NautilusFileAttributes attributes) +{ + NautilusFileAttributes delegated_attributes, non_delegated_attributes; + NautilusDesktopDirectoryFile *desktop_file; + + desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); + + partition_attributes (attributes, + &delegated_attributes, + &non_delegated_attributes); + + return real_check_if_ready (file, non_delegated_attributes) && + nautilus_file_check_if_ready (desktop_file->details->real_dir_file, + delegated_attributes); +} + +static gboolean +desktop_directory_file_get_item_count (NautilusFile *file, + guint *count, + gboolean *count_unreadable) +{ + NautilusDesktopDirectoryFile *desktop_file; + gboolean got_count; + + desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); + + got_count = nautilus_file_get_directory_item_count (desktop_file->details->real_dir_file, + count, + count_unreadable); + + if (count) { + *count += g_list_length (file->details->directory->details->file_list); + } + + return got_count; +} + +static NautilusRequestStatus +desktop_directory_file_get_deep_counts (NautilusFile *file, + guint *directory_count, + guint *file_count, + guint *unreadable_directory_count, + goffset *total_size) +{ + NautilusDesktopDirectoryFile *desktop_file; + NautilusRequestStatus status; + + desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); + + status = nautilus_file_get_deep_counts (desktop_file->details->real_dir_file, + directory_count, + file_count, + unreadable_directory_count, + total_size, + TRUE); + + if (file_count) { + *file_count += g_list_length (file->details->directory->details->file_list); + } + + return status; +} + +static gboolean +desktop_directory_file_get_date (NautilusFile *file, + NautilusDateType date_type, + time_t *date) +{ + NautilusDesktopDirectoryFile *desktop_file; + + desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); + + return nautilus_file_get_date (desktop_file->details->real_dir_file, + date_type, + date); +} + +static char * +desktop_directory_file_get_where_string (NautilusFile *file) +{ + return g_strdup (_("on the desktop")); +} + + +static void +monitor_destroy (gpointer data) +{ + DesktopMonitor *monitor = data; + + nautilus_file_monitor_remove + (NAUTILUS_FILE (monitor->desktop_file->details->real_dir_file), monitor); + g_free (monitor); +} + +static void +nautilus_desktop_directory_file_set_metadata (NautilusFile *file, + const char *key, + const char *value) +{ + nautilus_desktop_set_metadata_string (file, "directory", key, value); +} + +static void +nautilus_desktop_directory_file_set_metadata_as_list (NautilusFile *file, + const char *key, + char **value) +{ + nautilus_desktop_set_metadata_stringv (file, "directory", key, (const gchar **) value); +} + +static void +nautilus_desktop_directory_file_init (NautilusDesktopDirectoryFile *desktop_file) +{ + NautilusDesktopDirectory *desktop_directory; + NautilusDirectory *real_dir; + NautilusFile *real_dir_file; + + desktop_file->details = G_TYPE_INSTANCE_GET_PRIVATE (desktop_file, + NAUTILUS_TYPE_DESKTOP_DIRECTORY_FILE, + NautilusDesktopDirectoryFileDetails); + + desktop_directory = NAUTILUS_DESKTOP_DIRECTORY (nautilus_directory_get_by_uri (EEL_DESKTOP_URI)); + desktop_file->details->desktop_directory = desktop_directory; + + desktop_file->details->callbacks = g_hash_table_new + (desktop_callback_hash, desktop_callback_equal); + desktop_file->details->monitors = g_hash_table_new_full (NULL, NULL, + NULL, monitor_destroy); + + real_dir = nautilus_desktop_directory_get_real_directory (desktop_directory); + real_dir_file = nautilus_directory_get_corresponding_file (real_dir); + nautilus_directory_unref (real_dir); + + desktop_file->details->real_dir_file = real_dir_file; + g_signal_connect_object (real_dir_file, "changed", + G_CALLBACK (real_file_changed_callback), desktop_file, 0); +} + + +static void +desktop_callback_remove_file_cover (gpointer key, + gpointer value, + gpointer callback_data) +{ + desktop_callback_remove_file + (value, NAUTILUS_FILE (callback_data)); +} + + +static void +desktop_finalize (GObject *object) +{ + NautilusDesktopDirectoryFile *desktop_file; + NautilusDesktopDirectory *desktop_directory; + + desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (object); + desktop_directory = desktop_file->details->desktop_directory; + + /* Todo: ghash now safe? */ + eel_g_hash_table_safe_for_each + (desktop_file->details->callbacks, + desktop_callback_remove_file_cover, + desktop_file->details->real_dir_file); + + if (g_hash_table_size (desktop_file->details->callbacks) != 0) { + g_warning ("call_when_ready still pending when desktop virtual file is destroyed"); + } + + g_hash_table_destroy (desktop_file->details->callbacks); + g_hash_table_destroy (desktop_file->details->monitors); + + nautilus_file_unref (desktop_file->details->real_dir_file); + nautilus_directory_unref (NAUTILUS_DIRECTORY (desktop_directory)); + + G_OBJECT_CLASS (nautilus_desktop_directory_file_parent_class)->finalize (object); +} + +static void +nautilus_desktop_directory_file_class_init (NautilusDesktopDirectoryFileClass *klass) +{ + GObjectClass *object_class; + NautilusFileClass *file_class; + + object_class = G_OBJECT_CLASS (klass); + file_class = NAUTILUS_FILE_CLASS (klass); + + object_class->finalize = desktop_finalize; + + file_class->default_file_type = G_FILE_TYPE_DIRECTORY; + + file_class->monitor_add = desktop_directory_file_monitor_add; + file_class->monitor_remove = desktop_directory_file_monitor_remove; + file_class->call_when_ready = desktop_directory_file_call_when_ready; + file_class->cancel_call_when_ready = desktop_directory_file_cancel_call_when_ready; + file_class->check_if_ready = desktop_directory_file_check_if_ready; + file_class->get_item_count = desktop_directory_file_get_item_count; + file_class->get_deep_counts = desktop_directory_file_get_deep_counts; + file_class->get_date = desktop_directory_file_get_date; + file_class->get_where_string = desktop_directory_file_get_where_string; + file_class->set_metadata = nautilus_desktop_directory_file_set_metadata; + file_class->set_metadata_as_list = nautilus_desktop_directory_file_set_metadata_as_list; + + g_type_class_add_private (klass, sizeof (NautilusDesktopDirectoryFileDetails)); +} diff --git a/nautilus-desktop/nautilus-desktop-directory-file.h b/nautilus-desktop/nautilus-desktop-directory-file.h new file mode 100644 index 000000000..2a5097980 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-directory-file.h @@ -0,0 +1,53 @@ +/* + nautilus-desktop-directory-file.h: Subclass of NautilusFile to implement the + the case of the desktop directory + + Copyright (C) 2003 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, see . + + Author: Alexander Larsson +*/ + +#ifndef NAUTILUS_DESKTOP_DIRECTORY_FILE_H +#define NAUTILUS_DESKTOP_DIRECTORY_FILE_H + +#include + +#define NAUTILUS_TYPE_DESKTOP_DIRECTORY_FILE nautilus_desktop_directory_file_get_type() +#define NAUTILUS_DESKTOP_DIRECTORY_FILE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_DESKTOP_DIRECTORY_FILE, NautilusDesktopDirectoryFile)) +#define NAUTILUS_DESKTOP_DIRECTORY_FILE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DESKTOP_DIRECTORY_FILE, NautilusDesktopDirectoryFileClass)) +#define NAUTILUS_IS_DESKTOP_DIRECTORY_FILE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_DESKTOP_DIRECTORY_FILE)) +#define NAUTILUS_IS_DESKTOP_DIRECTORY_FILE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DESKTOP_DIRECTORY_FILE)) +#define NAUTILUS_DESKTOP_DIRECTORY_FILE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_DESKTOP_DIRECTORY_FILE, NautilusDesktopDirectoryFileClass)) + +typedef struct NautilusDesktopDirectoryFileDetails NautilusDesktopDirectoryFileDetails; + +typedef struct { + NautilusFile parent_slot; + NautilusDesktopDirectoryFileDetails *details; +} NautilusDesktopDirectoryFile; + +typedef struct { + NautilusFileClass parent_slot; +} NautilusDesktopDirectoryFileClass; + +GType nautilus_desktop_directory_file_get_type (void); + +#endif /* NAUTILUS_DESKTOP_DIRECTORY_FILE_H */ diff --git a/nautilus-desktop/nautilus-desktop-directory.c b/nautilus-desktop/nautilus-desktop-directory.c new file mode 100644 index 000000000..6a43ec5e8 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-directory.c @@ -0,0 +1,571 @@ +/* + nautilus-desktop-directory.c: Subclass of NautilusDirectory to implement + a virtual directory consisting of the desktop directory and the desktop + icons + + Copyright (C) 2003 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, see . + + Author: Alexander Larsson +*/ + +#include +#include "nautilus-desktop-directory.h" +#include "nautilus-desktop-directory-file.h" + +#include +#include +#include +#include +#include +#include + +struct NautilusDesktopDirectoryDetails { + NautilusDirectory *real_directory; + GHashTable *callbacks; + GHashTable *monitors; +}; + +typedef struct { + NautilusDesktopDirectory *desktop_dir; + NautilusDirectoryCallback callback; + gpointer callback_data; + + NautilusFileAttributes wait_for_attributes; + gboolean wait_for_file_list; + + GList *non_ready_directories; + GList *merged_file_list; +} MergedCallback; + + +typedef struct { + NautilusDesktopDirectory *desktop_dir; + + gboolean monitor_hidden_files; + NautilusFileAttributes monitor_attributes; +} MergedMonitor; + +static void desktop_directory_changed_callback (gpointer data); + +G_DEFINE_TYPE_WITH_CODE (NautilusDesktopDirectory, nautilus_desktop_directory, NAUTILUS_TYPE_DIRECTORY, + nautilus_ensure_extension_points (); + g_io_extension_point_implement (NAUTILUS_DIRECTORY_PROVIDER_EXTENSION_POINT_NAME, + g_define_type_id, + NAUTILUS_DESKTOP_DIRECTORY_PROVIDER_NAME, + 0)); +static gboolean +desktop_contains_file (NautilusDirectory *directory, + NautilusFile *file) +{ + NautilusDesktopDirectory *desktop; + + desktop = NAUTILUS_DESKTOP_DIRECTORY (directory); + + if (nautilus_directory_contains_file (desktop->details->real_directory, file)) { + return TRUE; + } + + return file->details->directory == directory; +} + +static guint +merged_callback_hash (gconstpointer merged_callback_as_pointer) +{ + const MergedCallback *merged_callback; + + merged_callback = merged_callback_as_pointer; + return GPOINTER_TO_UINT (merged_callback->callback) + ^ GPOINTER_TO_UINT (merged_callback->callback_data); +} + +static gboolean +merged_callback_equal (gconstpointer merged_callback_as_pointer, + gconstpointer merged_callback_as_pointer_2) +{ + const MergedCallback *merged_callback, *merged_callback_2; + + merged_callback = merged_callback_as_pointer; + merged_callback_2 = merged_callback_as_pointer_2; + + return merged_callback->callback == merged_callback_2->callback + && merged_callback->callback_data == merged_callback_2->callback_data; +} + +static void +merged_callback_destroy (MergedCallback *merged_callback) +{ + g_assert (merged_callback != NULL); + g_assert (NAUTILUS_IS_DESKTOP_DIRECTORY (merged_callback->desktop_dir)); + + g_list_free (merged_callback->non_ready_directories); + nautilus_file_list_free (merged_callback->merged_file_list); + g_free (merged_callback); +} + +static void +merged_callback_check_done (MergedCallback *merged_callback) +{ + /* Check if we are ready. */ + if (merged_callback->non_ready_directories != NULL) { + return; + } + + /* Remove from the hash table before sending it. */ + g_hash_table_steal (merged_callback->desktop_dir->details->callbacks, merged_callback); + + /* We are ready, so do the real callback. */ + (* merged_callback->callback) (NAUTILUS_DIRECTORY (merged_callback->desktop_dir), + merged_callback->merged_file_list, + merged_callback->callback_data); + + /* And we are done. */ + merged_callback_destroy (merged_callback); +} + +static void +merged_callback_remove_directory (MergedCallback *merged_callback, + NautilusDirectory *directory) +{ + merged_callback->non_ready_directories = g_list_remove + (merged_callback->non_ready_directories, directory); + merged_callback_check_done (merged_callback); +} + +static void +directory_ready_callback (NautilusDirectory *directory, + GList *files, + gpointer callback_data) +{ + MergedCallback *merged_callback; + + g_assert (NAUTILUS_IS_DIRECTORY (directory)); + g_assert (callback_data != NULL); + + merged_callback = callback_data; + g_assert (g_list_find (merged_callback->non_ready_directories, directory) != NULL); + + /* Update based on this call. */ + merged_callback->merged_file_list = g_list_concat + (merged_callback->merged_file_list, + nautilus_file_list_copy (files)); + + /* Check if we are ready. */ + merged_callback_remove_directory (merged_callback, directory); +} + +static void +desktop_call_when_ready (NautilusDirectory *directory, + NautilusFileAttributes file_attributes, + gboolean wait_for_file_list, + NautilusDirectoryCallback callback, + gpointer callback_data) +{ + NautilusDesktopDirectory *desktop; + MergedCallback search_key, *merged_callback; + + desktop = NAUTILUS_DESKTOP_DIRECTORY (directory); + + /* Check to be sure we aren't overwriting. */ + search_key.callback = callback; + search_key.callback_data = callback_data; + if (g_hash_table_lookup (desktop->details->callbacks, &search_key) != NULL) { + g_warning ("tried to add a new callback while an old one was pending"); + return; + } + + /* Create a merged_callback record. */ + merged_callback = g_new0 (MergedCallback, 1); + merged_callback->desktop_dir = desktop; + merged_callback->callback = callback; + merged_callback->callback_data = callback_data; + merged_callback->wait_for_attributes = file_attributes; + merged_callback->wait_for_file_list = wait_for_file_list; + merged_callback->non_ready_directories = g_list_prepend + (merged_callback->non_ready_directories, directory); + merged_callback->non_ready_directories = g_list_prepend + (merged_callback->non_ready_directories, desktop->details->real_directory); + + + merged_callback->merged_file_list = g_list_concat (NULL, + nautilus_file_list_copy (directory->details->file_list)); + + /* Put it in the hash table. */ + g_hash_table_insert (desktop->details->callbacks, + merged_callback, merged_callback); + + /* Now tell all the directories about it. */ + nautilus_directory_call_when_ready + (desktop->details->real_directory, + merged_callback->wait_for_attributes, + merged_callback->wait_for_file_list, + directory_ready_callback, merged_callback); + nautilus_directory_call_when_ready_internal + (directory, + NULL, + merged_callback->wait_for_attributes, + merged_callback->wait_for_file_list, + directory_ready_callback, + NULL, + merged_callback); + +} + +static void +desktop_cancel_callback (NautilusDirectory *directory, + NautilusDirectoryCallback callback, + gpointer callback_data) +{ + NautilusDesktopDirectory *desktop; + MergedCallback search_key, *merged_callback; + GList *node; + + desktop = NAUTILUS_DESKTOP_DIRECTORY (directory); + + /* Find the entry in the table. */ + search_key.callback = callback; + search_key.callback_data = callback_data; + merged_callback = g_hash_table_lookup (desktop->details->callbacks, &search_key); + if (merged_callback == NULL) { + return; + } + + /* Remove from the hash table before working with it. */ + g_hash_table_steal (merged_callback->desktop_dir->details->callbacks, merged_callback); + + /* Tell all the directories to cancel the call. */ + for (node = merged_callback->non_ready_directories; node != NULL; node = node->next) { + nautilus_directory_cancel_callback + (node->data, + directory_ready_callback, merged_callback); + } + merged_callback_destroy (merged_callback); +} + +static void +merged_monitor_destroy (MergedMonitor *monitor) +{ + NautilusDesktopDirectory *desktop; + + desktop = monitor->desktop_dir; + + /* Call through to the real directory remove calls. */ + nautilus_directory_file_monitor_remove (desktop->details->real_directory, monitor); + + nautilus_directory_monitor_remove_internal (NAUTILUS_DIRECTORY (desktop), NULL, monitor); + + g_free (monitor); +} + +static void +build_merged_callback_list (NautilusDirectory *directory, + GList *file_list, + gpointer callback_data) +{ + GList **merged_list; + + merged_list = callback_data; + *merged_list = g_list_concat (*merged_list, + nautilus_file_list_copy (file_list)); +} + +static void +desktop_monitor_add (NautilusDirectory *directory, + gconstpointer client, + gboolean monitor_hidden_files, + NautilusFileAttributes file_attributes, + NautilusDirectoryCallback callback, + gpointer callback_data) +{ + NautilusDesktopDirectory *desktop; + MergedMonitor *monitor; + GList *merged_callback_list; + + desktop = NAUTILUS_DESKTOP_DIRECTORY (directory); + + /* Map the client to a unique value so this doesn't interfere + * with direct monitoring of the directory by the same client. + */ + monitor = g_hash_table_lookup (desktop->details->monitors, client); + if (monitor != NULL) { + g_assert (monitor->desktop_dir == desktop); + } else { + monitor = g_new0 (MergedMonitor, 1); + monitor->desktop_dir = desktop; + g_hash_table_insert (desktop->details->monitors, + (gpointer) client, monitor); + } + monitor->monitor_hidden_files = monitor_hidden_files; + monitor->monitor_attributes = file_attributes; + + /* Call through to the real directory add calls. */ + merged_callback_list = NULL; + + /* Call up to real dir */ + nautilus_directory_file_monitor_add + (desktop->details->real_directory, monitor, + monitor_hidden_files, + file_attributes, + build_merged_callback_list, &merged_callback_list); + + /* Handle the desktop part */ + merged_callback_list = g_list_concat (merged_callback_list, + nautilus_file_list_copy (directory->details->file_list)); + + + if (callback != NULL) { + (* callback) (directory, merged_callback_list, callback_data); + } + nautilus_file_list_free (merged_callback_list); +} + +static void +desktop_monitor_remove (NautilusDirectory *directory, + gconstpointer client) +{ + NautilusDesktopDirectory *desktop; + MergedMonitor *monitor; + + desktop = NAUTILUS_DESKTOP_DIRECTORY (directory); + + monitor = g_hash_table_lookup (desktop->details->monitors, client); + if (monitor == NULL) { + return; + } + + g_hash_table_remove (desktop->details->monitors, client); +} + +static void +desktop_force_reload (NautilusDirectory *directory) +{ + NautilusDesktopDirectory *desktop; + + desktop = NAUTILUS_DESKTOP_DIRECTORY (directory); + + nautilus_directory_force_reload (desktop->details->real_directory); + + /* We don't invalidate the files in desktop, since they are always + up to date. (And we don't ever want to mark them invalid.) */ +} + +static gboolean +desktop_are_all_files_seen (NautilusDirectory *directory) +{ + NautilusDesktopDirectory *desktop; + + desktop = NAUTILUS_DESKTOP_DIRECTORY (directory); + + if (!nautilus_directory_are_all_files_seen (desktop->details->real_directory)) { + return FALSE; + } + + return TRUE; +} + +static gboolean +desktop_is_not_empty (NautilusDirectory *directory) +{ + NautilusDesktopDirectory *desktop; + + desktop = NAUTILUS_DESKTOP_DIRECTORY (directory); + + if (nautilus_directory_is_not_empty (desktop->details->real_directory)) { + return TRUE; + } + + return directory->details->file_list != NULL; +} + +static GList * +desktop_get_file_list (NautilusDirectory *directory) +{ + GList *real_dir_file_list, *desktop_dir_file_list = NULL; + + real_dir_file_list = nautilus_directory_get_file_list + (NAUTILUS_DESKTOP_DIRECTORY (directory)->details->real_directory); + desktop_dir_file_list = NAUTILUS_DIRECTORY_CLASS (nautilus_desktop_directory_parent_class)->get_file_list (directory); + + return g_list_concat (real_dir_file_list, desktop_dir_file_list); +} + +NautilusDirectory * +nautilus_desktop_directory_get_real_directory (NautilusDesktopDirectory *desktop) +{ + nautilus_directory_ref (desktop->details->real_directory); + return desktop->details->real_directory; +} + + +static void +desktop_finalize (GObject *object) +{ + NautilusDesktopDirectory *desktop; + + desktop = NAUTILUS_DESKTOP_DIRECTORY (object); + + nautilus_directory_unref (desktop->details->real_directory); + + g_hash_table_destroy (desktop->details->callbacks); + g_hash_table_destroy (desktop->details->monitors); + g_free (desktop->details); + + g_signal_handlers_disconnect_by_func (nautilus_preferences, + desktop_directory_changed_callback, + desktop); + + G_OBJECT_CLASS (nautilus_desktop_directory_parent_class)->finalize (object); +} + +static void +done_loading_callback (NautilusDirectory *real_directory, + NautilusDesktopDirectory *desktop) +{ + nautilus_directory_emit_done_loading (NAUTILUS_DIRECTORY (desktop)); +} + + +static void +forward_files_added_cover (NautilusDirectory *real_directory, + GList *files, + gpointer callback_data) +{ + nautilus_directory_emit_files_added (NAUTILUS_DIRECTORY (callback_data), files); +} + +static void +forward_files_changed_cover (NautilusDirectory *real_directory, + GList *files, + gpointer callback_data) +{ + nautilus_directory_emit_files_changed (NAUTILUS_DIRECTORY (callback_data), files); +} + +static void +update_desktop_directory (NautilusDesktopDirectory *desktop) +{ + char *desktop_path; + char *desktop_uri; + NautilusDirectory *real_directory; + + real_directory = desktop->details->real_directory; + if (real_directory != NULL) { + g_hash_table_foreach_remove (desktop->details->callbacks, (GHRFunc) gtk_true, NULL); + g_hash_table_foreach_remove (desktop->details->monitors, (GHRFunc) gtk_true, NULL); + + g_signal_handlers_disconnect_by_func (real_directory, done_loading_callback, desktop); + g_signal_handlers_disconnect_by_func (real_directory, forward_files_added_cover, desktop); + g_signal_handlers_disconnect_by_func (real_directory, forward_files_changed_cover, desktop); + + nautilus_directory_unref (real_directory); + } + + desktop_path = nautilus_get_desktop_directory (); + desktop_uri = g_filename_to_uri (desktop_path, NULL, NULL); + real_directory = nautilus_directory_get_by_uri (desktop_uri); + g_free (desktop_uri); + g_free (desktop_path); + + g_signal_connect_object (real_directory, "done-loading", + G_CALLBACK (done_loading_callback), desktop, 0); + g_signal_connect_object (real_directory, "files-added", + G_CALLBACK (forward_files_added_cover), desktop, 0); + g_signal_connect_object (real_directory, "files-changed", + G_CALLBACK (forward_files_changed_cover), desktop, 0); + + desktop->details->real_directory = real_directory; +} + +static NautilusFile * +real_new_file_from_filename (NautilusDirectory *directory, + const char *filename, + gboolean self_owned) +{ + NautilusFile *file; + + g_assert (NAUTILUS_IS_DIRECTORY (directory)); + g_assert (filename != NULL); + g_assert (filename[0] != '\0'); + + if (self_owned) { + file = NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_DESKTOP_DIRECTORY_FILE, NULL)); + } else { + g_critical ("Accessing desktop uris directly is not supported."); + + return NULL; + } + + nautilus_file_set_directory (file, directory); + + return file; +} + +static gboolean +real_handles_location (GFile *location) +{ + g_autofree gchar *uri; + + uri = g_file_get_uri (location); + + return eel_uri_is_desktop (uri); +} + +static void +desktop_directory_changed_callback (gpointer data) +{ + update_desktop_directory (NAUTILUS_DESKTOP_DIRECTORY (data)); + nautilus_directory_force_reload (NAUTILUS_DIRECTORY (data)); +} + +static void +nautilus_desktop_directory_init (NautilusDesktopDirectory *desktop) +{ + desktop->details = g_new0 (NautilusDesktopDirectoryDetails, 1); + + desktop->details->callbacks = g_hash_table_new_full + (merged_callback_hash, merged_callback_equal, + NULL, (GDestroyNotify)merged_callback_destroy); + desktop->details->monitors = g_hash_table_new_full (NULL, NULL, + NULL, (GDestroyNotify)merged_monitor_destroy); + + update_desktop_directory (NAUTILUS_DESKTOP_DIRECTORY (desktop)); +} + +static void +nautilus_desktop_directory_class_init (NautilusDesktopDirectoryClass *class) +{ + NautilusDirectoryClass *directory_class; + + directory_class = NAUTILUS_DIRECTORY_CLASS (class); + + G_OBJECT_CLASS (class)->finalize = desktop_finalize; + + directory_class->contains_file = desktop_contains_file; + directory_class->call_when_ready = desktop_call_when_ready; + directory_class->cancel_callback = desktop_cancel_callback; + directory_class->file_monitor_add = desktop_monitor_add; + directory_class->file_monitor_remove = desktop_monitor_remove; + directory_class->force_reload = desktop_force_reload; + directory_class->are_all_files_seen = desktop_are_all_files_seen; + directory_class->is_not_empty = desktop_is_not_empty; + directory_class->new_file_from_filename = real_new_file_from_filename; + directory_class->handles_location = real_handles_location; + /* Override get_file_list so that we can return the list of files + * in NautilusDesktopDirectory->details->real_directory, + * in addition to the list of standard desktop icons on the desktop. + */ + directory_class->get_file_list = desktop_get_file_list; +} + diff --git a/nautilus-desktop/nautilus-desktop-directory.h b/nautilus-desktop/nautilus-desktop-directory.h new file mode 100644 index 000000000..9e9dc4949 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-directory.h @@ -0,0 +1,58 @@ +/* + nautilus-desktop-directory.h: Subclass of NautilusDirectory to implement + a virtual directory consisting of the desktop directory and the desktop + icons + + Copyright (C) 2003 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, see . + + Author: Alexander Larsson +*/ + +#ifndef NAUTILUS_DESKTOP_DIRECTORY_H +#define NAUTILUS_DESKTOP_DIRECTORY_H + +#include + +#define NAUTILUS_TYPE_DESKTOP_DIRECTORY nautilus_desktop_directory_get_type() +#define NAUTILUS_DESKTOP_DIRECTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_DESKTOP_DIRECTORY, NautilusDesktopDirectory)) +#define NAUTILUS_DESKTOP_DIRECTORY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DESKTOP_DIRECTORY, NautilusDesktopDirectoryClass)) +#define NAUTILUS_IS_DESKTOP_DIRECTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_DESKTOP_DIRECTORY)) +#define NAUTILUS_IS_DESKTOP_DIRECTORY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DESKTOP_DIRECTORY)) +#define NAUTILUS_DESKTOP_DIRECTORY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_DESKTOP_DIRECTORY, NautilusDesktopDirectoryClass)) + +#define NAUTILUS_DESKTOP_DIRECTORY_PROVIDER_NAME "desktop-directory-provider" + +typedef struct NautilusDesktopDirectoryDetails NautilusDesktopDirectoryDetails; + +typedef struct { + NautilusDirectory parent_slot; + NautilusDesktopDirectoryDetails *details; +} NautilusDesktopDirectory; + +typedef struct { + NautilusDirectoryClass parent_slot; + +} NautilusDesktopDirectoryClass; + +GType nautilus_desktop_directory_get_type (void); +NautilusDirectory * nautilus_desktop_directory_get_real_directory (NautilusDesktopDirectory *desktop_directory); + +#endif /* NAUTILUS_DESKTOP_DIRECTORY_H */ diff --git a/nautilus-desktop/nautilus-desktop-icon-file.c b/nautilus-desktop/nautilus-desktop-icon-file.c new file mode 100644 index 000000000..073b81318 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-icon-file.c @@ -0,0 +1,520 @@ +/* + nautilus-desktop-icon-file.c: Subclass of NautilusFile to help implement the + virtual desktop icons. + + Copyright (C) 2003 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, see . + + Author: Alexander Larsson +*/ + +#include +#include "nautilus-desktop-icon-file.h" +#include "nautilus-desktop-metadata.h" +#include "nautilus-desktop-directory-file.h" +#include "nautilus-desktop-directory.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +struct NautilusDesktopIconFileDetails { + NautilusDesktopLink *link; +}; + +G_DEFINE_TYPE(NautilusDesktopIconFile, nautilus_desktop_icon_file, NAUTILUS_TYPE_FILE) + + +static void +desktop_icon_file_monitor_add (NautilusFile *file, + gconstpointer client, + NautilusFileAttributes attributes) +{ + nautilus_directory_monitor_add_internal + (file->details->directory, file, + client, TRUE, attributes, NULL, NULL); +} + +static void +desktop_icon_file_monitor_remove (NautilusFile *file, + gconstpointer client) +{ + nautilus_directory_monitor_remove_internal + (file->details->directory, file, client); +} + +static void +desktop_icon_file_call_when_ready (NautilusFile *file, + NautilusFileAttributes attributes, + NautilusFileCallback callback, + gpointer callback_data) +{ + nautilus_directory_call_when_ready_internal + (file->details->directory, file, + attributes, FALSE, NULL, callback, callback_data); +} + +static void +desktop_icon_file_cancel_call_when_ready (NautilusFile *file, + NautilusFileCallback callback, + gpointer callback_data) +{ + nautilus_directory_cancel_callback_internal + (file->details->directory, file, + NULL, callback, callback_data); +} + +static gboolean +desktop_icon_file_check_if_ready (NautilusFile *file, + NautilusFileAttributes attributes) +{ + return nautilus_directory_check_if_ready_internal + (file->details->directory, file, + attributes); +} + +static gboolean +desktop_icon_file_get_item_count (NautilusFile *file, + guint *count, + gboolean *count_unreadable) +{ + if (count != NULL) { + *count = 0; + } + if (count_unreadable != NULL) { + *count_unreadable = FALSE; + } + return TRUE; +} + +static NautilusRequestStatus +desktop_icon_file_get_deep_counts (NautilusFile *file, + guint *directory_count, + guint *file_count, + guint *unreadable_directory_count, + goffset *total_size) +{ + if (directory_count != NULL) { + *directory_count = 0; + } + if (file_count != NULL) { + *file_count = 0; + } + if (unreadable_directory_count != NULL) { + *unreadable_directory_count = 0; + } + if (total_size != NULL) { + *total_size = 0; + } + + return NAUTILUS_REQUEST_DONE; +} + +static gboolean +desktop_icon_file_get_date (NautilusFile *file, + NautilusDateType date_type, + time_t *date) +{ + NautilusDesktopIconFile *desktop_file; + + desktop_file = NAUTILUS_DESKTOP_ICON_FILE (file); + + return nautilus_desktop_link_get_date (desktop_file->details->link, + date_type, date); +} + +static char * +desktop_icon_file_get_where_string (NautilusFile *file) +{ + return g_strdup (_("on the desktop")); +} + +static void +nautilus_desktop_icon_file_init (NautilusDesktopIconFile *desktop_file) +{ + desktop_file->details = G_TYPE_INSTANCE_GET_PRIVATE (desktop_file, + NAUTILUS_TYPE_DESKTOP_ICON_FILE, + NautilusDesktopIconFileDetails); +} + +static void +update_info_from_link (NautilusDesktopIconFile *icon_file) +{ + NautilusFile *file; + NautilusDesktopLink *link; + char *display_name; + GMount *mount; + + file = NAUTILUS_FILE (icon_file); + + link = icon_file->details->link; + + if (link == NULL) { + return; + } + + eel_ref_str_unref (file->details->mime_type); + file->details->mime_type = eel_ref_str_get_unique ("application/x-nautilus-link"); + file->details->type = G_FILE_TYPE_SHORTCUT; + file->details->size = 0; + file->details->has_permissions = FALSE; + file->details->can_read = TRUE; + file->details->can_write = TRUE; + + file->details->can_mount = FALSE; + file->details->can_unmount = FALSE; + file->details->can_eject = FALSE; + if (file->details->mount) { + g_object_unref (file->details->mount); + } + mount = nautilus_desktop_link_get_mount (link); + file->details->mount = mount; + if (mount) { + file->details->can_unmount = g_mount_can_unmount (mount); + file->details->can_eject = g_mount_can_eject (mount); + } + + file->details->file_info_is_up_to_date = TRUE; + + display_name = nautilus_desktop_link_get_display_name (link); + nautilus_file_set_display_name (file, + display_name, NULL, TRUE); + g_free (display_name); + + if (file->details->icon != NULL) { + g_object_unref (file->details->icon); + } + file->details->icon = nautilus_desktop_link_get_icon (link); + g_free (file->details->activation_uri); + file->details->activation_uri = nautilus_desktop_link_get_activation_uri (link); + file->details->got_link_info = TRUE; + file->details->link_info_is_up_to_date = TRUE; + + file->details->directory_count = 0; + file->details->got_directory_count = TRUE; + file->details->directory_count_is_up_to_date = TRUE; +} + +void +nautilus_desktop_icon_file_update (NautilusDesktopIconFile *icon_file) +{ + NautilusFile *file; + + update_info_from_link (icon_file); + file = NAUTILUS_FILE (icon_file); + nautilus_file_changed (file); +} + +void +nautilus_desktop_icon_file_remove (NautilusDesktopIconFile *icon_file) +{ + NautilusFile *file; + GList list; + + icon_file->details->link = NULL; + + file = NAUTILUS_FILE (icon_file); + + /* ref here because we might be removing the last ref when we + * mark the file gone below, but we need to keep a ref at + * least long enough to send the change notification. + */ + nautilus_file_ref (file); + + file->details->is_gone = TRUE; + + list.data = file; + list.next = NULL; + list.prev = NULL; + + nautilus_directory_remove_file (file->details->directory, file); + nautilus_directory_emit_change_signals (file->details->directory, &list); + + nautilus_file_unref (file); +} + +NautilusDesktopIconFile * +nautilus_desktop_icon_file_new (NautilusDesktopLink *link) +{ + NautilusFile *file; + NautilusDirectory *directory; + NautilusDesktopIconFile *icon_file; + GList list; + char *name; + + directory = nautilus_directory_get_by_uri (EEL_DESKTOP_URI); + + file = NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_DESKTOP_ICON_FILE, NULL)); + +#ifdef NAUTILUS_FILE_DEBUG_REF + printf("%10p ref'd\n", file); + eazel_dump_stack_trace ("\t", 10); +#endif + + nautilus_file_set_directory (file, directory); + + icon_file = NAUTILUS_DESKTOP_ICON_FILE (file); + icon_file->details->link = link; + + name = nautilus_desktop_link_get_file_name (link); + file->details->name = eel_ref_str_new (name); + g_free (name); + + update_info_from_link (icon_file); + + nautilus_desktop_update_metadata_from_keyfile (file, file->details->name); + + nautilus_directory_add_file (directory, file); + + list.data = file; + list.next = NULL; + list.prev = NULL; + nautilus_directory_emit_files_added (directory, &list); + + return icon_file; +} + +/* Note: This can return NULL if the link was recently removed (i.e. unmounted) */ +NautilusDesktopLink * +nautilus_desktop_icon_file_get_link (NautilusDesktopIconFile *icon_file) +{ + if (icon_file->details->link) + return g_object_ref (icon_file->details->link); + else + return NULL; +} + +static void +nautilus_desktop_icon_file_unmount (NautilusFile *file, + GMountOperation *mount_op, + GCancellable *cancellable, + NautilusFileOperationCallback callback, + gpointer callback_data) +{ + NautilusDesktopIconFile *desktop_file; + GMount *mount; + + desktop_file = NAUTILUS_DESKTOP_ICON_FILE (file); + if (desktop_file) { + mount = nautilus_desktop_link_get_mount (desktop_file->details->link); + if (mount != NULL) { + nautilus_file_operations_unmount_mount (NULL, mount, FALSE, TRUE); + } + } + +} + +static void +nautilus_desktop_icon_file_eject (NautilusFile *file, + GMountOperation *mount_op, + GCancellable *cancellable, + NautilusFileOperationCallback callback, + gpointer callback_data) +{ + NautilusDesktopIconFile *desktop_file; + GMount *mount; + + desktop_file = NAUTILUS_DESKTOP_ICON_FILE (file); + if (desktop_file) { + mount = nautilus_desktop_link_get_mount (desktop_file->details->link); + if (mount != NULL) { + nautilus_file_operations_unmount_mount (NULL, mount, TRUE, TRUE); + } + } +} + +static char* +real_get_target_uri (NautilusFile *file) +{ + char *uri = NULL; + GFile *location; + NautilusDesktopLink *link; + + g_return_val_if_fail (NAUTILUS_IS_DESKTOP_ICON_FILE (file), NULL); + + link = nautilus_desktop_icon_file_get_link (NAUTILUS_DESKTOP_ICON_FILE (file)); + + if (link != NULL) { + location = nautilus_desktop_link_get_activation_location (link); + g_object_unref (link); + if (location != NULL) { + uri = g_file_get_uri (location); + g_object_unref (location); + + return uri; + } + } + + return NAUTILUS_FILE_CLASS (nautilus_desktop_icon_file_parent_class)->get_target_uri (file); +} + +static void +real_rename (NautilusFile *file, + const char *new_name, + NautilusFileOperationCallback callback, + gpointer callback_data) +{ + NautilusDesktopLink *link; + char *old_name; + gboolean success; + GError *error; + + g_return_if_fail (NAUTILUS_IS_FILE (file)); + g_return_if_fail (new_name != NULL); + g_return_if_fail (callback != NULL); + + /* Can't rename a file that's already gone. + * We need to check this here because there may be a new + * file with the same name. + */ + if (nautilus_file_rename_handle_file_gone (file, callback, callback_data)) { + return; + } + + link = nautilus_desktop_icon_file_get_link (NAUTILUS_DESKTOP_ICON_FILE (file)); + old_name = nautilus_file_get_display_name (file); + + if ((old_name != NULL && strcmp (new_name, old_name) == 0)) { + success = TRUE; + } else { + success = (link != NULL && nautilus_desktop_link_rename (link, new_name)); + } + + if (success) { + (* callback) (file, NULL, NULL, callback_data); + } else { + error = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, + _("Unable to rename desktop icon")); + (* callback) (file, NULL, error, callback_data); + g_error_free (error); + } + + g_free (old_name); + g_object_unref (link); + + return; +} + +static gboolean +real_can_rename (NautilusFile *file) +{ + NautilusDesktopLink *link; + gboolean can_rename; + + can_rename = NAUTILUS_FILE_CLASS (nautilus_desktop_icon_file_parent_class)->can_rename (file); + + if (!can_rename) + return FALSE; + + link = nautilus_desktop_icon_file_get_link (NAUTILUS_DESKTOP_ICON_FILE (file)); + + /* Certain types of links can't be renamed */ + if (link != NULL) { + can_rename = nautilus_desktop_link_can_rename (link); + g_object_unref (link); + } + + return can_rename; +} + +static gboolean +real_drag_can_accept_files (NautilusFile *drop_target_item) +{ + return TRUE; +} + +static void +real_invalidate_attributes_internal (NautilusFile *file, + NautilusFileAttributes attributes) +{ + /* Desktop icon files are always up to date. + * If we invalidate their attributes they + * will lose data, so we just ignore them. + */ + return; +} + +static gboolean +real_opens_in_view (NautilusFile *file) +{ + return TRUE; +} + +static gboolean +real_is_special_link (NautilusFile *file) +{ + return TRUE; +} + +static void +nautilus_desktop_icon_file_set_metadata (NautilusFile *file, + const char *key, + const char *value) +{ + nautilus_desktop_set_metadata_string (file, file->details->name, key, value); +} + +static void +nautilus_desktop_icon_file_set_metadata_as_list (NautilusFile *file, + const char *key, + char **value) +{ + nautilus_desktop_set_metadata_stringv (file, file->details->name, key, (const gchar **) value); +} + +static void +nautilus_desktop_icon_file_class_init (NautilusDesktopIconFileClass *klass) +{ + GObjectClass *object_class; + NautilusFileClass *file_class; + + object_class = G_OBJECT_CLASS (klass); + file_class = NAUTILUS_FILE_CLASS (klass); + + file_class->default_file_type = G_FILE_TYPE_DIRECTORY; + + file_class->monitor_add = desktop_icon_file_monitor_add; + file_class->monitor_remove = desktop_icon_file_monitor_remove; + file_class->call_when_ready = desktop_icon_file_call_when_ready; + file_class->cancel_call_when_ready = desktop_icon_file_cancel_call_when_ready; + file_class->check_if_ready = desktop_icon_file_check_if_ready; + file_class->get_item_count = desktop_icon_file_get_item_count; + file_class->get_deep_counts = desktop_icon_file_get_deep_counts; + file_class->get_date = desktop_icon_file_get_date; + file_class->get_where_string = desktop_icon_file_get_where_string; + file_class->set_metadata = nautilus_desktop_icon_file_set_metadata; + file_class->set_metadata_as_list = nautilus_desktop_icon_file_set_metadata_as_list; + file_class->unmount = nautilus_desktop_icon_file_unmount; + file_class->eject = nautilus_desktop_icon_file_eject; + file_class->can_rename = real_can_rename; + file_class->rename = real_rename; + file_class->get_target_uri = real_get_target_uri; + file_class->drag_can_accept_files = real_drag_can_accept_files; + file_class->invalidate_attributes_internal = real_invalidate_attributes_internal; + file_class->opens_in_view = real_opens_in_view; + file_class->is_special_link = real_is_special_link; + + g_type_class_add_private (object_class, sizeof(NautilusDesktopIconFileDetails)); +} diff --git a/nautilus-desktop/nautilus-desktop-icon-file.h b/nautilus-desktop/nautilus-desktop-icon-file.h new file mode 100644 index 000000000..c65236531 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-icon-file.h @@ -0,0 +1,60 @@ +/* + nautilus-desktop-file.h: Subclass of NautilusFile to implement the + the case of a desktop icon file + + Copyright (C) 2003 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, see . + + Author: Alexander Larsson +*/ + +#ifndef NAUTILUS_DESKTOP_ICON_FILE_H +#define NAUTILUS_DESKTOP_ICON_FILE_H + +#include "nautilus-desktop-link.h" + +#include + +#define NAUTILUS_TYPE_DESKTOP_ICON_FILE nautilus_desktop_icon_file_get_type() +#define NAUTILUS_DESKTOP_ICON_FILE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_DESKTOP_ICON_FILE, NautilusDesktopIconFile)) +#define NAUTILUS_DESKTOP_ICON_FILE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DESKTOP_ICON_FILE, NautilusDesktopIconFileClass)) +#define NAUTILUS_IS_DESKTOP_ICON_FILE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_DESKTOP_ICON_FILE)) +#define NAUTILUS_IS_DESKTOP_ICON_FILE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DESKTOP_ICON_FILE)) +#define NAUTILUS_DESKTOP_ICON_FILE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_DESKTOP_ICON_FILE, NautilusDesktopIconFileClass)) + +typedef struct NautilusDesktopIconFileDetails NautilusDesktopIconFileDetails; + +typedef struct { + NautilusFile parent_slot; + NautilusDesktopIconFileDetails *details; +} NautilusDesktopIconFile; + +typedef struct { + NautilusFileClass parent_slot; +} NautilusDesktopIconFileClass; + +GType nautilus_desktop_icon_file_get_type (void); + +NautilusDesktopIconFile *nautilus_desktop_icon_file_new (NautilusDesktopLink *link); +void nautilus_desktop_icon_file_update (NautilusDesktopIconFile *icon_file); +void nautilus_desktop_icon_file_remove (NautilusDesktopIconFile *icon_file); +NautilusDesktopLink *nautilus_desktop_icon_file_get_link (NautilusDesktopIconFile *icon_file); + +#endif /* NAUTILUS_DESKTOP_ICON_FILE_H */ diff --git a/nautilus-desktop/nautilus-desktop-link-monitor.c b/nautilus-desktop/nautilus-desktop-link-monitor.c new file mode 100644 index 000000000..54ce6daf9 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-link-monitor.c @@ -0,0 +1,432 @@ +/* + nautilus-desktop-link-monitor.c: singleton thatn manages the links + + Copyright (C) 2003 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, see . + + Author: Alexander Larsson +*/ + +#include +#include "nautilus-desktop-link-monitor.h" +#include "nautilus-desktop-link.h" +#include "nautilus-desktop-icon-file.h" +#include "nautilus-desktop-directory.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +struct NautilusDesktopLinkMonitorDetails { + GVolumeMonitor *volume_monitor; + NautilusDirectory *desktop_dir; + + NautilusDesktopLink *home_link; + NautilusDesktopLink *trash_link; + NautilusDesktopLink *network_link; + + GList *mount_links; +}; + +G_DEFINE_TYPE (NautilusDesktopLinkMonitor, nautilus_desktop_link_monitor, G_TYPE_OBJECT); + +static NautilusDesktopLinkMonitor *the_link_monitor = NULL; + +void +nautilus_desktop_link_monitor_shutdown (void) +{ + g_clear_object (&the_link_monitor); +} + +NautilusDesktopLinkMonitor * +nautilus_desktop_link_monitor_get (void) +{ + if (the_link_monitor == NULL) { + g_object_new (NAUTILUS_TYPE_DESKTOP_LINK_MONITOR, NULL); + eel_debug_call_at_shutdown (nautilus_desktop_link_monitor_shutdown); + } + return the_link_monitor; +} + +static gboolean +volume_file_name_used (NautilusDesktopLinkMonitor *monitor, + const char *name) +{ + GList *l; + char *other_name; + gboolean same; + + for (l = monitor->details->mount_links; l != NULL; l = l->next) { + other_name = nautilus_desktop_link_get_file_name (l->data); + same = strcmp (name, other_name) == 0; + g_free (other_name); + + if (same) { + return TRUE; + } + } + + return FALSE; +} + +char * +nautilus_desktop_link_monitor_make_filename_unique (NautilusDesktopLinkMonitor *monitor, + const char *filename) +{ + char *unique_name; + int i; + + i = 2; + unique_name = g_strdup (filename); + while (volume_file_name_used (monitor, unique_name)) { + g_free (unique_name); + unique_name = g_strdup_printf ("%s.%d", filename, i++); + } + return unique_name; +} + +static gboolean +has_mount (NautilusDesktopLinkMonitor *monitor, + GMount *mount) +{ + gboolean ret; + GMount *other_mount; + GList *l; + + ret = FALSE; + + for (l = monitor->details->mount_links; l != NULL; l = l->next) { + other_mount = nautilus_desktop_link_get_mount (l->data); + if (mount == other_mount) { + g_object_unref (other_mount); + ret = TRUE; + break; + } + g_object_unref (other_mount); + } + + return ret; +} + +static void +create_mount_link (NautilusDesktopLinkMonitor *monitor, + GMount *mount) +{ + NautilusDesktopLink *link; + + if (has_mount (monitor, mount)) + return; + + if ((!g_mount_is_shadowed (mount)) && + g_settings_get_boolean (nautilus_desktop_preferences, + NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE)) { + link = nautilus_desktop_link_new_from_mount (mount); + monitor->details->mount_links = g_list_prepend (monitor->details->mount_links, link); + } +} + +static void +remove_mount_link (NautilusDesktopLinkMonitor *monitor, + GMount *mount) +{ + GList *l; + NautilusDesktopLink *link; + GMount *other_mount; + + link = NULL; + for (l = monitor->details->mount_links; l != NULL; l = l->next) { + other_mount = nautilus_desktop_link_get_mount (l->data); + if (mount == other_mount) { + g_object_unref (other_mount); + link = l->data; + break; + } + g_object_unref (other_mount); + } + + if (link) { + monitor->details->mount_links = g_list_remove (monitor->details->mount_links, link); + g_object_unref (link); + } +} + + + +static void +mount_added_callback (GVolumeMonitor *volume_monitor, + GMount *mount, + NautilusDesktopLinkMonitor *monitor) +{ + create_mount_link (monitor, mount); +} + + +static void +mount_removed_callback (GVolumeMonitor *volume_monitor, + GMount *mount, + NautilusDesktopLinkMonitor *monitor) +{ + remove_mount_link (monitor, mount); +} + +static void +mount_changed_callback (GVolumeMonitor *volume_monitor, + GMount *mount, + NautilusDesktopLinkMonitor *monitor) +{ + /* TODO: update the mount with other details */ + + /* remove a mount if it goes into the shadows */ + if (g_mount_is_shadowed (mount) && has_mount (monitor, mount)) { + remove_mount_link (monitor, mount); + }} + +static void +update_link_visibility (NautilusDesktopLinkMonitor *monitor, + NautilusDesktopLink **link_ref, + NautilusDesktopLinkType link_type, + const char *preference_key) +{ + if (g_settings_get_boolean (nautilus_desktop_preferences, preference_key)) { + if (*link_ref == NULL) { + *link_ref = nautilus_desktop_link_new (link_type); + } + } else { + if (*link_ref != NULL) { + g_object_unref (*link_ref); + *link_ref = NULL; + } + } +} + +static void +desktop_home_visible_changed (gpointer callback_data) +{ + NautilusDesktopLinkMonitor *monitor; + + monitor = NAUTILUS_DESKTOP_LINK_MONITOR (callback_data); + + update_link_visibility (NAUTILUS_DESKTOP_LINK_MONITOR (monitor), + &monitor->details->home_link, + NAUTILUS_DESKTOP_LINK_HOME, + NAUTILUS_PREFERENCES_DESKTOP_HOME_VISIBLE); +} + +static void +desktop_trash_visible_changed (gpointer callback_data) +{ + NautilusDesktopLinkMonitor *monitor; + + monitor = NAUTILUS_DESKTOP_LINK_MONITOR (callback_data); + + update_link_visibility (NAUTILUS_DESKTOP_LINK_MONITOR (callback_data), + &monitor->details->trash_link, + NAUTILUS_DESKTOP_LINK_TRASH, + NAUTILUS_PREFERENCES_DESKTOP_TRASH_VISIBLE); +} + +static void +desktop_network_visible_changed (gpointer callback_data) +{ + NautilusDesktopLinkMonitor *monitor; + + monitor = NAUTILUS_DESKTOP_LINK_MONITOR (callback_data); + + update_link_visibility (NAUTILUS_DESKTOP_LINK_MONITOR (callback_data), + &monitor->details->network_link, + NAUTILUS_DESKTOP_LINK_NETWORK, + NAUTILUS_PREFERENCES_DESKTOP_NETWORK_VISIBLE); +} + +static void +desktop_volumes_visible_changed (gpointer callback_data) +{ + NautilusDesktopLinkMonitor *monitor; + GList *l, *mounts; + + monitor = NAUTILUS_DESKTOP_LINK_MONITOR (callback_data); + + if (g_settings_get_boolean (nautilus_desktop_preferences, + NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE)) { + if (monitor->details->mount_links == NULL) { + mounts = g_volume_monitor_get_mounts (monitor->details->volume_monitor); + for (l = mounts; l != NULL; l = l->next) { + create_mount_link (monitor, l->data); + g_object_unref (l->data); + } + g_list_free (mounts); + } + } else { + g_list_foreach (monitor->details->mount_links, (GFunc)g_object_unref, NULL); + g_list_free (monitor->details->mount_links); + monitor->details->mount_links = NULL; + } +} + +static void +create_link_and_add_preference (NautilusDesktopLink **link_ref, + NautilusDesktopLinkType link_type, + const char *preference_key, + GCallback callback, + gpointer callback_data) +{ + char *detailed_signal; + + if (g_settings_get_boolean (nautilus_desktop_preferences, preference_key)) { + *link_ref = nautilus_desktop_link_new (link_type); + } + + detailed_signal = g_strconcat ("changed::", preference_key, NULL); + g_signal_connect_swapped (nautilus_desktop_preferences, + detailed_signal, + callback, callback_data); + + g_free (detailed_signal); +} + +static void +nautilus_desktop_link_monitor_init (NautilusDesktopLinkMonitor *monitor) +{ + GList *l, *mounts; + GMount *mount; + + monitor->details = G_TYPE_INSTANCE_GET_PRIVATE (monitor, NAUTILUS_TYPE_DESKTOP_LINK_MONITOR, + NautilusDesktopLinkMonitorDetails); + + the_link_monitor = monitor; + monitor->details->volume_monitor = g_volume_monitor_get (); + + /* We keep around a ref to the desktop dir */ + monitor->details->desktop_dir = nautilus_directory_get_by_uri (EEL_DESKTOP_URI); + + /* Default links */ + + create_link_and_add_preference (&monitor->details->home_link, + NAUTILUS_DESKTOP_LINK_HOME, + NAUTILUS_PREFERENCES_DESKTOP_HOME_VISIBLE, + G_CALLBACK (desktop_home_visible_changed), + monitor); + + create_link_and_add_preference (&monitor->details->trash_link, + NAUTILUS_DESKTOP_LINK_TRASH, + NAUTILUS_PREFERENCES_DESKTOP_TRASH_VISIBLE, + G_CALLBACK (desktop_trash_visible_changed), + monitor); + + create_link_and_add_preference (&monitor->details->network_link, + NAUTILUS_DESKTOP_LINK_NETWORK, + NAUTILUS_PREFERENCES_DESKTOP_NETWORK_VISIBLE, + G_CALLBACK (desktop_network_visible_changed), + monitor); + + /* Mount links */ + + mounts = g_volume_monitor_get_mounts (monitor->details->volume_monitor); + for (l = mounts; l != NULL; l = l->next) { + mount = l->data; + create_mount_link (monitor, mount); + g_object_unref (mount); + } + g_list_free (mounts); + + g_signal_connect_swapped (nautilus_desktop_preferences, + "changed::" NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE, + G_CALLBACK (desktop_volumes_visible_changed), + monitor); + + g_signal_connect_object (monitor->details->volume_monitor, "mount-added", + G_CALLBACK (mount_added_callback), monitor, 0); + g_signal_connect_object (monitor->details->volume_monitor, "mount-removed", + G_CALLBACK (mount_removed_callback), monitor, 0); + g_signal_connect_object (monitor->details->volume_monitor, "mount-changed", + G_CALLBACK (mount_changed_callback), monitor, 0); +} + +static void +remove_link_and_preference (NautilusDesktopLink **link_ref, + const char *preference_key, + GCallback callback, + gpointer callback_data) +{ + if (*link_ref != NULL) { + g_object_unref (*link_ref); + *link_ref = NULL; + } + + g_signal_handlers_disconnect_by_func (nautilus_desktop_preferences, + callback, callback_data); +} + +static void +desktop_link_monitor_finalize (GObject *object) +{ + NautilusDesktopLinkMonitor *monitor; + + monitor = NAUTILUS_DESKTOP_LINK_MONITOR (object); + + /* Default links */ + + remove_link_and_preference (&monitor->details->home_link, + NAUTILUS_PREFERENCES_DESKTOP_HOME_VISIBLE, + G_CALLBACK (desktop_home_visible_changed), + monitor); + + remove_link_and_preference (&monitor->details->trash_link, + NAUTILUS_PREFERENCES_DESKTOP_TRASH_VISIBLE, + G_CALLBACK (desktop_trash_visible_changed), + monitor); + + remove_link_and_preference (&monitor->details->network_link, + NAUTILUS_PREFERENCES_DESKTOP_NETWORK_VISIBLE, + G_CALLBACK (desktop_network_visible_changed), + monitor); + + /* Mounts */ + + g_list_foreach (monitor->details->mount_links, (GFunc)g_object_unref, NULL); + g_list_free (monitor->details->mount_links); + monitor->details->mount_links = NULL; + + nautilus_directory_unref (monitor->details->desktop_dir); + monitor->details->desktop_dir = NULL; + + g_signal_handlers_disconnect_by_func (nautilus_desktop_preferences, + desktop_volumes_visible_changed, + monitor); + + g_object_unref (monitor->details->volume_monitor); + + G_OBJECT_CLASS (nautilus_desktop_link_monitor_parent_class)->finalize (object); +} + +static void +nautilus_desktop_link_monitor_class_init (NautilusDesktopLinkMonitorClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = desktop_link_monitor_finalize; + + g_type_class_add_private (klass, sizeof (NautilusDesktopLinkMonitorDetails)); +} diff --git a/nautilus-desktop/nautilus-desktop-link-monitor.h b/nautilus-desktop/nautilus-desktop-link-monitor.h new file mode 100644 index 000000000..304f23910 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-link-monitor.h @@ -0,0 +1,60 @@ +/* + nautilus-desktop-link-monitor.h: singleton that manages the desktop links + + Copyright (C) 2003 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, see . + + Author: Alexander Larsson +*/ + +#ifndef NAUTILUS_DESKTOP_LINK_MONITOR_H +#define NAUTILUS_DESKTOP_LINK_MONITOR_H + +#include +#include "nautilus-desktop-link.h" + +#define NAUTILUS_TYPE_DESKTOP_LINK_MONITOR nautilus_desktop_link_monitor_get_type() +#define NAUTILUS_DESKTOP_LINK_MONITOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_DESKTOP_LINK_MONITOR, NautilusDesktopLinkMonitor)) +#define NAUTILUS_DESKTOP_LINK_MONITOR_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DESKTOP_LINK_MONITOR, NautilusDesktopLinkMonitorClass)) +#define NAUTILUS_IS_DESKTOP_LINK_MONITOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_DESKTOP_LINK_MONITOR)) +#define NAUTILUS_IS_DESKTOP_LINK_MONITOR_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DESKTOP_LINK_MONITOR)) +#define NAUTILUS_DESKTOP_LINK_MONITOR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_DESKTOP_LINK_MONITOR, NautilusDesktopLinkMonitorClass)) + +typedef struct NautilusDesktopLinkMonitorDetails NautilusDesktopLinkMonitorDetails; + +typedef struct { + GObject parent_slot; + NautilusDesktopLinkMonitorDetails *details; +} NautilusDesktopLinkMonitor; + +typedef struct { + GObjectClass parent_slot; +} NautilusDesktopLinkMonitorClass; + +GType nautilus_desktop_link_monitor_get_type (void); + +NautilusDesktopLinkMonitor * nautilus_desktop_link_monitor_get (void); +void nautilus_desktop_link_monitor_shutdown (void); + +/* Used by nautilus-desktop-link.c */ +char * nautilus_desktop_link_monitor_make_filename_unique (NautilusDesktopLinkMonitor *monitor, + const char *filename); + +#endif /* NAUTILUS_DESKTOP_LINK_MONITOR_H */ diff --git a/nautilus-desktop/nautilus-desktop-link.c b/nautilus-desktop/nautilus-desktop-link.c new file mode 100644 index 000000000..df2566361 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-link.c @@ -0,0 +1,436 @@ +/* + nautilus-desktop-link.c: Class that handles the links on the desktop + + Copyright (C) 2003 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, see . + + Author: Alexander Larsson +*/ + +#include + +#include "nautilus-desktop-link.h" +#include "nautilus-desktop-link-monitor.h" +#include "nautilus-desktop-icon-file.h" +#include "nautilus-directory-private.h" +#include "nautilus-desktop-directory.h" + +#include +#include + +#include +#include +#include +#include + +#include + +struct NautilusDesktopLinkDetails { + NautilusDesktopLinkType type; + char *filename; + char *display_name; + GFile *activation_location; + GIcon *icon; + + NautilusDesktopIconFile *icon_file; + + /* Just for mount icons: */ + GMount *mount; +}; + +G_DEFINE_TYPE(NautilusDesktopLink, nautilus_desktop_link, G_TYPE_OBJECT) + +static void +create_icon_file (NautilusDesktopLink *link) +{ + link->details->icon_file = nautilus_desktop_icon_file_new (link); +} + +static void +nautilus_desktop_link_changed (NautilusDesktopLink *link) +{ + if (link->details->icon_file != NULL) { + nautilus_desktop_icon_file_update (link->details->icon_file); + } +} + +static void +mount_changed_callback (GMount *mount, NautilusDesktopLink *link) +{ + g_free (link->details->display_name); + if (link->details->activation_location) { + g_object_unref (link->details->activation_location); + } + if (link->details->icon) { + g_object_unref (link->details->icon); + } + + link->details->display_name = g_mount_get_name (mount); + link->details->activation_location = g_mount_get_default_location (mount); + link->details->icon = g_mount_get_icon (mount); + + nautilus_desktop_link_changed (link); +} + +static GIcon * +get_desktop_trash_icon (void) +{ + const gchar *icon_name; + + if (nautilus_trash_monitor_is_empty ()) { + icon_name = NAUTILUS_DESKTOP_ICON_TRASH; + } else { + icon_name = NAUTILUS_DESKTOP_ICON_TRASH_FULL; + } + + return g_themed_icon_new (icon_name); +} + +static void +trash_state_changed_callback (NautilusTrashMonitor *trash_monitor, + gboolean state, + gpointer callback_data) +{ + NautilusDesktopLink *link; + + link = NAUTILUS_DESKTOP_LINK (callback_data); + g_assert (link->details->type == NAUTILUS_DESKTOP_LINK_TRASH); + + if (link->details->icon) { + g_object_unref (link->details->icon); + } + link->details->icon = get_desktop_trash_icon (); + + nautilus_desktop_link_changed (link); +} + +static void +home_name_changed (gpointer callback_data) +{ + NautilusDesktopLink *link; + + link = NAUTILUS_DESKTOP_LINK (callback_data); + g_assert (link->details->type == NAUTILUS_DESKTOP_LINK_HOME); + + g_free (link->details->display_name); + link->details->display_name = g_settings_get_string (nautilus_desktop_preferences, + NAUTILUS_PREFERENCES_DESKTOP_HOME_NAME); + if (link->details->display_name[0] == 0) { + g_free (link->details->display_name); + link->details->display_name = g_strdup (_("Home")); + } + + nautilus_desktop_link_changed (link); +} + +static void +trash_name_changed (gpointer callback_data) +{ + NautilusDesktopLink *link; + + link = NAUTILUS_DESKTOP_LINK (callback_data); + g_assert (link->details->type == NAUTILUS_DESKTOP_LINK_TRASH); + + g_free (link->details->display_name); + link->details->display_name = g_settings_get_string (nautilus_desktop_preferences, + NAUTILUS_PREFERENCES_DESKTOP_TRASH_NAME); + nautilus_desktop_link_changed (link); +} + +static void +network_name_changed (gpointer callback_data) +{ + NautilusDesktopLink *link; + + link = NAUTILUS_DESKTOP_LINK (callback_data); + g_assert (link->details->type == NAUTILUS_DESKTOP_LINK_NETWORK); + + g_free (link->details->display_name); + link->details->display_name = g_settings_get_string (nautilus_desktop_preferences, + NAUTILUS_PREFERENCES_DESKTOP_NETWORK_NAME); + nautilus_desktop_link_changed (link); +} + +NautilusDesktopLink * +nautilus_desktop_link_new (NautilusDesktopLinkType type) +{ + NautilusDesktopLink *link; + + link = NAUTILUS_DESKTOP_LINK (g_object_new (NAUTILUS_TYPE_DESKTOP_LINK, NULL)); + + link->details->type = type; + switch (type) { + case NAUTILUS_DESKTOP_LINK_HOME: + link->details->filename = g_strdup ("home"); + link->details->display_name = g_settings_get_string (nautilus_desktop_preferences, + NAUTILUS_PREFERENCES_DESKTOP_HOME_NAME); + link->details->activation_location = g_file_new_for_path (g_get_home_dir ()); + link->details->icon = g_themed_icon_new (NAUTILUS_DESKTOP_ICON_HOME); + + g_signal_connect_swapped (nautilus_desktop_preferences, + "changed::" NAUTILUS_PREFERENCES_DESKTOP_HOME_NAME, + G_CALLBACK (home_name_changed), + link); + break; + + case NAUTILUS_DESKTOP_LINK_TRASH: + link->details->filename = g_strdup ("trash"); + link->details->display_name = g_settings_get_string (nautilus_desktop_preferences, + NAUTILUS_PREFERENCES_DESKTOP_TRASH_NAME); + link->details->activation_location = g_file_new_for_uri (EEL_TRASH_URI); + link->details->icon = get_desktop_trash_icon (); + + g_signal_connect_swapped (nautilus_desktop_preferences, + "changed::" NAUTILUS_PREFERENCES_DESKTOP_TRASH_NAME, + G_CALLBACK (trash_name_changed), + link); + g_signal_connect_object (nautilus_trash_monitor_get (), "trash-state-changed", + G_CALLBACK (trash_state_changed_callback), link, 0); + break; + + case NAUTILUS_DESKTOP_LINK_NETWORK: + link->details->filename = g_strdup ("network"); + link->details->display_name = g_settings_get_string (nautilus_desktop_preferences, + NAUTILUS_PREFERENCES_DESKTOP_NETWORK_NAME); + link->details->activation_location = g_file_new_for_uri ("network:///"); + link->details->icon = g_themed_icon_new (NAUTILUS_DESKTOP_ICON_NETWORK); + + g_signal_connect_swapped (nautilus_desktop_preferences, + "changed::" NAUTILUS_PREFERENCES_DESKTOP_NETWORK_NAME, + G_CALLBACK (network_name_changed), + link); + break; + + default: + case NAUTILUS_DESKTOP_LINK_MOUNT: + g_assert_not_reached(); + } + + create_icon_file (link); + + return link; +} + +NautilusDesktopLink * +nautilus_desktop_link_new_from_mount (GMount *mount) +{ + NautilusDesktopLink *link; + GVolume *volume; + char *name, *filename; + + link = NAUTILUS_DESKTOP_LINK (g_object_new (NAUTILUS_TYPE_DESKTOP_LINK, NULL)); + + link->details->type = NAUTILUS_DESKTOP_LINK_MOUNT; + + link->details->mount = g_object_ref (mount); + + /* We try to use the drive name to get somewhat stable filenames + for metadata */ + volume = g_mount_get_volume (mount); + if (volume != NULL) { + name = g_volume_get_name (volume); + g_object_unref (volume); + } else { + name = g_mount_get_name (mount); + } + + /* Replace slashes in name */ + filename = g_strconcat (g_strdelimit (name, "/", '-'), ".volume", NULL); + link->details->filename = + nautilus_desktop_link_monitor_make_filename_unique (nautilus_desktop_link_monitor_get (), + filename); + g_free (filename); + g_free (name); + + link->details->display_name = g_mount_get_name (mount); + + link->details->activation_location = g_mount_get_default_location (mount); + link->details->icon = g_mount_get_icon (mount); + + g_signal_connect_object (mount, "changed", + G_CALLBACK (mount_changed_callback), link, 0); + + create_icon_file (link); + + return link; +} + +GMount * +nautilus_desktop_link_get_mount (NautilusDesktopLink *link) +{ + if (link->details->mount) { + return g_object_ref (link->details->mount); + } + return NULL; +} + +NautilusDesktopLinkType +nautilus_desktop_link_get_link_type (NautilusDesktopLink *link) +{ + return link->details->type; +} + +char * +nautilus_desktop_link_get_file_name (NautilusDesktopLink *link) +{ + return g_strdup (link->details->filename); +} + +char * +nautilus_desktop_link_get_display_name (NautilusDesktopLink *link) +{ + return g_strdup (link->details->display_name); +} + +GIcon * +nautilus_desktop_link_get_icon (NautilusDesktopLink *link) +{ + if (link->details->icon != NULL) { + return g_object_ref (link->details->icon); + } + return NULL; +} + +GFile * +nautilus_desktop_link_get_activation_location (NautilusDesktopLink *link) +{ + if (link->details->activation_location) { + return g_object_ref (link->details->activation_location); + } + return NULL; +} + +char * +nautilus_desktop_link_get_activation_uri (NautilusDesktopLink *link) +{ + if (link->details->activation_location) { + return g_file_get_uri (link->details->activation_location); + } + return NULL; +} + + +gboolean +nautilus_desktop_link_get_date (NautilusDesktopLink *link, + NautilusDateType date_type, + time_t *date) +{ + return FALSE; +} + +gboolean +nautilus_desktop_link_can_rename (NautilusDesktopLink *link) +{ + return (link->details->type == NAUTILUS_DESKTOP_LINK_HOME || + link->details->type == NAUTILUS_DESKTOP_LINK_TRASH || + link->details->type == NAUTILUS_DESKTOP_LINK_NETWORK); +} + +gboolean +nautilus_desktop_link_rename (NautilusDesktopLink *link, + const char *name) +{ + switch (link->details->type) { + case NAUTILUS_DESKTOP_LINK_HOME: + g_settings_set_string (nautilus_desktop_preferences, + NAUTILUS_PREFERENCES_DESKTOP_HOME_NAME, + name); + break; + case NAUTILUS_DESKTOP_LINK_TRASH: + g_settings_set_string (nautilus_desktop_preferences, + NAUTILUS_PREFERENCES_DESKTOP_TRASH_NAME, + name); + break; + case NAUTILUS_DESKTOP_LINK_NETWORK: + g_settings_set_string (nautilus_desktop_preferences, + NAUTILUS_PREFERENCES_DESKTOP_NETWORK_NAME, + name); + break; + default: + g_assert_not_reached (); + /* FIXME: Do we want volume renaming? + * We didn't support that before. */ + break; + } + + return TRUE; +} + +static void +nautilus_desktop_link_init (NautilusDesktopLink *link) +{ + link->details = G_TYPE_INSTANCE_GET_PRIVATE (link, + NAUTILUS_TYPE_DESKTOP_LINK, + NautilusDesktopLinkDetails); +} + +static void +desktop_link_finalize (GObject *object) +{ + NautilusDesktopLink *link; + + link = NAUTILUS_DESKTOP_LINK (object); + + if (link->details->icon_file != NULL) { + nautilus_desktop_icon_file_remove (link->details->icon_file); + nautilus_file_unref (NAUTILUS_FILE (link->details->icon_file)); + link->details->icon_file = NULL; + } + + if (link->details->type == NAUTILUS_DESKTOP_LINK_HOME) { + g_signal_handlers_disconnect_by_func (nautilus_desktop_preferences, + home_name_changed, + link); + } + + if (link->details->type == NAUTILUS_DESKTOP_LINK_TRASH) { + g_signal_handlers_disconnect_by_func (nautilus_desktop_preferences, + trash_name_changed, + link); + } + + if (link->details->type == NAUTILUS_DESKTOP_LINK_NETWORK) { + g_signal_handlers_disconnect_by_func (nautilus_desktop_preferences, + network_name_changed, + link); + } + + if (link->details->type == NAUTILUS_DESKTOP_LINK_MOUNT) { + g_object_unref (link->details->mount); + } + + g_free (link->details->filename); + g_free (link->details->display_name); + if (link->details->activation_location) { + g_object_unref (link->details->activation_location); + } + if (link->details->icon) { + g_object_unref (link->details->icon); + } + + G_OBJECT_CLASS (nautilus_desktop_link_parent_class)->finalize (object); +} + +static void +nautilus_desktop_link_class_init (NautilusDesktopLinkClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = desktop_link_finalize; + + g_type_class_add_private (object_class, sizeof(NautilusDesktopLinkDetails)); +} diff --git a/nautilus-desktop/nautilus-desktop-link.h b/nautilus-desktop/nautilus-desktop-link.h new file mode 100644 index 000000000..7c1025b40 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-link.h @@ -0,0 +1,77 @@ +/* + nautilus-desktop-link.h: Class that handles the links on the desktop + + Copyright (C) 2003 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, see . + + Author: Alexander Larsson +*/ + +#ifndef NAUTILUS_DESKTOP_LINK_H +#define NAUTILUS_DESKTOP_LINK_H + +#include +#include + +#define NAUTILUS_TYPE_DESKTOP_LINK nautilus_desktop_link_get_type() +#define NAUTILUS_DESKTOP_LINK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_DESKTOP_LINK, NautilusDesktopLink)) +#define NAUTILUS_DESKTOP_LINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DESKTOP_LINK, NautilusDesktopLinkClass)) +#define NAUTILUS_IS_DESKTOP_LINK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_DESKTOP_LINK)) +#define NAUTILUS_IS_DESKTOP_LINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DESKTOP_LINK)) +#define NAUTILUS_DESKTOP_LINK_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_DESKTOP_LINK, NautilusDesktopLinkClass)) + +typedef struct NautilusDesktopLinkDetails NautilusDesktopLinkDetails; + +typedef struct { + GObject parent_slot; + NautilusDesktopLinkDetails *details; +} NautilusDesktopLink; + +typedef struct { + GObjectClass parent_slot; +} NautilusDesktopLinkClass; + +typedef enum { + NAUTILUS_DESKTOP_LINK_HOME, + NAUTILUS_DESKTOP_LINK_TRASH, + NAUTILUS_DESKTOP_LINK_MOUNT, + NAUTILUS_DESKTOP_LINK_NETWORK +} NautilusDesktopLinkType; + +GType nautilus_desktop_link_get_type (void); + +NautilusDesktopLink * nautilus_desktop_link_new (NautilusDesktopLinkType type); +NautilusDesktopLink * nautilus_desktop_link_new_from_mount (GMount *mount); +NautilusDesktopLinkType nautilus_desktop_link_get_link_type (NautilusDesktopLink *link); +char * nautilus_desktop_link_get_file_name (NautilusDesktopLink *link); +char * nautilus_desktop_link_get_display_name (NautilusDesktopLink *link); +GIcon * nautilus_desktop_link_get_icon (NautilusDesktopLink *link); +GFile * nautilus_desktop_link_get_activation_location (NautilusDesktopLink *link); +char * nautilus_desktop_link_get_activation_uri (NautilusDesktopLink *link); +gboolean nautilus_desktop_link_get_date (NautilusDesktopLink *link, + NautilusDateType date_type, + time_t *date); +GMount * nautilus_desktop_link_get_mount (NautilusDesktopLink *link); +gboolean nautilus_desktop_link_can_rename (NautilusDesktopLink *link); +gboolean nautilus_desktop_link_rename (NautilusDesktopLink *link, + const char *name); + + +#endif /* NAUTILUS_DESKTOP_LINK_H */ diff --git a/nautilus-desktop/nautilus-desktop-metadata.c b/nautilus-desktop/nautilus-desktop-metadata.c new file mode 100644 index 000000000..91a120095 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-metadata.c @@ -0,0 +1,90 @@ +/* + * Nautilus + * + * Copyright (C) 2011 Red Hat, Inc. + * + * Nautilus is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Nautilus is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; see the file COPYING. If not, + * see . + * + * Authors: Cosimo Cecchi + */ + +#include + +#include "nautilus-desktop-metadata.h" + +#include +#include + +static gchar * +get_keyfile_path (void) +{ + gchar *xdg_dir, *retval; + + xdg_dir = nautilus_get_user_directory (); + retval = g_build_filename (xdg_dir, "desktop-metadata", NULL); + + g_free (xdg_dir); + + return retval; +} + +void +nautilus_desktop_set_metadata_string (NautilusFile *file, + const gchar *name, + const gchar *key, + const gchar *string) +{ + gchar *keyfile_filename; + + keyfile_filename = get_keyfile_path (); + + nautilus_keyfile_metadata_set_string (file, keyfile_filename, + name, key, string); + + g_free (keyfile_filename); +} + +void +nautilus_desktop_set_metadata_stringv (NautilusFile *file, + const char *name, + const char *key, + const char * const *stringv) +{ + gchar *keyfile_filename; + + keyfile_filename = get_keyfile_path (); + + nautilus_keyfile_metadata_set_stringv (file, keyfile_filename, + name, key, stringv); + + g_free (keyfile_filename); +} + +gboolean +nautilus_desktop_update_metadata_from_keyfile (NautilusFile *file, + const gchar *name) +{ + gchar *keyfile_filename; + gboolean result; + + keyfile_filename = get_keyfile_path (); + + result = nautilus_keyfile_metadata_update_from_keyfile (file, + keyfile_filename, + name); + + g_free (keyfile_filename); + return result; +} diff --git a/nautilus-desktop/nautilus-desktop-metadata.h b/nautilus-desktop/nautilus-desktop-metadata.h new file mode 100644 index 000000000..f8c67d3cf --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-metadata.h @@ -0,0 +1,43 @@ +/* + * Nautilus + * + * Copyright (C) 2011 Red Hat, Inc. + * + * Nautilus is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Nautilus is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; see the file COPYING. If not, + * see . + * + * Authors: Cosimo Cecchi + */ + +#ifndef __NAUTILUS_DESKTOP_METADATA_H__ +#define __NAUTILUS_DESKTOP_METADATA_H__ + +#include + +#include + +void nautilus_desktop_set_metadata_string (NautilusFile *file, + const gchar *name, + const gchar *key, + const gchar *string); + +void nautilus_desktop_set_metadata_stringv (NautilusFile *file, + const char *name, + const char *key, + const char * const *stringv); + +gboolean nautilus_desktop_update_metadata_from_keyfile (NautilusFile *file, + const gchar *name); + +#endif /* __NAUTILUS_DESKTOP_METADATA_H__ */ diff --git a/nautilus-desktop/nautilus-desktop-window-slot.c b/nautilus-desktop/nautilus-desktop-window-slot.c new file mode 100644 index 000000000..d1c05e7fc --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-window-slot.c @@ -0,0 +1,67 @@ +/* nautilus-desktop-window-slot.c + * + * Copyright (C) 2016 Carlos Soriano + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "nautilus-desktop-window-slot.h" +#include "nautilus-desktop-canvas-view.h" + +struct _NautilusDesktopWindowSlot +{ + NautilusWindowSlot parent_instance; +}; + +G_DEFINE_TYPE (NautilusDesktopWindowSlot, nautilus_desktop_window_slot, NAUTILUS_TYPE_WINDOW_SLOT) + +static NautilusView * +real_get_view_for_location (NautilusWindowSlot *self, + GFile *location) +{ + return NAUTILUS_VIEW (nautilus_desktop_canvas_view_new (self)); +} + +NautilusDesktopWindowSlot * +nautilus_desktop_window_slot_new (NautilusWindow *window) +{ + return g_object_new (NAUTILUS_TYPE_DESKTOP_WINDOW_SLOT, + "window", window, + NULL); +} + +static void +nautilus_desktop_window_slot_class_init (NautilusDesktopWindowSlotClass *klass) +{ + NautilusWindowSlotClass *parent_class = NAUTILUS_WINDOW_SLOT_CLASS (klass); + + parent_class->get_view_for_location = real_get_view_for_location; +} + +static void +nautilus_desktop_window_slot_init (NautilusDesktopWindowSlot *self) +{ + GAction *action; + GActionGroup *action_group; + + /* Disable search on desktop */ + action_group = gtk_widget_get_action_group (GTK_WIDGET (self), "slot"); + + action = g_action_map_lookup_action (G_ACTION_MAP (action_group), "search-visible"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE); + + /* Disable the ability to change between types of views */ + action = g_action_map_lookup_action (G_ACTION_MAP (action_group), "files-view-mode"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE); +} diff --git a/nautilus-desktop/nautilus-desktop-window-slot.h b/nautilus-desktop/nautilus-desktop-window-slot.h new file mode 100644 index 000000000..fcc64afba --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-window-slot.h @@ -0,0 +1,36 @@ +/* nautilus-window-desktop-slot.h + * + * Copyright (C) 2016 Carlos Soriano + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef NAUTILUS_DESKTOP_WINDOW_SLOT_H +#define NAUTILUS_DESKTOP_WINDOW_SLOT_H + +#include +#include + +G_BEGIN_DECLS + +#define NAUTILUS_TYPE_DESKTOP_WINDOW_SLOT (nautilus_desktop_window_slot_get_type()) + +G_DECLARE_FINAL_TYPE (NautilusDesktopWindowSlot, nautilus_desktop_window_slot, NAUTILUS, DESKTOP_WINDOW_SLOT, NautilusWindowSlot) + + +NautilusDesktopWindowSlot *nautilus_desktop_window_slot_new (NautilusWindow *window); + +G_END_DECLS + +#endif /* NAUTILUS_DESKTOP_WINDOW_SLOT_H */ + diff --git a/nautilus-desktop/nautilus-desktop-window.c b/nautilus-desktop/nautilus-desktop-window.c new file mode 100644 index 000000000..3e361be80 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-window.c @@ -0,0 +1,416 @@ + +/* + * Nautilus + * + * Copyright (C) 2000 Eazel, Inc. + * + * Nautilus is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Nautilus is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Authors: Darin Adler + */ + +#include + +#include "nautilus-desktop-window.h" +#include "nautilus-desktop-window-slot.h" +#include "nautilus-desktop-link-monitor.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +struct NautilusDesktopWindowDetails { + gulong size_changed_id; + + gboolean loaded; + + GtkWidget *desktop_selection; +}; + +G_DEFINE_TYPE (NautilusDesktopWindow, nautilus_desktop_window, + NAUTILUS_TYPE_WINDOW); + +static void +nautilus_desktop_window_update_directory (NautilusDesktopWindow *window) +{ + GFile *location; + + g_assert (NAUTILUS_IS_DESKTOP_WINDOW (window)); + + window->details->loaded = FALSE; + location = g_file_new_for_uri (EEL_DESKTOP_URI); + /* We use NAUTILUS_WINDOW_OPEN_FLAG_DONT_MAKE_ACTIVE so the nautilus-window + * doesn't call gtk_window_present () which raises the window on the stack + * and actually hides it from the background */ + nautilus_application_open_location_full (NAUTILUS_APPLICATION (g_application_get_default ()), + location, + NAUTILUS_WINDOW_OPEN_FLAG_DONT_MAKE_ACTIVE, + NULL, NAUTILUS_WINDOW (window), NULL); + window->details->loaded = TRUE; + + g_object_unref (location); +} + +static void +nautilus_desktop_window_finalize (GObject *obj) +{ + nautilus_desktop_link_monitor_shutdown (); + + G_OBJECT_CLASS (nautilus_desktop_window_parent_class)->finalize (obj); +} + +static void +nautilus_desktop_window_init_actions (NautilusDesktopWindow *window) +{ + GAction *action; + + /* Don't allow close action on desktop */ + action = g_action_map_lookup_action (G_ACTION_MAP (window), + "close-current-view"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE); + + /* Don't allow new tab on desktop */ + action = g_action_map_lookup_action (G_ACTION_MAP (window), + "new-tab"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE); + + /* Don't allow switching to home dir on desktop */ + action = g_action_map_lookup_action (G_ACTION_MAP (window), + "go-home"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE); +} + +static void +selection_get_cb (GtkWidget *widget, + GtkSelectionData *selection_data, + guint info, + guint time) +{ + /* No extra targets atm */ +} + +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_constructed (GObject *obj) +{ + AtkObject *accessible; + NautilusDesktopWindow *window = NAUTILUS_DESKTOP_WINDOW (obj); + + G_OBJECT_CLASS (nautilus_desktop_window_parent_class)->constructed (obj); + + /* Initialize the desktop link monitor singleton */ + nautilus_desktop_link_monitor_get (); + + /* shouldn't really be needed given our semantic type + * of _NET_WM_TYPE_DESKTOP, but why not + */ + gtk_window_set_resizable (GTK_WINDOW (window), + FALSE); + gtk_window_set_decorated (GTK_WINDOW (window), + FALSE); + + gtk_window_move (GTK_WINDOW (window), 0, 0); + + 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); + + if (window->details->desktop_selection != NULL) { + /* 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); + + /* 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); + gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)), + "nautilus-desktop-window"); + +} + +static void +nautilus_desktop_window_screen_size_changed (GdkScreen *screen, + NautilusDesktopWindow *window) +{ + int width_request, height_request; + + width_request = gdk_screen_get_width (screen); + height_request = gdk_screen_get_height (screen); + + g_object_set (window, + "width_request", width_request, + "height_request", height_request, + NULL); +} + +static NautilusDesktopWindow * +nautilus_desktop_window_new (void) +{ + GdkScreen *screen; + GApplication *application; + NautilusDesktopWindow *window; + int width_request, height_request; + + application = g_application_get_default (); + screen = gdk_screen_get_default (); + width_request = gdk_screen_get_width (screen); + height_request = gdk_screen_get_height (screen); + + window = g_object_new (NAUTILUS_TYPE_DESKTOP_WINDOW, + "application", application, + "disable-chrome", TRUE, + "width_request", width_request, + "height_request", height_request, + NULL); + + return window; +} + +static NautilusDesktopWindow *the_desktop_window = NULL; + +void +nautilus_desktop_window_ensure (void) +{ + NautilusDesktopWindow *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 +nautilus_desktop_window_delete_event (GtkWidget *widget, + GdkEventAny *event) +{ + /* Returning true tells GTK+ not to delete the window. */ + return TRUE; +} + +static void +map (GtkWidget *widget) +{ + /* Chain up to realize our children */ + GTK_WIDGET_CLASS (nautilus_desktop_window_parent_class)->map (widget); + gdk_window_lower (gtk_widget_get_window (widget)); +} + +static void +unrealize (GtkWidget *widget) +{ + NautilusDesktopWindow *window; + NautilusDesktopWindowDetails *details; + + window = NAUTILUS_DESKTOP_WINDOW (widget); + details = window->details; + + if (details->size_changed_id != 0) { + g_signal_handler_disconnect (gtk_window_get_screen (GTK_WINDOW (window)), + details->size_changed_id); + details->size_changed_id = 0; + } + + gtk_widget_destroy (details->desktop_selection); + + GTK_WIDGET_CLASS (nautilus_desktop_window_parent_class)->unrealize (widget); +} + +static void +set_wmspec_desktop_hint (GdkWindow *window) +{ + GdkAtom atom; + + atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_DESKTOP", FALSE); + + gdk_property_change (window, + gdk_atom_intern ("_NET_WM_WINDOW_TYPE", FALSE), + gdk_x11_xatom_to_atom (XA_ATOM), 32, + GDK_PROP_MODE_REPLACE, (guchar *) &atom, 1); +} + +static void +realize (GtkWidget *widget) +{ + NautilusDesktopWindow *window; + NautilusDesktopWindowDetails *details; + GdkVisual *visual; + + window = NAUTILUS_DESKTOP_WINDOW (widget); + details = window->details; + + /* Make sure we get keyboard events */ + gtk_widget_set_events (widget, gtk_widget_get_events (widget) + | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); + + visual = gdk_screen_get_rgba_visual (gtk_widget_get_screen (widget)); + if (visual) { + gtk_widget_set_visual (widget, visual); + } + + /* Do the work of realizing. */ + GTK_WIDGET_CLASS (nautilus_desktop_window_parent_class)->realize (widget); + + /* This is the new way to set up the desktop window */ + set_wmspec_desktop_hint (gtk_widget_get_window (widget)); + + details->size_changed_id = + g_signal_connect (gtk_window_get_screen (GTK_WINDOW (window)), "size-changed", + G_CALLBACK (nautilus_desktop_window_screen_size_changed), window); +} + +static void +real_sync_title (NautilusWindow *window, + NautilusWindowSlot *slot) +{ + /* hardcode "Desktop" */ + gtk_window_set_title (GTK_WINDOW (window), _("Desktop")); +} + +static void +real_window_close (NautilusWindow *window) +{ + /* stub, does nothing */ + return; +} + +static NautilusWindowSlot * +real_create_slot (NautilusWindow *window, + GFile *location) +{ + return NAUTILUS_WINDOW_SLOT (nautilus_desktop_window_slot_new (window)); +} + +static void +nautilus_desktop_window_class_init (NautilusDesktopWindowClass *klass) +{ + GtkWidgetClass *wclass = GTK_WIDGET_CLASS (klass); + NautilusWindowClass *nclass = NAUTILUS_WINDOW_CLASS (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; + wclass->map = map; + wclass->delete_event = nautilus_desktop_window_delete_event; + + nclass->sync_title = real_sync_title; + nclass->close = real_window_close; + nclass->create_slot = real_create_slot; + + g_type_class_add_private (klass, sizeof (NautilusDesktopWindowDetails)); +} + +gboolean +nautilus_desktop_window_loaded (NautilusDesktopWindow *window) +{ + return window->details->loaded; +} diff --git a/nautilus-desktop/nautilus-desktop-window.h b/nautilus-desktop/nautilus-desktop-window.h new file mode 100644 index 000000000..818c23bc7 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-window.h @@ -0,0 +1,59 @@ + +/* + * Nautilus + * + * Copyright (C) 2000 Eazel, Inc. + * + * Nautilus is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Nautilus is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Authors: Darin Adler + */ + +/* nautilus-desktop-window.h + */ + +#ifndef NAUTILUS_DESKTOP_WINDOW_H +#define NAUTILUS_DESKTOP_WINDOW_H + +#include + +#define NAUTILUS_TYPE_DESKTOP_WINDOW nautilus_desktop_window_get_type() +#define NAUTILUS_DESKTOP_WINDOW(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_DESKTOP_WINDOW, NautilusDesktopWindow)) +#define NAUTILUS_DESKTOP_WINDOW_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DESKTOP_WINDOW, NautilusDesktopWindowClass)) +#define NAUTILUS_IS_DESKTOP_WINDOW(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_DESKTOP_WINDOW)) +#define NAUTILUS_IS_DESKTOP_WINDOW_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DESKTOP_WINDOW)) +#define NAUTILUS_DESKTOP_WINDOW_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_DESKTOP_WINDOW, NautilusDesktopWindowClass)) + +typedef struct NautilusDesktopWindowDetails NautilusDesktopWindowDetails; + +typedef struct { + NautilusWindow parent_spot; + NautilusDesktopWindowDetails *details; +} NautilusDesktopWindow; + +typedef struct { + NautilusWindowClass parent_spot; +} NautilusDesktopWindowClass; + +GType nautilus_desktop_window_get_type (void); +GtkWidget * nautilus_desktop_window_get (void); +void nautilus_desktop_window_ensure (void); +gboolean nautilus_desktop_window_loaded (NautilusDesktopWindow *window); + +#endif /* NAUTILUS_DESKTOP_WINDOW_H */ diff --git a/src/Makefile.am b/src/Makefile.am index e10e7edef..d58d67c0d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,11 +1,14 @@ include $(top_srcdir)/Makefile.shared +AUTOMAKE_OPTIONS = subdir-objects + bin_PROGRAMS= \ nautilus \ - nautilus-desktop \ nautilus-autorun-software \ $(NULL) +noinst_LTLIBRARIES=libnautilus.la + AM_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/libnautilus-private \ @@ -26,6 +29,10 @@ AM_CPPFLAGS = \ $(NULL) LDADD =\ + libnautilus.la \ + $(NULL) + +libnautilus_la_LIBADD =\ $(top_builddir)/libnautilus-private/libnautilus-private.la \ $(top_builddir)/libgd/libgd.la \ $(BASE_LIBS) \ @@ -82,9 +89,9 @@ headers = \ resource_files = $(shell glib-compile-resources --sourcedir=$(srcdir)/resources --generate-dependencies $(srcdir)/resources/nautilus.gresource.xml) nautilus-resources.c: resources/nautilus.gresource.xml $(resource_files) - glib-compile-resources --target=$@ --sourcedir=$(srcdir)/resources --generate-source --c-name nautilus $(srcdir)/resources/nautilus.gresource.xml + glib-compile-resources --manual-register --target=$@ --sourcedir=$(srcdir)/resources --generate-source --c-name nautilus $(srcdir)/resources/nautilus.gresource.xml nautilus-resources.h: resources/nautilus.gresource.xml $(resource_files) - glib-compile-resources --target=$@ --sourcedir=$(srcdir)/resources --generate-header --c-name nautilus $(srcdir)/resources/nautilus.gresource.xml + glib-compile-resources --manual-register --target=$@ --sourcedir=$(srcdir)/resources --generate-header --c-name nautilus $(srcdir)/resources/nautilus.gresource.xml nautilus-enum-types.h: stamp-nautilus-enum-types.h $(AM_V_GEN)true @@ -150,16 +157,8 @@ nautilus_no_main_sources = \ nautilus-canvas-view-container.h \ nautilus-dbus-manager.c \ nautilus-dbus-manager.h \ - nautilus-desktop-canvas-view.c \ - nautilus-desktop-canvas-view.h \ - nautilus-desktop-canvas-view-container.c \ - nautilus-desktop-canvas-view-container.h \ nautilus-desktop-item-properties.c \ nautilus-desktop-item-properties.h \ - nautilus-desktop-window.c \ - nautilus-desktop-window.h \ - nautilus-desktop-window-slot.c \ - nautilus-desktop-window-slot.h \ nautilus-error-reporting.c \ nautilus-error-reporting.h \ nautilus-preferences-window.c \ @@ -227,24 +226,13 @@ nautilus_no_main_sources = \ nautilus-x-content-bar.h \ $(NULL) -nautilus_SOURCES = \ - $(nautilus_no_main_sources) \ - nautilus-main.c \ - $(NULL) - -nautilus_desktop_SOURCES= \ - $(nautilus_no_main_sources) \ - main-desktop.c \ - nautilus-desktop-application.c \ - nautilus-desktop-application.h \ - $(NULL) - -nodist_nautilus_SOURCES = \ +nodist_libnautilus_la_SOURCES = \ $(nautilus_built_sources) \ + $(nautilus_no_main_sources) \ $(NULL) -nodist_nautilus_desktop_SOURCES = \ - $(nautilus_built_sources) \ +nautilus_SOURCES = \ + nautilus-main.c \ $(NULL) EMPTY_VIEW_SOURCES = \ diff --git a/src/main-desktop.c b/src/main-desktop.c deleted file mode 100644 index 7c488a8b4..000000000 --- a/src/main-desktop.c +++ /dev/null @@ -1,36 +0,0 @@ -#include - -#include "nautilus-desktop-application.h" - -#include -#include - -#ifdef HAVE_LOCALE_H -#include -#endif -#include -#include -#include - -int -main (int argc, char *argv[]) -{ - NautilusDesktopApplication *application; - int retval; - - /* Initialize gettext support */ - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); - - g_set_prgname ("nautilus-desktop"); - - application = nautilus_desktop_application_new (); - - retval = g_application_run (G_APPLICATION (application), - argc, argv); - - g_object_unref (application); - - return retval; -} diff --git a/src/nautilus-desktop-application.c b/src/nautilus-desktop-application.c deleted file mode 100644 index 31ff6e603..000000000 --- a/src/nautilus-desktop-application.c +++ /dev/null @@ -1,243 +0,0 @@ -/* nautilus-desktop-application.c - * - * Copyright (C) 2016 Carlos Soriano - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "config.h" - -#include "nautilus-desktop-application.h" -#include "nautilus-desktop-window.h" -#include "nautilus-desktop-directory.h" -#include "nautilus-file-utilities.h" - -#include "nautilus-freedesktop-generated.h" - -#include -#include -#include - -static NautilusFreedesktopFileManager1 *freedesktop_proxy = NULL; - -struct _NautilusDesktopApplication -{ - NautilusApplication parent_instance; - - GCancellable *freedesktop_cancellable; -}; - -G_DEFINE_TYPE (NautilusDesktopApplication, nautilus_desktop_application, NAUTILUS_TYPE_APPLICATION) - -static void -on_show_folders (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - GError *error = NULL; - - nautilus_freedesktop_file_manager1_call_show_items_finish (freedesktop_proxy, - res, - &error); - if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - { - g_warning ("Unable to show items with File Manager freedesktop proxy: %s", error->message); - } - - g_clear_error (&error); -} - -static void -open_location_on_dbus (NautilusDesktopApplication *self, - const gchar *uri) -{ - const gchar *uris[] = { uri, NULL }; - - nautilus_freedesktop_file_manager1_call_show_folders (freedesktop_proxy, - uris, - "", - self->freedesktop_cancellable, - on_show_folders, - self); -} - -static void -open_location_full (NautilusApplication *app, - GFile *location, - NautilusWindowOpenFlags flags, - GList *selection, - NautilusWindow *target_window, - NautilusWindowSlot *target_slot) -{ - NautilusDesktopApplication *self = NAUTILUS_DESKTOP_APPLICATION (app); - gchar *uri; - - uri = g_file_get_uri (location); - if (eel_uri_is_desktop (uri) && target_window && - NAUTILUS_IS_DESKTOP_WINDOW (target_window)) - { - nautilus_window_open_location_full (target_window, location, flags, selection, NULL); - } - else - { - if (freedesktop_proxy) - { - open_location_on_dbus (self, uri); - } - else - { - g_warning ("cannot open folder on desktop, freedesktop bus not ready\n"); - } - } - - g_free (uri); -} - -static void -nautilus_application_set_desktop_visible (NautilusDesktopApplication *self, - gboolean visible) -{ - GtkWidget *desktop_window; - - if (visible) - { - nautilus_desktop_window_ensure (); - } - else - { - desktop_window = nautilus_desktop_window_get (); - if (desktop_window != NULL) - { - gtk_widget_destroy (desktop_window); - } - } -} - -static void -update_desktop_from_gsettings (NautilusDesktopApplication *self) -{ - GdkDisplay *display; - gboolean visible; - -#ifdef GDK_WINDOWING_X11 - display = gdk_display_get_default (); - visible = g_settings_get_boolean (gnome_background_preferences, - NAUTILUS_PREFERENCES_SHOW_DESKTOP); - if (!GDK_IS_X11_DISPLAY (display)) - { - if (visible) - { - g_warning ("Desktop icons only supported on X11. Desktop not created"); - } - - return; - } - - nautilus_application_set_desktop_visible (self, visible); - - return; -#endif - - g_warning ("Desktop icons only supported on X11. Desktop not created"); -} - -static void -init_desktop (NautilusDesktopApplication *self) -{ - g_signal_connect_swapped (gnome_background_preferences, "changed::" NAUTILUS_PREFERENCES_SHOW_DESKTOP, - G_CALLBACK (update_desktop_from_gsettings), - self); - update_desktop_from_gsettings (self); -} - -static void -nautilus_desktop_application_activate (GApplication *app) -{ - /* Do nothing */ -} - -static void -nautilus_desktop_application_startup (GApplication *app) -{ - NautilusDesktopApplication *self = NAUTILUS_DESKTOP_APPLICATION (app); - GError *error = NULL; - - nautilus_application_startup_common (NAUTILUS_APPLICATION (app)); - self->freedesktop_cancellable = g_cancellable_new (); - freedesktop_proxy = nautilus_freedesktop_file_manager1_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - "org.freedesktop.FileManager1", - "/org/freedesktop/FileManager1", - self->freedesktop_cancellable, - &error); - - if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - { - g_warning ("Unable to create File Manager freedesktop proxy: %s", error->message); - } - - g_clear_error (&error); - - init_desktop (self); -} - -static void -nautilus_desktop_application_dispose (GObject *object) -{ - NautilusDesktopApplication *self = NAUTILUS_DESKTOP_APPLICATION (object); - - g_clear_object (&self->freedesktop_cancellable); - - - G_OBJECT_CLASS (nautilus_desktop_application_parent_class)->dispose (object); -} - -static void -nautilus_desktop_application_class_init (NautilusDesktopApplicationClass *klass) -{ - GApplicationClass *application_class = G_APPLICATION_CLASS (klass); - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - NautilusApplicationClass *parent_class = NAUTILUS_APPLICATION_CLASS (klass); - - parent_class->open_location_full = open_location_full; - - application_class->startup = nautilus_desktop_application_startup; - application_class->activate = nautilus_desktop_application_activate; - - gobject_class->dispose = nautilus_desktop_application_dispose; -} - -static void -nautilus_desktop_ensure_builtins (void) -{ - /* Ensure the type so it can be registered early as a directory extension provider*/ - g_type_ensure (NAUTILUS_TYPE_DESKTOP_DIRECTORY); -} - -static void -nautilus_desktop_application_init (NautilusDesktopApplication *self) -{ - nautilus_ensure_extension_points (); - nautilus_ensure_extension_builtins (); - nautilus_desktop_ensure_builtins (); -} - -NautilusDesktopApplication * -nautilus_desktop_application_new (void) -{ - return g_object_new (NAUTILUS_TYPE_DESKTOP_APPLICATION, - "application-id", "org.gnome.NautilusDesktop", - NULL); -} - diff --git a/src/nautilus-desktop-application.h b/src/nautilus-desktop-application.h deleted file mode 100644 index 4f4c62c47..000000000 --- a/src/nautilus-desktop-application.h +++ /dev/null @@ -1,36 +0,0 @@ -/* nautilus-desktop-application.h - * - * Copyright (C) 2016 Carlos Soriano - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef NAUTILUS_DESKTOP_APPLICATION_H -#define NAUTILUS_DESKTOP_APPLICATION_H - -#include -#include "nautilus-application.h" - -G_BEGIN_DECLS - -#define NAUTILUS_TYPE_DESKTOP_APPLICATION (nautilus_desktop_application_get_type()) - -G_DECLARE_FINAL_TYPE (NautilusDesktopApplication, nautilus_desktop_application, NAUTILUS, DESKTOP_APPLICATION, NautilusApplication) - -NautilusDesktopApplication *nautilus_desktop_application_new (void); - -G_END_DECLS - -#endif /* NAUTILUS_DESKTOP_APPLICATION_H */ - diff --git a/src/nautilus-desktop-canvas-view-container.c b/src/nautilus-desktop-canvas-view-container.c deleted file mode 100644 index 23db902d2..000000000 --- a/src/nautilus-desktop-canvas-view-container.c +++ /dev/null @@ -1,199 +0,0 @@ -/* nautilus-desktop-canvas-view-container.c - * - * Copyright (C) 2016 Carlos Soriano - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "nautilus-desktop-canvas-view-container.h" -#include "nautilus-desktop-icon-file.h" - -struct _NautilusDesktopCanvasViewContainer -{ - NautilusCanvasViewContainer parent_instance; -}; - -G_DEFINE_TYPE (NautilusDesktopCanvasViewContainer, nautilus_desktop_canvas_view_container, NAUTILUS_TYPE_CANVAS_VIEW_CONTAINER) - -/* Sort as follows: - * 0) home link - * 1) network link - * 2) mount links - * 3) other - * 4) trash link - */ -typedef enum { - SORT_HOME_LINK, - SORT_NETWORK_LINK, - SORT_MOUNT_LINK, - SORT_OTHER, - SORT_TRASH_LINK -} SortCategory; - -static SortCategory -get_sort_category (NautilusFile *file) -{ - NautilusDesktopLink *link; - SortCategory category; - - category = SORT_OTHER; - - if (NAUTILUS_IS_DESKTOP_ICON_FILE (file)) - { - link = nautilus_desktop_icon_file_get_link (NAUTILUS_DESKTOP_ICON_FILE (file)); - if (link != NULL) - { - switch (nautilus_desktop_link_get_link_type (link)) - { - case NAUTILUS_DESKTOP_LINK_HOME: - category = SORT_HOME_LINK; - break; - case NAUTILUS_DESKTOP_LINK_MOUNT: - category = SORT_MOUNT_LINK; - break; - case NAUTILUS_DESKTOP_LINK_TRASH: - category = SORT_TRASH_LINK; - break; - case NAUTILUS_DESKTOP_LINK_NETWORK: - category = SORT_NETWORK_LINK; - break; - default: - category = SORT_OTHER; - break; - } - g_object_unref (link); - } - } - - return category; -} - -static int -real_compare_icons (NautilusCanvasContainer *container, - NautilusCanvasIconData *data_a, - NautilusCanvasIconData *data_b) -{ - NautilusFile *file_a; - NautilusFile *file_b; - NautilusFilesView *directory_view; - SortCategory category_a, category_b; - - file_a = (NautilusFile *) data_a; - file_b = (NautilusFile *) data_b; - - directory_view = NAUTILUS_FILES_VIEW (NAUTILUS_CANVAS_VIEW_CONTAINER (container)->view); - g_return_val_if_fail (directory_view != NULL, 0); - - category_a = get_sort_category (file_a); - category_b = get_sort_category (file_b); - - if (category_a == category_b) - { - return nautilus_file_compare_for_sort (file_a, - file_b, - NAUTILUS_FILE_SORT_BY_DISPLAY_NAME, - nautilus_files_view_should_sort_directories_first (directory_view), - FALSE); - } - - if (category_a < category_b) - { - return -1; - } - else - { - return +1; - } -} - -static void -real_get_icon_text (NautilusCanvasContainer *container, - NautilusCanvasIconData *data, - char **editable_text, - char **additional_text, - gboolean include_invisible) -{ - NautilusFile *file; - gboolean use_additional; - - file = NAUTILUS_FILE (data); - - g_assert (NAUTILUS_IS_FILE (file)); - g_assert (editable_text != NULL); - - use_additional = (additional_text != NULL); - - /* Strip the suffix for nautilus object xml files. */ - *editable_text = nautilus_file_get_display_name (file); - - if (!use_additional) { - return; - } - - if (NAUTILUS_IS_DESKTOP_ICON_FILE (file) || - nautilus_file_is_nautilus_link (file)) - { - /* Don't show the normal extra information for desktop icons, - * or desktop files, it doesn't make sense. - */ - *additional_text = NULL; - - return; - } - - return NAUTILUS_CANVAS_CONTAINER_CLASS (nautilus_desktop_canvas_view_container_parent_class)->get_icon_text (container, - data, - editable_text, - additional_text, - include_invisible); -} - -static char * -real_get_icon_description (NautilusCanvasContainer *container, - NautilusCanvasIconData *data) -{ - NautilusFile *file; - - file = NAUTILUS_FILE (data); - g_assert (NAUTILUS_IS_FILE (file)); - - if (NAUTILUS_IS_DESKTOP_ICON_FILE (file)) - { - return NULL; - } - - return NAUTILUS_CANVAS_CONTAINER_CLASS (nautilus_desktop_canvas_view_container_parent_class)->get_icon_description (container, - data); -} - -NautilusDesktopCanvasViewContainer * -nautilus_desktop_canvas_view_container_new (void) -{ - return g_object_new (NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW_CONTAINER, NULL); -} - -static void -nautilus_desktop_canvas_view_container_class_init (NautilusDesktopCanvasViewContainerClass *klass) -{ - NautilusCanvasContainerClass *container_class = NAUTILUS_CANVAS_CONTAINER_CLASS (klass); - - container_class->get_icon_description = real_get_icon_description; - container_class->get_icon_text = real_get_icon_text; - container_class->compare_icons = real_compare_icons; -} - -static void -nautilus_desktop_canvas_view_container_init (NautilusDesktopCanvasViewContainer *self) -{ -} diff --git a/src/nautilus-desktop-canvas-view-container.h b/src/nautilus-desktop-canvas-view-container.h deleted file mode 100644 index 018062b7d..000000000 --- a/src/nautilus-desktop-canvas-view-container.h +++ /dev/null @@ -1,35 +0,0 @@ -/* nautilus-desktop-canvas-view-container.h - * - * Copyright (C) 2016 Carlos Soriano - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef NAUTILUS_DESKTOP_CANVAS_VIEW_CONTAINER_H -#define NAUTILUS_DESKTOP_CANVAS_VIEW_CONTAINER_H - -#include -#include "nautilus-canvas-view-container.h" - -G_BEGIN_DECLS - -#define NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW_CONTAINER (nautilus_desktop_canvas_view_container_get_type()) - -G_DECLARE_FINAL_TYPE (NautilusDesktopCanvasViewContainer, nautilus_desktop_canvas_view_container, NAUTILUS, DESKTOP_CANVAS_VIEW_CONTAINER, NautilusCanvasViewContainer) - -NautilusDesktopCanvasViewContainer *nautilus_desktop_canvas_view_container_new (void); - -G_END_DECLS - -#endif /* NAUTILUS_DESKTOP_CANVAS_VIEW_CONTAINER_H */ - diff --git a/src/nautilus-desktop-canvas-view.c b/src/nautilus-desktop-canvas-view.c deleted file mode 100644 index 5c79312c4..000000000 --- a/src/nautilus-desktop-canvas-view.c +++ /dev/null @@ -1,745 +0,0 @@ - -/* nautilus-desktop-canvas-view.c - implementation of canvas view for managing the desktop. - - Copyright (C) 2000, 2001 Eazel, Inc.mou - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - see . - - Authors: Mike Engber - Gene Z. Ragan - Miguel de Icaza -*/ - -#include -#include - -#include "nautilus-desktop-canvas-view.h" - -#include "nautilus-canvas-view-container.h" -#include "nautilus-desktop-canvas-view-container.h" -#include "nautilus-files-view.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct NautilusDesktopCanvasViewDetails -{ - GdkWindow *root_window; -}; - -static void default_zoom_level_changed (gpointer user_data); -static void real_update_context_menus (NautilusFilesView *view); -static char* real_get_backing_uri (NautilusFilesView *view); -static void real_check_empty_states (NautilusFilesView *view); -static char * real_get_file_paths_or_uris_as_newline_delimited_string (NautilusFilesView *view, - GList *selection, - gboolean get_paths); -static void nautilus_desktop_canvas_view_update_canvas_container_fonts (NautilusDesktopCanvasView *view); -static void font_changed_callback (gpointer callback_data); - -G_DEFINE_TYPE (NautilusDesktopCanvasView, nautilus_desktop_canvas_view, NAUTILUS_TYPE_CANVAS_VIEW) - -static char *desktop_directory; - -#define get_canvas_container(w) nautilus_canvas_view_get_canvas_container(NAUTILUS_CANVAS_VIEW (w)) - -#define POPUP_PATH_CANVAS_APPEARANCE "/selection/Canvas Appearance Items" - -static void -canvas_container_set_workarea (NautilusCanvasContainer *canvas_container, - GdkScreen *screen, - long *workareas, - int n_items) -{ - int left, right, top, bottom; - int screen_width, screen_height; - int i; - - left = right = top = bottom = 0; - - screen_width = gdk_screen_get_width (screen); - screen_height = gdk_screen_get_height (screen); - - for (i = 0; i < n_items; i += 4) { - int x = workareas [i]; - int y = workareas [i + 1]; - int width = workareas [i + 2]; - int height = workareas [i + 3]; - - if ((x + width) > screen_width || (y + height) > screen_height) - continue; - - left = MAX (left, x); - right = MAX (right, screen_width - width - x); - top = MAX (top, y); - bottom = MAX (bottom, screen_height - height - y); - } - - nautilus_canvas_container_set_margins (canvas_container, - left, right, top, bottom); -} - -static void -net_workarea_changed (NautilusDesktopCanvasView *canvas_view, - GdkWindow *window) -{ - long *nworkareas = NULL; - long *workareas = NULL; - GdkAtom type_returned; - int format_returned; - int length_returned; - NautilusCanvasContainer *canvas_container; - GdkScreen *screen; - - g_return_if_fail (NAUTILUS_IS_DESKTOP_CANVAS_VIEW (canvas_view)); - - canvas_container = get_canvas_container (canvas_view); - - /* Find the number of desktops so we know how long the - * workareas array is going to be (each desktop will have four - * elements in the workareas array describing - * x,y,width,height) */ - gdk_error_trap_push (); - if (!gdk_property_get (window, - gdk_atom_intern ("_NET_NUMBER_OF_DESKTOPS", FALSE), - gdk_x11_xatom_to_atom (XA_CARDINAL), - 0, 4, FALSE, - &type_returned, - &format_returned, - &length_returned, - (guchar **) &nworkareas)) { - g_warning("Can not calculate _NET_NUMBER_OF_DESKTOPS"); - } - if (gdk_error_trap_pop() - || nworkareas == NULL - || type_returned != gdk_x11_xatom_to_atom (XA_CARDINAL) - || format_returned != 32) - g_warning("Can not calculate _NET_NUMBER_OF_DESKTOPS"); - - /* Note : gdk_property_get() is broken (API documents admit - * this). As a length argument, it expects the number of - * _bytes_ of data you require. Internally, gdk_property_get - * converts that value to a count of 32 bit (4 byte) elements. - * However, the length returned is in bytes, but is calculated - * via the count of returned elements * sizeof(long). This - * means on a 64 bit system, the number of bytes you have to - * request does not correspond to the number of bytes you get - * back, and is the reason for the workaround below. - */ - gdk_error_trap_push (); - if (nworkareas == NULL || (*nworkareas < 1) - || !gdk_property_get (window, - gdk_atom_intern ("_NET_WORKAREA", FALSE), - gdk_x11_xatom_to_atom (XA_CARDINAL), - 0, ((*nworkareas) * 4 * 4), FALSE, - &type_returned, - &format_returned, - &length_returned, - (guchar **) &workareas)) { - g_warning("Can not get _NET_WORKAREA"); - workareas = NULL; - } - - if (gdk_error_trap_pop () - || workareas == NULL - || type_returned != gdk_x11_xatom_to_atom (XA_CARDINAL) - || ((*nworkareas) * 4 * sizeof(long)) != length_returned - || format_returned != 32) { - g_warning("Can not determine workarea, guessing at layout"); - nautilus_canvas_container_set_margins (canvas_container, - 0, 0, 0, 0); - } else { - screen = gdk_window_get_screen (window); - - canvas_container_set_workarea - (canvas_container, screen, workareas, length_returned / sizeof (long)); - } - - if (nworkareas != NULL) - g_free (nworkareas); - - if (workareas != NULL) - g_free (workareas); -} - -static GdkFilterReturn -desktop_canvas_view_property_filter (GdkXEvent *gdk_xevent, - GdkEvent *event, - gpointer data) -{ - XEvent *xevent = gdk_xevent; - NautilusDesktopCanvasView *canvas_view; - - canvas_view = NAUTILUS_DESKTOP_CANVAS_VIEW (data); - - switch (xevent->type) { - case PropertyNotify: - if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name ("_NET_WORKAREA")) - net_workarea_changed (canvas_view, event->any.window); - break; - default: - break; - } - - return GDK_FILTER_CONTINUE; -} - -static guint -real_get_id (NautilusFilesView *view) -{ - return NAUTILUS_VIEW_DESKTOP_ID; -} - -static void -nautilus_desktop_canvas_view_dispose (GObject *object) -{ - NautilusDesktopCanvasView *canvas_view; - - canvas_view = NAUTILUS_DESKTOP_CANVAS_VIEW (object); - - g_signal_handlers_disconnect_by_func (nautilus_icon_view_preferences, - default_zoom_level_changed, - canvas_view); - g_signal_handlers_disconnect_by_func (nautilus_preferences, - font_changed_callback, - canvas_view); - g_signal_handlers_disconnect_by_func (gnome_lockdown_preferences, - nautilus_files_view_update_context_menus, - canvas_view); - - G_OBJECT_CLASS (nautilus_desktop_canvas_view_parent_class)->dispose (object); -} - -static void -nautilus_desktop_canvas_view_end_loading (NautilusFilesView *view, - gboolean all_files_seen) -{ - gboolean needs_reorganization; - gchar *stored_size_icon; - guint current_zoom; - guint current_icon_size; - gchar *current_icon_size_string; - NautilusFile *file; - - NAUTILUS_FILES_VIEW_CLASS (nautilus_desktop_canvas_view_parent_class)->end_loading (view, all_files_seen); - - if (!all_files_seen) - return; - - file = nautilus_files_view_get_directory_as_file (view); - g_return_if_fail (file != NULL); - - stored_size_icon = nautilus_file_get_metadata (file, NAUTILUS_METADATA_KEY_DESKTOP_ICON_SIZE, NULL); - current_zoom = nautilus_canvas_container_get_zoom_level (get_canvas_container (view)); - current_icon_size = nautilus_canvas_container_get_icon_size_for_zoom_level (current_zoom); - needs_reorganization = stored_size_icon == NULL || atoi (stored_size_icon) != current_icon_size; - - if (needs_reorganization) { - current_icon_size_string = g_strdup_printf ("%d", current_icon_size); - nautilus_canvas_view_clean_up_by_name (NAUTILUS_CANVAS_VIEW (view)); - nautilus_file_set_metadata (file, NAUTILUS_METADATA_KEY_DESKTOP_ICON_SIZE, - NULL, current_icon_size_string); - - g_free (current_icon_size_string); - } - - g_free (stored_size_icon); -} - -static NautilusCanvasContainer * -real_create_canvas_container (NautilusCanvasView *canvas_view) -{ - return NAUTILUS_CANVAS_CONTAINER (nautilus_desktop_canvas_view_container_new ()); -} - -static void -nautilus_desktop_canvas_view_class_init (NautilusDesktopCanvasViewClass *class) -{ - NautilusFilesViewClass *vclass; - NautilusCanvasViewClass *canvas_class; - - vclass = NAUTILUS_FILES_VIEW_CLASS (class); - canvas_class = NAUTILUS_CANVAS_VIEW_CLASS (class); - - - G_OBJECT_CLASS (class)->dispose = nautilus_desktop_canvas_view_dispose; - - canvas_class->create_canvas_container = real_create_canvas_container; - - vclass->update_context_menus = real_update_context_menus; - vclass->get_view_id = real_get_id; - vclass->end_loading = nautilus_desktop_canvas_view_end_loading; - vclass->get_backing_uri = real_get_backing_uri; - vclass->check_empty_states = real_check_empty_states; - - g_type_class_add_private (class, sizeof (NautilusDesktopCanvasViewDetails)); -} - -static void -unrealized_callback (GtkWidget *widget, NautilusDesktopCanvasView *desktop_canvas_view) -{ - g_return_if_fail (desktop_canvas_view->details->root_window != NULL); - - /* Remove the property filter */ - gdk_window_remove_filter (desktop_canvas_view->details->root_window, - desktop_canvas_view_property_filter, - desktop_canvas_view); - desktop_canvas_view->details->root_window = NULL; -} - -static void -realized_callback (GtkWidget *widget, NautilusDesktopCanvasView *desktop_canvas_view) -{ - GdkWindow *root_window; - GdkScreen *screen; - - g_return_if_fail (desktop_canvas_view->details->root_window == NULL); - - screen = gtk_widget_get_screen (widget); - root_window = gdk_screen_get_root_window (screen); - - desktop_canvas_view->details->root_window = root_window; - - /* Read out the workarea geometry and update the icon container accordingly */ - net_workarea_changed (desktop_canvas_view, root_window); - - /* Setup the property filter */ - gdk_window_set_events (root_window, GDK_PROPERTY_CHANGE_MASK); - gdk_window_add_filter (root_window, - desktop_canvas_view_property_filter, - desktop_canvas_view); -} - -static void -desktop_canvas_container_realize (GtkWidget *widget, - NautilusDesktopCanvasView *desktop_canvas_view) -{ - GdkWindow *bin_window; - GdkRGBA transparent = { 0, 0, 0, 0 }; - - bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (widget)); - gdk_window_set_background_rgba (bin_window, &transparent); -} - -static NautilusCanvasZoomLevel -get_default_zoom_level (void) -{ - NautilusCanvasZoomLevel default_zoom_level; - - default_zoom_level = g_settings_get_enum (nautilus_icon_view_preferences, - NAUTILUS_PREFERENCES_ICON_VIEW_DEFAULT_ZOOM_LEVEL); - - return CLAMP (default_zoom_level, NAUTILUS_CANVAS_ZOOM_LEVEL_SMALL, NAUTILUS_CANVAS_ZOOM_LEVEL_LARGE); -} - -static void -set_up_zoom_level (NautilusDesktopCanvasView *desktop_canvas_view) -{ - NautilusCanvasZoomLevel new_level; - - new_level = get_default_zoom_level (); - nautilus_canvas_container_set_zoom_level (get_canvas_container (desktop_canvas_view), - new_level); -} - -static void -default_zoom_level_changed (gpointer user_data) -{ - NautilusCanvasZoomLevel new_level; - NautilusDesktopCanvasView *desktop_canvas_view; - gint new_icon_size; - NautilusFile *file; - gchar *new_icon_size_string; - - desktop_canvas_view = NAUTILUS_DESKTOP_CANVAS_VIEW (user_data); - file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (user_data)); - new_level = get_default_zoom_level (); - new_icon_size = nautilus_canvas_container_get_icon_size_for_zoom_level (new_level); - new_icon_size_string = g_strdup_printf ("%d", new_icon_size); - - nautilus_file_set_metadata (file, NAUTILUS_METADATA_KEY_DESKTOP_ICON_SIZE, - NULL, new_icon_size_string); - set_up_zoom_level (desktop_canvas_view); - - g_free (new_icon_size_string); -} - -static void -font_changed_callback (gpointer callback_data) -{ - g_return_if_fail (NAUTILUS_IS_DESKTOP_CANVAS_VIEW (callback_data)); - - nautilus_desktop_canvas_view_update_canvas_container_fonts (NAUTILUS_DESKTOP_CANVAS_VIEW (callback_data)); -} - -static void -nautilus_desktop_canvas_view_update_canvas_container_fonts (NautilusDesktopCanvasView *canvas_view) -{ - NautilusCanvasContainer *canvas_container; - char *font; - - canvas_container = get_canvas_container (canvas_view); - g_assert (canvas_container != NULL); - - font = g_settings_get_string (nautilus_desktop_preferences, - NAUTILUS_PREFERENCES_DESKTOP_FONT); - - nautilus_canvas_container_set_font (canvas_container, font); - - g_free (font); -} - -static const gchar * -get_control_center_command (const gchar ** params_out) -{ - gchar *path; - const gchar *retval; - const gchar *params; - const gchar *xdg_current_desktop; - gchar **desktop_names; - gboolean is_unity; - int i; - - path = NULL; - retval = NULL; - params = NULL; - - xdg_current_desktop = g_getenv ("XDG_CURRENT_DESKTOP"); - - /* Detect the Unity-based environments */ - is_unity = FALSE; - if (xdg_current_desktop != NULL) { - desktop_names = g_strsplit (xdg_current_desktop, ":", 0); - for (i = 0; desktop_names[i]; ++i) { - if (!g_strcmp0 (desktop_names[i], "Unity")) { - is_unity = TRUE; - break; - } - } - g_strfreev (desktop_names); - } - - /* In Unity look for unity-control-center */ - if (is_unity) { - path = g_find_program_in_path ("unity-control-center"); - if (path != NULL) { - retval = "unity-control-center"; - params = "appearance"; - goto out; - } - } - - /* Otherwise look for gnome-control-center */ - path = g_find_program_in_path ("gnome-control-center"); - if (path != NULL) { - retval = "gnome-control-center"; - params = "background"; - } - - out: - g_free (path); - if (params_out != NULL) { - *params_out = params; - } - - return retval; -} - -static void -action_change_background (GSimpleAction *action, - GVariant *state, - gpointer user_data) -{ - const gchar *control_center_cmd, *params; - - g_assert (NAUTILUS_FILES_VIEW (user_data)); - - control_center_cmd = get_control_center_command (¶ms); - if (control_center_cmd == NULL) { - return; - } - - nautilus_launch_application_from_command (gtk_widget_get_screen (GTK_WIDGET (user_data)), - control_center_cmd, - FALSE, - params, NULL); -} - -static void -action_empty_trash (GSimpleAction *action, - GVariant *state, - gpointer user_data) -{ - g_assert (NAUTILUS_IS_FILES_VIEW (user_data)); - - nautilus_file_operations_empty_trash (GTK_WIDGET (user_data)); -} - -static void -action_stretch (GSimpleAction *action, - GVariant *state, - gpointer user_data) -{ - nautilus_canvas_container_show_stretch_handles - (get_canvas_container (user_data)); -} - -static void -action_unstretch (GSimpleAction *action, - GVariant *state, - gpointer user_data) -{ - nautilus_canvas_container_unstretch (get_canvas_container (user_data)); -} - -static void -action_organize_desktop_by_name (GSimpleAction *action, - GVariant *state, - gpointer user_data) -{ - nautilus_canvas_view_clean_up_by_name (NAUTILUS_CANVAS_VIEW (user_data)); -} - -static gboolean -trash_link_is_selection (NautilusFilesView *view) -{ - GList *selection; - NautilusDesktopLink *link; - gboolean result; - - result = FALSE; - - selection = nautilus_view_get_selection (NAUTILUS_VIEW (view)); - - if ((g_list_length (selection) == 1) && - NAUTILUS_IS_DESKTOP_ICON_FILE (selection->data)) { - link = nautilus_desktop_icon_file_get_link (NAUTILUS_DESKTOP_ICON_FILE (selection->data)); - /* link may be NULL if the link was recently removed (unmounted) */ - if (link != NULL && - nautilus_desktop_link_get_link_type (link) == NAUTILUS_DESKTOP_LINK_TRASH) { - result = TRUE; - } - if (link) { - g_object_unref (link); - } - } - - nautilus_file_list_free (selection); - - return result; -} - -const GActionEntry desktop_view_entries[] = { - { "change-background", action_change_background }, - { "organize-desktop-by-name", action_organize_desktop_by_name }, - { "empty-trash", action_empty_trash }, - { "stretch", action_stretch }, - { "unstretch", action_unstretch }, -}; - -static void -real_check_empty_states (NautilusFilesView *view) -{ - /* Do nothing */ -} - -static char* -real_get_backing_uri (NautilusFilesView *view) -{ - gchar *uri; - NautilusDirectory *directory; - NautilusDirectory *model; - - g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL); - - model = nautilus_files_view_get_model (view); - - if (model == NULL) { - return NULL; - } - - directory = nautilus_desktop_directory_get_real_directory (NAUTILUS_DESKTOP_DIRECTORY (model)); - - uri = nautilus_directory_get_uri (directory); - - nautilus_directory_unref (directory); - - return uri; -} - -static void -real_update_context_menus (NautilusFilesView *view) -{ - NautilusCanvasContainer *canvas_container; - NautilusDesktopCanvasView *desktop_view; - GAction *action; - GActionGroup *view_action_group; - GList *selection; - int selection_count; - - g_assert (NAUTILUS_IS_DESKTOP_CANVAS_VIEW (view)); - - NAUTILUS_FILES_VIEW_CLASS (nautilus_desktop_canvas_view_parent_class)->update_context_menus (view); - - view_action_group = nautilus_files_view_get_action_group (view); - desktop_view = NAUTILUS_DESKTOP_CANVAS_VIEW (view); - selection = nautilus_view_get_selection (NAUTILUS_VIEW (view)); - selection_count = g_list_length (selection); - - action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "empty-trash"); - g_simple_action_set_enabled (G_SIMPLE_ACTION (action), trash_link_is_selection (view)); - - action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "keep-aligned"); - g_simple_action_set_enabled (G_SIMPLE_ACTION (action), TRUE); - - action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "organize-desktop-by-name"); - g_simple_action_set_enabled (G_SIMPLE_ACTION (action), TRUE); - - action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "change-background"); - g_simple_action_set_enabled (G_SIMPLE_ACTION (action), TRUE); - - action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "properties"); - g_simple_action_set_enabled (G_SIMPLE_ACTION (action), selection_count > 0); - - /* Stretch */ - canvas_container = get_canvas_container (desktop_view); - - action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "stretch"); - g_simple_action_set_enabled (G_SIMPLE_ACTION (action), selection_count == 1 && - canvas_container != NULL && - !nautilus_canvas_container_has_stretch_handles (canvas_container)); - - nautilus_file_list_free (selection); - - /* Unstretch */ - action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "unstretch"); - g_simple_action_set_enabled (G_SIMPLE_ACTION (action), canvas_container != NULL && - nautilus_canvas_container_is_stretched (canvas_container)); -} - -static void -nautilus_desktop_canvas_view_init (NautilusDesktopCanvasView *desktop_canvas_view) -{ - NautilusCanvasContainer *canvas_container; - GtkAllocation allocation; - GActionGroup *view_action_group; - GtkAdjustment *hadj, *vadj; - - desktop_canvas_view->details = G_TYPE_INSTANCE_GET_PRIVATE (desktop_canvas_view, - NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW, - NautilusDesktopCanvasViewDetails); - - if (desktop_directory == NULL) { - desktop_directory = nautilus_get_desktop_directory (); - } - - canvas_container = get_canvas_container (desktop_canvas_view); - - nautilus_canvas_container_set_is_fixed_size (canvas_container, TRUE); - nautilus_canvas_container_set_is_desktop (canvas_container, TRUE); - nautilus_canvas_container_set_store_layout_timestamps (canvas_container, TRUE); - - /* Set allocation to be at 0, 0 */ - gtk_widget_get_allocation (GTK_WIDGET (canvas_container), &allocation); - allocation.x = 0; - allocation.y = 0; - gtk_widget_set_allocation (GTK_WIDGET (canvas_container), &allocation); - - gtk_widget_queue_resize (GTK_WIDGET (canvas_container)); - - hadj = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (canvas_container)); - vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (canvas_container)); - - gtk_adjustment_set_value (hadj, 0); - gtk_adjustment_set_value (vadj, 0); - - nautilus_files_view_ignore_hidden_file_preferences - (NAUTILUS_FILES_VIEW (desktop_canvas_view)); - - nautilus_files_view_set_show_foreign (NAUTILUS_FILES_VIEW (desktop_canvas_view), - FALSE); - - g_signal_connect_object (canvas_container, "realize", - G_CALLBACK (desktop_canvas_container_realize), desktop_canvas_view, 0); - - g_signal_connect_object (desktop_canvas_view, "realize", - G_CALLBACK (realized_callback), desktop_canvas_view, 0); - g_signal_connect_object (desktop_canvas_view, "unrealize", - G_CALLBACK (unrealized_callback), desktop_canvas_view, 0); - - g_signal_connect_swapped (nautilus_icon_view_preferences, - "changed::" NAUTILUS_PREFERENCES_ICON_VIEW_DEFAULT_ZOOM_LEVEL, - G_CALLBACK (default_zoom_level_changed), - desktop_canvas_view); - - g_signal_connect_swapped (nautilus_desktop_preferences, - "changed::" NAUTILUS_PREFERENCES_DESKTOP_FONT, - G_CALLBACK (font_changed_callback), - desktop_canvas_view); - - set_up_zoom_level (desktop_canvas_view); - nautilus_desktop_canvas_view_update_canvas_container_fonts (desktop_canvas_view); - - g_signal_connect_swapped (gnome_lockdown_preferences, - "changed::" NAUTILUS_PREFERENCES_LOCKDOWN_COMMAND_LINE, - G_CALLBACK (nautilus_files_view_update_context_menus), - desktop_canvas_view); - - view_action_group = nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (desktop_canvas_view)); - - g_action_map_add_action_entries (G_ACTION_MAP (view_action_group), - desktop_view_entries, - G_N_ELEMENTS (desktop_view_entries), - NAUTILUS_FILES_VIEW (desktop_canvas_view)); -} - -NautilusFilesView * -nautilus_desktop_canvas_view_new (NautilusWindowSlot *slot) -{ - return g_object_new (NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW, - "window-slot", slot, - "supports-zooming", FALSE, - "supports-auto-layout", FALSE, - "supports-manual-layout", TRUE, - "supports-scaling", TRUE, - "supports-keep-aligned", TRUE, - NULL); -} diff --git a/src/nautilus-desktop-canvas-view.h b/src/nautilus-desktop-canvas-view.h deleted file mode 100644 index e40d80ff4..000000000 --- a/src/nautilus-desktop-canvas-view.h +++ /dev/null @@ -1,54 +0,0 @@ - -/* fm-icon-view.h - interface for icon view of directory. - - Copyright (C) 2000 Eazel, Inc. - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - see . - - Authors: Mike Engber -*/ - -#ifndef NAUTILUS_DESKTOP_CANVAS_VIEW_H -#define NAUTILUS_DESKTOP_CANVAS_VIEW_H - -#include "nautilus-canvas-view.h" - -#define NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW nautilus_desktop_canvas_view_get_type() -#define NAUTILUS_DESKTOP_CANVAS_VIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW, NautilusDesktopCanvasView)) -#define NAUTILUS_DESKTOP_CANVAS_VIEW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW, NautilusDesktopCanvasViewClass)) -#define NAUTILUS_IS_DESKTOP_CANVAS_VIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW)) -#define NAUTILUS_IS_DESKTOP_CANVAS_VIEW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW)) -#define NAUTILUS_DESKTOP_CANVAS_VIEW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW, NautilusDesktopCanvasViewClass)) - -typedef struct NautilusDesktopCanvasViewDetails NautilusDesktopCanvasViewDetails; -typedef struct { - NautilusCanvasView parent; - NautilusDesktopCanvasViewDetails *details; -} NautilusDesktopCanvasView; - -typedef struct { - NautilusCanvasViewClass parent_class; -} NautilusDesktopCanvasViewClass; - -/* GObject support */ -GType nautilus_desktop_canvas_view_get_type (void); -NautilusFilesView * nautilus_desktop_canvas_view_new (NautilusWindowSlot *slot); - -#endif /* NAUTILUS_DESKTOP_CANVAS_VIEW_H */ diff --git a/src/nautilus-desktop-window-slot.c b/src/nautilus-desktop-window-slot.c deleted file mode 100644 index d1c05e7fc..000000000 --- a/src/nautilus-desktop-window-slot.c +++ /dev/null @@ -1,67 +0,0 @@ -/* nautilus-desktop-window-slot.c - * - * Copyright (C) 2016 Carlos Soriano - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "nautilus-desktop-window-slot.h" -#include "nautilus-desktop-canvas-view.h" - -struct _NautilusDesktopWindowSlot -{ - NautilusWindowSlot parent_instance; -}; - -G_DEFINE_TYPE (NautilusDesktopWindowSlot, nautilus_desktop_window_slot, NAUTILUS_TYPE_WINDOW_SLOT) - -static NautilusView * -real_get_view_for_location (NautilusWindowSlot *self, - GFile *location) -{ - return NAUTILUS_VIEW (nautilus_desktop_canvas_view_new (self)); -} - -NautilusDesktopWindowSlot * -nautilus_desktop_window_slot_new (NautilusWindow *window) -{ - return g_object_new (NAUTILUS_TYPE_DESKTOP_WINDOW_SLOT, - "window", window, - NULL); -} - -static void -nautilus_desktop_window_slot_class_init (NautilusDesktopWindowSlotClass *klass) -{ - NautilusWindowSlotClass *parent_class = NAUTILUS_WINDOW_SLOT_CLASS (klass); - - parent_class->get_view_for_location = real_get_view_for_location; -} - -static void -nautilus_desktop_window_slot_init (NautilusDesktopWindowSlot *self) -{ - GAction *action; - GActionGroup *action_group; - - /* Disable search on desktop */ - action_group = gtk_widget_get_action_group (GTK_WIDGET (self), "slot"); - - action = g_action_map_lookup_action (G_ACTION_MAP (action_group), "search-visible"); - g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE); - - /* Disable the ability to change between types of views */ - action = g_action_map_lookup_action (G_ACTION_MAP (action_group), "files-view-mode"); - g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE); -} diff --git a/src/nautilus-desktop-window-slot.h b/src/nautilus-desktop-window-slot.h deleted file mode 100644 index fc895ce63..000000000 --- a/src/nautilus-desktop-window-slot.h +++ /dev/null @@ -1,36 +0,0 @@ -/* nautilus-window-desktop-slot.h - * - * Copyright (C) 2016 Carlos Soriano - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef NAUTILUS_DESKTOP_WINDOW_SLOT_H -#define NAUTILUS_DESKTOP_WINDOW_SLOT_H - -#include "nautilus-window-slot.h" -#include "nautilus-window.h" - -G_BEGIN_DECLS - -#define NAUTILUS_TYPE_DESKTOP_WINDOW_SLOT (nautilus_desktop_window_slot_get_type()) - -G_DECLARE_FINAL_TYPE (NautilusDesktopWindowSlot, nautilus_desktop_window_slot, NAUTILUS, DESKTOP_WINDOW_SLOT, NautilusWindowSlot) - - -NautilusDesktopWindowSlot *nautilus_desktop_window_slot_new (NautilusWindow *window); - -G_END_DECLS - -#endif /* NAUTILUS_DESKTOP_WINDOW_SLOT_H */ - diff --git a/src/nautilus-desktop-window.c b/src/nautilus-desktop-window.c deleted file mode 100644 index 5b78cb38e..000000000 --- a/src/nautilus-desktop-window.c +++ /dev/null @@ -1,415 +0,0 @@ - -/* - * Nautilus - * - * Copyright (C) 2000 Eazel, Inc. - * - * Nautilus is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * Nautilus is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - * Authors: Darin Adler - */ - -#include -#include "nautilus-desktop-window.h" -#include "nautilus-window.h" -#include "nautilus-application.h" -#include "nautilus-desktop-window-slot.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -struct NautilusDesktopWindowDetails { - gulong size_changed_id; - - gboolean loaded; - - GtkWidget *desktop_selection; -}; - -G_DEFINE_TYPE (NautilusDesktopWindow, nautilus_desktop_window, - NAUTILUS_TYPE_WINDOW); - -static void -nautilus_desktop_window_update_directory (NautilusDesktopWindow *window) -{ - GFile *location; - - g_assert (NAUTILUS_IS_DESKTOP_WINDOW (window)); - - window->details->loaded = FALSE; - location = g_file_new_for_uri (EEL_DESKTOP_URI); - /* We use NAUTILUS_WINDOW_OPEN_FLAG_DONT_MAKE_ACTIVE so the nautilus-window - * doesn't call gtk_window_present () which raises the window on the stack - * and actually hides it from the background */ - nautilus_application_open_location_full (NAUTILUS_APPLICATION (g_application_get_default ()), - location, - NAUTILUS_WINDOW_OPEN_FLAG_DONT_MAKE_ACTIVE, - NULL, NAUTILUS_WINDOW (window), NULL); - window->details->loaded = TRUE; - - g_object_unref (location); -} - -static void -nautilus_desktop_window_finalize (GObject *obj) -{ - nautilus_desktop_link_monitor_shutdown (); - - G_OBJECT_CLASS (nautilus_desktop_window_parent_class)->finalize (obj); -} - -static void -nautilus_desktop_window_init_actions (NautilusDesktopWindow *window) -{ - GAction *action; - - /* Don't allow close action on desktop */ - action = g_action_map_lookup_action (G_ACTION_MAP (window), - "close-current-view"); - g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE); - - /* Don't allow new tab on desktop */ - action = g_action_map_lookup_action (G_ACTION_MAP (window), - "new-tab"); - g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE); - - /* Don't allow switching to home dir on desktop */ - action = g_action_map_lookup_action (G_ACTION_MAP (window), - "go-home"); - g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE); -} - -static void -selection_get_cb (GtkWidget *widget, - GtkSelectionData *selection_data, - guint info, - guint time) -{ - /* No extra targets atm */ -} - -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_constructed (GObject *obj) -{ - AtkObject *accessible; - NautilusDesktopWindow *window = NAUTILUS_DESKTOP_WINDOW (obj); - - G_OBJECT_CLASS (nautilus_desktop_window_parent_class)->constructed (obj); - - /* Initialize the desktop link monitor singleton */ - nautilus_desktop_link_monitor_get (); - - /* shouldn't really be needed given our semantic type - * of _NET_WM_TYPE_DESKTOP, but why not - */ - gtk_window_set_resizable (GTK_WINDOW (window), - FALSE); - gtk_window_set_decorated (GTK_WINDOW (window), - FALSE); - - gtk_window_move (GTK_WINDOW (window), 0, 0); - - 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); - - if (window->details->desktop_selection != NULL) { - /* 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); - - /* 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); - gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)), - "nautilus-desktop-window"); - -} - -static void -nautilus_desktop_window_screen_size_changed (GdkScreen *screen, - NautilusDesktopWindow *window) -{ - int width_request, height_request; - - width_request = gdk_screen_get_width (screen); - height_request = gdk_screen_get_height (screen); - - g_object_set (window, - "width_request", width_request, - "height_request", height_request, - NULL); -} - -static NautilusDesktopWindow * -nautilus_desktop_window_new (void) -{ - GdkScreen *screen; - GApplication *application; - NautilusDesktopWindow *window; - int width_request, height_request; - - application = g_application_get_default (); - screen = gdk_screen_get_default (); - width_request = gdk_screen_get_width (screen); - height_request = gdk_screen_get_height (screen); - - window = g_object_new (NAUTILUS_TYPE_DESKTOP_WINDOW, - "application", application, - "disable-chrome", TRUE, - "width_request", width_request, - "height_request", height_request, - NULL); - - return window; -} - -static NautilusDesktopWindow *the_desktop_window = NULL; - -void -nautilus_desktop_window_ensure (void) -{ - NautilusDesktopWindow *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 -nautilus_desktop_window_delete_event (GtkWidget *widget, - GdkEventAny *event) -{ - /* Returning true tells GTK+ not to delete the window. */ - return TRUE; -} - -static void -map (GtkWidget *widget) -{ - /* Chain up to realize our children */ - GTK_WIDGET_CLASS (nautilus_desktop_window_parent_class)->map (widget); - gdk_window_lower (gtk_widget_get_window (widget)); -} - -static void -unrealize (GtkWidget *widget) -{ - NautilusDesktopWindow *window; - NautilusDesktopWindowDetails *details; - - window = NAUTILUS_DESKTOP_WINDOW (widget); - details = window->details; - - if (details->size_changed_id != 0) { - g_signal_handler_disconnect (gtk_window_get_screen (GTK_WINDOW (window)), - details->size_changed_id); - details->size_changed_id = 0; - } - - gtk_widget_destroy (details->desktop_selection); - - GTK_WIDGET_CLASS (nautilus_desktop_window_parent_class)->unrealize (widget); -} - -static void -set_wmspec_desktop_hint (GdkWindow *window) -{ - GdkAtom atom; - - atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_DESKTOP", FALSE); - - gdk_property_change (window, - gdk_atom_intern ("_NET_WM_WINDOW_TYPE", FALSE), - gdk_x11_xatom_to_atom (XA_ATOM), 32, - GDK_PROP_MODE_REPLACE, (guchar *) &atom, 1); -} - -static void -realize (GtkWidget *widget) -{ - NautilusDesktopWindow *window; - NautilusDesktopWindowDetails *details; - GdkVisual *visual; - - window = NAUTILUS_DESKTOP_WINDOW (widget); - details = window->details; - - /* Make sure we get keyboard events */ - gtk_widget_set_events (widget, gtk_widget_get_events (widget) - | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); - - visual = gdk_screen_get_rgba_visual (gtk_widget_get_screen (widget)); - if (visual) { - gtk_widget_set_visual (widget, visual); - } - - /* Do the work of realizing. */ - GTK_WIDGET_CLASS (nautilus_desktop_window_parent_class)->realize (widget); - - /* This is the new way to set up the desktop window */ - set_wmspec_desktop_hint (gtk_widget_get_window (widget)); - - details->size_changed_id = - g_signal_connect (gtk_window_get_screen (GTK_WINDOW (window)), "size-changed", - G_CALLBACK (nautilus_desktop_window_screen_size_changed), window); -} - -static void -real_sync_title (NautilusWindow *window, - NautilusWindowSlot *slot) -{ - /* hardcode "Desktop" */ - gtk_window_set_title (GTK_WINDOW (window), _("Desktop")); -} - -static void -real_window_close (NautilusWindow *window) -{ - /* stub, does nothing */ - return; -} - -static NautilusWindowSlot * -real_create_slot (NautilusWindow *window, - GFile *location) -{ - return NAUTILUS_WINDOW_SLOT (nautilus_desktop_window_slot_new (window)); -} - -static void -nautilus_desktop_window_class_init (NautilusDesktopWindowClass *klass) -{ - GtkWidgetClass *wclass = GTK_WIDGET_CLASS (klass); - NautilusWindowClass *nclass = NAUTILUS_WINDOW_CLASS (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; - wclass->map = map; - wclass->delete_event = nautilus_desktop_window_delete_event; - - nclass->sync_title = real_sync_title; - nclass->close = real_window_close; - nclass->create_slot = real_create_slot; - - g_type_class_add_private (klass, sizeof (NautilusDesktopWindowDetails)); -} - -gboolean -nautilus_desktop_window_loaded (NautilusDesktopWindow *window) -{ - return window->details->loaded; -} diff --git a/src/nautilus-desktop-window.h b/src/nautilus-desktop-window.h deleted file mode 100644 index 589d2b48b..000000000 --- a/src/nautilus-desktop-window.h +++ /dev/null @@ -1,59 +0,0 @@ - -/* - * Nautilus - * - * Copyright (C) 2000 Eazel, Inc. - * - * Nautilus is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * Nautilus is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - * Authors: Darin Adler - */ - -/* nautilus-desktop-window.h - */ - -#ifndef NAUTILUS_DESKTOP_WINDOW_H -#define NAUTILUS_DESKTOP_WINDOW_H - -#include "nautilus-window.h" - -#define NAUTILUS_TYPE_DESKTOP_WINDOW nautilus_desktop_window_get_type() -#define NAUTILUS_DESKTOP_WINDOW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_DESKTOP_WINDOW, NautilusDesktopWindow)) -#define NAUTILUS_DESKTOP_WINDOW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DESKTOP_WINDOW, NautilusDesktopWindowClass)) -#define NAUTILUS_IS_DESKTOP_WINDOW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_DESKTOP_WINDOW)) -#define NAUTILUS_IS_DESKTOP_WINDOW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DESKTOP_WINDOW)) -#define NAUTILUS_DESKTOP_WINDOW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_DESKTOP_WINDOW, NautilusDesktopWindowClass)) - -typedef struct NautilusDesktopWindowDetails NautilusDesktopWindowDetails; - -typedef struct { - NautilusWindow parent_spot; - NautilusDesktopWindowDetails *details; -} NautilusDesktopWindow; - -typedef struct { - NautilusWindowClass parent_spot; -} NautilusDesktopWindowClass; - -GType nautilus_desktop_window_get_type (void); -GtkWidget * nautilus_desktop_window_get (void); -void nautilus_desktop_window_ensure (void); -gboolean nautilus_desktop_window_loaded (NautilusDesktopWindow *window); - -#endif /* NAUTILUS_DESKTOP_WINDOW_H */ diff --git a/src/nautilus-main.c b/src/nautilus-main.c index ce3c5910e..01c65508a 100644 --- a/src/nautilus-main.c +++ b/src/nautilus-main.c @@ -29,6 +29,7 @@ #include #include "nautilus-application.h" +#include "nautilus-resources.h" #include #include @@ -87,7 +88,7 @@ main (int argc, char *argv[]) #ifdef HAVE_EXEMPI xmp_init(); #endif - + nautilus_register_resource (); /* Run the nautilus application. */ application = nautilus_application_new (); -- cgit v1.2.1