/******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2006 Lubos Lunak Copyright (C) 2010, 2011 Martin Gräßlin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #ifndef KWIN_EFFECTSIMPL_H #define KWIN_EFFECTSIMPL_H #include "kwineffects.h" #include "scene.h" #include "xcbutils.h" #include #include #include namespace Plasma { class Theme; } class QDBusPendingCallWatcher; class QDBusServiceWatcher; class KService; class OrgFreedesktopScreenSaverInterface; namespace KWin { class AbstractThumbnailItem; class DesktopThumbnailItem; class WindowThumbnailItem; class Client; class Compositor; class Deleted; class Unmanaged; class ScreenLockerWatcher; class EffectsHandlerImpl : public EffectsHandler { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kwin.Effects") Q_PROPERTY(QStringList activeEffects READ activeEffects) Q_PROPERTY(QStringList loadedEffects READ loadedEffects) Q_PROPERTY(QStringList listOfEffects READ listOfEffects) public: EffectsHandlerImpl(Compositor *compositor, Scene *scene); virtual ~EffectsHandlerImpl(); virtual void prePaintScreen(ScreenPrePaintData& data, int time); virtual void paintScreen(int mask, QRegion region, ScreenPaintData& data); /** * Special hook to perform a paintScreen but just with the windows on @p desktop. **/ void paintDesktop(int desktop, int mask, QRegion region, ScreenPaintData& data); virtual void postPaintScreen(); virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time); virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data); virtual void postPaintWindow(EffectWindow* w); virtual void paintEffectFrame(EffectFrame* frame, QRegion region, double opacity, double frameOpacity); Effect *provides(Effect::Feature ef); virtual void drawWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data); virtual void buildQuads(EffectWindow* w, WindowQuadList& quadList); virtual void activateWindow(EffectWindow* c); virtual EffectWindow* activeWindow() const; virtual void moveWindow(EffectWindow* w, const QPoint& pos, bool snap = false, double snapAdjust = 1.0); virtual void windowToDesktop(EffectWindow* w, int desktop); virtual void windowToScreen(EffectWindow* w, int screen); virtual void setShowingDesktop(bool showing); virtual QString currentActivity() const; virtual int currentDesktop() const; virtual int numberOfDesktops() const; virtual void setCurrentDesktop(int desktop); virtual void setNumberOfDesktops(int desktops); virtual QSize desktopGridSize() const; virtual int desktopGridWidth() const; virtual int desktopGridHeight() const; virtual int workspaceWidth() const; virtual int workspaceHeight() const; virtual int desktopAtCoords(QPoint coords) const; virtual QPoint desktopGridCoords(int id) const; virtual QPoint desktopCoords(int id) const; virtual int desktopAbove(int desktop = 0, bool wrap = true) const; virtual int desktopToRight(int desktop = 0, bool wrap = true) const; virtual int desktopBelow(int desktop = 0, bool wrap = true) const; virtual int desktopToLeft(int desktop = 0, bool wrap = true) const; virtual QString desktopName(int desktop) const; virtual bool optionRollOverDesktops() const; virtual int displayWidth() const; virtual int displayHeight() const; virtual QPoint cursorPos() const; virtual bool grabKeyboard(Effect* effect); virtual void ungrabKeyboard(); // not performing XGrabPointer virtual void startMouseInterception(Effect *effect, Qt::CursorShape shape); virtual void stopMouseInterception(Effect *effect); virtual void* getProxy(QString name); virtual void startMousePolling(); virtual void stopMousePolling(); virtual EffectWindow* findWindow(WId id) const; virtual EffectWindowList stackingOrder() const; virtual void setElevatedWindow(EffectWindow* w, bool set); virtual void setTabBoxWindow(EffectWindow*); virtual void setTabBoxDesktop(int); virtual EffectWindowList currentTabBoxWindowList() const; virtual void refTabBox(); virtual void unrefTabBox(); virtual void closeTabBox(); virtual QList< int > currentTabBoxDesktopList() const; virtual int currentTabBoxDesktop() const; virtual EffectWindow* currentTabBoxWindow() const; virtual void setActiveFullScreenEffect(Effect* e); virtual Effect* activeFullScreenEffect() const; virtual void addRepaintFull(); virtual void addRepaint(const QRect& r); virtual void addRepaint(const QRegion& r); virtual void addRepaint(int x, int y, int w, int h); virtual int activeScreen() const; virtual int numScreens() const; virtual int screenNumber(const QPoint& pos) const; virtual QRect clientArea(clientAreaOption, int screen, int desktop) const; virtual QRect clientArea(clientAreaOption, const EffectWindow* c) const; virtual QRect clientArea(clientAreaOption, const QPoint& p, int desktop) const; virtual double animationTimeFactor() const; virtual WindowQuadType newWindowQuadType(); virtual void defineCursor(Qt::CursorShape shape); bool checkInputWindowEvent(xcb_button_press_event_t *e); bool checkInputWindowEvent(xcb_motion_notify_event_t *e); virtual void checkInputWindowStacking(); virtual void reserveElectricBorder(ElectricBorder border, Effect *effect); virtual void unreserveElectricBorder(ElectricBorder border, Effect *effect); virtual unsigned long xrenderBufferPicture(); virtual QPainter* scenePainter(); virtual void reconfigure(); virtual void registerPropertyType(long atom, bool reg); virtual QByteArray readRootProperty(long atom, long type, int format) const; virtual void deleteRootProperty(long atom) const; virtual xcb_atom_t announceSupportProperty(const QByteArray& propertyName, Effect* effect); virtual void removeSupportProperty(const QByteArray& propertyName, Effect* effect); virtual bool hasDecorationShadows() const; virtual bool decorationsHaveAlpha() const; virtual bool decorationSupportsBlurBehind() const; virtual EffectFrame* effectFrame(EffectFrameStyle style, bool staticSize, const QPoint& position, Qt::Alignment alignment) const; virtual QVariant kwinOption(KWinOption kwopt); virtual bool isScreenLocked() const; virtual bool makeOpenGLContextCurrent() override; virtual void doneOpenGLContextCurrent() override; // internal (used by kwin core or compositing code) void startPaint(); void grabbedKeyboardEvent(QKeyEvent* e); bool hasKeyboardGrab() const; void desktopResized(const QSize &size); virtual void reloadEffect(Effect *effect); QStringList loadedEffects() const; QStringList listOfEffects() const; QList elevatedWindows() const; QStringList activeEffects() const; /** * @returns Whether we are currently in a desktop rendering process triggered by paintDesktop hook **/ bool isDesktopRendering() const { return m_desktopRendering; } /** * @returns the desktop currently being rendered in the paintDesktop hook. **/ int currentRenderedDesktop() const { return m_currentRenderedDesktop; } public Q_SLOTS: void slotCurrentTabAboutToChange(EffectWindow* from, EffectWindow* to); void slotTabAdded(EffectWindow* from, EffectWindow* to); void slotTabRemoved(EffectWindow* c, EffectWindow* newActiveWindow); // slots for D-Bus interface Q_SCRIPTABLE void reconfigureEffect(const QString& name); Q_SCRIPTABLE bool loadEffect(const QString& name, bool checkDefault = false); Q_SCRIPTABLE void toggleEffect(const QString& name); Q_SCRIPTABLE void unloadEffect(const QString& name); Q_SCRIPTABLE bool isEffectLoaded(const QString& name) const; Q_SCRIPTABLE QString supportInformation(const QString& name) const; Q_SCRIPTABLE QString debug(const QString& name, const QString& parameter = QString()) const; protected Q_SLOTS: void slotDesktopChanged(int old, KWin::Client *withClient); void slotClientAdded(KWin::Client *c); void slotClientShown(KWin::Toplevel*); void slotUnmanagedAdded(KWin::Unmanaged *u); void slotUnmanagedShown(KWin::Toplevel*); void slotWindowClosed(KWin::Toplevel *c); void slotClientActivated(KWin::Client *c); void slotDeletedRemoved(KWin::Deleted *d); void slotClientMaximized(KWin::Client *c, KDecorationDefines::MaximizeMode maxMode); void slotClientStartUserMovedResized(KWin::Client *c); void slotClientStepUserMovedResized(KWin::Client *c, const QRect &geometry); void slotClientFinishUserMovedResized(KWin::Client *c); void slotOpacityChanged(KWin::Toplevel *t, qreal oldOpacity); void slotClientMinimized(KWin::Client *c, bool animate); void slotClientUnminimized(KWin::Client *c, bool animate); void slotClientModalityChanged(); void slotGeometryShapeChanged(KWin::Toplevel *t, const QRect &old); void slotPaddingChanged(KWin::Toplevel *t, const QRect &old); void slotWindowDamaged(KWin::Toplevel *t, const QRect& r); void slotPropertyNotify(KWin::Toplevel *t, long atom); void slotPropertyNotify(long atom); protected: bool loadScriptedEffect(const QString &name, KService *service); KLibrary* findEffectLibrary(KService* service); void effectsChanged(); void setupClientConnections(KWin::Client *c); void setupUnmanagedConnections(KWin::Unmanaged *u); Effect* keyboard_grab_effect; Effect* fullscreen_effect; QList elevated_windows; QMultiMap< int, EffectPair > effect_order; QHash< long, int > registered_atoms; int next_window_quad_type; private Q_SLOTS: void slotEffectsQueried(); private: typedef QVector< Effect*> EffectsList; typedef EffectsList::const_iterator EffectsIterator; EffectsList m_activeEffects; EffectsIterator m_currentDrawWindowIterator; EffectsIterator m_currentPaintWindowIterator; EffectsIterator m_currentPaintEffectFrameIterator; EffectsIterator m_currentPaintScreenIterator; EffectsIterator m_currentBuildQuadsIterator; typedef QHash< QByteArray, QList< Effect*> > PropertyEffectMap; PropertyEffectMap m_propertiesForEffects; QHash m_managedProperties; Compositor *m_compositor; Scene *m_scene; ScreenLockerWatcher *m_screenLockerWatcher; bool m_desktopRendering; int m_currentRenderedDesktop; Xcb::Window m_mouseInterceptionWindow; QList m_grabbedMouseEffects; }; class EffectWindowImpl : public EffectWindow { Q_OBJECT public: explicit EffectWindowImpl(Toplevel *toplevel); virtual ~EffectWindowImpl(); virtual void enablePainting(int reason); virtual void disablePainting(int reason); virtual bool isPaintingEnabled(); virtual void refWindow(); virtual void unrefWindow(); virtual const EffectWindowGroup* group() const; virtual QRegion shape() const; virtual QRect decorationInnerRect() const; virtual QByteArray readProperty(long atom, long type, int format) const; virtual void deleteProperty(long atom) const; virtual EffectWindow* findModal(); virtual EffectWindowList mainWindows() const; virtual WindowQuadList buildQuads(bool force = false) const; virtual void referencePreviousWindowPixmap(); virtual void unreferencePreviousWindowPixmap(); const Toplevel* window() const; Toplevel* window(); void setWindow(Toplevel* w); // internal void setSceneWindow(Scene::Window* w); // internal const Scene::Window* sceneWindow() const; // internal Scene::Window* sceneWindow(); // internal void elevate(bool elevate); void setData(int role, const QVariant &data); QVariant data(int role) const; void registerThumbnail(AbstractThumbnailItem *item); QHash > const &thumbnails() const { return m_thumbnails; } QList const &desktopThumbnails() const { return m_desktopThumbnails; } private Q_SLOTS: void thumbnailDestroyed(QObject *object); void thumbnailTargetChanged(); void desktopThumbnailDestroyed(QObject *object); private: void insertThumbnail(WindowThumbnailItem *item); Toplevel* toplevel; Scene::Window* sw; // This one is used only during paint pass. QHash dataMap; QHash > m_thumbnails; QList m_desktopThumbnails; }; class EffectWindowGroupImpl : public EffectWindowGroup { public: explicit EffectWindowGroupImpl(Group* g); virtual EffectWindowList members() const; private: Group* group; }; class EffectFrameImpl : public QObject, public EffectFrame { Q_OBJECT public: explicit EffectFrameImpl(EffectFrameStyle style, bool staticSize = true, QPoint position = QPoint(-1, -1), Qt::Alignment alignment = Qt::AlignCenter); virtual ~EffectFrameImpl(); virtual void free(); virtual void render(QRegion region = infiniteRegion(), double opacity = 1.0, double frameOpacity = 1.0); virtual Qt::Alignment alignment() const; virtual void setAlignment(Qt::Alignment alignment); virtual const QFont& font() const; virtual void setFont(const QFont& font); virtual const QRect& geometry() const; virtual void setGeometry(const QRect& geometry, bool force = false); virtual const QIcon& icon() const override; virtual void setIcon(const QIcon& icon) override; virtual const QSize& iconSize() const; virtual void setIconSize(const QSize& size); virtual void setPosition(const QPoint& point); virtual const QString& text() const; virtual void setText(const QString& text); virtual EffectFrameStyle style() const { return m_style; }; Plasma::FrameSvg& frame() { return m_frame; } bool isStatic() const { return m_static; }; void finalRender(QRegion region, double opacity, double frameOpacity) const; virtual void setShader(GLShader* shader) { m_shader = shader; } virtual GLShader* shader() const { return m_shader; } virtual void setSelection(const QRect& selection); const QRect& selection() const { return m_selectionGeometry; } Plasma::FrameSvg& selectionFrame() { return m_selection; } /** * The foreground text color as specified by the default Plasma theme. */ QColor styledTextColor(); private Q_SLOTS: void plasmaThemeChanged(); private: Q_DISABLE_COPY(EffectFrameImpl) // As we need to use Qt slots we cannot copy this class void align(QRect &geometry); // positions geometry around m_point respecting m_alignment void autoResize(); // Auto-resize if not a static size EffectFrameStyle m_style; Plasma::FrameSvg m_frame; // TODO: share between all EffectFrames Plasma::FrameSvg m_selection; // Position bool m_static; QPoint m_point; Qt::Alignment m_alignment; QRect m_geometry; // Contents QString m_text; QFont m_font; QIcon m_icon; QSize m_iconSize; QRect m_selectionGeometry; Scene::EffectFrame* m_sceneFrame; GLShader* m_shader; Plasma::Theme *m_theme; }; class ScreenLockerWatcher : public QObject { Q_OBJECT public: explicit ScreenLockerWatcher(QObject *parent = 0); virtual ~ScreenLockerWatcher(); bool isLocked() const { return m_locked; } Q_SIGNALS: void locked(bool locked); private Q_SLOTS: void setLocked(bool activated); void activeQueried(QDBusPendingCallWatcher *watcher); void serviceOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner); void serviceRegisteredQueried(); void serviceOwnerQueried(); private: OrgFreedesktopScreenSaverInterface *m_interface; QDBusServiceWatcher *m_serviceWatcher; bool m_locked; }; inline QList EffectsHandlerImpl::elevatedWindows() const { return elevated_windows; } inline EffectWindowGroupImpl::EffectWindowGroupImpl(Group* g) : group(g) { } EffectWindow* effectWindow(Toplevel* w); EffectWindow* effectWindow(Scene::Window* w); inline const Scene::Window* EffectWindowImpl::sceneWindow() const { return sw; } inline Scene::Window* EffectWindowImpl::sceneWindow() { return sw; } inline const Toplevel* EffectWindowImpl::window() const { return toplevel; } inline Toplevel* EffectWindowImpl::window() { return toplevel; } } // namespace #endif