[Xfce4-commits] <libxfce4ui:new-sm-client> add support for setting the app's .desktop file

Brian J. Tarricone brian at tarricone.org
Thu Sep 17 10:24:01 CEST 2009


Updating branch refs/heads/kelnos/new-sm-client
         to fec139a69b6c2988e7de4cbbdc0ddb2a61d35104 (commit)
       from 8a8c77471fd86988d3f1948cb056ecf11b475c65 (commit)

commit fec139a69b6c2988e7de4cbbdc0ddb2a61d35104
Author: Brian J. Tarricone <brian at tarricone.org>
Date:   Thu Sep 17 01:23:07 2009 -0700

    add support for setting the app's .desktop file

 docs/libxfce4ui-sections.txt  |    1 +
 docs/tmpl/xfce-sm-client.sgml |   14 ++++
 libxfce4ui/libxfce4ui.symbols |    2 +
 libxfce4ui/xfce-sm-client.c   |  155 +++++++++++++++++++++++++++++++++++++++--
 libxfce4ui/xfce-sm-client.h   |    3 +
 5 files changed, 169 insertions(+), 6 deletions(-)

diff --git a/docs/libxfce4ui-sections.txt b/docs/libxfce4ui-sections.txt
index e5de489..d3a9b10 100644
--- a/docs/libxfce4ui-sections.txt
+++ b/docs/libxfce4ui-sections.txt
@@ -84,6 +84,7 @@ xfce_sm_client_get_full
 xfce_sm_client_connect
 xfce_sm_client_disconnect
 xfce_sm_client_is_resumed
+xfce_sm_client_set_desktop_file
 xfce_sm_client_request_shutdown
 xfce_sm_client_get_client_id
 xfce_sm_client_get_state_file
diff --git a/docs/tmpl/xfce-sm-client.sgml b/docs/tmpl/xfce-sm-client.sgml
index 313bff2..b9547b6 100644
--- a/docs/tmpl/xfce-sm-client.sgml
+++ b/docs/tmpl/xfce-sm-client.sgml
@@ -85,6 +85,11 @@
 
 </para>
 
+<!-- ##### ARG XfceSMClient:desktop-file ##### -->
+<para>
+
+</para>
+
 <!-- ##### ARG XfceSMClient:discard-command ##### -->
 <para>
 
@@ -217,6 +222,15 @@
 @Returns: 
 
 
+<!-- ##### FUNCTION xfce_sm_client_set_desktop_file ##### -->
+<para>
+
+</para>
+
+ at sm_client: 
+ at desktop_file: 
+
+
 <!-- ##### FUNCTION xfce_sm_client_request_shutdown ##### -->
 <para>
 
diff --git a/libxfce4ui/libxfce4ui.symbols b/libxfce4ui/libxfce4ui.symbols
index 4ad0203..d75091d 100644
--- a/libxfce4ui/libxfce4ui.symbols
+++ b/libxfce4ui/libxfce4ui.symbols
@@ -102,6 +102,8 @@ xfce_sm_client_get_with_argv
 xfce_sm_client_get_full
 xfce_sm_client_connect
 xfce_sm_client_disconnect
+xfce_sm_client_is_resumed
+xfce_sm_client_set_desktop_file
 xfce_sm_client_request_shutdown
 xfce_sm_client_get_client_id
 xfce_sm_client_get_state_file
diff --git a/libxfce4ui/xfce-sm-client.c b/libxfce4ui/xfce-sm-client.c
index bccbee4..21d0e59 100644
--- a/libxfce4ui/xfce-sm-client.c
+++ b/libxfce4ui/xfce-sm-client.c
@@ -160,6 +160,7 @@ struct _XfceSMClient
     gchar **argv;
 
     gchar *state_file;
+    gchar *desktop_file;
 };
 
 typedef struct _XfceSMClientClass
@@ -208,6 +209,7 @@ enum
     PROP_CLONE_COMMAND,
     PROP_RESTART_COMMAND,
     PROP_DISCARD_COMMAND,
+    PROP_DESKTOP_FILE,
     PROP_ARGC,
     PROP_ARGV,
 };
@@ -412,6 +414,12 @@ xfce_sm_client_class_init(XfceSMClientClass *klass)
                                                        "A command used to discard any information about the current saved state",
                                                        G_TYPE_STRV,
                                                        G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
+    g_object_class_install_property(gobject_class, PROP_DESKTOP_FILE,
+                                    g_param_spec_string("desktop-file",
+                                                        "Desktop file",
+                                                        "The application's .desktop file",
+                                                        NULL,
+                                                        G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
 
     /* these are "private" properties */
     g_object_class_install_property(gobject_class, PROP_ARGC,
@@ -480,6 +488,10 @@ xfce_sm_client_get_property(GObject *obj,
             g_value_set_boxed(value, sm_client->discard_command);
             break;
 
+        case PROP_DESKTOP_FILE:
+            g_value_set_string(value, sm_client->desktop_file);
+            break;
+
         case PROP_ARGC:
         case PROP_ARGV:
         default:
@@ -533,6 +545,11 @@ xfce_sm_client_set_property(GObject *obj,
                                                g_value_get_boxed(value));
             break;
 
+        case PROP_DESKTOP_FILE:
+            xfce_sm_client_set_desktop_file(sm_client,
+                                            g_value_get_string(value));
+            break;
+
         case PROP_ARGC:
             if(sm_client->argc)
                 g_critical("XfceSMClient: Received argc twice");
@@ -590,6 +607,7 @@ xfce_sm_client_finalize(GObject *obj)
 #endif
 
     g_free(sm_client->state_file);
+    g_free(sm_client->desktop_file);
 
     g_free(sm_client->client_id);
     g_free(sm_client->current_directory);
@@ -1503,8 +1521,9 @@ xfce_sm_client_connect(XfceSMClient *sm_client,
     char buf[256] = "";
     unsigned long mask;
     SmcCallbacks callbacks;
-    SmProp prop1, prop2, prop3, prop4, prop5, prop6, *props[6];
-    SmPropValue prop1val, prop2val, prop3val, prop4val, prop5val, prop6val;
+    SmProp prop1, prop2, prop3, prop4, prop5, prop6, prop7, *props[7];
+    SmPropValue prop1val, prop2val, prop3val, prop4val, prop5val, prop6val, prop7val;
+    int n_props = 0;
     char pid[32];
     char hint = SmRestartIfRunning;
     char priority = sm_client->priority;
@@ -1584,6 +1603,7 @@ xfce_sm_client_connect(XfceSMClient *sm_client,
     prop1.vals = &prop1val;
     prop1val.value = sm_client->program;
     prop1val.length = strlen(sm_client->program);
+    n_props++;
 
     prop2.name = SmUserID;
     prop2.type = SmARRAY8;
@@ -1591,6 +1611,7 @@ xfce_sm_client_connect(XfceSMClient *sm_client,
     prop2.vals = &prop2val;
     prop2val.value = (char *)g_get_user_name();
     prop2val.length = strlen(prop2val.value);
+    n_props++;
 
     prop3.name = SmRestartStyleHint;
     prop3.type = SmCARD8;
@@ -1598,6 +1619,7 @@ xfce_sm_client_connect(XfceSMClient *sm_client,
     prop3.vals = &prop3val;
     prop3val.value = &hint;
     prop3val.length = 1;
+    n_props++;
 
     g_snprintf(pid, sizeof(pid), "%d", getpid());
     prop4.name = SmProcessID;
@@ -1606,6 +1628,7 @@ xfce_sm_client_connect(XfceSMClient *sm_client,
     prop4.vals = &prop4val;
     prop4val.value = pid;
     prop4val.length = strlen(prop4val.value);
+    n_props++;
 
     prop5.name = SmCurrentDirectory;
     prop5.type = SmARRAY8;
@@ -1616,6 +1639,7 @@ xfce_sm_client_connect(XfceSMClient *sm_client,
     else
         prop5val.value = (char *)xfce_get_homedir();
     prop5val.length = strlen(prop5val.value);
+    n_props++;
 
     prop6.name = "_GSM_Priority";
     prop6.type = SmCARD8;
@@ -1623,6 +1647,17 @@ xfce_sm_client_connect(XfceSMClient *sm_client,
     prop6.vals = &prop6val;
     prop6val.value = &priority;
     prop6val.length = 1;
+    n_props++;
+
+    if(sm_client->desktop_file) {
+        prop7.name = "_GSM_DesktopFile";
+        prop7.type = SmARRAY8;
+        prop7.num_vals = 1;
+        prop7.vals = &prop7val;
+        prop7val.value = (char *)sm_client->desktop_file;
+        prop7val.length = strlen(sm_client->desktop_file);
+        n_props++;
+    }
 
     props[0] = &prop1;
     props[1] = &prop2;
@@ -1630,10 +1665,9 @@ xfce_sm_client_connect(XfceSMClient *sm_client,
     props[3] = &prop4;
     props[4] = &prop5;
     props[5] = &prop6;
+    props[6] = &prop7;
 
-    SmcSetProperties(sm_client->session_connection, 6, props);
-
-    g_object_notify(G_OBJECT(sm_client), "session-connection");
+    SmcSetProperties(sm_client->session_connection, n_props, props);
 #endif
 
     return TRUE;
@@ -1671,7 +1705,6 @@ xfce_sm_client_disconnect(XfceSMClient *sm_client)
     sm_client->session_connection = NULL;
     gdk_set_sm_client_id(NULL);
 
-    g_object_notify(G_OBJECT(sm_client), "session-connection");
     xfce_sm_client_set_state(sm_client, XFCE_SM_CLIENT_STATE_DISCONNECTED);
 #endif
 }
@@ -1694,6 +1727,116 @@ xfce_sm_client_is_resumed(XfceSMClient *sm_client)
 }
 
 /**
+ * xfce_sm_client_set_desktop_file:
+ * @sm_client: An #XfceSMClient
+ * @desktop_file: The path to the application's .desktop file
+ *
+ * Sets the application's .desktop file.  In addition to informing
+ * the session manager of the .desktop file so it can present localized
+ * names and an icon in session listings and the splash screen, this
+ * also calls g_set_application_name() and
+ * gtk_window_set_default_icon_name() (or
+ * gtk_window_set_default_icon_from_file()) if the Name and Icon
+ * keys are present, respectively.
+ *
+ * If a relative path to the file is provided, this function will search
+ * the standard application directories as specified by the
+ * <ulink type="http" url="http://standards.freedesktop.org/menu-spec/latest/">XDG
+ * Desktop Menu Specification</ulink>.
+ **/
+void
+xfce_sm_client_set_desktop_file(XfceSMClient *sm_client,
+                                const gchar *desktop_file)
+{
+    XfceRc *rcfile = NULL;
+    gchar *real_desktop_file = NULL;
+    const gchar *name, *icon, *exec;
+
+    g_return_if_fail(XFCE_IS_SM_CLIENT(sm_client));
+    g_return_if_fail(desktop_file);
+
+    if(!xfce_safe_strcmp(sm_client->desktop_file, desktop_file))
+        return;
+
+    if(!g_path_is_absolute(desktop_file)) {
+        gchar res_name[1024];
+
+        g_snprintf(res_name, sizeof(res_name), "applications/%s", desktop_file);
+        real_desktop_file = xfce_resource_lookup(XFCE_RESOURCE_DATA, res_name);
+        if(!real_desktop_file) {
+            g_warning("Cannot find file \"%s\" in the standard search path",
+                      desktop_file);
+            return;
+        }
+
+        desktop_file = real_desktop_file;
+    }
+
+    rcfile = xfce_rc_simple_open(desktop_file, TRUE);
+    if(!rcfile) {
+        g_warning("Unable to open \"%s\"", desktop_file);
+        goto out;
+    }
+
+    if(!xfce_rc_has_group(rcfile, "Desktop Entry")) {
+        g_warning("File \"%s\" is not a valid .desktop file", desktop_file);
+        goto out;
+    }
+
+    g_free(sm_client->desktop_file);
+    sm_client->desktop_file = g_strdup(desktop_file);
+
+    xfce_rc_set_group(rcfile, "Desktop Entry");
+
+    name = xfce_rc_read_entry(rcfile, "Name", NULL);
+    if(name)
+        g_set_application_name(name);
+
+    icon = xfce_rc_read_entry(rcfile, "Icon", NULL);
+    if(icon) {
+        if(g_path_is_absolute(icon))
+            gtk_window_set_default_icon_from_file(icon, NULL);
+        else
+            gtk_window_set_default_icon_name(icon);
+    }
+
+    exec = xfce_rc_read_entry(rcfile, "Exec", NULL);
+    if(exec) {
+        gchar **clone_argv = NULL;
+        gint clone_argc = 0;
+
+        /* FIXME: pull out the %-var substitutions first */
+
+        if(g_shell_parse_argv(exec, &clone_argc, &clone_argv, NULL)) {
+            xfce_sm_client_set_clone_command(sm_client, clone_argv);
+            g_strfreev(clone_argv);
+        }
+    }
+
+#ifdef HAVE_LIBSM
+    if(sm_client->session_connection) {
+        SmProp prop, *props[1];
+        SmPropValue propval;
+
+        prop.name = "_GSM_DesktopFile";
+        prop.type = SmARRAY8;
+        prop.num_vals = 1;
+        prop.vals = &propval;
+        propval.value = sm_client->desktop_file;
+        propval.length = strlen(sm_client->desktop_file);
+        props[0] = ∝
+
+        SmcSetProperties(sm_client->session_connection, 1, props);
+    }
+#endif /* HAVE_LIBSM */
+
+out:
+    if(rcfile)
+        xfce_rc_close(rcfile);
+    g_free(real_desktop_file);
+}
+
+/**
  * xfce_sm_client_request_shutdown:
  * @sm_client: An #XfceSMClient
  * @shutdown_hint: The type of shutdown requested
diff --git a/libxfce4ui/xfce-sm-client.h b/libxfce4ui/xfce-sm-client.h
index b7d6200..70175e4 100644
--- a/libxfce4ui/xfce-sm-client.h
+++ b/libxfce4ui/xfce-sm-client.h
@@ -90,6 +90,9 @@ void xfce_sm_client_request_shutdown(XfceSMClient *sm_client,
 
 gboolean xfce_sm_client_is_resumed(XfceSMClient *sm_client);
 
+void xfce_sm_client_set_desktop_file(XfceSMClient *sm_client,
+                                     const gchar *desktop_file);
+
 G_CONST_RETURN gchar *xfce_sm_client_get_client_id(XfceSMClient *sm_client);
 
 G_CONST_RETURN gchar *xfce_sm_client_get_state_file(XfceSMClient *sm_client);



More information about the Xfce4-commits mailing list