1/********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>.
19*********************************************************************/
20
21// own
22#include "dbusinterface.h"
23
24// kwin
25// TODO: remove together with deprecated methods
26#include "client.h"
27#include "composite.h"
28#include "decorations.h"
29#include "effects.h"
30#include "kwinadaptor.h"
31#include "workspace.h"
32#include "virtualdesktops.h"
33#ifdef KWIN_BUILD_ACTIVITIES
34#include "activities.h"
35#endif
36
37// Qt
38#include <QDBusServiceWatcher>
39
40namespace KWin
41{
42
43DBusInterface::DBusInterface(QObject *parent)
44 : QObject(parent)
45{
46 (void) new KWinAdaptor(this);
47
48 QDBusConnection dbus = QDBusConnection::sessionBus();
49 dbus.registerObject("/KWin", this);
50 if (!dbus.registerService("org.kde.KWin")) {
51 QDBusServiceWatcher *dog = new QDBusServiceWatcher("org.kde.KWin", dbus, QDBusServiceWatcher::WatchForUnregistration, this);
52 connect (dog, SIGNAL(serviceUnregistered(QString)), SLOT(becomeKWinService(QString)));
53 }
54 connect(Compositor::self(), SIGNAL(compositingToggled(bool)), SIGNAL(compositingToggled(bool)));
55 dbus.connect(QString(), "/KWin", "org.kde.KWin", "reloadConfig",
56 Workspace::self(), SLOT(slotReloadConfig()));
57 dbus.connect(QString(), "/KWin", "org.kde.KWin", "reinitCompositing",
58 Compositor::self(), SLOT(slotReinitialize()));
59}
60
61void DBusInterface::becomeKWinService(const QString &service)
62{
63 // TODO: this watchdog exists to make really safe that we at some point get the service
64 // but it's probably no longer needed since we explicitly unregister the service with the deconstructor
65 if (service == "org.kde.KWin" && QDBusConnection::sessionBus().registerService("org.kde.KWin") && sender()) {
66 sender()->deleteLater(); // bye doggy :'(
67 }
68}
69
70DBusInterface::~DBusInterface()
71{
72 QDBusConnection::sessionBus().unregisterService("org.kde.KWin"); // this is the long standing legal service
73 // KApplication automatically also grabs org.kde.kwin, so it's often been used externally - ensure to free it as well
74 QDBusConnection::sessionBus().unregisterService("org.kde.kwin");
75}
76
77void DBusInterface::circulateDesktopApplications()
78{
79 Workspace *ws = Workspace::self();
80 const uint desktop = VirtualDesktopManager::self()->current();
81 const QList<Client*> &desktops = ws->desktopList();
82 if (desktops.count() > 1) {
83 bool change_active = ws->activeClient()->isDesktop();
84 ws->raiseClient(ws->findDesktop(false, desktop));
85 if (change_active) // if the previously topmost Desktop was active, activate this new one
86 ws->activateClient(ws->findDesktop(true, desktop));
87 }
88 // if there's no active client, make desktop the active one
89 if (desktops.count() > 0 && ws->activeClient() == NULL && ws->mostRecentlyActivatedClient() == NULL)
90 ws->activateClient(ws->findDesktop(true, desktop));
91}
92
93// wrap void methods with no arguments to Workspace
94#define WRAP(name) \
95void DBusInterface::name() \
96{\
97 Workspace::self()->name();\
98}
99
100WRAP(reconfigure)
101
102#undef WRAP
103
104void DBusInterface::killWindow()
105{
106 Workspace::self()->slotKillWindow();
107}
108
109#define WRAP(name) \
110void DBusInterface::name() \
111{\
112 Placement::self()->name();\
113}
114
115WRAP(cascadeDesktop)
116WRAP(unclutterDesktop)
117
118#undef WRAP
119
120// wrap returning methods with no arguments to Workspace
121#define WRAP( rettype, name ) \
122rettype DBusInterface::name( ) \
123{\
124 return Workspace::self()->name(); \
125}
126
127WRAP(QString, supportInformation)
128WRAP(bool, waitForCompositingSetup)
129
130#undef WRAP
131
132bool DBusInterface::startActivity(const QString &in0)
133{
134#ifdef KWIN_BUILD_ACTIVITIES
135 return Activities::self()->start(in0);
136#else
137 return false;
138#endif
139}
140
141bool DBusInterface::stopActivity(const QString &in0)
142{
143#ifdef KWIN_BUILD_ACTIVITIES
144 return Activities::self()->stop(in0);
145#else
146 return false;
147#endif
148}
149
150void DBusInterface::doNotManage(const QString &name)
151{
152 Q_UNUSED(name)
153}
154
155void DBusInterface::showWindowMenuAt(qlonglong winId, int x, int y)
156{
157 Q_UNUSED(winId)
158 Q_UNUSED(x)
159 Q_UNUSED(y)
160 Workspace::self()->slotWindowOperations();
161}
162
163// wrap returning methods with no arguments to COMPOSITOR
164#define WRAP( rettype, name ) \
165rettype DBusInterface::name( ) \
166{\
167 return Compositor::self()->name(); \
168}
169
170WRAP(QString, compositingNotPossibleReason)
171WRAP(QString, compositingType)
172
173#undef WRAP
174
175bool DBusInterface::compositingPossible()
176{
177 return Compositor::self()->isCompositingPossible();
178}
179
180bool DBusInterface::openGLIsBroken()
181{
182 return Compositor::self()->isOpenGLBroken();
183}
184
185bool DBusInterface::compositingActive()
186{
187 return Compositor::self()->isActive();
188}
189
190void DBusInterface::toggleCompositing()
191{
192 Compositor::self()->toggleCompositing();
193}
194
195// wrap returning QStringList methods with no argument to EffectsHandlerImpl
196#define WRAP( name ) \
197QStringList DBusInterface::name( ) \
198{\
199 if (effects) { \
200 return static_cast< EffectsHandlerImpl* >(effects)->name(); \
201 } \
202 return QStringList(); \
203}
204
205WRAP(activeEffects)
206WRAP(listOfEffects)
207WRAP(loadedEffects)
208
209#undef WRAP
210
211// wrap void methods with one argument to EffectsHandlerImpl
212#define WRAP( name, argtype ) \
213void DBusInterface::name( argtype arg ) \
214{\
215 if (effects) { \
216 static_cast< EffectsHandlerImpl* >(effects)->name(arg); \
217 } \
218}
219
220WRAP(loadEffect, const QString &)
221WRAP(reconfigureEffect, const QString &)
222WRAP(toggleEffect, const QString &)
223WRAP(unloadEffect, const QString &)
224
225#undef WRAP
226
227QString DBusInterface::supportInformationForEffect(const QString &name)
228{
229 if (effects) {
230 static_cast< EffectsHandlerImpl* >(effects)->supportInformation(name);
231 }
232 return QString();
233}
234
235int DBusInterface::currentDesktop()
236{
237 return VirtualDesktopManager::self()->current();
238}
239
240bool DBusInterface::setCurrentDesktop(int desktop)
241{
242 return VirtualDesktopManager::self()->setCurrent(desktop);
243}
244
245void DBusInterface::nextDesktop()
246{
247 VirtualDesktopManager::self()->moveTo<DesktopNext>();
248}
249
250void DBusInterface::previousDesktop()
251{
252 VirtualDesktopManager::self()->moveTo<DesktopPrevious>();
253}
254
255QList< int > DBusInterface::decorationSupportedColors()
256{
257 return decorationPlugin()->supportedColors();
258}
259
260} // namespace
261