e717c131bf
Eg. gtk+ alters the modality after mapping and before unmapping the window. Therfore the former implementation ahd a wrong idea about the modality until the window was activated and again had a wrong idea when the dialog closed, keeping the main client dimmed. Modality changes at runtime are uncommon but legal and can happen anytime. BUG: 321340 FIXED-IN: 4.11 REVIEW: 111154
492 lines
17 KiB
C++
492 lines
17 KiB
C++
/********************************************************************
|
|
KWin - the KDE window manager
|
|
This file is part of the KDE project.
|
|
|
|
Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
|
|
Copyright (C) 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
|
|
|
|
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 <http://www.gnu.org/licenses/>.
|
|
*********************************************************************/
|
|
|
|
#ifndef KWIN_EFFECTSIMPL_H
|
|
#define KWIN_EFFECTSIMPL_H
|
|
|
|
#include "kwineffects.h"
|
|
|
|
#include "scene.h"
|
|
#include "xcbutils.h"
|
|
|
|
#include <QStack>
|
|
#include <QHash>
|
|
#include <Plasma/FrameSvg>
|
|
|
|
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);
|
|
virtual bool checkInputWindowEvent(XEvent* e);
|
|
virtual void checkInputWindowStacking();
|
|
|
|
virtual void reserveElectricBorder(ElectricBorder border, Effect *effect);
|
|
virtual void unreserveElectricBorder(ElectricBorder border, Effect *effect);
|
|
|
|
virtual unsigned long xrenderBufferPicture();
|
|
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;
|
|
|
|
// 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<EffectWindow*> 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 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<EffectWindow*> elevated_windows;
|
|
QMultiMap< int, EffectPair > effect_order;
|
|
QHash< long, int > registered_atoms;
|
|
int next_window_quad_type;
|
|
|
|
private Q_SLOTS:
|
|
void slotEffectsQueried();
|
|
|
|
private:
|
|
QList< Effect* > m_activeEffects;
|
|
QList< Effect* >::iterator m_currentDrawWindowIterator;
|
|
QList< Effect* >::iterator m_currentPaintWindowIterator;
|
|
QList< Effect* >::iterator m_currentPaintEffectFrameIterator;
|
|
QList< Effect* >::iterator m_currentPaintScreenIterator;
|
|
QList< Effect* >::iterator m_currentBuildQuadsIterator;
|
|
typedef QHash< QByteArray, QList< Effect*> > PropertyEffectMap;
|
|
PropertyEffectMap m_propertiesForEffects;
|
|
QHash<QByteArray, qulonglong> m_managedProperties;
|
|
Compositor *m_compositor;
|
|
Scene *m_scene;
|
|
ScreenLockerWatcher *m_screenLockerWatcher;
|
|
bool m_desktopRendering;
|
|
int m_currentRenderedDesktop;
|
|
Xcb::Window m_mouseInterceptionWindow;
|
|
QList<Effect*> 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<WindowThumbnailItem*, QWeakPointer<EffectWindowImpl> > const &thumbnails() const {
|
|
return m_thumbnails;
|
|
}
|
|
QList<DesktopThumbnailItem*> 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<int, QVariant> dataMap;
|
|
QHash<WindowThumbnailItem*, QWeakPointer<EffectWindowImpl> > m_thumbnails;
|
|
QList<DesktopThumbnailItem*> 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 QPixmap& icon() const;
|
|
virtual void setIcon(const QPixmap& icon);
|
|
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.
|
|
*/
|
|
static 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;
|
|
QPixmap m_icon;
|
|
QSize m_iconSize;
|
|
QRect m_selectionGeometry;
|
|
|
|
Scene::EffectFrame* m_sceneFrame;
|
|
GLShader* m_shader;
|
|
};
|
|
|
|
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<EffectWindow*> 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
|