Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:dliang
nautilus
nautilus-172870-support-drives-and-volumes.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File nautilus-172870-support-drives-and-volumes.diff of Package nautilus
2006-05-22 Federico Mena Quintero <federico@novell.com> * src/file-manager/fm-directory-view.c (ActivateParameters): Added a file_changed_id field. (fm_directory_view_activate_file): Initialize parameters->file_changed_id to 0. (activation_drive_mounted_callback): If the drive thinks it is not mounted yet, it is because gnome-vfs-volume-monitor hasn't emitted its volume_mounted signal yet. In that case, wait for the parameters->file to change --- that will let us know that the drive really got mounted. (activation_file_changed_after_drive_mounted): New function to handle the "changed" signal on parameters->file from above. Actually call activate_activation_uri_ready_callback() here, since the drive now really knows that it is mounted, and parameters->file has been updated with its activation URI. 2006-05-21 Federico Mena Quintero <federico@novell.com> * libnautilus-private/nautilus-desktop-link.c (reread_drive_or_volume): New helper function; moved the code to read the data from the drive_or_volume over from nautilus_desktop_link_new_from_drive_or_volume(). (nautilus_desktop_link_new_from_drive_or_volume): Use reread_drive_or_volume(). (nautilus_desktop_link_update_from_volume): Call reread_drive_or_volume(). This will actually cause the link to update its data when the volume changes. Duh! 2006-05-19 Federico Mena Quintero <federico@novell.com> * libnautilus-private/nautilus-desktop-link.h: New prototype for nautilus_desktop_link_update_from_volume(). * libnautilus-private/nautilus-desktop-link.c (nautilus_desktop_link_update_from_volume): New function. NautilusDesktopLinks can now change between containing an unmounted drive, and a mounted volume. This lets us have stable desktop icons with no reloading of the volumes. * libnautilus-private/nautilus-desktop-link-monitor.c (find_unique_link_for_drive): New helper function. (volume_mounted_callback): If the volume has a drive, first use find_unique_link_for_drive() to see if there's a drive link that can be updated for the volume. Otherwise, create a new link. (volume_unmounted_callback): Instead of refreshing the links, see if we can just update an existing volume link, or if we just need to remove the link altogether. (nautilus_desktop_link_monitor_init): Connect separate callbacks to drive_connected and drive_disconnected. (drive_connected_callback): Add a link for the drive if we don't have one already. (drive_disconnected_callback): Remove all the links that correspond to the drive. diff -uNrp nautilus-old/libnautilus-private/nautilus-desktop-link.c nautilus-new/libnautilus-private/nautilus-desktop-link.c --- nautilus-old/libnautilus-private/nautilus-desktop-link.c 2006-06-01 13:18:34.000000000 -0500 +++ nautilus-new/libnautilus-private/nautilus-desktop-link.c 2006-06-01 13:26:18.000000000 -0500 @@ -192,28 +192,25 @@ nautilus_desktop_link_new (NautilusDeskt return link; } -NautilusDesktopLink * -nautilus_desktop_link_new_from_drive_or_volume (GObject *object) +static void +reread_drive_or_volume (NautilusDesktopLink *link) { - NautilusDesktopLink *link; char *name, *filename; char *display_name, *activation_uri, *icon; - gboolean is_volume; - is_volume = GNOME_IS_VFS_VOLUME (object); - - g_return_val_if_fail (GNOME_IS_VFS_DRIVE (object) || is_volume, NULL); + g_assert (link->details->type == NAUTILUS_DESKTOP_LINK_VOLUME); + g_assert (link->details->drive_or_volume != NULL); - link = NAUTILUS_DESKTOP_LINK (g_object_new (NAUTILUS_TYPE_DESKTOP_LINK, NULL)); - - link->details->type = NAUTILUS_DESKTOP_LINK_VOLUME; + g_free (link->details->filename); + g_free (link->details->display_name); + g_free (link->details->activation_uri); + g_free (link->details->icon); - if (is_volume) { + if (GNOME_IS_VFS_VOLUME (link->details->drive_or_volume)) { GnomeVFSVolume *volume; GnomeVFSDrive *drive; - volume = gnome_vfs_volume_ref (GNOME_VFS_VOLUME (object)); - link->details->drive_or_volume = G_OBJECT (volume); + volume = GNOME_VFS_VOLUME (link->details->drive_or_volume); /* We try to use the drive name to get somewhat stable filenames for metadata */ @@ -231,8 +228,9 @@ nautilus_desktop_link_new_from_drive_or_ } else { GnomeVFSDrive *drive; - drive = gnome_vfs_drive_ref (GNOME_VFS_DRIVE (object)); - link->details->drive_or_volume = G_OBJECT (drive); + g_assert (GNOME_IS_VFS_DRIVE (link->details->drive_or_volume)); + + drive = GNOME_VFS_DRIVE (link->details->drive_or_volume); name = gnome_vfs_drive_get_display_name (drive); @@ -251,7 +249,35 @@ nautilus_desktop_link_new_from_drive_or_ link->details->display_name = display_name; link->details->activation_uri = activation_uri; link->details->icon = icon; +} + +NautilusDesktopLink * +nautilus_desktop_link_new_from_drive_or_volume (GObject *object) +{ + NautilusDesktopLink *link; + gboolean is_volume; + + is_volume = GNOME_IS_VFS_VOLUME (object); + + g_return_val_if_fail (GNOME_IS_VFS_DRIVE (object) || is_volume, NULL); + + link = NAUTILUS_DESKTOP_LINK (g_object_new (NAUTILUS_TYPE_DESKTOP_LINK, NULL)); + + link->details->type = NAUTILUS_DESKTOP_LINK_VOLUME; + + if (is_volume) { + GnomeVFSVolume *volume; + volume = gnome_vfs_volume_ref (GNOME_VFS_VOLUME (object)); + link->details->drive_or_volume = G_OBJECT (volume); + } else { + GnomeVFSDrive *drive; + + drive = gnome_vfs_drive_ref (GNOME_VFS_DRIVE (object)); + link->details->drive_or_volume = G_OBJECT (drive); + } + + reread_drive_or_volume (link); create_icon_file (link); return link; @@ -443,3 +469,64 @@ nautilus_desktop_link_class_init (gpoint object_class->finalize = desktop_link_finalize; } + +void +nautilus_desktop_link_update_from_volume (NautilusDesktopLink *link, + GnomeVFSVolume *volume) +{ + g_return_if_fail (NAUTILUS_IS_DESKTOP_LINK (link)); + g_return_if_fail (GNOME_IS_VFS_VOLUME (volume)); + + g_assert (link->details->type == NAUTILUS_DESKTOP_LINK_VOLUME); + g_assert (link->details->drive_or_volume != NULL); + + if (GNOME_IS_VFS_DRIVE (link->details->drive_or_volume)) { + GnomeVFSDrive *drive; + + drive = gnome_vfs_volume_get_drive (volume); + + /* Do we need to use gnome_vfs_drive_compare()? */ + g_assert (G_OBJECT (drive) == G_OBJECT (link->details->drive_or_volume)); + gnome_vfs_drive_unref (drive); + + /* The link is for a drive. If the new volume is mounted, + * replace the link's object with the volume. If the new volume + * is unmounted, just refresh the link (who knows why we didn't + * get the mount notification before). + */ + + if (gnome_vfs_volume_is_mounted (volume)) { + gnome_vfs_drive_unref (GNOME_VFS_DRIVE (link->details->drive_or_volume)); + + gnome_vfs_volume_ref (volume); + link->details->drive_or_volume = G_OBJECT (volume); + } + + /* The link will get updated below */ + } else { + g_assert (GNOME_IS_VFS_VOLUME (link->details->drive_or_volume)); + + /* Do we need to use gnome_vfs_volume_compare()? */ + g_assert (GNOME_VFS_VOLUME (link->details->drive_or_volume) == volume); + + /* If the volume got unmounted, restore the link's object to the + * corresponding drive. Otherwise, we shouldn't need to be + * called, but just update the link in that case. + */ + + if (!gnome_vfs_volume_is_mounted (volume)) { + GnomeVFSDrive *drive; + + drive = gnome_vfs_volume_get_drive (volume); + + gnome_vfs_volume_unref (GNOME_VFS_VOLUME (link->details->drive_or_volume)); + + link->details->drive_or_volume = G_OBJECT (drive); + } + + /* The link will get updated below */ + } + + reread_drive_or_volume (link); + nautilus_desktop_link_changed (link); +} diff -uNrp nautilus-old/libnautilus-private/nautilus-desktop-link.h nautilus-new/libnautilus-private/nautilus-desktop-link.h --- nautilus-old/libnautilus-private/nautilus-desktop-link.h 2006-06-01 13:18:34.000000000 -0500 +++ nautilus-new/libnautilus-private/nautilus-desktop-link.h 2006-06-01 13:26:18.000000000 -0500 @@ -77,4 +77,7 @@ gboolean nautilus_desktop gboolean nautilus_desktop_link_rename (NautilusDesktopLink *link, const char *name); +void nautilus_desktop_link_update_from_volume (NautilusDesktopLink *link, + GnomeVFSVolume *volume); + #endif /* NAUTILUS_DESKTOP_LINK_H */ diff -uNrp nautilus-old/libnautilus-private/nautilus-desktop-link-monitor.c nautilus-new/libnautilus-private/nautilus-desktop-link-monitor.c --- nautilus-old/libnautilus-private/nautilus-desktop-link-monitor.c 2006-06-01 13:18:34.000000000 -0500 +++ nautilus-new/libnautilus-private/nautilus-desktop-link-monitor.c 2006-06-01 13:26:18.000000000 -0500 @@ -206,15 +206,28 @@ nautilus_desktop_link_monitor_make_filen return unique_name; } +static gboolean +should_show_drive (GnomeVFSDrive *drive) +{ + return (gnome_vfs_drive_is_user_visible (drive) + && !gnome_vfs_drive_is_mounted (drive) + && eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE)); +} + +static gboolean +should_show_volume (GnomeVFSVolume *volume) +{ + return (gnome_vfs_volume_is_user_visible (volume) + && eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE)); +} + static void create_drive_link (NautilusDesktopLinkMonitor *monitor, GnomeVFSDrive *drive) { NautilusDesktopLink *link; - if (!(eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE) - && gnome_vfs_drive_is_user_visible (drive) - && !gnome_vfs_drive_is_mounted (drive))) + if (!should_show_drive (drive)) return; link = nautilus_desktop_link_new_from_drive_or_volume (G_OBJECT (drive)); @@ -229,22 +242,132 @@ create_volume_link (NautilusDesktopLinkM link = NULL; - if (!gnome_vfs_volume_is_user_visible (volume)) { + if (!should_show_volume (volume)) { return; } - if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE)) { - link = nautilus_desktop_link_new_from_drive_or_volume (G_OBJECT (volume)); - monitor->details->volume_links = g_list_prepend (monitor->details->volume_links, link); + link = nautilus_desktop_link_new_from_drive_or_volume (G_OBJECT (volume)); + monitor->details->volume_links = g_list_prepend (monitor->details->volume_links, link); +} + +static gboolean +link_corresponds_to_drive (NautilusDesktopLink *link, + GnomeVFSDrive *drive) +{ + GObject *drive_or_volume; + gboolean same; + + drive_or_volume = nautilus_desktop_link_get_drive_or_volume (link); + same = FALSE; + + if (GNOME_IS_VFS_DRIVE (drive_or_volume)) { + GnomeVFSDrive *link_drive; + + link_drive = GNOME_VFS_DRIVE (drive_or_volume); + + if (link_drive == drive) { + same = TRUE; + } + + gnome_vfs_drive_unref (link_drive); + } else { + GnomeVFSVolume *link_volume; + GnomeVFSDrive *link_drive; + + link_volume = GNOME_VFS_VOLUME (drive_or_volume); + link_drive = gnome_vfs_volume_get_drive (link_volume); + + if (link_drive == drive) { + same = TRUE; + } + + if (link_drive) { + gnome_vfs_drive_unref (link_drive); + } + + gnome_vfs_volume_unref (link_volume); + } + + return same; +} + +static NautilusDesktopLink * +find_unique_link_for_drive (NautilusDesktopLinkMonitor *monitor, + GnomeVFSDrive *drive) +{ + GList *l; + NautilusDesktopLink *first_volume_link_for_drive; + + first_volume_link_for_drive = NULL; + + for (l = monitor->details->volume_links; l; l = l->next) { + NautilusDesktopLink *link; + + link = NAUTILUS_DESKTOP_LINK (l->data); + + if (link_corresponds_to_drive (link, drive)) { + if (first_volume_link_for_drive == NULL) { + first_volume_link_for_drive = link; + } else { + return NULL; /* We know that we have more than + * one link for volumes that belong + * to the same drive, so there is + * no unique link for the drive. + */ + } + } } + + return first_volume_link_for_drive; } static void -drive_connect_disconnect_callback (GnomeVFSVolumeMonitor *volume_monitor, - GnomeVFSDrive *drive, - NautilusDesktopLinkMonitor *monitor) +drive_connected_callback (GnomeVFSVolumeMonitor *volume_monitor, + GnomeVFSDrive *drive, + NautilusDesktopLinkMonitor *monitor) { - refresh_volume_links (monitor); + NautilusDesktopLink *link; + + /* fprintf (stderr, "drive connected!\n"); */ + + link = find_unique_link_for_drive (monitor, drive); + + if (link) + return; /* huh, we already have a link for that drive... */ + + create_drive_link (monitor, drive); +} + +static void +drive_disconnected_callback (GnomeVFSVolumeMonitor *volume_monitor, + GnomeVFSDrive *drive, + NautilusDesktopLinkMonitor *monitor) +{ + GList *l; + + /* fprintf (stderr, "drive disconnected!\n"); */ + + /* Remove all the links that correspond to that drive, even if they have + * mounted volumes. + */ + + l = monitor->details->volume_links; + + while (l) { + GList *next; + NautilusDesktopLink *link; + + next = l->next; + link = NAUTILUS_DESKTOP_LINK (l->data); + + if (link_corresponds_to_drive (link, drive)) { + g_object_unref (link); + monitor->details->volume_links = g_list_remove_link (monitor->details->volume_links, l); + g_list_free_1 (l); + } + + l = next; + } } static void @@ -252,11 +375,65 @@ volume_mounted_callback (GnomeVFSVolumeM GnomeVFSVolume *volume, NautilusDesktopLinkMonitor *monitor) { -#if 0 - create_volume_link (monitor, volume); -#else - refresh_volume_links (monitor); -#endif + GnomeVFSDrive *drive; + + /* fprintf (stderr, "volume mounted!\n"); */ + + drive = gnome_vfs_volume_get_drive (volume); + + if (drive) { + NautilusDesktopLink *link; + + /* We may have an existing link for the drive, which needs to be + * updated for the volume. Or we may have several volumes + * within the same drive; in this case, we need to create a + * completely new link. + */ + + link = find_unique_link_for_drive (monitor, drive); + gnome_vfs_drive_unref (drive); + + if (link) { + /* fprintf (stderr, "updating desktop link from mounted volume\n"); */ + nautilus_desktop_link_update_from_volume (link, volume); + } else { + /* fprintf (stderr, "creating desktop link\n"); */ + create_volume_link (monitor, volume); + } + } else { + /* fprintf (stderr, "creating desktop link\n"); */ + create_volume_link (monitor, volume); + } +} + +static NautilusDesktopLink * +find_link_for_volume (NautilusDesktopLinkMonitor *monitor, + GnomeVFSVolume *volume) +{ + GList *l; + + for (l = monitor->details->volume_links; l != NULL; l = l->next) { + NautilusDesktopLink *link; + GObject *drive_or_volume; + gboolean same; + + link = NAUTILUS_DESKTOP_LINK (l->data); + drive_or_volume = nautilus_desktop_link_get_drive_or_volume (link); + + same = FALSE; + + if (GNOME_IS_VFS_VOLUME (drive_or_volume)) { + same = (GNOME_VFS_VOLUME (drive_or_volume) == volume); + gnome_vfs_volume_unref (GNOME_VFS_VOLUME (drive_or_volume)); + } else { + gnome_vfs_drive_unref (GNOME_VFS_DRIVE (drive_or_volume)); + } + + if (same) + return link; + } + + return NULL; } @@ -265,34 +442,34 @@ volume_unmounted_callback (GnomeVFSVolum GnomeVFSVolume *volume, NautilusDesktopLinkMonitor *monitor) { -#if 0 - GList *l; NautilusDesktopLink *link; - GObject *other_volume; + GnomeVFSDrive *drive; + gboolean remove_link; - link = NULL; - for (l = monitor->details->volume_links; l != NULL; l = l->next) { - other_volume = nautilus_desktop_link_get_drive_or_volume (l->data); - if (GNOME_IS_VFS_VOLUME (other_volume) && volume == GNOME_VFS_VOLUME (other_volume)) { - gnome_vfs_volume_unref (GNOME_VFS_VOLUME (other_volume)); - link = l->data; - break; - } + /* fprintf (stderr, "volume unmounted!\n"); */ - if (GNOME_IS_VFS_VOLUME (other_volume)) { - gnome_vfs_volume_unref (GNOME_VFS_VOLUME (other_volume)); + link = find_link_for_volume (monitor, volume); + if (!link) { + return; + } + + remove_link = FALSE; + + drive = gnome_vfs_volume_get_drive (volume); + if (drive) { + if (should_show_drive (drive)) { + nautilus_desktop_link_update_from_volume (link, volume); } else { - gnome_vfs_drive_unref (GNOME_VFS_DRIVE (other_volume)); + remove_link = TRUE; } + } else { + remove_link = TRUE; } - if (link) { + if (remove_link) { monitor->details->volume_links = g_list_remove (monitor->details->volume_links, link); g_object_unref (link); } -#else - refresh_volume_links (monitor); -#endif } static void @@ -485,10 +662,10 @@ nautilus_desktop_link_monitor_init (gpoi volume_monitor = gnome_vfs_get_volume_monitor (); monitor->details->connected_id = g_signal_connect_object (volume_monitor, "drive_connected", - G_CALLBACK (drive_connect_disconnect_callback), + G_CALLBACK (drive_connected_callback), monitor, 0); - monitor->details->disconnected_id = g_signal_connect_object (volume_monitor, "drive_connected", - G_CALLBACK (drive_connect_disconnect_callback), + monitor->details->disconnected_id = g_signal_connect_object (volume_monitor, "drive_disconnected", + G_CALLBACK (drive_disconnected_callback), monitor, 0); monitor->details->mount_id = g_signal_connect_object (volume_monitor, "volume_mounted", G_CALLBACK (volume_mounted_callback), monitor, 0); diff -uNrp nautilus-old/src/file-manager/fm-directory-view.c nautilus-new/src/file-manager/fm-directory-view.c --- nautilus-old/src/file-manager/fm-directory-view.c 2006-06-01 13:18:34.000000000 -0500 +++ nautilus-new/src/file-manager/fm-directory-view.c 2006-06-01 13:26:18.000000000 -0500 @@ -278,6 +278,7 @@ typedef struct { gboolean mounted; gboolean mounting; gboolean cancelled; + gulong file_changed_id; } ActivateParameters; enum { @@ -7385,6 +7386,25 @@ activate_callback (NautilusFile *file, g } static void +activation_file_changed_after_drive_mounted (NautilusFile *file, + gpointer data) +{ + ActivateParameters *parameters; + GnomeVFSDrive *drive; + + parameters = data; + + drive = nautilus_file_get_drive (parameters->file); /* we don't own this reference */ + g_assert (drive != NULL); + g_assert (gnome_vfs_drive_is_mounted (drive)); + + g_signal_handler_disconnect (parameters->file, parameters->file_changed_id); + parameters->file_changed_id = 0; + + activate_activation_uri_ready_callback (parameters->file, parameters); +} + +static void activation_drive_mounted_callback (gboolean succeeded, char *error, char *detailed_error, @@ -7398,9 +7418,35 @@ activation_drive_mounted_callback (gbool parameters->mounting = FALSE; if (succeeded && !parameters->cancelled) { - activate_activation_uri_ready_callback (parameters->file, - parameters); + GnomeVFSDrive *drive; + + /* fprintf (stderr, "LOG: activation_drive_mounted_callback(): drive got mounted successfully\n"); */ + + drive = nautilus_file_get_drive (parameters->file); /* we don't own this reference */ + g_assert (drive != NULL); + + if (gnome_vfs_drive_is_mounted (drive)) { + /* fprintf (stderr, "LOG: activation_drive_mounted_callback(): drive is really mounted; activating...\n"); */ + activate_activation_uri_ready_callback (parameters->file, + parameters); + } else { + /* Hack alert: Here, the drive is already mounted, but + * gnome-vfs-volume-monitor thinks that it is not. This + * is because gnome-vfs-daemon has not yet notified it. + * So we'll wait for the parameters->file to change: + * this will happen when gnome-vfs-volume-monitor + * actually picks up and emits the volume_mounted + * notification, and the NautilusDesktopLink modifies + * the NautilusFile. + */ + /* fprintf (stderr, "LOG: activation_drive_mounted_callback(): delaying activation...\n"); */ + parameters->file_changed_id = + g_signal_connect (parameters->file, "changed", + G_CALLBACK (activation_file_changed_after_drive_mounted), + parameters); + } } else { + /* fprintf (stderr, "LOG: activation_drive_mounted_callback(): drive didn't get mounted\n"); */ if (!parameters->cancelled) { stop_activate (parameters); @@ -7448,6 +7494,7 @@ activate_activation_uri_ready_callback ( if (drive != NULL && !gnome_vfs_drive_is_mounted (drive)) { parameters->mounting = TRUE; + /* fprintf (stderr, "LOG: activate_activation_uri_ready_callback() calling gnome_vfs_drive_mount()\n"); */ gnome_vfs_drive_mount (drive, activation_drive_mounted_callback, callback_data); return; } @@ -7458,6 +7505,7 @@ activate_activation_uri_ready_callback ( */ actual_file = NULL; uri = nautilus_file_get_activation_uri (file); + /* fprintf (stderr, "LOG: activate_activation_uri_ready_callback() got activation uri %s\n", uri); */ if (!(eel_str_has_prefix (uri, NAUTILUS_DESKTOP_COMMAND_SPECIFIER) || eel_str_has_prefix (uri, NAUTILUS_COMMAND_SPECIFIER))) { actual_file = nautilus_file_get (uri); @@ -7528,6 +7576,7 @@ fm_directory_view_activate_file (FMDirec parameters->mounted = FALSE; parameters->mounting = FALSE; parameters->cancelled = FALSE; + parameters->file_changed_id = 0; file_name = nautilus_file_get_display_name (file); timed_wait_prompt = g_strdup_printf (_("Opening \"%s\"."), file_name);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor