]> Dogcows Code - chaz/openbox/blobdiff - obt/link.c
improved .desktop parsing.
[chaz/openbox] / obt / link.c
index 8249118d210a8e8e19d08cb9d2247cf30f828477..bdddcf547b12dc1e723a3839e9d9819472010a62 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "obt/link.h"
 #include "obt/ddparse.h"
+#include "obt/paths.h"
 #include <glib.h>
 
 struct _ObtLink {
@@ -25,9 +26,17 @@ struct _ObtLink {
 
     ObtLinkType type;
     gchar *name; /*!< Specific name for the object (eg Firefox) */
+    gboolean display; /*<! When false, do not display this link in menus or
+                           launchers, etc */
+    gboolean deleted; /*<! When true, the Link could exist but is deleted
+                           for the current user */
     gchar *generic; /*!< Generic name for the object (eg Web Browser) */
     gchar *comment; /*!< Comment/description to display for the object */
     gchar *icon; /*!< Name/path for an icon for the object */
+    guint env_required; /*!< The environments that must be present to use this
+                          link. */
+    guint env_restricted; /*!< The environments that must _not_ be present to
+                            use this link. */
 
     union _ObtLinkData {
         struct _ObtLinkApp {
@@ -44,34 +53,127 @@ struct _ObtLink {
             gchar *startup_wmclass;
         } app;
         struct _ObtLinkLink {
-            gchar *url;
-        } link;
+            gchar *addr;
+        } url;
         struct _ObtLinkDir {
         } dir;
     } d;
 };
 
-ObtLink* obt_link_from_ddfile(const gchar *name, GSList *paths)
+ObtLink* obt_link_from_ddfile(const gchar *ddname, GSList *paths,
+                              ObtPaths *p)
 {
-    ObtLink *lnk;
+    ObtLink *link;
     GHashTable *groups, *keys;
     ObtDDParseGroup *g;
+    ObtDDParseValue *v;
 
-    groups = obt_ddparse_file(name, paths);
-    if (!groups) return NULL;
+    /* parse the file, and get a hash table of the groups */
+    groups = obt_ddparse_file(ddname, paths);
+    if (!groups) return NULL; /* parsing failed */
+    /* grab the Desktop Entry group */
     g = g_hash_table_lookup(groups, "Desktop Entry");
-    if (!g) {
-        g_hash_table_destroy(groups);
-        return NULL;
-    }
-
+    g_assert(g != NULL);
+    /* grab the keys that appeared in the Desktop Entry group */
     keys = obt_ddparse_group_keys(g);
 
-    lnk = g_slice_new(ObtLink);
-    lnk->ref = 1;
-    /* XXX turn the values in the .desktop file into an ObtLink */
+    /* build the ObtLink (we steal all strings from the parser) */
+    link = g_slice_new0(ObtLink);
+    link->ref = 1;
+    link->display = TRUE;
+
+    v = g_hash_table_lookup(keys, "Type");
+    g_assert(v);
+    link->type = v->value.enumerable;
+
+    if ((v = g_hash_table_lookup(keys, "Hidden")))
+        link->deleted = v->value.boolean;
+
+    if ((v = g_hash_table_lookup(keys, "NoDisplay")))
+        link->display = !v->value.boolean;
+
+    if ((v = g_hash_table_lookup(keys, "GenericName")))
+        link->generic = v->value.string, v->value.string = NULL;
+
+    if ((v = g_hash_table_lookup(keys, "Comment")))
+        link->comment = v->value.string, v->value.string = NULL;
+
+    if ((v = g_hash_table_lookup(keys, "Icon")))
+        link->icon = v->value.string, v->value.string = NULL;
+
+    if ((v = g_hash_table_lookup(keys, "OnlyShowIn")))
+        link->env_required = v->value.environments;
+    else
+        link->env_required = 0;
+
+    if ((v = g_hash_table_lookup(keys, "NotShowIn")))
+        link->env_restricted = v->value.environments;
+    else
+        link->env_restricted = 0;
+
+    /* type-specific keys */
+
+    if (link->type == OBT_LINK_TYPE_APPLICATION) {
+        gchar *c;
+        gboolean percent;
+
+        v = g_hash_table_lookup(keys, "Exec");
+        g_assert(v);
+        link->d.app.exec = v->value.string;
+        v->value.string = NULL;
+
+        /* parse link->d.app.exec to determine link->d.app.open */
+        percent = FALSE;
+        for (c = link->d.app.exec; *c; ++c) {
+            if (*c == '%') percent = !percent;
+            if (percent) {
+                switch (*c) {
+                case 'f': link->d.app.open = OBT_LINK_APP_SINGLE_LOCAL; break;
+                case 'F': link->d.app.open = OBT_LINK_APP_MULTI_LOCAL; break;
+                case 'u': link->d.app.open = OBT_LINK_APP_SINGLE_URL; break;
+                case 'U': link->d.app.open = OBT_LINK_APP_MULTI_URL; break;
+                }
+            }
+        }
+
+        if ((v = g_hash_table_lookup(keys, "TryExec"))) {
+            /* XXX spawn a thread to check TryExec? */
+            link->display = link->display &&
+                obt_paths_try_exec(p, v->value.string);
+        }
+
+        if ((v = g_hash_table_lookup(keys, "Path"))) {
+            /* steal the string */
+            link->d.app.wdir = v->value.string;
+            v->value.string = NULL;
+        }
+
+        if ((v = g_hash_table_lookup(keys, "Terminal")))
+            link->d.app.term = v->value.boolean;
+
+        if ((v = g_hash_table_lookup(keys, "StartupNotify")))
+            link->d.app.startup = v->value.boolean ?
+                OBT_LINK_APP_STARTUP_PROTOCOL_SUPPORT :
+                OBT_LINK_APP_STARTUP_NO_SUPPORT;
+        else {
+            link->d.app.startup = OBT_LINK_APP_STARTUP_LEGACY_SUPPORT;
+            if ((v = g_hash_table_lookup(keys, "StartupWMClass"))) {
+                /* steal the string */
+                link->d.app.startup_wmclass = v->value.string;
+                v->value.string = NULL;
+            }
+        }
+
+        /* XXX there's more app specific stuff */
+    }
+    else if (link->type == OBT_LINK_TYPE_URL) {
+        v = g_hash_table_lookup(keys, "URL");
+        g_assert(v);
+        link->d.url.addr = v->value.string;
+        v->value.string = NULL;
+    }
 
-    return lnk;
+    return link;
 }
 
 void obt_link_ref(ObtLink *dd)
This page took 0.023057 seconds and 4 git commands to generate.