1/********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
6Copyright (C) 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program. If not, see <http://www.gnu.org/licenses/>.
20*********************************************************************/
21
22#ifndef KWIN_EFFECTSIMPL_H
23#define KWIN_EFFECTSIMPL_H
24
25#include "kwineffects.h"
26
27#include "scene.h"
28#include "xcbutils.h"
29
30#include <QStack>
31#include <QHash>
32#include <Plasma/FrameSvg>
33
34class QDBusPendingCallWatcher;
35class QDBusServiceWatcher;
36class KService;
37class OrgFreedesktopScreenSaverInterface;
38
39
40namespace KWin
41{
42
43class AbstractThumbnailItem;
44class DesktopThumbnailItem;
45class WindowThumbnailItem;
46
47class Client;
48class Compositor;
49class Deleted;
50class Unmanaged;
51class ScreenLockerWatcher;
52
53class EffectsHandlerImpl : public EffectsHandler
54{
55 Q_OBJECT
56 Q_CLASSINFO("D-Bus Interface", "org.kde.kwin.Effects")
57 Q_PROPERTY(QStringList activeEffects READ activeEffects)
58 Q_PROPERTY(QStringList loadedEffects READ loadedEffects)
59 Q_PROPERTY(QStringList listOfEffects READ listOfEffects)
60public:
61 EffectsHandlerImpl(Compositor *compositor, Scene *scene);
62 virtual ~EffectsHandlerImpl();
63 virtual void prePaintScreen(ScreenPrePaintData& data, int time);
64 virtual void paintScreen(int mask, QRegion region, ScreenPaintData& data);
65 /**
66 * Special hook to perform a paintScreen but just with the windows on @p desktop.
67 **/
68 void paintDesktop(int desktop, int mask, QRegion region, ScreenPaintData& data);
69 virtual void postPaintScreen();
70 virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time);
71 virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
72 virtual void postPaintWindow(EffectWindow* w);
73 virtual void paintEffectFrame(EffectFrame* frame, QRegion region, double opacity, double frameOpacity);
74
75 Effect *provides(Effect::Feature ef);
76
77 virtual void drawWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
78
79 virtual void buildQuads(EffectWindow* w, WindowQuadList& quadList);
80
81 virtual void activateWindow(EffectWindow* c);
82 virtual EffectWindow* activeWindow() const;
83 virtual void moveWindow(EffectWindow* w, const QPoint& pos, bool snap = false, double snapAdjust = 1.0);
84 virtual void windowToDesktop(EffectWindow* w, int desktop);
85 virtual void windowToScreen(EffectWindow* w, int screen);
86 virtual void setShowingDesktop(bool showing);
87
88 virtual QString currentActivity() const;
89 virtual int currentDesktop() const;
90 virtual int numberOfDesktops() const;
91 virtual void setCurrentDesktop(int desktop);
92 virtual void setNumberOfDesktops(int desktops);
93 virtual QSize desktopGridSize() const;
94 virtual int desktopGridWidth() const;
95 virtual int desktopGridHeight() const;
96 virtual int workspaceWidth() const;
97 virtual int workspaceHeight() const;
98 virtual int desktopAtCoords(QPoint coords) const;
99 virtual QPoint desktopGridCoords(int id) const;
100 virtual QPoint desktopCoords(int id) const;
101 virtual int desktopAbove(int desktop = 0, bool wrap = true) const;
102 virtual int desktopToRight(int desktop = 0, bool wrap = true) const;
103 virtual int desktopBelow(int desktop = 0, bool wrap = true) const;
104 virtual int desktopToLeft(int desktop = 0, bool wrap = true) const;
105 virtual QString desktopName(int desktop) const;
106 virtual bool optionRollOverDesktops() const;
107
108 virtual int displayWidth() const;
109 virtual int displayHeight() const;
110 virtual QPoint cursorPos() const;
111 virtual bool grabKeyboard(Effect* effect);
112 virtual void ungrabKeyboard();
113 // not performing XGrabPointer
114 virtual void startMouseInterception(Effect *effect, Qt::CursorShape shape);
115 virtual void stopMouseInterception(Effect *effect);
116 virtual void* getProxy(QString name);
117 virtual void startMousePolling();
118 virtual void stopMousePolling();
119 virtual EffectWindow* findWindow(WId id) const;
120 virtual EffectWindowList stackingOrder() const;
121 virtual void setElevatedWindow(EffectWindow* w, bool set);
122
123 virtual void setTabBoxWindow(EffectWindow*);
124 virtual void setTabBoxDesktop(int);
125 virtual EffectWindowList currentTabBoxWindowList() const;
126 virtual void refTabBox();
127 virtual void unrefTabBox();
128 virtual void closeTabBox();
129 virtual QList< int > currentTabBoxDesktopList() const;
130 virtual int currentTabBoxDesktop() const;
131 virtual EffectWindow* currentTabBoxWindow() const;
132
133 virtual void setActiveFullScreenEffect(Effect* e);
134 virtual Effect* activeFullScreenEffect() const;
135
136 virtual void addRepaintFull();
137 virtual void addRepaint(const QRect& r);
138 virtual void addRepaint(const QRegion& r);
139 virtual void addRepaint(int x, int y, int w, int h);
140 virtual int activeScreen() const;
141 virtual int numScreens() const;
142 virtual int screenNumber(const QPoint& pos) const;
143 virtual QRect clientArea(clientAreaOption, int screen, int desktop) const;
144 virtual QRect clientArea(clientAreaOption, const EffectWindow* c) const;
145 virtual QRect clientArea(clientAreaOption, const QPoint& p, int desktop) const;
146 virtual double animationTimeFactor() const;
147 virtual WindowQuadType newWindowQuadType();
148
149 virtual void defineCursor(Qt::CursorShape shape);
150 virtual bool checkInputWindowEvent(XEvent* e);
151 virtual void checkInputWindowStacking();
152
153 virtual void reserveElectricBorder(ElectricBorder border, Effect *effect);
154 virtual void unreserveElectricBorder(ElectricBorder border, Effect *effect);
155
156 virtual unsigned long xrenderBufferPicture();
157 virtual void reconfigure();
158 virtual void registerPropertyType(long atom, bool reg);
159 virtual QByteArray readRootProperty(long atom, long type, int format) const;
160 virtual void deleteRootProperty(long atom) const;
161 virtual xcb_atom_t announceSupportProperty(const QByteArray& propertyName, Effect* effect);
162 virtual void removeSupportProperty(const QByteArray& propertyName, Effect* effect);
163
164 virtual bool hasDecorationShadows() const;
165
166 virtual bool decorationsHaveAlpha() const;
167
168 virtual bool decorationSupportsBlurBehind() const;
169
170 virtual EffectFrame* effectFrame(EffectFrameStyle style, bool staticSize, const QPoint& position, Qt::Alignment alignment) const;
171
172 virtual QVariant kwinOption(KWinOption kwopt);
173 virtual bool isScreenLocked() const;
174
175 // internal (used by kwin core or compositing code)
176 void startPaint();
177 void grabbedKeyboardEvent(QKeyEvent* e);
178 bool hasKeyboardGrab() const;
179 void desktopResized(const QSize &size);
180
181 virtual void reloadEffect(Effect *effect);
182 QStringList loadedEffects() const;
183 QStringList listOfEffects() const;
184
185 QList<EffectWindow*> elevatedWindows() const;
186 QStringList activeEffects() const;
187
188 /**
189 * @returns Whether we are currently in a desktop rendering process triggered by paintDesktop hook
190 **/
191 bool isDesktopRendering() const {
192 return m_desktopRendering;
193 }
194 /**
195 * @returns the desktop currently being rendered in the paintDesktop hook.
196 **/
197 int currentRenderedDesktop() const {
198 return m_currentRenderedDesktop;
199 }
200
201public Q_SLOTS:
202 void slotCurrentTabAboutToChange(EffectWindow* from, EffectWindow* to);
203 void slotTabAdded(EffectWindow* from, EffectWindow* to);
204 void slotTabRemoved(EffectWindow* c, EffectWindow* newActiveWindow);
205
206 // slots for D-Bus interface
207 Q_SCRIPTABLE void reconfigureEffect(const QString& name);
208 Q_SCRIPTABLE bool loadEffect(const QString& name, bool checkDefault = false);
209 Q_SCRIPTABLE void toggleEffect(const QString& name);
210 Q_SCRIPTABLE void unloadEffect(const QString& name);
211 Q_SCRIPTABLE bool isEffectLoaded(const QString& name) const;
212 Q_SCRIPTABLE QString supportInformation(const QString& name) const;
213 Q_SCRIPTABLE QString debug(const QString& name, const QString& parameter = QString()) const;
214
215protected Q_SLOTS:
216 void slotDesktopChanged(int old, KWin::Client *withClient);
217 void slotDesktopPresenceChanged(KWin::Client *c, int old);
218 void slotClientAdded(KWin::Client *c);
219 void slotClientShown(KWin::Toplevel*);
220 void slotUnmanagedAdded(KWin::Unmanaged *u);
221 void slotUnmanagedShown(KWin::Toplevel*);
222 void slotWindowClosed(KWin::Toplevel *c);
223 void slotClientActivated(KWin::Client *c);
224 void slotDeletedRemoved(KWin::Deleted *d);
225 void slotClientMaximized(KWin::Client *c, KDecorationDefines::MaximizeMode maxMode);
226 void slotClientStartUserMovedResized(KWin::Client *c);
227 void slotClientStepUserMovedResized(KWin::Client *c, const QRect &geometry);
228 void slotClientFinishUserMovedResized(KWin::Client *c);
229 void slotOpacityChanged(KWin::Toplevel *t, qreal oldOpacity);
230 void slotClientMinimized(KWin::Client *c, bool animate);
231 void slotClientUnminimized(KWin::Client *c, bool animate);
232 void slotClientModalityChanged();
233 void slotGeometryShapeChanged(KWin::Toplevel *t, const QRect &old);
234 void slotPaddingChanged(KWin::Toplevel *t, const QRect &old);
235 void slotWindowDamaged(KWin::Toplevel *t, const QRect& r);
236 void slotPropertyNotify(KWin::Toplevel *t, long atom);
237 void slotPropertyNotify(long atom);
238
239protected:
240 bool loadScriptedEffect(const QString &name, KService *service);
241 KLibrary* findEffectLibrary(KService* service);
242 void effectsChanged();
243 void setupClientConnections(KWin::Client *c);
244 void setupUnmanagedConnections(KWin::Unmanaged *u);
245
246 Effect* keyboard_grab_effect;
247 Effect* fullscreen_effect;
248 QList<EffectWindow*> elevated_windows;
249 QMultiMap< int, EffectPair > effect_order;
250 QHash< long, int > registered_atoms;
251 int next_window_quad_type;
252
253private Q_SLOTS:
254 void slotEffectsQueried();
255
256private:
257 typedef QVector< Effect*> EffectsList;
258 typedef EffectsList::const_iterator EffectsIterator;
259 EffectsList m_activeEffects;
260 EffectsIterator m_currentDrawWindowIterator;
261 EffectsIterator m_currentPaintWindowIterator;
262 EffectsIterator m_currentPaintEffectFrameIterator;
263 EffectsIterator m_currentPaintScreenIterator;
264 EffectsIterator m_currentBuildQuadsIterator;
265 typedef QHash< QByteArray, QList< Effect*> > PropertyEffectMap;
266 PropertyEffectMap m_propertiesForEffects;
267 QHash<QByteArray, qulonglong> m_managedProperties;
268 Compositor *m_compositor;
269 Scene *m_scene;
270 ScreenLockerWatcher *m_screenLockerWatcher;
271 bool m_desktopRendering;
272 int m_currentRenderedDesktop;
273 Xcb::Window m_mouseInterceptionWindow;
274 QList<Effect*> m_grabbedMouseEffects;
275};
276
277class EffectWindowImpl : public EffectWindow
278{
279 Q_OBJECT
280public:
281 explicit EffectWindowImpl(Toplevel *toplevel);
282 virtual ~EffectWindowImpl();
283
284 virtual void enablePainting(int reason);
285 virtual void disablePainting(int reason);
286 virtual bool isPaintingEnabled();
287
288 virtual void refWindow();
289 virtual void unrefWindow();
290
291 virtual const EffectWindowGroup* group() const;
292
293 virtual QRegion shape() const;
294 virtual QRect decorationInnerRect() const;
295 virtual QByteArray readProperty(long atom, long type, int format) const;
296 virtual void deleteProperty(long atom) const;
297
298 virtual EffectWindow* findModal();
299 virtual EffectWindowList mainWindows() const;
300
301 virtual WindowQuadList buildQuads(bool force = false) const;
302
303 virtual void referencePreviousWindowPixmap();
304 virtual void unreferencePreviousWindowPixmap();
305
306 const Toplevel* window() const;
307 Toplevel* window();
308
309 void setWindow(Toplevel* w); // internal
310 void setSceneWindow(Scene::Window* w); // internal
311 const Scene::Window* sceneWindow() const; // internal
312 Scene::Window* sceneWindow(); // internal
313
314 void elevate(bool elevate);
315
316 void setData(int role, const QVariant &data);
317 QVariant data(int role) const;
318
319 void registerThumbnail(AbstractThumbnailItem *item);
320 QHash<WindowThumbnailItem*, QWeakPointer<EffectWindowImpl> > const &thumbnails() const {
321 return m_thumbnails;
322 }
323 QList<DesktopThumbnailItem*> const &desktopThumbnails() const {
324 return m_desktopThumbnails;
325 }
326private Q_SLOTS:
327 void thumbnailDestroyed(QObject *object);
328 void thumbnailTargetChanged();
329 void desktopThumbnailDestroyed(QObject *object);
330private:
331 void insertThumbnail(WindowThumbnailItem *item);
332 Toplevel* toplevel;
333 Scene::Window* sw; // This one is used only during paint pass.
334 QHash<int, QVariant> dataMap;
335 QHash<WindowThumbnailItem*, QWeakPointer<EffectWindowImpl> > m_thumbnails;
336 QList<DesktopThumbnailItem*> m_desktopThumbnails;
337};
338
339class EffectWindowGroupImpl
340 : public EffectWindowGroup
341{
342public:
343 explicit EffectWindowGroupImpl(Group* g);
344 virtual EffectWindowList members() const;
345private:
346 Group* group;
347};
348
349class EffectFrameImpl
350 : public QObject, public EffectFrame
351{
352 Q_OBJECT
353public:
354 explicit EffectFrameImpl(EffectFrameStyle style, bool staticSize = true, QPoint position = QPoint(-1, -1),
355 Qt::Alignment alignment = Qt::AlignCenter);
356 virtual ~EffectFrameImpl();
357
358 virtual void free();
359 virtual void render(QRegion region = infiniteRegion(), double opacity = 1.0, double frameOpacity = 1.0);
360 virtual Qt::Alignment alignment() const;
361 virtual void setAlignment(Qt::Alignment alignment);
362 virtual const QFont& font() const;
363 virtual void setFont(const QFont& font);
364 virtual const QRect& geometry() const;
365 virtual void setGeometry(const QRect& geometry, bool force = false);
366 virtual const QPixmap& icon() const;
367 virtual void setIcon(const QPixmap& icon);
368 virtual const QSize& iconSize() const;
369 virtual void setIconSize(const QSize& size);
370 virtual void setPosition(const QPoint& point);
371 virtual const QString& text() const;
372 virtual void setText(const QString& text);
373 virtual EffectFrameStyle style() const {
374 return m_style;
375 };
376 Plasma::FrameSvg& frame() {
377 return m_frame;
378 }
379 bool isStatic() const {
380 return m_static;
381 };
382 void finalRender(QRegion region, double opacity, double frameOpacity) const;
383 virtual void setShader(GLShader* shader) {
384 m_shader = shader;
385 }
386 virtual GLShader* shader() const {
387 return m_shader;
388 }
389 virtual void setSelection(const QRect& selection);
390 const QRect& selection() const {
391 return m_selectionGeometry;
392 }
393 Plasma::FrameSvg& selectionFrame() {
394 return m_selection;
395 }
396 /**
397 * The foreground text color as specified by the default Plasma theme.
398 */
399 static QColor styledTextColor();
400
401private Q_SLOTS:
402 void plasmaThemeChanged();
403
404private:
405 Q_DISABLE_COPY(EffectFrameImpl) // As we need to use Qt slots we cannot copy this class
406 void align(QRect &geometry); // positions geometry around m_point respecting m_alignment
407 void autoResize(); // Auto-resize if not a static size
408
409 EffectFrameStyle m_style;
410 Plasma::FrameSvg m_frame; // TODO: share between all EffectFrames
411 Plasma::FrameSvg m_selection;
412
413 // Position
414 bool m_static;
415 QPoint m_point;
416 Qt::Alignment m_alignment;
417 QRect m_geometry;
418
419 // Contents
420 QString m_text;
421 QFont m_font;
422 QPixmap m_icon;
423 QSize m_iconSize;
424 QRect m_selectionGeometry;
425
426 Scene::EffectFrame* m_sceneFrame;
427 GLShader* m_shader;
428};
429
430class ScreenLockerWatcher : public QObject
431{
432 Q_OBJECT
433public:
434 explicit ScreenLockerWatcher(QObject *parent = 0);
435 virtual ~ScreenLockerWatcher();
436 bool isLocked() const {
437 return m_locked;
438 }
439Q_SIGNALS:
440 void locked(bool locked);
441private Q_SLOTS:
442 void setLocked(bool activated);
443 void activeQueried(QDBusPendingCallWatcher *watcher);
444 void serviceOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner);
445 void serviceRegisteredQueried();
446 void serviceOwnerQueried();
447private:
448 OrgFreedesktopScreenSaverInterface *m_interface;
449 QDBusServiceWatcher *m_serviceWatcher;
450 bool m_locked;
451};
452
453inline
454QList<EffectWindow*> EffectsHandlerImpl::elevatedWindows() const
455{
456 return elevated_windows;
457}
458
459
460inline
461EffectWindowGroupImpl::EffectWindowGroupImpl(Group* g)
462 : group(g)
463{
464}
465
466EffectWindow* effectWindow(Toplevel* w);
467EffectWindow* effectWindow(Scene::Window* w);
468
469inline
470const Scene::Window* EffectWindowImpl::sceneWindow() const
471{
472 return sw;
473}
474
475inline
476Scene::Window* EffectWindowImpl::sceneWindow()
477{
478 return sw;
479}
480
481inline
482const Toplevel* EffectWindowImpl::window() const
483{
484 return toplevel;
485}
486
487inline
488Toplevel* EffectWindowImpl::window()
489{
490 return toplevel;
491}
492
493
494} // namespace
495
496#endif
497