1 /* This file is part of Clementine.
2    Copyright 2011, David Sansome <me@davidsansome.com>
3    Copyright 2014, Krzysztof Sobiecki <sobkas@gmail.com>
4    Copyright 2014, John Maguire <john.maguire@gmail.com>
5 
6    Clementine is free software: you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation, either version 3 of the License, or
9    (at your option) any later version.
10 
11    Clementine is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with Clementine.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "ubuntuunityhack.h"
21 #include "core/logging.h"
22 
23 #include <QFile>
24 #include <QProcess>
25 
26 const char* UbuntuUnityHack::kGSettingsFileName = "gsettings";
27 const char* UbuntuUnityHack::kUnityPanel = "com.canonical.Unity.Panel";
28 const char* UbuntuUnityHack::kUnitySystrayWhitelist = "systray-whitelist";
29 
UbuntuUnityHack(QObject * parent)30 UbuntuUnityHack::UbuntuUnityHack(QObject* parent) : QObject(parent) {
31   // Check if we're on Ubuntu first.
32   QFile lsb_release("/etc/lsb-release");
33   if (lsb_release.open(QIODevice::ReadOnly)) {
34     QByteArray data = lsb_release.readAll();
35     if (!data.contains("DISTRIB_ID=Ubuntu")) {
36       // It's not Ubuntu - don't do anything.
37       return;
38     }
39   }
40 
41   // Get the systray whitelist from gsettings.  If this fails we're probably
42   // not running on a system with unity
43   QProcess* get = new QProcess(this);
44   connect(get, SIGNAL(finished(int)), SLOT(GetFinished(int)));
45   connect(get, SIGNAL(error(QProcess::ProcessError)), SLOT(GetError()));
46   get->start(kGSettingsFileName, QStringList() << "get" << kUnityPanel
47                                                << kUnitySystrayWhitelist);
48 }
49 
GetError()50 void UbuntuUnityHack::GetError() {
51   QProcess* get = qobject_cast<QProcess*>(sender());
52   if (!get) {
53     return;
54   }
55 
56   get->deleteLater();
57 }
58 
GetFinished(int exit_code)59 void UbuntuUnityHack::GetFinished(int exit_code) {
60   QProcess* get = qobject_cast<QProcess*>(sender());
61   if (!get) {
62     return;
63   }
64 
65   get->deleteLater();
66 
67   if (exit_code != 0) {
68     // Probably not running in Unity.
69     return;
70   }
71 
72   QByteArray whitelist = get->readAllStandardOutput();
73 
74   qLog(Debug) << "Unity whitelist is" << whitelist;
75 
76   int index = whitelist.lastIndexOf(']');
77   if (index == -1 || whitelist.contains("'clementine'")) {
78     return;
79   }
80 
81   whitelist = whitelist.left(index) + QString(", 'clementine'").toUtf8() +
82               whitelist.mid(index);
83 
84   qLog(Debug) << "Setting unity whitelist to" << whitelist;
85 
86   QProcess* set = new QProcess(this);
87   connect(set, SIGNAL(finished(int)), set, SLOT(deleteLater()));
88   set->start(kGSettingsFileName, QStringList() << "set" << kUnityPanel
89                                                << kUnitySystrayWhitelist
90                                                << whitelist);
91 
92   qLog(Info) << "Clementine has added itself to the Unity system tray"
93              << "whitelist, but this won't take effect until the next time"
94              << "you log out and log back in.";
95 }
96