Extend XDG_DATA_DIRS to include Quassel-specific directories
authorManuel Nickschas <sputnick@quassel-irc.org>
Sat, 25 Oct 2014 14:01:30 +0000 (16:01 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sat, 25 Oct 2014 21:16:33 +0000 (23:16 +0200)
XDG_DATA_DIRS is used for example by Qt to find icon themes and other
application data. In order to avoid having to hack our own locations into
various places, we extend the variable at runtime to include them instead.

This is only relevant if KDE integration is not enabled; otherwise KDE will
specify a list of data dirs (this means that Quassel needs to be installed
properly for everything to work as expected if KDE integration is enabled).

src/common/quassel.cpp
src/common/quassel.h

index 7a8c75d..8928193 100644 (file)
@@ -112,6 +112,7 @@ bool Quassel::init()
     _initialized = true;
     qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
 
+    setupEnvironment();
     registerMetaTypes();
 
     Network::setDefaultCodecForServer("ISO-8859-1");
@@ -211,6 +212,37 @@ void Quassel::registerMetaTypes()
 }
 
 
+void Quassel::setupEnvironment()
+{
+    // On modern Linux systems, XDG_DATA_DIRS contains a list of directories containing application data. This
+    // is, for example, used by Qt for finding icons and other things. In case Quassel is installed in a non-standard
+    // prefix (or run from the build directory), it makes sense to add this to XDG_DATA_DIRS so we don't have to
+    // hack extra search paths into various places.
+#ifdef Q_OS_UNIX
+    QString xdgDataVar = QFile::decodeName(qgetenv("XDG_DATA_DIRS"));
+    if (xdgDataVar.isEmpty())
+        xdgDataVar = QLatin1String("/usr/local/share:/usr/share"); // sane defaults
+
+    QStringList xdgDirs = xdgDataVar.split(QLatin1Char(':'), QString::SkipEmptyParts);
+
+    // Add our install prefix (if we're not in a bindir, this just adds the current workdir)
+    QString appDir = QCoreApplication::applicationDirPath();
+    int binpos = appDir.lastIndexOf("/bin");
+    if (binpos >= 0) {
+        appDir.replace(binpos, 4, "/share");
+        xdgDirs.append(appDir);
+        // Also append apps/quassel, this is only for QIconLoader to find icons there
+        xdgDirs.append(appDir + "/apps/quassel");
+    } else
+        xdgDirs.append(appDir);  // build directory is always the last fallback
+
+    xdgDirs.removeDuplicates();
+
+    qputenv("XDG_DATA_DIRS", QFile::encodeName(xdgDirs.join(":")));
+#endif
+}
+
+
 void Quassel::setupBuildInfo()
 {
     _buildInfo.applicationName = "quassel";
index b141f32..034c560 100644 (file)
@@ -148,6 +148,7 @@ protected:
     inline void disableCrashhandler();
 
 private:
+    void setupEnvironment();
     void registerMetaTypes();
 
     static void handleSignal(int signal);