[Xfce4-commits] <xfdesktop:master> Add helper methods to spawn GAppInfos, similar to Thunar.

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


Updating branch refs/heads/master
         to 59e4134dc4d6bce5297016269d2ac213c472d724 (commit)
       from 083901eba2cdca3e0ceaa1efcb79b003c53db354 (commit)

commit 59e4134dc4d6bce5297016269d2ac213c472d724
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Thu Oct 21 18:58:42 2010 +0200

    Add helper methods to spawn GAppInfos, similar to Thunar.
    
    The new methods are:
      * xfdesktop_file_utils_app_info_launch()
      * xfdesktop_file_utils_file_is_executable()
    
    The first one launches a GAppInfo and properly sets the working
    directory before and after the application is spawned.
    
    The second determines whether a file can be executed. This depends on
    the executable bit as well as the content type and the file extension
    (.desktop can be executed, .directory can't).
    
    Check for sys/params.h and pwd.h.

 configure.ac.in            |    4 +-
 src/xfdesktop-file-utils.c |  154 +++++++++++++++++++++++++++++++++++++++++---
 src/xfdesktop-file-utils.h |    7 ++
 3 files changed, 153 insertions(+), 12 deletions(-)

diff --git a/configure.ac.in b/configure.ac.in
index 6a3ba6d..d1a35fd 100644
--- a/configure.ac.in
+++ b/configure.ac.in
@@ -53,8 +53,8 @@ AC_PROG_INTLTOOL([intltool_minimum_version], [no-xml])
 
 dnl check for standard header files
 AC_HEADER_STDC
-AC_CHECK_HEADERS([ctype.h errno.h fcntl.h math.h signal.h stddef.h \
-                  string.h sys/mman.h sys/stat.h sys/statvfs.h \
+AC_CHECK_HEADERS([ctype.h errno.h fcntl.h math.h pwd.h signal.h stddef.h \
+                  string.h sys/mman.h sys/param.h sys/stat.h sys/statvfs.h \
                   sys/types.h sys/wait.h time.h \
                   unistd.h])
 AC_CHECK_FUNCS([mmap sigaction srandom])
diff --git a/src/xfdesktop-file-utils.c b/src/xfdesktop-file-utils.c
index d7059eb..3f60161 100644
--- a/src/xfdesktop-file-utils.c
+++ b/src/xfdesktop-file-utils.c
@@ -23,6 +23,13 @@
 #include <config.h>
 #endif
 
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
@@ -153,6 +160,51 @@ xfdesktop_file_utils_get_file_kind(const ThunarVfsInfo *info,
     return str;
 }
 
+static
+gboolean xfdesktop_file_utils_is_desktop_file(GFileInfo *info)
+{
+    const gchar *content_type;
+    gboolean is_desktop_file = FALSE;
+
+    content_type = g_file_info_get_content_type(info);
+    if(content_type)
+        is_desktop_file = g_content_type_equals(content_type, "application/x-desktop");
+
+    return is_desktop_file 
+        && !g_str_has_suffix(g_file_info_get_name(info), ".directory");
+}
+
+gboolean
+xfdesktop_file_utils_file_is_executable(GFileInfo *info)
+{
+    const gchar *content_type;
+    gboolean can_execute = FALSE;
+
+    g_return_val_if_fail(G_IS_FILE_INFO(info), FALSE);
+
+    if(g_file_info_get_attribute_boolean(info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE)) {
+        /* get the content type of the file */
+        content_type = g_file_info_get_content_type(info);
+        if(content_type != NULL) {
+#ifdef G_OS_WIN32
+            /* check for .exe, .bar or .com */
+            can_execute = g_content_type_can_be_executable(content_type);
+#else
+            /* check if the content type is save to execute, we don't use
+             * g_content_type_can_be_executable() for unix because it also returns
+             * true for "text/plain" and we don't want that */
+            if(g_content_type_is_a(content_type, "application/x-executable")
+               || g_content_type_is_a(content_type, "application/x-shellscript"))
+            {
+                can_execute = TRUE;
+            }
+#endif
+        }
+    }
+
+    return can_execute || xfdesktop_file_utils_is_desktop_file(info);
+}
+
 
 GList *
 xfdesktop_file_utils_file_icon_list_to_file_list(GList *icon_list)
@@ -400,6 +452,91 @@ xfdesktop_file_utils_launch_fallback(const ThunarVfsInfo *info,
     return ret;
 }
 
+static gchar *
+xfdesktop_file_utils_change_working_directory (const gchar *new_directory)
+{
+  gchar *old_directory;
+
+  g_return_val_if_fail(new_directory && *new_directory != '\0', NULL);
+
+  /* allocate a path buffer for the old working directory */
+  old_directory = g_malloc0(sizeof(gchar) * MAXPATHLEN);
+
+  /* try to determine the current working directory */
+#ifdef G_PLATFORM_WIN32
+  if(!_getcwd(old_directory, MAXPATHLEN))
+#else
+  if(!getcwd (old_directory, MAXPATHLEN))
+#endif
+  {
+      /* working directory couldn't be determined, reset the buffer */
+      g_free(old_directory);
+      old_directory = NULL;
+  }
+
+  /* try switching to the new working directory */
+#ifdef G_PLATFORM_WIN32
+  if(_chdir (new_directory))
+#else
+  if(chdir (new_directory))
+#endif
+  {
+      /* switching failed, we don't need to return the old directory */
+      g_free(old_directory);
+      old_directory = NULL;
+  }
+
+  return old_directory;
+}
+
+gboolean
+xfdesktop_file_utils_app_info_launch(GAppInfo *app_info,
+                                     GFile *working_directory,
+                                     GList *files,
+                                     GAppLaunchContext *context,
+                                     GError **error)
+{
+    gboolean result = FALSE;
+    gchar *new_path = NULL;
+    gchar *old_path = NULL;
+
+    g_return_val_if_fail(G_IS_APP_INFO(app_info), FALSE);
+    g_return_val_if_fail(working_directory == NULL || G_IS_FILE(working_directory), FALSE);
+    g_return_val_if_fail(files != NULL && files->data != NULL, FALSE);
+    g_return_val_if_fail(G_IS_APP_LAUNCH_CONTEXT(context), FALSE);
+    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
+
+    /* check if we want to set the working directory of the spawned app */
+    if(working_directory) {
+        /* determine the working directory path */
+        new_path = g_file_get_path(working_directory);
+        if(new_path) {
+            /* switch to the desired working directory, remember that 
+             * of xfdesktop itself */
+            old_path = xfdesktop_file_utils_change_working_directory(new_path);
+
+            /* forget about the new working directory path */
+            g_free(new_path);
+        }
+    }
+
+    /* launch the paths with the specified app info */
+    result = g_app_info_launch(app_info, files, context, error);
+
+    /* check if we need to reset the working directory to the one xfdesktop was
+     * opened from */
+    if(old_path) {
+        /* switch to xfdesktop's original working directory */
+        new_path = xfdesktop_file_utils_change_working_directory(old_path);
+
+        /* clean up */
+        g_free (new_path);
+        g_free (old_path);
+    }
+
+    return result;
+}
+
 static void
 xfdesktop_file_utils_display_folder_cb(DBusGProxy *proxy,
                                        GError *error,
@@ -415,8 +552,7 @@ xfdesktop_file_utils_display_folder_cb(DBusGProxy *proxy,
         xfce_message_dialog(parent,
                             _("Launch Error"), GTK_STOCK_DIALOG_ERROR,
                             _("The folder could not be opened"),
-                            _("This feature requires a file manager service to "
-                              "be present (such as the one supplied by Thunar)."),
+                            error->message,
                             GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
     }
 }
@@ -480,8 +616,7 @@ xfdesktop_file_utils_rename_file_cb(DBusGProxy *proxy,
         xfce_message_dialog(parent,
                             _("Rename Error"), GTK_STOCK_DIALOG_ERROR,
                             _("The file could not be renamed"),
-                            _("This feature requires a file manager service to "
-                              "be present (such as the one supplied by Thunar)."),
+                            error->message,
                             GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
     }
 }
@@ -542,8 +677,7 @@ xfdesktop_file_utils_create_file_cb(DBusGProxy *proxy,
         xfce_message_dialog(parent,
                             _("Create File Error"), GTK_STOCK_DIALOG_ERROR,
                             _("Could not create a new file"),
-                            _("This feature requires a file manager service to "
-                              "be present (such as the one supplied by Thunar)."),
+                            error->message,
                             GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
     }
 }
@@ -607,8 +741,7 @@ xfdesktop_file_utils_show_properties_dialog_cb(DBusGProxy *proxy,
         xfce_message_dialog(parent,
                             _("File Properties Error"), GTK_STOCK_DIALOG_ERROR,
                             _("The file properties dialog could not be opened"),
-                            _("This feature requires a file manager service to "
-                              "be present (such as the one supplied by Thunar)."),
+                            error->message,
                             GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
     }
 }
@@ -669,8 +802,7 @@ xfdesktop_file_utils_launch_cb(DBusGProxy *proxy,
         xfce_message_dialog(parent,
                             _("Launch Error"), GTK_STOCK_DIALOG_ERROR,
                             _("The file could not be opened"),
-                            _("This feature requires a file manager service to "
-                              "be present (such as the one supplied by Thunar)."),
+                            error->message,
                             GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
     }
 }
@@ -693,6 +825,8 @@ xfdesktop_file_utils_launch(GFile *file,
         gchar *uri = g_file_get_uri(file);
         gchar *display_name = gdk_screen_make_display_name(screen);
         gchar *startup_id = g_strdup_printf("_TIME%d", gtk_get_current_event_time());
+
+        g_debug ("launching %s", uri);
         
         if(!xfdesktop_file_manager_proxy_launch_async(fileman_proxy,
                                                       uri, display_name, startup_id,
diff --git a/src/xfdesktop-file-utils.h b/src/xfdesktop-file-utils.h
index d437635..5d31a5b 100644
--- a/src/xfdesktop-file-utils.h
+++ b/src/xfdesktop-file-utils.h
@@ -57,6 +57,7 @@ void xfdesktop_file_utils_move_into(GtkWindow *parent,
 
 gchar *xfdesktop_file_utils_get_file_kind(const ThunarVfsInfo *info,
                                           gboolean *is_link);
+gboolean xfdesktop_file_utils_file_is_executable(GFileInfo *info);
 
 GList *xfdesktop_file_utils_file_icon_list_to_file_list(GList *icon_list);
 gchar *xfdesktop_file_utils_file_list_to_string(GList *file_list);
@@ -77,6 +78,12 @@ gboolean xfdesktop_file_utils_launch_fallback(const ThunarVfsInfo *info,
                                               GdkScreen *screen,
                                               GtkWindow *parent);
 
+gboolean xfdesktop_file_utils_app_info_launch(GAppInfo *app_info,
+                                              GFile *working_directory,
+                                              GList *files,
+                                              GAppLaunchContext *context,
+                                              GError **error);
+
 void xfdesktop_file_utils_open_folder(GFile *file,
                                       GdkScreen *screen,
                                       GtkWindow *parent);



More information about the Xfce4-commits mailing list