1 #include <QObject>
2 #include <QProcess>
3 #include <QApplication>
4 #include <QDir>
5 #include "unify.h"
6 
7 // Platform includes
8 #if defined(Q_OS_WIN)
9 #include "devicemanager_win.h"
10 #include "screensaver_win.h"
11 #elif defined(Q_OS_MAC)
12 #include "devicemanager_mac.h"
13 #include "screensaver_mac.h"
14 #else
15 #include <dlfcn.h>
16 #include "devicemanager_unix.h"
17 #include "screensaver_unix.h"
18 #endif
19 
20 
21 // Platform defines
22 #if defined(Q_OS_WIN)
23     #define ScreenSaverPlatform     ScreenSaverWin
24     #define DeviceManagerPlatform   DeviceManagerWin
25 #elif defined(Q_OS_MAC)
26     #define ScreenSaverPlatform     ScreenSaverMac
27     #define DeviceManagerPlatform   DeviceManagerMac
28 #else
29     #define ScreenSaverPlatform     ScreenSaverUnix
30     #define DeviceManagerPlatform   DeviceManagerUnix
31 #endif
32 
33 
34 // Platform flags
35 const bool Platform::isMac =
36 #if defined(Q_OS_MAC)
37     true
38 #else
39     false
40 #endif
41 ;
42 
43 const bool Platform::isWindows =
44 #if defined(Q_OS_WIN)
45     true
46 #else
47     false
48 #endif
49 ;
50 
51 const bool Platform::isUnix =
52 #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
53     true
54 #else
55     false
56 #endif
57 ;
58 
59 
deviceManager()60 DeviceManager *Platform::deviceManager()
61 {
62     static DeviceManagerPlatform *dm = nullptr;
63     if (dm == nullptr) {
64         Q_ASSERT(qApp);
65         dm = new DeviceManagerPlatform(qApp);
66         QObject::connect(dm, &DeviceManager::destroyed, [&] {
67             dm = nullptr;
68         });
69     }
70     return dm;
71 }
72 
screenSaver()73 ScreenSaver *Platform::screenSaver()
74 {
75     static ScreenSaverPlatform *ss = nullptr;
76     if (ss == nullptr) {
77         Q_ASSERT(qApp);
78         ss = new ScreenSaverPlatform(qApp);
79         QObject::connect(ss, &ScreenSaver::destroyed, [&] {
80             ss = nullptr;
81         });
82     }
83     return ss;
84 }
85 
resourcesPath()86 QString Platform::resourcesPath()
87 {
88     if (Platform::isMac)
89         return QApplication::applicationDirPath() + "/../Resources";
90     if (Platform::isWindows)
91         return QApplication::applicationDirPath();
92     if (Platform::isUnix) {
93 #ifdef MPCQT_PREFIX
94         return MPCQT_PREFIX "/share/mpc-qt";
95 #endif
96     }
97     return ".";
98 }
99 
fixedConfigPath(QString configPath)100 QString Platform::fixedConfigPath(QString configPath)
101 {
102     if (isWindows) {
103         // backward compatability sucks
104         configPath.replace("AppData/Local","AppData/Roaming");
105     }
106     return configPath;
107 }
108 
sanitizedFilename(QString fileName)109 QString Platform::sanitizedFilename(QString fileName)
110 {
111     if (isWindows)
112         fileName.replace(':', '.');
113     return fileName;
114 }
115 
tiledDesktopsExist()116 bool Platform::tiledDesktopsExist()
117 {
118     return isUnix;
119 }
120 
tilingDesktopActive()121 bool Platform::tilingDesktopActive()
122 {
123     if (!isUnix)
124         return false;
125 
126     QProcessEnvironment env;
127     QStringList tilers({ "awesome", "bspwm", "dwm", "i3", "larswm", "ion",
128         "qtile", "ratpoison", "stumpwm", "wmii", "xmonad"});
129     QString desktop = env.value("XDG_SESSION_DESKTOP", "=");
130     if (tilers.contains(desktop))
131         return true;
132     desktop = env.value("XDG_DATA_DIRS", "=");
133     for (QString &wm : tilers)
134         if (desktop.contains(wm))
135             return true;
136     for (QString &wm: tilers) {
137         QProcess process;
138         process.start("pgrep", QStringList({"-x", wm}));
139         process.waitForFinished();
140         if (!process.readAllStandardOutput().isEmpty())
141             return true;
142     }
143     return false;
144 }
145 
disableAutomaticAccel(QWidget * what)146 void Platform::disableAutomaticAccel(QWidget *what)
147 {
148 #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
149     static auto symbol = "_ZN19KAcceleratorManager10setNoAccelEP7QWidget";
150 
151     void *d = dlopen("libKF5WidgetsAddons.so", RTLD_LAZY);
152     if (!d)
153         return;
154     typedef void (*DisablerFunc)(QWidget *);
155     DisablerFunc setNoAccel;
156     setNoAccel = reinterpret_cast<DisablerFunc>(dlsym(d, symbol));
157     if (setNoAccel)
158         setNoAccel(what);
159     dlclose(d);
160 #else
161     Q_UNUSED(what);
162 #endif
163 }
164