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|$)");
}
*/
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;
}
}
}