[Xfce4-commits] <xfce4-places-plugin:master> port-to-gio.patch

Andrzej noreply at xfce.org
Mon Apr 2 21:42:06 CEST 2012


Updating branch refs/heads/master
         to 606dfab1ae932ec30ab8fb72a8cb1d004f7f50d6 (commit)
       from 3479fe61dab59a90a6c89602d4d3a05fd1f26654 (commit)

commit 606dfab1ae932ec30ab8fb72a8cb1d004f7f50d6
Author: Andrzej <ndrwrdck at gmail.com>
Date:   Tue Apr 3 04:32:04 2012 +0900

    port-to-gio.patch
    
    Xfce #7317

 panel-plugin/Makefile.am            |   31 ++-
 panel-plugin/model.h                |    3 +-
 panel-plugin/model_system.c         |   63 +++---
 panel-plugin/model_user.c           |    4 +-
 panel-plugin/model_volumes.c        |  434 ++++++++++++++++++++++++++---------
 panel-plugin/model_volumes_notify.c |  317 +++++++++++++++++++++++++
 panel-plugin/model_volumes_notify.h |   37 +++
 panel-plugin/view.c                 |   54 ++++-
 panel-plugin/xfce46-compat.c        |  253 --------------------
 panel-plugin/xfce46-compat.h        |   18 --
 po/POTFILES.in                      |    1 +
 11 files changed, 786 insertions(+), 429 deletions(-)

diff --git a/panel-plugin/Makefile.am b/panel-plugin/Makefile.am
index ab2dee4..f3f6fb5 100644
--- a/panel-plugin/Makefile.am
+++ b/panel-plugin/Makefile.am
@@ -6,11 +6,13 @@ xfce4_popup_places_SOURCES =						\
 
 xfce4_popup_places_CFLAGS =						\
 	$(LIBX11_CFLAGS)						\
+	$(EXO_CFLAGS)							\
 	$(GTK_CFLAGS)
 
 xfce4_popup_places_LDADD =						\
 	$(LIBX11_LDFLAGS)						\
 	$(LIBX11_LIBS)							\
+	$(EXO_LIBS)							\
 	$(GTK_LIBS)
 
 
@@ -20,7 +22,14 @@ plugindir = $(libexecdir)/xfce4/panel-plugins
 plugin_PROGRAMS =							\
 	xfce4-places-plugin
 
+if HAVE_LIBNOTIFY
+xfce4_places_plugin_notify_sources =					\
+	model_volumes_notify.c						\
+	model_volumes_notify.h
+endif
+
 xfce4_places_plugin_SOURCES =						\
+	$(xfce4_places_plugin_notify_sources)				\
 	places.c							\
 	places.h							\
 	support.c							\
@@ -38,9 +47,7 @@ xfce4_places_plugin_SOURCES =						\
 	model_volumes.c							\
 	model_volumes.h							\
 	button.c							\
-	button.h							\
-	xfce46-compat.c							\
-	xfce46-compat.h
+	button.h
 
 
 
@@ -48,19 +55,33 @@ xfce4_places_plugin_CFLAGS =						\
 	-I$(top_builddir)						\
 	-I$(top_srcdir)							\
 	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"				\
+	$(GIO_CFLAGS)							\
+	$(GIO_UNIX_CFLAGS)						\
+	$(GLIB_CFLAGS)							\
+	$(GTHREAD_CFLAGS)						\
 	$(GTK_CFLAGS)							\
+	$(LIBNOTIFY_CFLAGS)						\
+	$(LIBX11_CFLAGS)						\
 	$(LIBXFCE4UTIL_CFLAGS)						\
 	$(LIBXFCE4UI_CFLAGS)						\
 	$(LIBXFCE4PANEL_CFLAGS)						\
-        $(THUNAR_VFS_CFLAGS)						\
+	$(EXO_CFLAGS)							\
 	$(PLATFORM_CFLAGS)
 
 xfce4_places_plugin_LDADD =						\
+	$(GIO_LIBS)							\
+	$(GIO_UNIX_LIBS)						\
+	$(GLIB_LIBS)							\
+	$(GTHREAD_LIBS)							\
+	$(GTK_LIBS)							\
+	$(LIBNOTIFY_LIBS)						\
+	$(LIBX11_LDFLAGS)						\
+	$(LIBX11_LIBS)							\
 	$(LIBXFCE4UTIL_LIBS)						\
 	$(LIBXFCE4UI_LIBS)						\
 	$(LIBXFCE4PANEL_LIBS)						\
 	$(LIBX11_LIBS)							\
-	@THUNAR_VFS_LIBS@
+	$(EXO_LIBS)
 
 
 #
diff --git a/panel-plugin/model.h b/panel-plugin/model.h
index c2a41de..cbbee3d 100644
--- a/panel-plugin/model.h
+++ b/panel-plugin/model.h
@@ -23,6 +23,7 @@
 #define _XFCE_PANEL_PLACES_MODEL_H
 
 #include <glib.h>
+#include <gio/gio.h>
 
 /* Places Bookmark Action */
 typedef struct _PlacesBookmarkAction PlacesBookmarkAction;
@@ -59,7 +60,7 @@ struct _PlacesBookmark
     gchar                 *label;          /* must not be NULL */
     gchar                 *uri;            /* may be NULL */
     places_uri_scheme      uri_scheme;    
-    gchar                 *icon;           /* may be NULL */
+    GIcon                 *icon;           /* may be NULL */
     PlacesBookmarkAction  *primary_action; /* may be NULL */
     gboolean               force_gray;
     GList                 *actions;        /* may be NULL (empty) */
diff --git a/panel-plugin/model_system.c b/panel-plugin/model_system.c
index e9aa968..aed425f 100644
--- a/panel-plugin/model_system.c
+++ b/panel-plugin/model_system.c
@@ -30,13 +30,11 @@
 #include <string.h>
 
 #include <glib.h>
+#include <gio/gio.h>
 
 #include <libxfce4util/libxfce4util.h>
 
-#define EXO_API_SUBJECT_TO_CHANGE
-#include <thunar-vfs/thunar-vfs.h>
-
-#define TRASH          THUNAR_VFS_CHECK_VERSION(0,4,0)
+#define TRASH          1
 #define XDG_USER_DIRS  GLIB_CHECK_VERSION(2,14,0)
 
 #define pbg_priv(pbg) ((PBSysData*) pbg->priv)
@@ -49,7 +47,7 @@ typedef struct
     gchar         *desktop_dir;     /* NULL => no desktop or desktop is same as home */
 #if TRASH
     gboolean       trash_is_empty;
-    ThunarVfsPath *trash_path;
+    GFile *trash_path;
 #endif
 
 } PBSysData;
@@ -72,7 +70,7 @@ pbsys_finalize_trash_bookmark(PlacesBookmark *bookmark)
     g_assert(bookmark != NULL);
 
     if(bookmark->icon != NULL){
-        g_free(bookmark->icon);
+        g_object_unref(bookmark->icon);
         bookmark->icon = NULL;
     }
 }
@@ -80,15 +78,14 @@ pbsys_finalize_trash_bookmark(PlacesBookmark *bookmark)
 
 #if TRASH
 static gboolean
-pbsys_trash_is_empty(const ThunarVfsInfo *trash_info)
+pbsys_trash_is_empty(GFileInfo *trash_info)
 {
-    if (trash_info->custom_icon == NULL)
-        return FALSE;
-    if (strcmp("user-trash-full", trash_info->custom_icon) == 0)
-        return FALSE;
-    if (strcmp("gnome-fs-trash-full", trash_info->custom_icon) == 0)
+    guint item_count = g_file_info_get_attribute_uint32(trash_info,
+                                                        G_FILE_ATTRIBUTE_TRASH_ITEM_COUNT);
+    if(item_count == 0)
+        return TRUE;
+    else
         return FALSE;
-    return TRUE;
 }
 #endif
 
@@ -130,7 +127,7 @@ pbsys_get_bookmarks(PlacesBookmarkGroup *bookmark_group)
     PlacesBookmark *bookmark;
     PlacesBookmarkAction *open, *terminal;
 #if TRASH
-    ThunarVfsInfo *trash_info;
+    GFileInfo *trash_info;
 #endif
     const gchar *home_dir = xfce_get_homedir();
     gchar *desktop_dir;
@@ -142,7 +139,7 @@ pbsys_get_bookmarks(PlacesBookmarkGroup *bookmark_group)
     /* Home */
     bookmark                = places_bookmark_create((gchar*) g_get_user_name());
     bookmark->uri           = (gchar*) home_dir;
-    bookmark->icon          = "user-home";
+    bookmark->icon          = g_themed_icon_new("user-home");
 
     terminal                 = places_create_open_terminal_action(bookmark);
     bookmark->actions        = g_list_prepend(bookmark->actions, terminal);
@@ -159,15 +156,20 @@ pbsys_get_bookmarks(PlacesBookmarkGroup *bookmark_group)
     bookmark->uri_scheme    = PLACES_URI_SCHEME_TRASH;
     bookmark->finalize      = pbsys_finalize_trash_bookmark;;
 
-    /* Try for an icon from ThunarVFS to indicate whether trash is empty or not */
+    /* Try for an icon to indicate whether trash is empty or not */
     
-    trash_info = thunar_vfs_info_new_for_path(pbg_priv(bookmark_group)->trash_path, NULL);
+    trash_info = g_file_query_info(pbg_priv(bookmark_group)->trash_path,
+                    "trash::*",
+                    G_FILE_QUERY_INFO_NONE,
+                    NULL, NULL);
     pbg_priv(bookmark_group)->trash_is_empty = pbsys_trash_is_empty(trash_info);
-    if(trash_info->custom_icon != NULL)
-        bookmark->icon = g_strdup(trash_info->custom_icon);
+    if (bookmark->icon != NULL)
+        g_object_unref(bookmark->icon);
+    if (pbg_priv(bookmark_group)->trash_is_empty)
+        bookmark->icon = g_themed_icon_new("user-trash");
     else
-        bookmark->icon = g_strdup("user-trash-full");
-    thunar_vfs_info_unref(trash_info);
+        bookmark->icon = g_themed_icon_new("user-trash-full");
+    g_object_unref(trash_info);
 
     open                     = places_create_open_action(bookmark);
     bookmark->actions        = g_list_prepend(bookmark->actions, open);
@@ -185,7 +187,7 @@ pbsys_get_bookmarks(PlacesBookmarkGroup *bookmark_group)
     if(desktop_dir != NULL){
         bookmark                = places_bookmark_create(_("Desktop"));
         bookmark->uri           = desktop_dir;
-        bookmark->icon          = "user-desktop";
+        bookmark->icon          = g_themed_icon_new("user-desktop");
         bookmark->finalize      = pbsys_finalize_desktop_bookmark;
 
 
@@ -201,7 +203,7 @@ pbsys_get_bookmarks(PlacesBookmarkGroup *bookmark_group)
     /* File System (/) */
     bookmark                = places_bookmark_create(_("File System"));
     bookmark->uri           = "/";
-    bookmark->icon          = "gtk-harddisk";
+    bookmark->icon          = g_themed_icon_new("gtk-harddisk");
 
     terminal                 = places_create_open_terminal_action(bookmark);
     bookmark->actions        = g_list_prepend(bookmark->actions, terminal);
@@ -220,7 +222,7 @@ pbsys_changed(PlacesBookmarkGroup *bookmark_group)
     gchar *desktop_dir;
 #if TRASH
     gboolean trash_is_empty;
-    ThunarVfsInfo *trash_info;
+    GFileInfo *trash_info;
 #endif
 
     if(!pbg_priv(bookmark_group)->check_changed)
@@ -236,9 +238,12 @@ pbsys_changed(PlacesBookmarkGroup *bookmark_group)
 
 #if TRASH
     /* see if trash gets a different icon (e.g., was empty, now full) */
-    trash_info = thunar_vfs_info_new_for_path(pbg_priv(bookmark_group)->trash_path, NULL);
+    trash_info = g_file_query_info(pbg_priv(bookmark_group)->trash_path,
+                    "trash::*",
+                    G_FILE_QUERY_INFO_NONE,
+                    NULL, NULL);
     trash_is_empty = pbsys_trash_is_empty(trash_info);
-    thunar_vfs_info_unref(trash_info);
+    g_object_unref(trash_info);
     
     if(trash_is_empty != pbg_priv(bookmark_group)->trash_is_empty)
         return TRUE;
@@ -251,8 +256,7 @@ static void
 pbsys_finalize(PlacesBookmarkGroup *bookmark_group)
 {
 #if TRASH
-    thunar_vfs_path_unref(pbg_priv(bookmark_group)->trash_path);
-    thunar_vfs_shutdown();
+    g_object_unref(pbg_priv(bookmark_group)->trash_path);
 #endif
 
     g_free(pbg_priv(bookmark_group)->desktop_dir);
@@ -273,8 +277,7 @@ places_bookmarks_system_create(void)
     bookmark_group->priv          = g_new0(PBSysData, 1);
     
 #if TRASH
-    thunar_vfs_init();
-    pbg_priv(bookmark_group)->trash_path = thunar_vfs_path_get_for_trash();
+    pbg_priv(bookmark_group)->trash_path = g_file_new_for_uri("trash:///");
 #endif
 
     return bookmark_group;
diff --git a/panel-plugin/model_user.c b/panel-plugin/model_user.c
index a8a4b4c..f3fc290 100644
--- a/panel-plugin/model_user.c
+++ b/panel-plugin/model_user.c
@@ -168,7 +168,7 @@ pbuser_build_bookmarks(PlacesBookmarkGroup *bookmark_group)
         /* create the BookmarkInfo container */
         bookmark        = places_bookmark_create(name);           /* label needs to be freed */
         bookmark->uri   = path;                                   /* uri   needs to be freed */
-        bookmark->icon  = "folder";
+        bookmark->icon  = g_themed_icon_new("folder");
         bookmark->priv  = GINT_TO_POINTER(pbuser_dir_exists(path));
         bookmark->finalize = pbuser_finalize_bookmark;
 
@@ -213,7 +213,7 @@ pbuser_get_bookmarks(PlacesBookmarkGroup *bookmark_group)
             clone                 = places_bookmark_create(g_strdup(orig->label));
             clone->uri            = g_strdup(orig->uri);
             clone->uri_scheme     = orig->uri_scheme;
-            clone->icon           = orig->icon;
+            clone->icon           = g_object_ref(orig->icon);
             clone->finalize       = pbuser_finalize_bookmark;
     
             terminal              = places_create_open_terminal_action(clone);
diff --git a/panel-plugin/model_volumes.c b/panel-plugin/model_volumes.c
index 8824681..893c762 100644
--- a/panel-plugin/model_volumes.c
+++ b/panel-plugin/model_volumes.c
@@ -27,8 +27,15 @@
 #include "model_volumes.h"
 #include "support.h"
 
-#define EXO_API_SUBJECT_TO_CHANGE
-#include <thunar-vfs/thunar-vfs.h>
+#include <gio/gio.h>
+#ifdef HAVE_GIO_UNIX
+#include <gio/gunixmounts.h>
+#endif
+#include <gtk/gtk.h>
+ 
+#ifdef HAVE_LIBNOTIFY
+#include "model_volumes_notify.h"
+#endif
 
 #include <libxfce4util/libxfce4util.h>
 
@@ -38,76 +45,156 @@
 
 typedef struct
 {
-
-    ThunarVfsVolumeManager *volume_manager;
+    GVolumeMonitor *volume_monitor;
     gboolean   changed;
     gboolean   mount_and_open_by_default;
-
 } PBVolData;
 
 
 /********** Actions Callbacks **********/
+static void
+pbvol_eject_finish(GObject *object,
+                GAsyncResult *result,
+                gpointer user_data)
+{
+    GVolume *volume = G_VOLUME(object);
+    GError *error = NULL;
+
+    g_return_if_fail(G_IS_VOLUME(object));
+    g_return_if_fail(G_IS_ASYNC_RESULT(result));
+
+    if (!g_volume_eject_with_operation_finish(volume, result, &error)) {
+         /* ignore GIO errors handled internally */
+         if(error->domain != G_IO_ERROR || error->code != G_IO_ERROR_FAILED_HANDLED) {
+             gchar *volume_name = g_volume_get_name(volume);
+             places_show_error_dialog(error,
+                                 _("Failed to eject \"%s\""),
+                                 volume_name);
+             g_free(volume_name);
+         }
+         g_error_free(error);
+    }
+
+#ifdef HAVE_LIBNOTIFY
+    pbvol_notify_eject_finish(volume);
+#endif
+}
 
 static void
 pbvol_eject(PlacesBookmarkAction *action)
 {
-    GError *error = NULL;
-    ThunarVfsVolume *volume;
+    GVolume *volume;
 
     DBG("Eject");
 
-    g_return_if_fail(THUNAR_VFS_IS_VOLUME(action->priv));
-    volume = THUNAR_VFS_VOLUME(action->priv);
+    g_return_if_fail(G_IS_VOLUME(action->priv));
+    volume = G_VOLUME(action->priv);
 
-    if(!thunar_vfs_volume_eject(volume, NULL, &error)){
-        places_show_error_dialog(error,
-                                 _("Failed to eject \"%s\""),
-                                 thunar_vfs_volume_get_name (volume));
-        g_error_free (error);
+    if (g_volume_can_eject(volume)) {
+#ifdef HAVE_LIBNOTIFY
+        pbvol_notify_eject(volume);
+#endif
+        g_volume_eject_with_operation(volume, G_MOUNT_UNMOUNT_NONE, NULL,
+                           NULL,
+                           pbvol_eject_finish,
+                           g_object_ref(volume));
     }
 }
 
 static void
-pbvol_unmount(PlacesBookmarkAction *action)
+pbvol_unmount_finish(GObject *object,
+                GAsyncResult *result,
+                gpointer user_data)
 {
+    GMount *mount = G_MOUNT(object);
     GError *error = NULL;
-    ThunarVfsVolume *volume;
+
+    g_return_if_fail(G_IS_MOUNT(object));
+    g_return_if_fail(G_IS_ASYNC_RESULT(result));
+
+    if (!g_mount_unmount_with_operation_finish(mount, result, &error)) {
+         /* ignore GIO errors handled internally */
+         if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_FAILED_HANDLED) {
+             gchar *mount_name = g_mount_get_name(mount);
+             places_show_error_dialog(error,
+                                     _("Failed to unmount \"%s\""),
+                                     mount_name);
+             g_free(mount_name);
+         }
+         g_error_free (error);
+    }
+
+#ifdef HAVE_LIBNOTIFY
+    pbvol_notify_unmount_finish(mount);
+#endif
+}
+
+static void
+pbvol_unmount(PlacesBookmarkAction *action)
+{
+    GVolume *volume;
+    GMount *mount;
 
     DBG("Unmount");
 
-    g_return_if_fail(THUNAR_VFS_IS_VOLUME(action->priv));
-    volume = THUNAR_VFS_VOLUME(action->priv);
+    g_return_if_fail(G_IS_VOLUME(action->priv));
+    volume = G_VOLUME(action->priv);
+    mount = g_volume_get_mount(volume);
 
-    if(thunar_vfs_volume_is_mounted(volume)){
-        if(!thunar_vfs_volume_unmount(volume, NULL, &error)){
+    if (mount) {
+#ifdef HAVE_LIBNOTIFY
+        pbvol_notify_unmount(mount);
+#endif
+        g_mount_unmount_with_operation(mount, G_MOUNT_UNMOUNT_NONE, NULL,
+                            NULL,
+                            pbvol_unmount_finish, 
+                            g_object_ref(volume));
+    }
+}
 
-            places_show_error_dialog(error,
-                                     _("Failed to unmount \"%s\""),
-                                     thunar_vfs_volume_get_name (volume));
-            g_error_free (error);
-        }
+static void
+pbvol_mount_finish(GObject *object,
+                GAsyncResult *result,
+                gpointer user_data)
+{
+    GVolume *volume = G_VOLUME(object);
+    GError *error = NULL;
+
+    DBG("Mount finish");
+
+    if (!g_volume_mount_finish(volume, result, &error)) {
+         /* ignore GIO errors handled internally */
+         if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_FAILED_HANDLED) {
+             gchar *volume_name = g_volume_get_name(volume);
+             places_show_error_dialog(error,
+                                     _("Failed to mount \"%s\""),
+                                     volume_name);
+             g_free(volume_name);
+         }
+         g_error_free (error);
     }
 }
 
 static void
 pbvol_mount(PlacesBookmarkAction *action)
 {
-    GError *error = NULL;
-    ThunarVfsVolume *volume;
+    GVolume *volume;
+    GMount *mount;
 
     DBG("Mount");
 
-    g_return_if_fail(THUNAR_VFS_IS_VOLUME(action->priv));
-    volume = THUNAR_VFS_VOLUME(action->priv);
+    g_return_if_fail(G_IS_VOLUME(action->priv));
+    volume = G_VOLUME(action->priv);
+    mount = g_volume_get_mount(volume);
 
-    if(!thunar_vfs_volume_is_mounted(volume)){
-        if(!thunar_vfs_volume_mount(volume, NULL, &error)){
+    if (!mount) {
+        GMountOperation *operation = gtk_mount_operation_new(NULL);
 
-            places_show_error_dialog(error,
-                                     _("Failed to mount \"%s\""),
-                                     thunar_vfs_volume_get_name (volume));
-            g_error_free (error);
-        }
+        g_volume_mount(volume, G_MOUNT_MOUNT_NONE, operation, NULL,
+                       pbvol_mount_finish, 
+                       g_object_ref(volume));
+
+        g_object_unref(operation);
     }
 }
 
@@ -115,33 +202,166 @@ static void
 pbvol_mount_and_open(PlacesBookmarkAction *action)
 {
     gchar *uri;
-    ThunarVfsVolume *volume;
+    GVolume *volume;
+    GMount *mount;
 
     DBG("Mount and open");
     
-    g_return_if_fail(THUNAR_VFS_IS_VOLUME(action->priv));
-    volume = THUNAR_VFS_VOLUME(action->priv);
+    g_return_if_fail(G_IS_VOLUME(action->priv));
+    volume = G_VOLUME(action->priv);
+    mount = g_volume_get_mount(volume);
 
-    if(!thunar_vfs_volume_is_mounted(volume))
+    if (!mount)
         pbvol_mount(action);
 
-    if(thunar_vfs_volume_is_mounted(volume)){
-        uri = thunar_vfs_path_dup_uri(thunar_vfs_volume_get_mount_point(volume));
+    if (mount) {
+        GFile *file = g_mount_get_root(mount);
+        uri = g_file_get_uri(file);
         places_load_file_browser(uri);
         g_free(uri);
+        g_object_unref(file);
+        g_object_unref(mount);
     }
 }
 
-static inline gboolean
-pbvol_show_volume(ThunarVfsVolume *volume){
-    
-    DBG("Volume: %s [mounted=%x removable=%x present=%x]", thunar_vfs_volume_get_name(volume), 
-                                                           thunar_vfs_volume_is_mounted(volume),
-                                                           thunar_vfs_volume_is_removable(volume), 
-                                                           thunar_vfs_volume_is_present(volume));
+#ifdef HAVE_GIO_UNIX
+static gboolean
+pbvol_mount_is_internal (GMount *mount)
+{
+    const gchar *point_mount_path;
+    gboolean is_internal = FALSE;
+    GFile *root;
+    GList *lp;
+    GList *mount_points;
+    gchar *mount_path;
+
+    g_return_val_if_fail(G_IS_MOUNT(mount), FALSE);
+
+    /* determine the mount path */
+    root = g_mount_get_root(mount);
+    mount_path = g_file_get_path(root);
+    g_object_unref(root);
+
+    /* assume non-internal if we cannot determine the path */
+    if (!mount_path)
+        return FALSE;
+
+    if (g_unix_is_mount_path_system_internal(mount_path)) {
+        /* mark as internal */
+        is_internal = TRUE;
+    } else {
+        /* get a list of all mount points */
+        mount_points = g_unix_mount_points_get(NULL);
+
+        /* search for the mount point associated with the mount entry */
+        for (lp = mount_points; !is_internal && lp != NULL; lp = lp->next) {
+            point_mount_path = g_unix_mount_point_get_mount_path(lp->data);
+
+            /* check if this is the mount point we are looking for */
+            if (g_strcmp0(mount_path, point_mount_path) == 0) {
+                /* mark as internal if the user cannot mount this device */
+                if (!g_unix_mount_point_is_user_mountable(lp->data))
+                    is_internal = TRUE;
+            }
+                
+            /* free the mount point, we no longer need it */
+            g_unix_mount_point_free(lp->data);
+        }
+
+        /* free the mount point list */
+        g_list_free(mount_points);
+    }
 
-    return thunar_vfs_volume_is_removable(volume) && 
-           thunar_vfs_volume_is_present(volume);
+    g_free(mount_path);
+
+
+    return is_internal;
+}
+#endif
+
+
+gboolean
+pbvol_is_removable(GVolume *volume)
+{
+    gboolean can_eject = FALSE;
+    gboolean can_mount = FALSE;
+    gboolean can_unmount = FALSE;
+    gboolean is_removable = FALSE;
+    gboolean is_internal = FALSE;
+    GDrive *drive;
+    GMount *mount;
+
+    g_return_val_if_fail(G_IS_VOLUME(volume), FALSE);
+
+    /* check if the volume can be ejected */
+    can_eject = g_volume_can_eject(volume);
+
+    /* determine the drive for the volume */
+    drive = g_volume_get_drive(volume);
+    if (drive) {
+        /*check if the drive media can be removed */
+        is_removable = g_drive_is_media_removable(drive);
+
+        /* release the drive */
+        g_object_unref(drive);
+    }
+    /* determine the mount for the volume (if it is mounted at all) */
+    mount = g_volume_get_mount(volume);
+    if (mount) {
+#ifdef HAVE_GIO_UNIX
+        is_internal = pbvol_mount_is_internal (mount);
+#endif
+
+        /* check if the volume can be unmounted */
+        can_unmount = g_mount_can_unmount(mount);
+
+        /* release the mount */
+        g_object_unref(mount);
+    }
+
+    /* determine whether the device can be mounted */
+    can_mount = g_volume_can_mount(volume);
+
+    return (!is_internal) && (can_eject || can_unmount || is_removable || can_mount);
+}
+
+gboolean
+pbvol_is_present(GVolume *volume)
+{
+    gboolean has_media = FALSE;
+    gboolean is_shadowed = FALSE;
+    GDrive *drive;
+    GMount *mount;
+
+    g_return_val_if_fail(G_IS_VOLUME(volume), FALSE);
+
+    drive = g_volume_get_drive (volume);
+    if(drive) {
+        has_media = g_drive_has_media(drive);
+        g_object_unref(drive);
+    }
+
+    mount = g_volume_get_mount(volume);
+    if(mount) {
+        is_shadowed = g_mount_is_shadowed(mount);
+        g_object_unref(mount);
+    }
+
+    return has_media && !is_shadowed;
+}
+
+static inline gboolean
+pbvol_show_volume(GVolume *volume){
+    GMount *mount = g_volume_get_mount(volume);
+    DBG("Volume: %s [mounted=%x removable=%x present=%x]", g_volume_get_name(volume), 
+                                                           mount,
+                                                           pbvol_is_removable(volume), 
+                                                           pbvol_is_present(volume));
+    if (mount)
+       g_object_unref(mount);
+
+    return pbvol_is_removable(volume) && 
+           pbvol_is_present(volume);
 }
 
 static void
@@ -153,29 +373,23 @@ pbvol_set_changed(PlacesBookmarkGroup *bookmark_group)
 
 
 static void
-pbvol_volumes_added(ThunarVfsVolumeManager *volman, GList *volumes, PlacesBookmarkGroup *bookmark_group)
+pbvol_volume_added(GVolumeMonitor *monitor, GVolume *volume, PlacesBookmarkGroup *bookmark_group)
 {
     DBG("-");
 
     pbg_priv(bookmark_group)->changed = TRUE;
-    while(volumes != NULL){
-        g_signal_connect_swapped(THUNAR_VFS_VOLUME(volumes->data), "changed",
-                                 G_CALLBACK(pbvol_set_changed), bookmark_group);
-        volumes = volumes->next;
-    }
+    g_signal_connect_swapped(G_VOLUME(volume), "changed",
+                             G_CALLBACK(pbvol_set_changed), bookmark_group);
 }
 
 static void
-pbvol_volumes_removed(ThunarVfsVolumeManager *volman, GList *volumes, PlacesBookmarkGroup *bookmark_group)
+pbvol_volume_removed(GVolumeMonitor *monitor, GVolume *volume, PlacesBookmarkGroup *bookmark_group)
 {
     DBG("-");
 
     pbg_priv(bookmark_group)->changed = TRUE;
-    while(volumes != NULL){
-        g_signal_handlers_disconnect_by_func(THUNAR_VFS_VOLUME(volumes->data),
-                                             G_CALLBACK(pbvol_set_changed), bookmark_group);
-        volumes = volumes->next;
-    }
+    g_signal_handlers_disconnect_by_func(G_VOLUME(volume),
+                                         G_CALLBACK(pbvol_set_changed), bookmark_group);
 }
 
 static void
@@ -189,12 +403,9 @@ pbvol_bookmark_finalize(PlacesBookmark *bookmark)
 
 static void
 pbvol_bookmark_action_finalize(PlacesBookmarkAction *action){
-
-    ThunarVfsVolume *volume;
-
     g_assert(action != NULL && action->priv != NULL);
 
-    volume = THUNAR_VFS_VOLUME(action->priv);
+    GVolume *volume = G_VOLUME(action->priv);
     g_object_unref(volume);
     action->priv = NULL;
 }
@@ -206,24 +417,28 @@ pbvol_get_bookmarks(PlacesBookmarkGroup *bookmark_group)
     PlacesBookmark *bookmark;
     PlacesBookmarkAction *action, *terminal, *open;
     const GList *volumes;
-    ThunarVfsVolume *volume;
-    GtkIconTheme *icon_theme = gtk_icon_theme_get_default();
+    GVolume *volume;
+    GMount *mount;
+    GIcon *icon;
 
-    volumes = thunar_vfs_volume_manager_get_volumes(pbg_priv(bookmark_group)->volume_manager);
-    while(volumes != NULL){
-        volume = THUNAR_VFS_VOLUME(volumes->data);
+    volumes = g_volume_monitor_get_volumes(pbg_priv(bookmark_group)->volume_monitor);
+    while (volumes != NULL) {
+        volume = volumes->data;
+        mount = g_volume_get_mount(volume);
 
         if(pbvol_show_volume(volume)){
 
-            bookmark            = places_bookmark_create((gchar*) thunar_vfs_volume_get_name(volume));
-            if(thunar_vfs_volume_is_mounted(volume))
-                bookmark->uri   = thunar_vfs_path_dup_uri(thunar_vfs_volume_get_mount_point(volume));
-            else
+            bookmark            = places_bookmark_create((gchar*) g_volume_get_name(volume));
+            if (mount) {
+                GFile *file = g_mount_get_root(mount);
+                bookmark->uri   = g_file_get_uri(file);
+                g_object_unref(file);
+            } else
                 bookmark->uri   = NULL;
-            bookmark->icon      = (gchar*) thunar_vfs_volume_lookup_icon_name(volume, icon_theme);
+            bookmark->icon      = g_volume_get_icon(volume);
             bookmark->finalize  = pbvol_bookmark_finalize;
 
-            if(!thunar_vfs_volume_is_mounted(volume)){
+            if (!mount) {
 
                 g_object_ref(volume);
                 action              = places_bookmark_action_create(_("Mount and Open"));
@@ -256,7 +471,7 @@ pbvol_get_bookmarks(PlacesBookmarkGroup *bookmark_group)
 
             }
 
-            if(thunar_vfs_volume_is_ejectable(volume)){
+            if (g_volume_can_eject(volume)) {
 
                 g_object_ref(volume);
                 action              = places_bookmark_action_create(_("Eject"));
@@ -266,18 +481,15 @@ pbvol_get_bookmarks(PlacesBookmarkGroup *bookmark_group)
                 action->finalize    = pbvol_bookmark_action_finalize;
                 bookmark->actions   = g_list_append(bookmark->actions, action);
 
-            }else{
-                if(thunar_vfs_volume_is_mounted(volume)){
-
-                    g_object_ref(volume);
-                    action              = places_bookmark_action_create(_("Unmount"));
-                    action->may_block   = TRUE;
-                    action->priv        = volume;
-                    action->action      = pbvol_unmount;
-                    action->finalize    = pbvol_bookmark_action_finalize;
-                    bookmark->actions   = g_list_append(bookmark->actions, action);
-
-                }
+            }
+            if (mount) {
+                g_object_ref(volume);
+                action              = places_bookmark_action_create(_("Unmount"));
+                action->may_block   = TRUE;
+                action->priv        = volume;
+                action->action      = pbvol_unmount;
+                action->finalize    = pbvol_bookmark_action_finalize;
+                bookmark->actions   = g_list_append(bookmark->actions, action);
             }
 
             bookmarks = g_list_prepend(bookmarks, bookmark);
@@ -303,21 +515,20 @@ pbvol_finalize(PlacesBookmarkGroup *bookmark_group)
 {
     const GList *volumes;
     
-    volumes = thunar_vfs_volume_manager_get_volumes(pbg_priv(bookmark_group)->volume_manager);
+    volumes = g_volume_monitor_get_volumes(pbg_priv(bookmark_group)->volume_monitor);
     while(volumes != NULL){
-        g_signal_handlers_disconnect_by_func(THUNAR_VFS_VOLUME(volumes->data),
+        g_signal_handlers_disconnect_by_func(G_VOLUME(volumes->data),
                                              G_CALLBACK(pbvol_set_changed), bookmark_group);
         volumes = volumes->next;
     }
 
-    g_signal_handlers_disconnect_by_func(pbg_priv(bookmark_group)->volume_manager,
-                                         G_CALLBACK(pbvol_volumes_added), bookmark_group);
-    g_signal_handlers_disconnect_by_func(pbg_priv(bookmark_group)->volume_manager,
-                                         G_CALLBACK(pbvol_volumes_removed), bookmark_group);
+    g_signal_handlers_disconnect_by_func(pbg_priv(bookmark_group)->volume_monitor,
+                                         G_CALLBACK(pbvol_volume_added), bookmark_group);
+    g_signal_handlers_disconnect_by_func(pbg_priv(bookmark_group)->volume_monitor,
+                                         G_CALLBACK(pbvol_volume_removed), bookmark_group);
 
-    g_object_unref(pbg_priv(bookmark_group)->volume_manager);
-    pbg_priv(bookmark_group)->volume_manager = NULL;
-    thunar_vfs_shutdown();
+    g_object_unref(pbg_priv(bookmark_group)->volume_monitor);
+    pbg_priv(bookmark_group)->volume_monitor = NULL;
     
     g_free(pbg_priv(bookmark_group));
     bookmark_group->priv = NULL;
@@ -326,7 +537,7 @@ pbvol_finalize(PlacesBookmarkGroup *bookmark_group)
 PlacesBookmarkGroup*
 places_bookmarks_volumes_create(gboolean mount_and_open_by_default)
 {
-    const GList *volumes;
+    GList *volumes;
     PlacesBookmarkGroup *bookmark_group;
 
     bookmark_group                      = places_bookmark_group_create();
@@ -334,24 +545,25 @@ places_bookmarks_volumes_create(gboolean mount_and_open_by_default)
     bookmark_group->changed             = pbvol_changed;
     bookmark_group->finalize            = pbvol_finalize;
     bookmark_group->priv                = g_new0(PBVolData, 1);
-    
-    thunar_vfs_init();
-    pbg_priv(bookmark_group)->volume_manager = thunar_vfs_volume_manager_get_default();
+
+    pbg_priv(bookmark_group)->volume_monitor = g_volume_monitor_get();
     pbg_priv(bookmark_group)->changed        = TRUE;
     pbg_priv(bookmark_group)->mount_and_open_by_default = mount_and_open_by_default;
     
-    volumes = thunar_vfs_volume_manager_get_volumes(pbg_priv(bookmark_group)->volume_manager);
-    while(volumes != NULL){
-        g_signal_connect_swapped(THUNAR_VFS_VOLUME(volumes->data), "changed",
+    volumes = g_volume_monitor_get_volumes(pbg_priv(bookmark_group)->volume_monitor);
+    while(volumes != NULL) {
+        g_signal_connect_swapped(G_OBJECT(volumes->data), "changed",
                                  G_CALLBACK(pbvol_set_changed), bookmark_group);
+        g_object_unref(volumes->data);
         volumes = volumes->next;
     }
+    g_list_free(volumes);
 
-    g_signal_connect(pbg_priv(bookmark_group)->volume_manager, "volumes-added",
-                     G_CALLBACK(pbvol_volumes_added), bookmark_group);
+    g_signal_connect(pbg_priv(bookmark_group)->volume_monitor, "volume-added",
+                     G_CALLBACK(pbvol_volume_added), bookmark_group);
 
-    g_signal_connect(pbg_priv(bookmark_group)->volume_manager, "volumes-removed",
-                     G_CALLBACK(pbvol_volumes_removed), bookmark_group);
+    g_signal_connect(pbg_priv(bookmark_group)->volume_monitor, "volume-removed",
+                     G_CALLBACK(pbvol_volume_removed), bookmark_group);
 
     return bookmark_group;
 }
diff --git a/panel-plugin/model_volumes_notify.c b/panel-plugin/model_volumes_notify.c
new file mode 100644
index 0000000..6a4318f
--- /dev/null
+++ b/panel-plugin/model_volumes_notify.c
@@ -0,0 +1,317 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2010 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * 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, write to the Free 
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * NOTE: THIS FILE WAS COPIED FROM THUNAR. FUNCTION PREFIXES WERE
+ * ALIGNED TO PLACES PLUGIN AND A FEW TRANSLATOR HINTS WERE ADDED.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <libnotify/notify.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include "model_volumes_notify.h"
+
+
+
+static gboolean pbvol_notify_initted = FALSE;
+
+
+
+static gboolean
+pbvol_notify_init (void)
+{
+  gchar *spec_version = NULL;
+
+  if (!pbvol_notify_initted
+      && notify_init (PACKAGE_NAME))
+    {
+      /* we do this to work around bugs in libnotify < 0.6.0. Older
+       * versions crash in notify_uninit() when no notifications are
+       * displayed before. These versions also segfault when the
+       * ret_spec_version parameter of notify_get_server_info is
+       * NULL... */
+      notify_get_server_info (NULL, NULL, NULL, &spec_version);
+      g_free (spec_version);
+
+      pbvol_notify_initted = TRUE;
+    }
+
+  return pbvol_notify_initted;
+}
+
+
+
+void
+pbvol_notify_unmount (GMount *mount)
+{
+  const gchar * const *icon_names;
+  NotifyNotification  *notification = NULL;
+  const gchar         *summary;
+  GFileInfo           *info;
+  gboolean             read_only = FALSE;
+  GFile               *icon_file;
+  GFile               *mount_point;
+  GIcon               *icon;
+  gchar               *icon_name = NULL;
+  gchar               *message;
+  gchar               *name;
+
+  g_return_if_fail (G_IS_MOUNT (mount));
+
+  if (!pbvol_notify_init ())
+    return;
+
+  mount_point = g_mount_get_root (mount);
+  
+  info = g_file_query_info (mount_point, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, 
+                            G_FILE_QUERY_INFO_NONE, NULL, NULL);
+
+  if (info != NULL)
+    {
+      read_only = !g_file_info_get_attribute_boolean (info, 
+                                                      G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
+
+      g_object_unref (info);
+    }
+
+  g_object_unref (mount_point);
+
+  name = g_mount_get_name (mount);
+
+  icon = g_mount_get_icon (mount);
+  if (G_IS_THEMED_ICON (icon))
+    {
+      icon_names = g_themed_icon_get_names (G_THEMED_ICON (icon));
+      if (icon_names != NULL)
+        icon_name = g_strdup (icon_names[0]);
+    }
+  else if (G_IS_FILE_ICON (icon))
+    {
+      icon_file = g_file_icon_get_file (G_FILE_ICON (icon));
+      if (icon_file != NULL)
+        {
+          icon_name = g_file_get_path (icon_file);
+          g_object_unref (icon_file);
+        }
+    }
+  g_object_unref (icon);
+
+  if (icon_name == NULL)
+    icon_name = g_strdup ("drive-removable-media");
+
+  if (read_only)
+    {
+      /* TRANSLATORS: Please use the same translation here as in Thunar */
+      summary = _("Unmounting device");
+
+      /* TRANSLATORS: Please use the same translation here as in Thunar */
+      message = g_strdup_printf (_("The device \"%s\" is being unmounted by the system. "
+                                   "Please do not remove the media or disconnect the "
+                                   "drive"), name);
+    }
+  else
+    {
+      /* TRANSLATORS: Please use the same translation here as in Thunar */
+      summary = _("Writing data to device");
+
+      /* TRANSLATORS: Please use the same translation here as in Thunar */
+      message = g_strdup_printf (_("There is data that needs to be written to the "
+                                   "device \"%s\" before it can be removed. Please "
+                                   "do not remove the media or disconnect the drive"),
+                                   name);
+    }
+
+#ifdef NOTIFY_CHECK_VERSION
+#if NOTIFY_CHECK_VERSION (0, 7, 0)
+  notification = notify_notification_new (summary, message, icon_name);
+#else
+  notification = notify_notification_new (summary, message, icon_name, NULL);
+#endif
+#else
+  notification = notify_notification_new (summary, message, icon_name, NULL);
+#endif
+  notify_notification_set_urgency (notification, NOTIFY_URGENCY_CRITICAL);
+  notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
+  notify_notification_show (notification, NULL);
+
+  g_object_set_data_full (G_OBJECT (mount), "pbvol-notification", notification, 
+                          g_object_unref);
+
+  g_free (message);
+  g_free (icon_name);
+  g_free (name);
+}
+
+
+
+void
+pbvol_notify_unmount_finish (GMount *mount)
+{
+  NotifyNotification *notification;
+
+  g_return_if_fail (G_IS_MOUNT (mount));
+
+  notification = g_object_get_data (G_OBJECT (mount), "pbvol-notification");
+  if (notification != NULL)
+    {
+      notify_notification_close (notification, NULL);
+      g_object_set_data (G_OBJECT (mount), "pbvol-notification", NULL);
+    }
+}
+
+
+
+void
+pbvol_notify_eject (GVolume *volume)
+{
+  const gchar * const *icon_names;
+  NotifyNotification  *notification = NULL;
+  const gchar         *summary;
+  GFileInfo           *info;
+  gboolean             read_only = FALSE;
+  GMount              *mount;
+  GFile               *icon_file;
+  GFile               *mount_point;
+  GIcon               *icon;
+  gchar               *icon_name = NULL;
+  gchar               *message;
+  gchar               *name;
+
+  g_return_if_fail (G_IS_VOLUME (volume));
+
+  if (!pbvol_notify_init ())
+    return;
+
+  mount = g_volume_get_mount (volume);
+  if (mount != NULL)
+    {
+      mount_point = g_mount_get_root (mount);
+      
+      info = g_file_query_info (mount_point, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, 
+                                G_FILE_QUERY_INFO_NONE, NULL, NULL);
+
+      if (info != NULL)
+        {
+          read_only =
+            !g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
+
+          g_object_unref (info);
+        }
+
+      g_object_unref (mount_point);
+    }
+
+  name = g_volume_get_name (volume);
+
+  icon = g_volume_get_icon (volume);
+  if (G_IS_THEMED_ICON (icon))
+    {
+      icon_names = g_themed_icon_get_names (G_THEMED_ICON (icon));
+      if (icon_names != NULL)
+        icon_name = g_strdup (icon_names[0]);
+    }
+  else if (G_IS_FILE_ICON (icon))
+    {
+      icon_file = g_file_icon_get_file (G_FILE_ICON (icon));
+      if (icon_file != NULL)
+        {
+          icon_name = g_file_get_path (icon_file);
+          g_object_unref (icon_file);
+        }
+    }
+  g_object_unref (icon);
+
+  if (icon_name == NULL)
+    icon_name = g_strdup ("drive-removable-media");
+
+  if (read_only)
+    {
+      /* TRANSLATORS: Please use the same translation here as in Thunar */
+      summary = _("Ejecting device");
+
+      /* TRANSLATORS: Please use the same translation here as in Thunar */
+      message = g_strdup_printf (_("The device \"%s\" is being ejected. "
+                                   "This may take some time"), name);
+    }
+  else
+    {
+      /* TRANSLATORS: Please use the same translation here as in Thunar */
+      summary = _("Writing data to device");
+
+      /* TRANSLATORS: Please use the same translation here as in Thunar */
+      message = g_strdup_printf (_("There is data that needs to be written to the "
+                                   "device \"%s\" before it can be removed. Please "
+                                   "do not remove the media or disconnect the drive"),
+                                   name);
+    }
+
+#ifdef NOTIFY_CHECK_VERSION
+#if NOTIFY_CHECK_VERSION (0, 7, 0)
+  notification = notify_notification_new (summary, message, icon_name);
+#else
+  notification = notify_notification_new (summary, message, icon_name, NULL);
+#endif
+#else
+  notification = notify_notification_new (summary, message, icon_name, NULL);
+#endif
+  notify_notification_set_urgency (notification, NOTIFY_URGENCY_CRITICAL);
+  notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
+  notify_notification_show (notification, NULL);
+
+  g_object_set_data_full (G_OBJECT (volume), "pbvol-notification", notification, 
+                          g_object_unref);
+
+  g_free (message);
+  g_free (icon_name);
+  g_free (name);
+}
+
+
+
+void
+pbvol_notify_eject_finish (GVolume *volume)
+{
+  NotifyNotification *notification;
+
+  g_return_if_fail (G_IS_VOLUME (volume));
+
+  notification = g_object_get_data (G_OBJECT (volume), "pbvol-notification");
+  if (notification != NULL)
+    {
+      notify_notification_close (notification, NULL);
+      g_object_set_data (G_OBJECT (volume), "pbvol-notification", NULL);
+    }
+}
+
+
+
+void
+pbvol_notify_uninit (void)
+{
+  if (pbvol_notify_initted
+      && notify_is_initted ())
+    notify_uninit ();
+}
diff --git a/panel-plugin/model_volumes_notify.h b/panel-plugin/model_volumes_notify.h
new file mode 100644
index 0000000..55e74e5
--- /dev/null
+++ b/panel-plugin/model_volumes_notify.h
@@ -0,0 +1,37 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2010 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * 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, write to the Free 
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _XFCE_PANEL_PLACES_MODEL_VOLUMES_NOTIFY_H__
+#define _XFCE_PANEL_PLACES_MODEL_VOLUMES_NOTIFY_H__
+
+#include <glib.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+void pbvol_notify_unmount        (GMount  *mount);
+void pbvol_notify_unmount_finish (GMount  *mount);
+void pbvol_notify_eject          (GVolume *volume);
+void pbvol_notify_eject_finish   (GVolume *volume);
+void pbvol_notify_uninit         (void);
+
+G_END_DECLS
+
+#endif /* !_XFCE_PANEL_PLACES_MODEL_VOLUMES_NOTIFY_H__ */
diff --git a/panel-plugin/view.c b/panel-plugin/view.c
index dd3a2f7..64f3952 100644
--- a/panel-plugin/view.c
+++ b/panel-plugin/view.c
@@ -57,8 +57,6 @@
 
 #include <string.h>
 
-#include "xfce46-compat.h"
-
 #include "view.h"
 #include "support.h"
 #include "cfg.h"
@@ -69,6 +67,10 @@
 #include "xfce4-popup-places.h"
 #include "button.h"
 
+#ifdef HAVE_LIBNOTIFY
+#include "model_volumes_notify.h"
+#endif
+
 struct _PlacesViewCfgIface
 {
     PlacesView          *places_view;
@@ -454,6 +456,42 @@ pview_cb_recent_items_clear3(GtkWidget *clear_item, GdkEventButton *event, GtkWi
 
 /********** UI Helpers **********/
 
+static GdkPixbuf *
+pview_get_icon(GIcon *icon)
+{
+    GtkIconTheme *itheme = gtk_icon_theme_get_default();
+    GdkPixbuf *pix = NULL;
+    gint width, height, size;
+
+    g_return_val_if_fail(icon != NULL, NULL);
+
+    if (gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height))
+        size = MAX(width, height);
+    else
+        size = 32;
+
+    if (G_IS_THEMED_ICON(icon)) {
+        GtkIconInfo *icon_info = gtk_icon_theme_lookup_by_gicon(itheme,
+                                                                icon, size,
+                                                                GTK_ICON_LOOKUP_USE_BUILTIN | GTK_ICON_LOOKUP_GENERIC_FALLBACK | GTK_ICON_LOOKUP_FORCE_SIZE);
+        if (icon_info) {
+            GdkPixbuf *pix_theme = gtk_icon_info_load_icon(icon_info, NULL);
+            pix = gdk_pixbuf_copy(pix_theme);
+            gtk_icon_info_free(icon_info);
+            g_object_unref(G_OBJECT(pix_theme));
+        }
+    } else if(G_IS_LOADABLE_ICON(icon)) {
+        GInputStream *stream = g_loadable_icon_load(G_LOADABLE_ICON(icon),
+                                                    size, NULL, NULL, NULL);
+        if (stream) {
+            pix = gdk_pixbuf_new_from_stream(stream, NULL, NULL);
+            g_object_unref(stream);
+        }
+    }
+
+    return pix;
+}
+
 static void
 pview_destroy_menu(PlacesView *view)
 {
@@ -503,13 +541,7 @@ pview_add_menu_item(PlacesView *view, PlacesBookmark *bookmark)
 
     /* try to set icon */
     if(view->cfg->show_icons && bookmark->icon != NULL){
-        gint icon_size;
-        gint width, height;
-        if (gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height))
-                icon_size = MAX(width, height);
-        else
-                icon_size = 32;
-        pb = xfce_panel_pixbuf_from_source(bookmark->icon, NULL, icon_size);
+        pb = pview_get_icon(bookmark->icon);
 
         if(G_LIKELY(pb != NULL)){
             image = gtk_image_new_from_pixbuf(pb);
@@ -922,6 +954,10 @@ places_view_finalize(PlacesView *view)
     view->view_cfg_iface = NULL;
 
     g_free(view);
+
+#ifdef HAVE_LIBNOTIFY
+    pbvol_notify_uninit();
+#endif
 }
 
 /* vim: set ai et tabstop=4: */
diff --git a/panel-plugin/xfce46-compat.c b/panel-plugin/xfce46-compat.c
deleted file mode 100644
index 9bf8fb1..0000000
--- a/panel-plugin/xfce46-compat.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Code was taken from libxfce4panel (LGPL2 or any later version),
- * distributed here under the GPL.
- *
- * Copyright (c) 2005-2007 Jasper Huijsmans <jasper at xfce.org>
- *
- *  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 Library General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#ifndef HAVE_LIBXFCE4PANEL_46
-
-#include "xfce46-compat.h"
-
-#include <libxfce4panel/xfce-panel-plugin.h>
-#include <libxfce4panel/xfce-panel-macros.h>
-
-/* support macros for debugging */
-#ifndef NDEBUG
-#define _panel_assert(expr)                  g_assert (expr)
-#define _panel_assert_not_reached()          g_assert_not_reached ()
-#define _panel_return_if_fail(expr)          g_return_if_fail (expr)
-#define _panel_return_val_if_fail(expr, val) g_return_val_if_fail (expr, (val))
-#else
-#define _panel_assert(expr)                  G_STMT_START{ (void)0; }G_STMT_END
-#define _panel_assert_not_reached()          G_STMT_START{ (void)0; }G_STMT_END
-#define _panel_return_if_fail(expr)          G_STMT_START{ (void)0; }G_STMT_END
-#define _panel_return_val_if_fail(expr, val) G_STMT_START{ (void)0; }G_STMT_END
-#endif
-
-/**
- * xfce_panel_plugin_arrow_type:
- * @plugin        : an #XfcePanelPlugin
- *
- * Determine the #GtkArrowType for a widget that opens a menu and uses
- *  xfce_panel_plugin_position_menu() to position the menu.
- *
- * Returns: The #GtkArrowType to use.
- **/
-GtkArrowType
-xfce_panel_plugin_arrow_type (XfcePanelPlugin *plugin)
-{
-    XfceScreenPosition  position;
-    GdkScreen          *screen;
-    GdkRectangle        geom;
-    gint                mon, x, y;
-
-    if (!GTK_WIDGET_REALIZED (plugin))
-        return GTK_ARROW_UP;
-
-    position = xfce_panel_plugin_get_screen_position (plugin);
-    switch (position)
-    {
-        /* top */
-        case XFCE_SCREEN_POSITION_NW_H:
-        case XFCE_SCREEN_POSITION_N:
-        case XFCE_SCREEN_POSITION_NE_H:
-            return GTK_ARROW_DOWN;
-
-        /* left */
-        case XFCE_SCREEN_POSITION_NW_V:
-        case XFCE_SCREEN_POSITION_W:
-        case XFCE_SCREEN_POSITION_SW_V:
-            return GTK_ARROW_RIGHT;
-
-        /* right */
-        case XFCE_SCREEN_POSITION_NE_V:
-        case XFCE_SCREEN_POSITION_E:
-        case XFCE_SCREEN_POSITION_SE_V:
-            return GTK_ARROW_LEFT;
-
-        /* bottom */
-        case XFCE_SCREEN_POSITION_SW_H:
-        case XFCE_SCREEN_POSITION_S:
-        case XFCE_SCREEN_POSITION_SE_H:
-            return GTK_ARROW_UP;
-
-        /* floating */
-        default:
-            /* get the screen information */
-            screen = gtk_widget_get_screen (GTK_WIDGET (plugin));
-            mon = gdk_screen_get_monitor_at_window (screen, GTK_WIDGET (plugin)->window);
-            gdk_screen_get_monitor_geometry (screen, mon, &geom);
-            gdk_window_get_root_origin (GTK_WIDGET (plugin)->window, &x, &y);
-
-            /* get the position based on the screen position */
-            if (position == XFCE_SCREEN_POSITION_FLOATING_H)
-                return ((y < (geom.y + geom.height / 2)) ? GTK_ARROW_DOWN : GTK_ARROW_UP);
-            else
-                return ((x < (geom.x + geom.width / 2)) ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT);
-    }
-}
-
-
-
-/**
- * xfce_panel_plugin_position_widget:
- * @plugin        : an #XfcePanelPlugin
- * @menu_widget   : a #GtkWidget that will be used as popup menu
- * @attach_widget : a #GtkWidget relative to which the menu should be positioned
- * @x             : return location for the x coordinate
- * @y             : return location for the y coordinate
- *
- * The menu widget is positioned relative to @attach_widget.
- * If @attach_widget is NULL, the menu widget is instead positioned
- * relative to @panel_plugin.
- *
- * This function is intended for custom menu widgets.
- * For a regular #GtkMenu you should use xfce_panel_plugin_position_menu()
- * instead (as callback argument to gtk_menu_popup()).
- *
- * See also: xfce_panel_plugin_position_menu().
- **/
-void
-xfce_panel_plugin_position_widget (XfcePanelPlugin  *plugin,
-                                   GtkWidget        *menu_widget,
-                                   GtkWidget        *attach_widget,
-                                   gint             *x,
-                                   gint             *y)
-{
-    GtkRequisition  req;
-    GdkScreen      *screen;
-    GdkRectangle    geom;
-    gint            mon;
-
-    _panel_return_if_fail (XFCE_IS_PANEL_PLUGIN (plugin));
-    _panel_return_if_fail (GTK_IS_WIDGET (menu_widget));
-    _panel_return_if_fail (attach_widget == NULL || GTK_IS_WIDGET (attach_widget));
-
-    if (attach_widget == NULL)
-        attach_widget = GTK_WIDGET (plugin);
-
-    if (!GTK_WIDGET_REALIZED (menu_widget))
-        gtk_widget_realize (menu_widget);
-
-    gtk_widget_size_request (menu_widget, &req);
-    gdk_window_get_origin (attach_widget->window, x, y);
-
-    switch (xfce_panel_plugin_arrow_type (plugin))
-    {
-        case GTK_ARROW_UP:
-            *y -= req.height;
-            break;
-
-        case GTK_ARROW_DOWN:
-            *y += attach_widget->allocation.height;
-            break;
-
-        case GTK_ARROW_LEFT:
-            *x -= req.width;
-            break;
-
-        default: /* GTK_ARROW_RIGHT and GTK_ARROW_NONE */
-            *x += attach_widget->allocation.width;
-            break;
-    }
-
-    screen = gtk_widget_get_screen (attach_widget);
-    mon = gdk_screen_get_monitor_at_window (screen, attach_widget->window);
-    gdk_screen_get_monitor_geometry (screen, mon, &geom);
-
-    /* keep inside the screen */
-    if (*x > geom.x + geom.width - req.width)
-        *x = geom.x + geom.width - req.width;
-    if (*x < geom.x)
-        *x = geom.x;
-    if (*y > geom.y + geom.height - req.height)
-        *y = geom.y + geom.height - req.height;
-    if (*y < geom.y)
-        *y = geom.y;
-
-    if (G_LIKELY (GTK_IS_MENU (menu_widget)))
-        gtk_menu_set_screen (GTK_MENU (menu_widget), screen);
-    else if (GTK_IS_WINDOW (menu_widget))
-        gtk_window_set_screen (GTK_WINDOW (menu_widget), screen);
-}
-
-
-
-/**
- * xfce_panel_plugin_position_menu:
- * @menu         : a #GtkMenu
- * @x            : return location for the x coordinate
- * @y            : return location for the y coordinate
- * @push_in      : keep inside the screen (see #GtkMenuPositionFunc)
- * @panel_plugin : a pointer to an #XfcePanelPlugin
- *
- * Function to be used as #GtkMenuPositionFunc in a call to gtk_menu_popup().
- * As data argument it needs an #XfcePanelPlugin.
- *
- * The menu is normally positioned relative to @panel_plugin. If you want the
- * menu to be positioned relative to another widget, you can use
- * gtk_menu_attach_to_widget() to explicitly set a 'parent' widget.
- *
- * As a convenience, xfce_panel_plugin_position_menu() calls
- * xfce_panel_plugin_register_menu() for the menu.
- *
- * <example>
- * void
- * myplugin_popup_menu (XfcePanelPlugin *plugin,
- *                      GtkMenu         *menu,
- *                      GdkEventButton  *ev)
- * {
- *     gtk_menu_popup (menu, NULL, NULL,
- *                     xfce_panel_plugin_position_menu, plugin,
- *                     ev->button, ev->time );
- * }
- * </example>
- *
- * For a custom widget that will be used as a popup menu, use
- * xfce_panel_plugin_position_widget() instead.
- *
- * See also: gtk_menu_popup().
- **/
-void
-xfce_panel_plugin_position_menu (GtkMenu  *menu,
-                                 gint     *x,
-                                 gint     *y,
-                                 gboolean *push_in,
-                                 gpointer  panel_plugin)
-{
-    XfcePanelPlugin *plugin = XFCE_PANEL_PLUGIN (panel_plugin);
-    GtkWidget       *attach_widget;
-
-    attach_widget = gtk_menu_get_attach_widget (menu);
-
-    xfce_panel_plugin_position_widget (plugin,
-                                       GTK_WIDGET (menu),
-                                       attach_widget,
-                                       x, y);
-
-    /* keep inside screen */
-    *push_in = TRUE;
-
-    xfce_panel_plugin_register_menu (plugin, menu);
-}
-
-#endif
diff --git a/panel-plugin/xfce46-compat.h b/panel-plugin/xfce46-compat.h
deleted file mode 100644
index e4addc5..0000000
--- a/panel-plugin/xfce46-compat.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _XFCE46_COMPAT
-#define _XFCE46_COMPAT
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#ifndef HAVE_LIBXFCE4PANEL_46
-
-#include <gtk/gtk.h>
-
-void                 xfce_panel_plugin_position_menu        (GtkMenu          *menu,
-                                                             gint             *x,
-                                                             gint             *y,
-                                                             gboolean         *push_in,
-                                                             gpointer          panel_plugin);
-#endif
-#endif
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 7640f28..fb35613 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -9,6 +9,7 @@ panel-plugin/model_user.c
 panel-plugin/model_user.h
 panel-plugin/model_volumes.c
 panel-plugin/model_volumes.h
+panel-plugin/model_volumes_notify.c
 panel-plugin/view.c
 panel-plugin/view.h
 panel-plugin/cfg.c


More information about the Xfce4-commits mailing list