]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Unity/X11: More dirty hacks to match executables to .desktop files.
authorVMware, Inc <>
Tue, 28 Jun 2011 19:53:24 +0000 (12:53 -0700)
committerMarcelo Vanzin <mvanzin@vmware.com>
Tue, 28 Jun 2011 19:53:24 +0000 (12:53 -0700)
Summary:
o Now recognizing "gnome-" prefix for .desktop entries.
o Matching Firefox and Thunderbird to mozilla-{firefox,thunderbird}.
o All pattern matching stuff is setup once in WindowPathFactory's constructor.

Details:
Unity/X11 wasn't returning icons for Firefox, Nautilus, and GNOME's calculator.
Turns out what RHEL packaged some GNOME apps with their .desktop files
including a gnome- prefix.  This is similar to the kde4- prefix we saw with
OpenSUSE.  The Mozilla apps were packaged with mozilla- prefixes.

This change tosses in a few hacks to accommodate.

Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/services/plugins/unity/unitylib/vmware/tools/unity/windowPathFactory.hh
open-vm-tools/services/plugins/unity/unitylib/windowPathFactory.cc

index 5bd7f2f45f2f7fe409c3e6b15add1499895836ad..016caf45548e34ade1b42bda706714caf8b57785 100644 (file)
@@ -55,6 +55,7 @@ public:
 private:
    typedef std::tr1::unordered_map<Glib::ustring, WindowPathPair,
                                    std::tr1::hash<std::string> > ExecMap;
+   typedef std::pair<Glib::RefPtr<Glib::Regex>, std::string> ExecPattern;
 
    Glib::ustring CanonicalizeAppName(const Glib::ustring& appName,
                                      const Glib::ustring& cwd);
@@ -67,6 +68,8 @@ private:
 
    Display* mDpy;
    ExecMap mExecMap;
+   std::vector<std::string> mEnvPrefixes;
+   std::vector<ExecPattern> mExecPatterns;
    Glib::RefPtr<Glib::Regex> mSkipPatterns;
 };
 
index b0eacc1283788b52fbac4932f56f960db2a2d38f..b439211e4a5399a96065e6ff44052bf14ad85ace 100644 (file)
@@ -74,6 +74,39 @@ namespace unity {
 WindowPathFactory::WindowPathFactory(Display* dpy)
    : mDpy(dpy)
 {
+   /*
+    * PR631378 - see
+    * http://standards.freedesktop.org/menu-spec/latest/ar01s04.html#menu-file-elements
+    *
+    * With OpenSUSE 11.2, apps under /usr/share/applications/kde4 are referred
+    * to as kde4-$app, not just $app.
+    */
+   mEnvPrefixes.push_back("");
+   mEnvPrefixes.push_back("gnome-");
+   mEnvPrefixes.push_back("kde4-");
+
+   /*
+    * There isn't always a direct correspondance between an application's executable's
+    * path and its .desktop file.  For example on Ubuntu 10.10 Mozilla Firefox has a
+    * firefox.desktop which launches "firefox".  However "firefox" is just a symlink to
+    * a wrapper around the actual Firefox executable, firefox-bin.  It's the latter
+    * which Unity/X11 will encounter and use as a starting point to find the app's
+    * .desktop file.
+    *
+    * Below are pairs of regular expressions and candidate application names.  If an
+    * executable name matches pair.first(), we'll check for a pair.second()+".desktop".
+    */
+   // XXX Keep this in an external file.
+#define WPFADDMATCH(pattern, target)       \
+   mExecPatterns.push_back(std::make_pair(Glib::Regex::create(pattern), target))
+   WPFADDMATCH("acroread$", "AdobeReader");
+   WPFADDMATCH("firefox(-bin|$)", "firefox");
+   WPFADDMATCH("firefox(-bin|$)", "mozilla-firefox");
+   WPFADDMATCH("thunderbird(-bin|$)", "thunderbird");
+   WPFADDMATCH("thunderbird(-bin|$)", "mozilla-thunderbird");
+   WPFADDMATCH("soffice", "openoffice.org-base");
+#undef WPFADDMATCH
+
    // XXX Keep this in an external file.
    mSkipPatterns = Glib::Regex::create("^(sh|bash)-?|(perl|python)(-|\\d|$)");
 }
@@ -262,62 +295,35 @@ WindowPathFactory::FindByArgv(const Glib::ustring& cwd,        // IN
     */
 
    Glib::ustring testString = Glib::path_get_basename(*arg);
-   bool guessed = false;
 
-   /*
-    * PR631378 - see
-    * http://standards.freedesktop.org/menu-spec/latest/ar01s04.html#menu-file-elements
-    *
-    * With OpenSUSE 11.2, apps under /usr/share/applications/kde4 are referred
-    * to as kde4-$app, not just $app.
-    *
-    * XXX Prefixes should be discovered at runtime when analyzing .menu files.
-    */
-   std::vector<std::string> prefixes;
-   prefixes.push_back("");
-   prefixes.push_back("kde4-");
-
-tryagain:
-   for (std::vector<std::string>::iterator i = prefixes.begin();
-        i != prefixes.end();
-        ++i) {
-
-      /* Try for a DesktopAppInfo identified by arg. */
-      Glib::ustring desktopId = Glib::ustring::compose("%1%2.desktop", *i, testString);
-      Glib::RefPtr<Gio::DesktopAppInfo> desktopApp =
-         Gio::DesktopAppInfo::create(desktopId);
-      if (desktopApp) {
-         GDesktopAppInfo* gobj = desktopApp->gobj();
-         pathPair.second = g_desktop_app_info_get_filename(gobj);
-         mExecMap[*arg] = pathPair;
-         return true;
+   std::vector<std::string> candidates;
+   candidates.push_back(testString);
+
+   for (std::vector<ExecPattern>::iterator pattern = mExecPatterns.begin();
+        pattern != mExecPatterns.end();
+        ++pattern) {
+      if (pattern->first->match(testString)) {
+         candidates.push_back(pattern->second);
       }
    }
 
-   /* Attempt #2: Get our static map on. */
-   if (!guessed) {
-      static struct {
-         const gchar *pattern;
-         const gchar *exec;
-      } fudgePatterns[] = {
-         /*
-          * XXX Worth compiling once?  Consider placing in an external filter
-          * file to allow users to update it themselves easily.
-          */
-         { "*acroread", "AdobeReader" },
-         { "*firefox*-bin", "firefox" },
-         { "*thunderbird*-bin", "thunderbird" },
-         { "*soffice*", "openoffice.org-base" }
-      };
-      unsigned int i;
-
-      guessed = true;
-
-      for (i = 0; i < ARRAYSIZE(fudgePatterns); i++) {
-         if (g_pattern_match_simple(fudgePatterns[i].pattern,
-                                    testString.c_str())) {
-            testString = fudgePatterns[i].exec;
-            goto tryagain;
+   for (std::vector<std::string>::iterator candidate = candidates.begin();
+        candidate != candidates.end();
+        ++candidate)
+   {
+      for (std::vector<std::string>::iterator i = mEnvPrefixes.begin();
+           i != mEnvPrefixes.end();
+           ++i) {
+         /* Try for a DesktopAppInfo identified by arg. */
+         Glib::ustring desktopId =
+            Glib::ustring::compose("%1%2.desktop", *i, *candidate);
+         Glib::RefPtr<Gio::DesktopAppInfo> desktopApp =
+            Gio::DesktopAppInfo::create(desktopId);
+         if (desktopApp) {
+            GDesktopAppInfo* gobj = desktopApp->gobj();
+            pathPair.second = g_desktop_app_info_get_filename(gobj);
+            mExecMap[*arg] = pathPair;
+            return true;
          }
       }
    }