diff options
author | Brian Tarricone <brian@tarricone.org> | 2006-02-13 05:21:36 +0000 |
---|---|---|
committer | Brian Tarricone <brian@tarricone.org> | 2006-02-13 05:21:36 +0000 |
commit | 909f20e34f98920fab174d87b75ca3e56d895c02 (patch) | |
tree | d99fd9a4ad695361fa86aba77699741f3454fdac /src/xfdesktop-file-icon.c | |
parent | 48b89f4fb1fd496f9ec74344f3658ce47cdc8ce5 (diff) | |
download | xfdesktop-909f20e34f98920fab174d87b75ca3e56d895c02.tar.gz |
patch from benny:
"One of the things I noticed about your implementation is that you use
ThunarVfsPath's and determine the ThunarVfsInfo on-demand. As said on
thunar-dev, this can cause trouble if the info takes long to load (i.e.
it's a symlink to a slow device or a network share, etc.). Therefore,
unless you receive a change notification, the info should also be
determined asynchronously using thunar_vfs_listdir(). The attached patch
changes XfdesktopFileIcon to use ThunarVfsInfo directly instead of
ThunarVfsPath. There was also a bug in there which caused xfdesktop to
crash when the file name contains non-UTF-8 chars, because you used the
path name directly, instead of using ThunarVfsInfo->display_name, which
is garantied to be UTF-8 (while the path name is always in the local
file system encoding).
"I also changed the "Open" action for folders to try
org.xfce.FileManager.Launch() first, prior to falling back to hardcoded
Thunar invocation. This way, things will also work with other file managers.
"And for thunar_vfs_info_execute() you passed the path of the executable
as parameter (-> path_list), which was probably not what you wanted
(yeah, I know I should write better documentation), since this will
actually expand to exec("<executable> <executable>"). The path_list
parameter for _execute() gives the paths that should be passed as
parameters to the command."
(Old svn revision: 19852)
Diffstat (limited to 'src/xfdesktop-file-icon.c')
-rw-r--r-- | src/xfdesktop-file-icon.c | 267 |
1 files changed, 109 insertions, 158 deletions
diff --git a/src/xfdesktop-file-icon.c b/src/xfdesktop-file-icon.c index 87ae64f8..0d4753dd 100644 --- a/src/xfdesktop-file-icon.c +++ b/src/xfdesktop-file-icon.c @@ -1,7 +1,8 @@ /* * xfdesktop - xfce4's desktop manager * - * Copyright (c) 2006 Brian Tarricone, <bjt23@cornell.edu> + * Copyright(c) 2006 Brian Tarricone, <bjt23@cornell.edu> + * Copyright(c) 2006 Benedikt Meurer, <benny@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 @@ -39,9 +40,8 @@ struct _XfdesktopFileIconPrivate gint16 col; GdkPixbuf *pix; gint cur_pix_size; - gchar *label; GdkRectangle extents; - ThunarVfsPath *path; + ThunarVfsInfo *info; GdkScreen *gscreen; }; @@ -69,7 +69,6 @@ static void xfdesktop_file_icon_activated(XfdesktopIcon *icon); static void xfdesktop_file_icon_menu_popup(XfdesktopIcon *icon); -static ThunarVfsMimeInfo *xfdesktop_file_icon_get_mime_info(XfdesktopFileIcon *icon); static GdkPixbuf *xfdesktop_fallback_icon = NULL; static GQuark xfdesktop_mime_app_quark = 0; @@ -81,7 +80,6 @@ G_DEFINE_TYPE_EXTENDED(XfdesktopFileIcon, xfdesktop_file_icon, xfdesktop_file_icon_icon_init)) -/* FIXME: memleak */ static ThunarVfsMimeDatabase *thunar_mime_database = NULL; @@ -98,6 +96,14 @@ xfdesktop_file_icon_class_init(XfdesktopFileIconClass *klass) static void xfdesktop_file_icon_init(XfdesktopFileIcon *icon) { + /* grab a shared reference on the mime database */ + if(thunar_mime_database == NULL) { + thunar_mime_database = thunar_vfs_mime_database_get_default(); + g_object_add_weak_pointer(G_OBJECT(thunar_mime_database), (gpointer) &thunar_mime_database); + } else { + g_object_ref(G_OBJECT(thunar_mime_database)); + } + icon->priv = g_new0(XfdesktopFileIconPrivate, 1); } @@ -109,10 +115,8 @@ xfdesktop_file_icon_finalize(GObject *obj) if(icon->priv->pix) g_object_unref(G_OBJECT(icon->priv->pix)); - g_free(icon->priv->label); - - if(icon->priv->path) - thunar_vfs_path_unref(icon->priv->path); + if(icon->priv->info) + thunar_vfs_info_unref(icon->priv->info); g_free(icon->priv); @@ -135,11 +139,11 @@ xfdesktop_file_icon_icon_init(XfdesktopIconIface *iface) XfdesktopFileIcon * -xfdesktop_file_icon_new(ThunarVfsPath *path, +xfdesktop_file_icon_new(ThunarVfsInfo *info, GdkScreen *screen) { XfdesktopFileIcon *file_icon = g_object_new(XFDESKTOP_TYPE_FILE_ICON, NULL); - file_icon->priv->path = thunar_vfs_path_ref(path); + file_icon->priv->info = thunar_vfs_info_ref(info); file_icon->priv->gscreen = screen; return file_icon; @@ -151,52 +155,31 @@ xfdesktop_file_icon_peek_pixbuf(XfdesktopIcon *icon, gint size) { XfdesktopFileIcon *file_icon = XFDESKTOP_FILE_ICON(icon); + const gchar *icon_name; if(!file_icon->priv->pix || size != file_icon->priv->cur_pix_size) { - ThunarVfsInfo *info; - if(file_icon->priv->pix) { g_object_unref(G_OBJECT(file_icon->priv->pix)); file_icon->priv->pix = NULL; } - - info = thunar_vfs_info_new_for_path(file_icon->priv->path, NULL); - - if(info) { - if(info->type == THUNAR_VFS_FILE_TYPE_DIRECTORY) { - file_icon->priv->pix = xfce_themed_icon_load("stock_folder", size); + + icon_name = thunar_vfs_info_get_custom_icon(file_icon->priv->info); + if(icon_name) { + file_icon->priv->pix = xfce_themed_icon_load(icon_name, size); + if(file_icon->priv->pix) + file_icon->priv->cur_pix_size = size; + } + + if(!file_icon->priv->pix) { + /* FIXME: GtkIconTheme/XfceIconTheme */ + icon_name = thunar_vfs_mime_info_lookup_icon_name(file_icon->priv->info->mime_info, + gtk_icon_theme_get_default()); + + if(icon_name) { + file_icon->priv->pix = xfce_themed_icon_load(icon_name, size); if(file_icon->priv->pix) file_icon->priv->cur_pix_size = size; - } else { - const gchar *custom_icon = thunar_vfs_info_get_custom_icon(info); - - if(custom_icon) { - file_icon->priv->pix = xfce_themed_icon_load(custom_icon, size); - if(file_icon->priv->pix) - file_icon->priv->cur_pix_size = size; - } - - if(!file_icon->priv->pix) { - ThunarVfsMimeInfo *mime_info; - - mime_info = xfdesktop_file_icon_get_mime_info(file_icon); - if(mime_info) { - /* FIXME: GtkIconTheme/XfceIconTheme */ - const gchar *icon_name = thunar_vfs_mime_info_lookup_icon_name(mime_info, - gtk_icon_theme_get_default()); - - if(icon_name) { - file_icon->priv->pix = xfce_themed_icon_load(icon_name, size); - if(file_icon->priv->pix) - file_icon->priv->cur_pix_size = size; - } - - thunar_vfs_mime_info_unref(mime_info); - } - } } - - thunar_vfs_info_unref(info); } } @@ -225,16 +208,7 @@ xfdesktop_file_icon_peek_pixbuf(XfdesktopIcon *icon, static G_CONST_RETURN gchar * xfdesktop_file_icon_peek_label(XfdesktopIcon *icon) { - XfdesktopFileIcon *file_icon = XFDESKTOP_FILE_ICON(icon); - - if(!file_icon->priv->label) { - const char *name = thunar_vfs_path_get_name(file_icon->priv->path); - if(name) - file_icon->priv->label = g_filename_to_utf8(name, -1, NULL, - NULL, NULL); - } - - return file_icon->priv->label; + return XFDESKTOP_FILE_ICON(icon)->priv->info->display_name; } static void @@ -296,57 +270,62 @@ static void xfdesktop_file_icon_activated(XfdesktopIcon *icon) { XfdesktopFileIcon *file_icon = XFDESKTOP_FILE_ICON(icon); - ThunarVfsMimeInfo *mime_info; ThunarVfsMimeApplication *mime_app; - ThunarVfsInfo *info = thunar_vfs_info_new_for_path(file_icon->priv->path, - NULL); + const ThunarVfsInfo *info = file_icon->priv->info; gboolean succeeded = FALSE; - GList *path_list = g_list_prepend(NULL, file_icon->priv->path); + gchar *thunar_app, *folder_name, *commandline; + gchar *display_name; + gint status; + GList *path_list = g_list_prepend(NULL, info->path); TRACE("entering"); - if(info) { - if(info->type == THUNAR_VFS_FILE_TYPE_DIRECTORY) { - gchar *thunar_app = g_find_program_in_path("Thunar"); + if(info->type == THUNAR_VFS_FILE_TYPE_DIRECTORY) { + folder_name = thunar_vfs_path_dup_string(file_icon->priv->info->path); + display_name = gdk_screen_make_display_name(file_icon->priv->gscreen); + + /* try the org.xfce.FileManager D-BUS interface first */ + commandline = g_strdup_printf("dbus-send --print-reply --dest=org.xfce.FileManager " + "/org/xfce/FileManager org.xfce.FileManager.Launch " + "string:\"%s\" string:\"%s\"", folder_name, display_name); + succeeded = (g_spawn_command_line_sync(commandline, NULL, NULL, &status, NULL) && status == 0); + g_free(commandline); + + /* hardcoded fallback to Thunar if that didn't work */ + if(!succeeded) { + thunar_app = g_find_program_in_path("Thunar"); if(thunar_app) { - gchar *folder_name = thunar_vfs_path_dup_string(file_icon->priv->path); - gchar *commandline = g_strconcat(thunar_app, " \"", folder_name, - "\"", NULL); + commandline = g_strconcat("env DISPLAY=\"", display_name, "\" ", thunar_app, " \"", folder_name, "\"", NULL); DBG("executing:\n%s\n", commandline); succeeded = xfce_exec(commandline, FALSE, TRUE, NULL); - g_free(folder_name); g_free(commandline); } g_free(thunar_app); - } else if(info->flags & THUNAR_VFS_FILE_FLAGS_EXECUTABLE) { - succeeded = thunar_vfs_info_execute(info, - file_icon->priv->gscreen, - path_list, - NULL); } - - thunar_vfs_info_unref(info); + + g_free(display_name); + g_free(folder_name); + } else if(info->flags & THUNAR_VFS_FILE_FLAGS_EXECUTABLE) { + succeeded = thunar_vfs_info_execute(info, + file_icon->priv->gscreen, + NULL, + NULL); } if(!succeeded) { - mime_info = xfdesktop_file_icon_get_mime_info(file_icon); - if(mime_info) { - mime_app = thunar_vfs_mime_database_get_default_application(thunar_mime_database, - mime_info); - if(mime_app) { - DBG("executing"); - - succeeded = thunar_vfs_mime_handler_exec(THUNAR_VFS_MIME_HANDLER(mime_app), - file_icon->priv->gscreen, - path_list, - NULL); - g_object_unref(G_OBJECT(mime_app)); - } - - thunar_vfs_mime_info_unref(mime_info); + mime_app = thunar_vfs_mime_database_get_default_application(thunar_mime_database, + info->mime_info); + if(mime_app) { + DBG("executing"); + + succeeded = thunar_vfs_mime_handler_exec(THUNAR_VFS_MIME_HANDLER(mime_app), + file_icon->priv->gscreen, + path_list, + NULL); + g_object_unref(G_OBJECT(mime_app)); } } @@ -361,11 +340,9 @@ xfdesktop_file_icon_menu_rename(GtkWidget *widget, GtkWidget *dlg, *entry, *lbl, *img, *hbox, *vbox, *topvbox; GdkPixbuf *pix; gchar *title, *p; - const gchar *name; gint w, h; - title = g_strdup_printf(_("Rename \"%s\""), - thunar_vfs_path_get_name(icon->priv->path)); + title = g_strdup_printf(_("Rename \"%s\""), icon->priv->info->display_name); dlg = gtk_dialog_new_with_buttons(title, NULL, GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, @@ -400,10 +377,9 @@ xfdesktop_file_icon_menu_rename(GtkWidget *widget, gtk_box_pack_start(GTK_BOX(vbox), lbl, FALSE, FALSE, 0); entry = gtk_entry_new(); - name = xfdesktop_file_icon_peek_label(XFDESKTOP_ICON(icon)); - gtk_entry_set_text(GTK_ENTRY(entry), name); - if((p = g_utf8_strrchr(name, -1, '.'))) { - gint offset = g_utf8_strlen(name, p - name); + gtk_entry_set_text(GTK_ENTRY(entry), icon->priv->info->display_name); + if((p = g_utf8_strrchr(icon->priv->info->display_name, -1, '.'))) { + gint offset = g_utf8_strlen(icon->priv->info->display_name, p - icon->priv->info->display_name); gtk_editable_set_position(GTK_EDITABLE(entry), offset); gtk_editable_select_region(GTK_EDITABLE(entry), 0, offset); } @@ -412,16 +388,15 @@ xfdesktop_file_icon_menu_rename(GtkWidget *widget, gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0); if(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dlg))) { - ThunarVfsInfo *info = thunar_vfs_info_new_for_path(icon->priv->path, - NULL); gchar *new_name; GError *error = NULL; new_name = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1); - if(!thunar_vfs_info_rename(info, new_name, &error)) { + // FIXME: Need to re-register with the VFS monitor after successfull rename + if(!thunar_vfs_info_rename(icon->priv->info, new_name, &error)) { gchar *primary = g_strdup_printf(_("Failed to rename \"%s\" to \"%s\":"), - name, new_name); + icon->priv->info->display_name, new_name); xfce_message_dialog(NULL, _("Error"), GTK_STOCK_DIALOG_ERROR, primary, error->message, GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL); @@ -440,8 +415,7 @@ xfdesktop_delete_file_error(ThunarVfsJob *job, gpointer user_data) { XfdesktopFileIcon *icon = XFDESKTOP_FILE_ICON(user_data); - gchar *primary = g_strdup_printf("There was an error deleting \"%s\":", - thunar_vfs_path_get_name(icon->priv->path)); + gchar *primary = g_strdup_printf("There was an error deleting \"%s\":", icon->priv->info->display_name); xfce_message_dialog(NULL, _("Error"), GTK_STOCK_DIALOG_ERROR, primary, error->message, GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, @@ -460,7 +434,7 @@ xfdesktop_file_icon_menu_delete(GtkWidget *widget, ThunarVfsJob *job; primary = g_strdup_printf("Are you sure that you want to permanently delete \"%s\"?", - thunar_vfs_path_get_name(icon->priv->path)); + icon->priv->info->display_name); ret = xfce_message_dialog(NULL, _("Question"), GTK_STOCK_DIALOG_QUESTION, primary, _("If you delete a file, it is permanently lost."), @@ -468,7 +442,9 @@ xfdesktop_file_icon_menu_delete(GtkWidget *widget, GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT, NULL); g_free(primary); if(GTK_RESPONSE_ACCEPT == ret) { - job = thunar_vfs_unlink_file(icon->priv->path, NULL); + job = thunar_vfs_unlink_file(icon->priv->info->path, NULL); + // FIXME: This is going to crash if the icon is destroyed and the + // error signal is emitted afterwards g_signal_connect(G_OBJECT(job), "error", G_CALLBACK(xfdesktop_delete_file_error), icon); g_signal_connect(G_OBJECT(job), "finished", @@ -482,7 +458,7 @@ xfdesktop_file_icon_menu_executed(GtkWidget *widget, { XfdesktopFileIcon *icon = XFDESKTOP_FILE_ICON(user_data); ThunarVfsMimeApplication *mime_app; - GList *path_list = g_list_append(NULL, icon->priv->path); + GList *path_list = g_list_append(NULL, icon->priv->info->path); mime_app = g_object_get_qdata(G_OBJECT(widget), xfdesktop_mime_app_quark); g_return_if_fail(mime_app); @@ -550,8 +526,8 @@ static void xfdesktop_file_icon_menu_popup(XfdesktopIcon *icon) { XfdesktopFileIcon *file_icon = XFDESKTOP_FILE_ICON(icon); - ThunarVfsMimeInfo *mime_info = xfdesktop_file_icon_get_mime_info(file_icon); - ThunarVfsInfo *info; + ThunarVfsInfo *info = file_icon->priv->info; + ThunarVfsMimeInfo *mime_info = info->mime_info; GList *mime_apps, *l; GtkWidget *menu, *mi, *img; @@ -560,7 +536,6 @@ xfdesktop_file_icon_menu_popup(XfdesktopIcon *icon) g_signal_connect_swapped(G_OBJECT(menu), "deactivate", G_CALLBACK(g_idle_add), menu_deactivate_idled); - info = thunar_vfs_info_new_for_path(file_icon->priv->path, NULL); if(info->type == THUNAR_VFS_FILE_TYPE_DIRECTORY) { img = gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU); gtk_widget_show(img); @@ -576,38 +551,35 @@ xfdesktop_file_icon_menu_popup(XfdesktopIcon *icon) gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img); gtk_widget_show(mi); gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); - } if(mime_info) { - mime_apps = thunar_vfs_mime_database_get_applications(thunar_mime_database, - mime_info); - if(mime_apps) { - gint w, h; - ThunarVfsMimeApplication *mime_app = mime_apps->data; - - gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &w, &h); - - mi = xfdesktop_menu_item_from_mime_app(file_icon, mime_app, w, - TRUE); + } + mime_apps = thunar_vfs_mime_database_get_applications(thunar_mime_database, + mime_info); + if(mime_apps) { + gint w, h; + ThunarVfsMimeApplication *mime_app = mime_apps->data; + + gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &w, &h); + + mi = xfdesktop_menu_item_from_mime_app(file_icon, mime_app, w, + TRUE); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); + + if(mime_apps->next) { + mi = gtk_separator_menu_item_new(); + gtk_widget_show(mi); gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); - if(mime_apps->next) { - mi = gtk_separator_menu_item_new(); - gtk_widget_show(mi); + for(l = mime_apps->next; l; l = l->next) { + mime_app = l->data; + mi = xfdesktop_menu_item_from_mime_app(file_icon, + mime_app, w, + FALSE); gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); - - for(l = mime_apps->next; l; l = l->next) { - mime_app = l->data; - mi = xfdesktop_menu_item_from_mime_app(file_icon, - mime_app, w, - FALSE); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); - } } - - /* don't free the mime apps! just the list! */ - g_list_free(mime_apps); } - thunar_vfs_mime_info_unref(mime_info); + /* don't free the mime apps! just the list! */ + g_list_free(mime_apps); } /* FIXME: implement this */ @@ -617,8 +589,6 @@ xfdesktop_file_icon_menu_popup(XfdesktopIcon *icon) gtk_widget_set_sensitive(mi, FALSE); } - thunar_vfs_info_unref(info); - mi = gtk_separator_menu_item_new(); gtk_widget_show(mi); gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); @@ -679,23 +649,4 @@ xfdesktop_file_icon_menu_popup(XfdesktopIcon *icon) -static ThunarVfsMimeInfo * -xfdesktop_file_icon_get_mime_info(XfdesktopFileIcon *icon) -{ - ThunarVfsMimeInfo *mime_info = NULL; - gchar *file_path; - - if(!thunar_mime_database) - thunar_mime_database = thunar_vfs_mime_database_get_default(); - - if(!icon->priv->label) - xfdesktop_file_icon_peek_label(XFDESKTOP_ICON(icon)); - - file_path = thunar_vfs_path_dup_string(icon->priv->path); - mime_info = thunar_vfs_mime_database_get_info_for_file(thunar_mime_database, - file_path, - icon->priv->label); - g_free(file_path); - - return mime_info; -} + |