[Xfce4-commits] <xfdesktop:master> Load special icons with GIO, update drag and drop code to use D-Bus.

Jannis Pohlmann noreply at xfce.org
Tue Nov 2 01:14:40 CET 2010


Updating branch refs/heads/master
         to c77a5421a1e8ac37d78746c413a7b636b3c510f2 (commit)
       from 72ab19e02f85f486ef19fb5f33adc6251921fee6 (commit)

commit c77a5421a1e8ac37d78746c413a7b636b3c510f2
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Tue Oct 26 21:32:52 2010 +0200

    Load special icons with GIO, update drag and drop code to use D-Bus.
    
    A bit more work is required to make the trash work again. We also need a
    way to monitor home, filesystem and trash because all those icons refer
    to normal directories.

 src/xfdesktop-file-icon-manager.c |    2 +
 src/xfdesktop-regular-file-icon.c |   15 +-
 src/xfdesktop-special-file-icon.c |  349 ++++++++++---------------------------
 3 files changed, 103 insertions(+), 263 deletions(-)

diff --git a/src/xfdesktop-file-icon-manager.c b/src/xfdesktop-file-icon-manager.c
index 7e0d114..2f0c981 100644
--- a/src/xfdesktop-file-icon-manager.c
+++ b/src/xfdesktop-file-icon-manager.c
@@ -2000,6 +2000,8 @@ xfdesktop_file_icon_manager_add_special_file_icon(XfdesktopFileIconManager *fman
                                             XFDESKTOP_FILE_ICON(icon),
                                             FALSE))
     {
+        /* TODO need to make file monitoring work for special icons like
+         * the filesystem root and the trash bin */
         g_hash_table_replace(fmanager->priv->special_icons,
                              GINT_TO_POINTER(type), icon);
         return XFDESKTOP_FILE_ICON(icon);
diff --git a/src/xfdesktop-regular-file-icon.c b/src/xfdesktop-regular-file-icon.c
index b57de9f..5f136a0 100644
--- a/src/xfdesktop-regular-file-icon.c
+++ b/src/xfdesktop-regular-file-icon.c
@@ -373,6 +373,7 @@ xfdesktop_regular_file_icon_do_drop_dest(XfdesktopIcon *icon,
     XfdesktopFileIcon *src_file_icon = XFDESKTOP_FILE_ICON(src_icon);
     GFileInfo *src_info;
     GFile *src_file;
+    gboolean result = FALSE;
     
     DBG("entering");
     
@@ -397,7 +398,7 @@ xfdesktop_regular_file_icon_do_drop_dest(XfdesktopIcon *icon,
         xfdesktop_file_utils_execute(NULL, regular_file_icon->priv->file, &files,
                                      regular_file_icon->priv->gscreen);
 
-        return TRUE;
+        result = TRUE;
     } else {
         GFile *parent, *dest_file;
         gchar *name;
@@ -425,16 +426,18 @@ xfdesktop_regular_file_icon_do_drop_dest(XfdesktopIcon *icon,
                 g_warning("Unsupported drag action: %d", action);
         }
 
-        xfdesktop_file_utils_transfer_file(action, src_file, dest_file,
-                                           regular_file_icon->priv->gscreen);
+        if(dest_file) {
+            xfdesktop_file_utils_transfer_file(action, src_file, dest_file,
+                                               regular_file_icon->priv->gscreen);
+
+            result = TRUE;
+        }
 
         g_object_unref(dest_file);
         g_free(name);
-        
-        return TRUE;
     }
     
-    return FALSE;
+    return result;
 }
 
 static G_CONST_RETURN gchar *
diff --git a/src/xfdesktop-special-file-icon.c b/src/xfdesktop-special-file-icon.c
index 86e8735..d2e93b0 100644
--- a/src/xfdesktop-special-file-icon.c
+++ b/src/xfdesktop-special-file-icon.c
@@ -69,7 +69,6 @@ struct _XfdesktopSpecialFileIconPrivate
     
     /* only needed for trash */
     DBusGProxy *dbus_proxy;
-    DBusGProxyCall *dbus_querytrash_call;
     gboolean trash_full;
 };
 
@@ -98,9 +97,6 @@ static void xfdesktop_special_file_icon_tfi_init(ThunarxFileInfoIface *iface);
 
 
 static inline void xfdesktop_special_file_icon_invalidate_pixbuf(XfdesktopSpecialFileIcon *icon);
-static void xfdesktop_special_file_icon_trash_changed_cb(DBusGProxy *proxy,
-                                                         gboolean trash_full,
-                                                         gpointer user_data);
 
 
 #ifdef HAVE_THUNARX
@@ -161,19 +157,13 @@ xfdesktop_special_file_icon_finalize(GObject *obj)
                                          G_CALLBACK(xfdesktop_special_file_icon_invalidate_pixbuf),
                                          icon);
     
-    if(icon->priv->dbus_proxy) {
-        if(icon->priv->dbus_querytrash_call) {
-            dbus_g_proxy_cancel_call(icon->priv->dbus_proxy,
-                                     icon->priv->dbus_querytrash_call);
-        }
-        dbus_g_proxy_disconnect_signal(icon->priv->dbus_proxy, "TrashChanged",
-                                       G_CALLBACK(xfdesktop_special_file_icon_trash_changed_cb),
-                                       icon);
-        g_object_unref(G_OBJECT(icon->priv->dbus_proxy));
-    }
-    
     if(icon->priv->pix)
         g_object_unref(G_OBJECT(icon->priv->pix));
+
+    g_object_unref(icon->priv->file);
+
+    if(icon->priv->file_info)
+        g_object_unref(icon->priv->file_info);
     
     if(icon->priv->info)
         thunar_vfs_info_unref(icon->priv->info);
@@ -270,8 +260,8 @@ xfdesktop_special_file_icon_get_allowed_drag_actions(XfdesktopIcon *icon)
     switch(special_file_icon->priv->type) {
         case XFDESKTOP_SPECIAL_FILE_ICON_FILESYSTEM:
             /* move is just impossible, and copy seems a bit retarded.  link
-             * is possible, but thunar-vfs doesn't support it (deliberately). */
-            actions = 0;
+             * is possible */
+            actions = GDK_ACTION_LINK;
             break;
         
         case XFDESKTOP_SPECIAL_FILE_ICON_HOME:
@@ -281,9 +271,9 @@ xfdesktop_special_file_icon_get_allowed_drag_actions(XfdesktopIcon *icon)
             break;
             
         case XFDESKTOP_SPECIAL_FILE_ICON_TRASH:
-            /* i don't think we can even do a link here; thunar doesn't let
-             * us, anyway. */
-            actions = 0;
+            /* move is impossible, but we can copy and link the trash root
+             * anywhere */
+            actions = GDK_ACTION_COPY | GDK_ACTION_LINK;
             break;
     }
     
@@ -294,87 +284,27 @@ static GdkDragAction
 xfdesktop_special_file_icon_get_allowed_drop_actions(XfdesktopIcon *icon)
 {
     XfdesktopSpecialFileIcon *special_file_icon = XFDESKTOP_SPECIAL_FILE_ICON(icon);
-    const ThunarVfsInfo *info;
+    GFileInfo *info;
     GdkDragAction actions = 0;
-    
-    switch(special_file_icon->priv->type) {
-        case XFDESKTOP_SPECIAL_FILE_ICON_FILESYSTEM:
-            /* we should hope the user isn't running as root, but we might as
-             * well let them hang themselves if they are */
-            info = xfdesktop_file_icon_peek_info(XFDESKTOP_FILE_ICON(icon));
-            if(info && info->flags & THUNAR_VFS_FILE_FLAGS_WRITABLE)
+
+    if(special_file_icon->priv->type != XFDESKTOP_SPECIAL_FILE_ICON_TRASH) {
+        info = xfdesktop_file_icon_peek_file_info(XFDESKTOP_FILE_ICON(icon));
+        if(info) {
+            if(g_file_info_get_attribute_boolean(info,
+                                                 G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
+            {
+                DBG("can move, copy and link");
                 actions = GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK;
-            else
-                actions = 0;
-            break;
-        
-        case XFDESKTOP_SPECIAL_FILE_ICON_HOME:
-            /* assume the user can write to their own home directory */
-            actions = GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK;
-            break;
-            
-        case XFDESKTOP_SPECIAL_FILE_ICON_TRASH:
-            actions = GDK_ACTION_MOVE;  /* anything else is just silly */
-            break;
+            }
+        }
+    } else {
+        DBG("can move");
+        actions = GDK_ACTION_MOVE; /* everything else is just silly */
     }
     
     return actions;
 }
 
-static void
-xfdesktop_special_file_icon_drag_job_error(ThunarVfsJob *job,
-                                           GError *error,
-                                           gpointer user_data)
-{
-    XfdesktopSpecialFileIcon *special_file_icon = XFDESKTOP_SPECIAL_FILE_ICON(user_data);
-    XfdesktopFileIcon *src_file_icon = g_object_get_data(G_OBJECT(job),
-                                                         "--xfdesktop-src-file-icon");
-    XfdesktopFileUtilsFileop fileop = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(job),
-                                                                        "--xfdesktop-file-icon-action"));
-    const ThunarVfsInfo *src_info = xfdesktop_file_icon_peek_info(src_file_icon);
-    
-    g_return_if_fail(special_file_icon);
-
-    if(!src_file_icon)
-        return;
-    
-    xfdesktop_file_utils_handle_fileop_error(NULL, src_info,
-                                             special_file_icon->priv->info,
-                                             fileop, error);
-}
-
-static ThunarVfsInteractiveJobResponse
-xfdesktop_special_file_icon_interactive_job_ask(ThunarVfsJob *job,
-                                                const gchar *message,
-                                                ThunarVfsInteractiveJobResponse choices,
-                                                gpointer user_data)
-{
-    GtkWidget *icon_view = xfdesktop_icon_peek_icon_view(XFDESKTOP_ICON(user_data));
-    GtkWidget *toplevel = gtk_widget_get_toplevel(icon_view);
-    return xfdesktop_file_utils_interactive_job_ask(GTK_WINDOW(toplevel),
-                                                    message, choices);
-}
-
-static void
-xfdesktop_special_file_icon_drag_job_finished(ThunarVfsJob *job,
-                                      gpointer user_data)
-{
-    XfdesktopSpecialFileIcon *special_file_icon = XFDESKTOP_SPECIAL_FILE_ICON(user_data);
-    XfdesktopFileIcon *src_file_icon = g_object_get_data(G_OBJECT(job),
-                                                         "--xfdesktop-src-file-icon");
-    
-    if(!xfdesktop_file_icon_remove_active_job(XFDESKTOP_FILE_ICON(special_file_icon), job))
-        g_critical("ThunarVfsJob 0x%p not found in active jobs list", job);
-    
-    if(!xfdesktop_file_icon_remove_active_job(src_file_icon, job))
-        g_critical("ThunarVfsJob 0x%p not found in active jobs list", job);
-    
-    g_object_unref(G_OBJECT(job));
-    
-    g_object_unref(G_OBJECT(src_file_icon));
-    g_object_unref(G_OBJECT(special_file_icon));
-}
-
 static gboolean
 xfdesktop_special_file_icon_do_drop_dest(XfdesktopIcon *icon,
                                          XfdesktopIcon *src_icon,
@@ -382,10 +312,10 @@ xfdesktop_special_file_icon_do_drop_dest(XfdesktopIcon *icon,
 {
     XfdesktopSpecialFileIcon *special_file_icon = XFDESKTOP_SPECIAL_FILE_ICON(icon);
     XfdesktopFileIcon *src_file_icon = XFDESKTOP_FILE_ICON(src_icon);
-    const ThunarVfsInfo *src_info;
-    ThunarVfsJob *job = NULL;
-    const gchar *name = NULL;
-    ThunarVfsPath *dest_path;
+    GFileInfo *src_info;
+    GFile *src_file;
+    GFile *dest_file = NULL;
+    gboolean result = FALSE;
     
     DBG("entering");
     
@@ -393,86 +323,58 @@ xfdesktop_special_file_icon_do_drop_dest(XfdesktopIcon *icon,
     g_return_val_if_fail(xfdesktop_special_file_icon_get_allowed_drop_actions(icon),
                          FALSE);
     
-    src_info = xfdesktop_file_icon_peek_info(src_file_icon);
+    src_file = xfdesktop_file_icon_peek_file(src_file_icon);
+
+    src_info = xfdesktop_file_icon_peek_file_info(src_file_icon);
     if(!src_info)
         return FALSE;
     
-    if(thunar_vfs_path_is_root(src_info->path))
-        return FALSE;
-    
-    name = thunar_vfs_path_get_name(src_info->path);
-    if(!name)
-        return FALSE;
-    
-    dest_path = thunar_vfs_path_relative(special_file_icon->priv->info->path,
-                                         name);
-    if(!dest_path)
-        return FALSE;
-    
-    if(special_file_icon->priv->type == XFDESKTOP_SPECIAL_FILE_ICON_TRASH)  {
-        /* any drop to the trash is a move */
-        action = GDK_ACTION_MOVE;
-    }
-    
-    switch(action) {
-        case GDK_ACTION_MOVE:
-            DBG("doing move");
-            job = thunar_vfs_move_file(src_info->path, dest_path, NULL);
-            break;
-        
-        case GDK_ACTION_COPY:
-            DBG("doing copy");
-            job = thunar_vfs_copy_file(src_info->path, dest_path, NULL);
+    if(special_file_icon->priv->type == XFDESKTOP_SPECIAL_FILE_ICON_TRASH) {
+        GList files;
+
+        DBG("doing trash");
+
+        /* fake a file list */
+        files.data = src_file;
+        files.prev = files.next = NULL;
+
+        /* let the trash service handle the trash operation */
+        xfdesktop_file_utils_trash_files(&files, special_file_icon->priv->gscreen, NULL);
+    } else {
+        gchar *name = g_file_get_basename(src_file);
+        if(!name)
+            return FALSE;
+    
+        switch(action) {
+            case GDK_ACTION_MOVE:
+                DBG("doing move");
+                dest_file = g_object_ref(special_file_icon->priv->file);
                 break;
-        
-        case GDK_ACTION_LINK:
-            DBG("doing link");
-            job = thunar_vfs_link_file(src_info->path, dest_path, NULL);
-            break;
-        
-        default:
-            g_warning("Unsupported drag action: %d", action);
+            case GDK_ACTION_COPY:
+                DBG("doing copy");
+                dest_file = g_file_get_child(special_file_icon->priv->file, name);
+                break;
+            case GDK_ACTION_LINK:
+                DBG("doing link");
+                dest_file = g_object_ref(special_file_icon->priv->file);
+                break;
+            default:
+                g_warning("Unsupported drag action: %d", action);
+        }
+
+        /* let the file manager service move/copy/link the file */
+        if(dest_file) {
+            xfdesktop_file_utils_transfer_file(action, src_file, dest_file,
+                                               special_file_icon->priv->gscreen);
+
+            result = TRUE;
+        }
+
+        g_object_unref(dest_file);
+        g_free(name);
     }
-        
-    thunar_vfs_path_unref(dest_path);
-    
-    if(job) {
-        DBG("got job, action initiated");
-        
-        /* ensure they aren't destroyed until the job is finished */
-        g_object_ref(G_OBJECT(src_file_icon));
-        g_object_ref(G_OBJECT(special_file_icon));
-        
-        g_object_set_data(G_OBJECT(job), "--xfdesktop-file-icon-callback",
-                          G_CALLBACK(xfdesktop_special_file_icon_drag_job_finished));
-        g_object_set_data(G_OBJECT(job), "--xfdesktop-file-icon-data", icon);
-        xfdesktop_file_icon_add_active_job(XFDESKTOP_FILE_ICON(special_file_icon),
-                                           job);
-        xfdesktop_file_icon_add_active_job(src_file_icon, job);
-        
-        g_object_set_data(G_OBJECT(job), "--xfdesktop-src-file-icon",
-                          src_file_icon);
-        g_object_set_data(G_OBJECT(job), "--xfdesktop-file-icon-action",
-                          GINT_TO_POINTER(action == GDK_ACTION_MOVE
-                                          ? XFDESKTOP_FILE_UTILS_FILEOP_MOVE
-                                          : (action == GDK_ACTION_COPY
-                                             ? XFDESKTOP_FILE_UTILS_FILEOP_COPY
-                                             : XFDESKTOP_FILE_UTILS_FILEOP_LINK)));
-        g_signal_connect(G_OBJECT(job), "error",
-                         G_CALLBACK(xfdesktop_special_file_icon_drag_job_error),
-                         special_file_icon);
-        g_signal_connect(G_OBJECT(job), "ask",
-                         G_CALLBACK(xfdesktop_special_file_icon_interactive_job_ask),
-                         special_file_icon);
-        g_signal_connect(G_OBJECT(job), "finished",
-                         G_CALLBACK(xfdesktop_special_file_icon_drag_job_finished),
-                         special_file_icon);
-        
-        return TRUE;
-    } else
-        return FALSE;
-    
-    return FALSE;
+
+    return result;
 }
 
 static G_CONST_RETURN gchar *
@@ -701,46 +603,6 @@ xfdesktop_special_file_icon_peek_file(XfdesktopFileIcon *icon)
     return XFDESKTOP_SPECIAL_FILE_ICON(icon)->priv->file;
 }
 
-static void
-xfdesktop_special_file_icon_trash_changed_cb(DBusGProxy *proxy,
-                                             gboolean trash_full,
-                                             gpointer user_data)
-{
-    XfdesktopSpecialFileIcon *special_file_icon = XFDESKTOP_SPECIAL_FILE_ICON(user_data);
-    
-    TRACE("entering (%p, %d, %p)", proxy, trash_full, user_data);
-    
-    if(trash_full == special_file_icon->priv->trash_full)
-        return;
-    
-    special_file_icon->priv->trash_full = trash_full;
-    
-    xfdesktop_special_file_icon_invalidate_pixbuf(special_file_icon);
-    xfdesktop_icon_pixbuf_changed(XFDESKTOP_ICON(special_file_icon));
-}
-
-static void
-xfdesktop_special_file_icon_query_trash_cb(DBusGProxy *proxy,
-                                           gboolean trash_full,
-                                           GError *error,
-                                           gpointer user_data)
-{
-    XfdesktopSpecialFileIcon *icon = XFDESKTOP_SPECIAL_FILE_ICON(user_data);
-    
-    if(error) {
-        xfdesktop_special_file_icon_trash_handle_error(icon,
-                                                       "QueryTrash",
-                                                       error->message);
-    } else {
-        icon->priv->trash_full = trash_full;
-        xfdesktop_special_file_icon_invalidate_pixbuf(icon);
-        xfdesktop_icon_pixbuf_changed(XFDESKTOP_ICON(icon));
-    }
-    
-    icon->priv->dbus_querytrash_call = NULL;
-}
-
-
 /* public API */
 
 XfdesktopSpecialFileIcon *
@@ -749,19 +611,20 @@ xfdesktop_special_file_icon_new(XfdesktopSpecialFileIconType type,
 {
     XfdesktopSpecialFileIcon *special_file_icon;
     ThunarVfsPath *path = NULL;
+    GFile *file = NULL;
     gchar *uri;
     
     switch(type) {
         case XFDESKTOP_SPECIAL_FILE_ICON_FILESYSTEM:
-            path = thunar_vfs_path_get_for_root();
+            file = g_file_new_for_uri("file:///");
             break;
         
         case XFDESKTOP_SPECIAL_FILE_ICON_HOME:
-            path = thunar_vfs_path_get_for_home();
+            file = g_file_new_for_path(xfce_get_homedir());
             break;
         
         case XFDESKTOP_SPECIAL_FILE_ICON_TRASH:
-            path = thunar_vfs_path_get_for_trash();
+            file = g_file_new_for_uri("trash:///");
             break;
         
         default:
@@ -771,57 +634,29 @@ xfdesktop_special_file_icon_new(XfdesktopSpecialFileIconType type,
     special_file_icon = g_object_new(XFDESKTOP_TYPE_SPECIAL_FILE_ICON, NULL);
     special_file_icon->priv->type = type;
     special_file_icon->priv->gscreen = screen;
-    special_file_icon->priv->info = thunar_vfs_info_new_for_path(path, NULL);
-    thunar_vfs_path_unref(path);
+    special_file_icon->priv->file = file;
 
-    /* convert the ThunarVfsPath into a GFile */
-    uri = thunar_vfs_path_dup_uri(special_file_icon->priv->info->path);
-    special_file_icon->priv->file = g_file_new_for_uri(uri);
-    g_free(uri);
-
-    /* query file information from GIO */
-    special_file_icon->priv->file_info = g_file_query_info(special_file_icon->priv->file,
+    special_file_icon->priv->file_info = g_file_query_info(file, 
                                                            XFDESKTOP_FILE_INFO_NAMESPACE,
                                                            G_FILE_QUERY_INFO_NONE,
                                                            NULL, NULL);
 
+    if(!special_file_icon->priv->file_info) {
+        g_object_unref(special_file_icon);
+        return NULL;
+    }
+
     /* query file system information from GIO */
     special_file_icon->priv->filesystem_info = g_file_query_filesystem_info(special_file_icon->priv->file,
                                                                             XFDESKTOP_FILESYSTEM_INFO_NAMESPACE,
                                                                             NULL, NULL);
 
-    if(G_UNLIKELY(!special_file_icon->priv->info)) {
-        g_object_unref(G_OBJECT(special_file_icon));
-        return NULL;
-    }
-    
-    if(XFDESKTOP_SPECIAL_FILE_ICON_TRASH == type) {
-        DBusGProxy *trash_proxy = xfdesktop_file_utils_peek_trash_proxy();
-            
-        if(G_LIKELY(trash_proxy)) {
-            DBusGProxyCall *call;
-            
-            special_file_icon->priv->dbus_proxy = g_object_ref(G_OBJECT(trash_proxy));
-            dbus_g_proxy_connect_signal(special_file_icon->priv->dbus_proxy,
-                                        "TrashChanged",
-                                        G_CALLBACK(xfdesktop_special_file_icon_trash_changed_cb),
-                                        special_file_icon, NULL);
-            
-            call = xfdesktop_trash_proxy_query_trash_async(special_file_icon->priv->dbus_proxy,
-                                                           xfdesktop_special_file_icon_query_trash_cb,
-                                                           special_file_icon);
-            if(!call) {
-                xfdesktop_special_file_icon_trash_handle_error(special_file_icon,
-                                                               "QueryTrash",
-                                                               NULL);
-            }
-            special_file_icon->priv->dbus_querytrash_call = call;
-        } else {
-            /* we might as well just bail here */
-            g_object_unref(G_OBJECT(special_file_icon));
-            return NULL;
-        }
-    }
+    /* query a ThunarVfsInfo for the icon URI */
+    uri = g_file_get_uri(file);
+    path = thunar_vfs_path_new(uri, NULL);
+    special_file_icon->priv->info = thunar_vfs_info_new_for_path(path, NULL);
+    thunar_vfs_path_unref(path);
+    g_free(uri);
     
     g_signal_connect_swapped(G_OBJECT(gtk_icon_theme_get_for_screen(screen)),
                              "changed",



More information about the Xfce4-commits mailing list