1 /*
2     KWin - the KDE window manager
3     This file is part of the KDE project.
4 
5     SPDX-FileCopyrightText: 2006 Lubos Lunak <l.lunak@kde.org>
6     SPDX-FileCopyrightText: 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
7 
8     SPDX-License-Identifier: GPL-2.0-or-later
9 */
10 
11 #ifndef KWIN_EFFECTSIMPL_H
12 #define KWIN_EFFECTSIMPL_H
13 
14 #include "kwineffects.h"
15 
16 #include "scene.h"
17 
18 #include <QHash>
19 #include <Plasma/FrameSvg>
20 
21 #include <memory>
22 
23 class QMouseEvent;
24 class QWheelEvent;
25 
26 namespace Plasma {
27 class Theme;
28 }
29 
30 namespace KWaylandServer
31 {
32 class Display;
33 }
34 
35 class QDBusPendingCallWatcher;
36 class QDBusServiceWatcher;
37 
38 
39 namespace KWin
40 {
41 class AbstractClient;
42 class Compositor;
43 class Deleted;
44 class EffectLoader;
45 class Group;
46 class Toplevel;
47 class Unmanaged;
48 class WindowPropertyNotifyX11Filter;
49 
50 class KWIN_EXPORT EffectsHandlerImpl : public EffectsHandler
51 {
52     Q_OBJECT
53     Q_CLASSINFO("D-Bus Interface", "org.kde.kwin.Effects")
54     Q_PROPERTY(QStringList activeEffects READ activeEffects)
55     Q_PROPERTY(QStringList loadedEffects READ loadedEffects)
56     Q_PROPERTY(QStringList listOfEffects READ listOfEffects)
57 public:
58     EffectsHandlerImpl(Compositor *compositor, Scene *scene);
59     ~EffectsHandlerImpl() override;
60     void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
61     void paintScreen(int mask, const QRegion &region, ScreenPaintData& data) override;
62     /**
63      * Special hook to perform a paintScreen but just with the windows on @p desktop.
64      */
65     void paintDesktop(int desktop, int mask, QRegion region, ScreenPaintData& data);
66     void postPaintScreen() override;
67     void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) override;
68     void paintWindow(EffectWindow* w, int mask, const QRegion &region, WindowPaintData& data) override;
69     void postPaintWindow(EffectWindow* w) override;
70     void paintEffectFrame(EffectFrame* frame, const QRegion &region, double opacity, double frameOpacity) override;
71 
72     Effect *provides(Effect::Feature ef);
73 
74     void drawWindow(EffectWindow* w, int mask, const QRegion &region, WindowPaintData& data) override;
75 
76     void activateWindow(EffectWindow* c) override;
77     EffectWindow* activeWindow() const override;
78     void moveWindow(EffectWindow* w, const QPoint& pos, bool snap = false, double snapAdjust = 1.0) override;
79     void windowToDesktop(EffectWindow* w, int desktop) override;
80     void windowToScreen(EffectWindow* w, int screen) override;
81     void setShowingDesktop(bool showing) override;
82 
83     QString currentActivity() const override;
84     int currentDesktop() const override;
85     int numberOfDesktops() const override;
86     void setCurrentDesktop(int desktop) override;
87     void setNumberOfDesktops(int desktops) override;
88     QSize desktopGridSize() const override;
89     int desktopGridWidth() const override;
90     int desktopGridHeight() const override;
91     int workspaceWidth() const override;
92     int workspaceHeight() const override;
93     int desktopAtCoords(QPoint coords) const override;
94     QPoint desktopGridCoords(int id) const override;
95     QPoint desktopCoords(int id) const override;
96     int desktopAbove(int desktop = 0, bool wrap = true) const override;
97     int desktopToRight(int desktop = 0, bool wrap = true) const override;
98     int desktopBelow(int desktop = 0, bool wrap = true) const override;
99     int desktopToLeft(int desktop = 0, bool wrap = true) const override;
100     QString desktopName(int desktop) const override;
101     bool optionRollOverDesktops() const override;
102 
103     QPoint cursorPos() const override;
104     bool grabKeyboard(Effect* effect) override;
105     void ungrabKeyboard() override;
106     // not performing XGrabPointer
107     void startMouseInterception(Effect *effect, Qt::CursorShape shape) override;
108     void stopMouseInterception(Effect *effect) override;
109     bool isMouseInterception() const;
110     void registerGlobalShortcut(const QKeySequence &shortcut, QAction *action) override;
111     void registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action) override;
112     void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action) override;
113     void registerRealtimeTouchpadSwipeShortcut(SwipeDirection dir, QAction* onUp, std::function<void(qreal)> progressCallback) override;
114     void registerTouchpadSwipeShortcut(SwipeDirection direction, QAction *action) override;
115     void* getProxy(QString name) override;
116     void startMousePolling() override;
117     void stopMousePolling() override;
118     EffectWindow* findWindow(WId id) const override;
119     EffectWindow* findWindow(KWaylandServer::SurfaceInterface *surf) const override;
120     EffectWindow *findWindow(QWindow *w) const override;
121     EffectWindow *findWindow(const QUuid &id) const override;
122     EffectWindowList stackingOrder() const override;
123     void setElevatedWindow(KWin::EffectWindow* w, bool set) override;
124 
125     void setTabBoxWindow(EffectWindow*) override;
126     void setTabBoxDesktop(int) override;
127     EffectWindowList currentTabBoxWindowList() const override;
128     void refTabBox() override;
129     void unrefTabBox() override;
130     void closeTabBox() override;
131     QList< int > currentTabBoxDesktopList() const override;
132     int currentTabBoxDesktop() const override;
133     EffectWindow* currentTabBoxWindow() const override;
134 
135     void setActiveFullScreenEffect(Effect* e) override;
136     Effect* activeFullScreenEffect() const override;
137     bool hasActiveFullScreenEffect() const override;
138 
139     void addRepaintFull() override;
140     void addRepaint(const QRect& r) override;
141     void addRepaint(const QRegion& r) override;
142     void addRepaint(int x, int y, int w, int h) override;
143     int activeScreen() const override;
144     int numScreens() const override;
145     int screenNumber(const QPoint& pos) const override;
146     QRect clientArea(clientAreaOption, int screen, int desktop) const override;
147     QRect clientArea(clientAreaOption, const EffectWindow* c) const override;
148     QRect clientArea(clientAreaOption, const QPoint& p, int desktop) const override;
149     QSize virtualScreenSize() const override;
150     QRect virtualScreenGeometry() const override;
151     double animationTimeFactor() const override;
152 
153     void defineCursor(Qt::CursorShape shape) override;
154     bool checkInputWindowEvent(QMouseEvent *e);
155     bool checkInputWindowEvent(QWheelEvent *e);
156     void checkInputWindowStacking();
157 
158     void reserveElectricBorder(ElectricBorder border, Effect *effect) override;
159     void unreserveElectricBorder(ElectricBorder border, Effect *effect) override;
160 
161     void registerTouchBorder(ElectricBorder border, QAction *action) override;
162     void unregisterTouchBorder(ElectricBorder border, QAction *action) override;
163 
164     QPainter* scenePainter() override;
165     void reconfigure() override;
166     QByteArray readRootProperty(long atom, long type, int format) const override;
167     xcb_atom_t announceSupportProperty(const QByteArray& propertyName, Effect* effect) override;
168     void removeSupportProperty(const QByteArray& propertyName, Effect* effect) override;
169 
170     bool hasDecorationShadows() const override;
171 
172     bool decorationsHaveAlpha() const override;
173 
174     bool decorationSupportsBlurBehind() const override;
175 
176     EffectFrame* effectFrame(EffectFrameStyle style, bool staticSize, const QPoint& position, Qt::Alignment alignment) const override;
177 
178     QVariant kwinOption(KWinOption kwopt) override;
179     bool isScreenLocked() const override;
180 
181     bool makeOpenGLContextCurrent() override;
182     void doneOpenGLContextCurrent() override;
183 
184     xcb_connection_t *xcbConnection() const override;
185     xcb_window_t x11RootWindow() const override;
186 
187     // internal (used by kwin core or compositing code)
188     void startPaint();
189     void grabbedKeyboardEvent(QKeyEvent* e);
190     bool hasKeyboardGrab() const;
191 
192     void reloadEffect(Effect *effect) override;
193     QStringList loadedEffects() const;
194     QStringList listOfEffects() const;
195     void unloadAllEffects();
196 
197     QList<EffectWindow*> elevatedWindows() const;
198     QStringList activeEffects() const;
199 
200     /**
201      * @returns whether or not any effect is currently active where KWin should not use direct scanout
202      */
203     bool blocksDirectScanout() const;
204 
205     /**
206      * @returns Whether we are currently in a desktop rendering process triggered by paintDesktop hook
207      */
isDesktopRendering()208     bool isDesktopRendering() const {
209         return m_desktopRendering;
210     }
211     /**
212      * @returns the desktop currently being rendered in the paintDesktop hook.
213      */
currentRenderedDesktop()214     int currentRenderedDesktop() const {
215         return m_currentRenderedDesktop;
216     }
217 
218     KWaylandServer::Display *waylandDisplay() const override;
219 
220     bool animationsSupported() const override;
221 
222     PlatformCursorImage cursorImage() const override;
223 
224     void hideCursor() override;
225     void showCursor() override;
226 
227     void startInteractiveWindowSelection(std::function<void(KWin::EffectWindow*)> callback) override;
228     void startInteractivePositionSelection(std::function<void(const QPoint &)> callback) override;
229 
230     void showOnScreenMessage(const QString &message, const QString &iconName = QString()) override;
231     void hideOnScreenMessage(OnScreenMessageHideFlags flags = OnScreenMessageHideFlags()) override;
232 
233     KSharedConfigPtr config() const override;
234     KSharedConfigPtr inputConfig() const override;
235 
scene()236     Scene *scene() const {
237         return m_scene;
238     }
239 
240     bool touchDown(qint32 id, const QPointF &pos, quint32 time);
241     bool touchMotion(qint32 id, const QPointF &pos, quint32 time);
242     bool touchUp(qint32 id, quint32 time);
243 
244     void highlightWindows(const QVector<EffectWindow *> &windows);
245 
isPropertyTypeRegistered(xcb_atom_t atom)246     bool isPropertyTypeRegistered(xcb_atom_t atom) const {
247         return registered_atoms.contains(atom);
248     }
249 
250     void windowToDesktops(EffectWindow *w, const QVector<uint> &desktops) override;
251 
252     /**
253      * Finds an effect with the given name.
254      *
255      * @param name The name of the effect.
256      * @returns The effect with the given name @p name, or nullptr if there
257      *     is no such effect loaded.
258      */
259     Effect *findEffect(const QString &name) const;
260 
261     void renderEffectQuickView(EffectQuickView *effectQuickView) const override;
262 
263     SessionState sessionState() const override;
264     QList<EffectScreen *> screens() const override;
265     EffectScreen *screenAt(const QPoint &point) const override;
266     EffectScreen *findScreen(const QString &name) const override;
267     EffectScreen *findScreen(int screenId) const override;
268     void renderScreen(EffectScreen *screen) override;
269 
270 public Q_SLOTS:
271     void slotCurrentTabAboutToChange(EffectWindow* from, EffectWindow* to);
272     void slotTabAdded(EffectWindow* from, EffectWindow* to);
273     void slotTabRemoved(EffectWindow* c, EffectWindow* newActiveWindow);
274 
275     // slots for D-Bus interface
276     Q_SCRIPTABLE void reconfigureEffect(const QString& name);
277     Q_SCRIPTABLE bool loadEffect(const QString& name);
278     Q_SCRIPTABLE void toggleEffect(const QString& name);
279     Q_SCRIPTABLE void unloadEffect(const QString& name);
280     Q_SCRIPTABLE bool isEffectLoaded(const QString& name) const;
281     Q_SCRIPTABLE bool isEffectSupported(const QString& name);
282     Q_SCRIPTABLE QList<bool> areEffectsSupported(const QStringList &names);
283     Q_SCRIPTABLE QString supportInformation(const QString& name) const;
284     Q_SCRIPTABLE QString debug(const QString& name, const QString& parameter = QString()) const;
285 
286 protected Q_SLOTS:
287     void slotClientShown(KWin::Toplevel*);
288     void slotUnmanagedShown(KWin::Toplevel*);
289     void slotWindowClosed(KWin::Toplevel *c, KWin::Deleted *d);
290     void slotClientMaximized(KWin::AbstractClient *c, MaximizeMode maxMode);
291     void slotOpacityChanged(KWin::Toplevel *t, qreal oldOpacity);
292     void slotClientModalityChanged();
293     void slotGeometryShapeChanged(KWin::Toplevel *t, const QRect &old);
294     void slotFrameGeometryChanged(Toplevel *toplevel, const QRect &oldGeometry);
295     void slotWindowDamaged(KWin::Toplevel *t, const QRegion& r);
296     void slotOutputEnabled(AbstractOutput *output);
297     void slotOutputDisabled(AbstractOutput *output);
298 
299 protected:
300     void connectNotify(const QMetaMethod &signal) override;
301     void disconnectNotify(const QMetaMethod &signal) override;
302     void effectsChanged();
303     void setupClientConnections(KWin::AbstractClient *client);
304     void setupUnmanagedConnections(KWin::Unmanaged *u);
305 
306     /**
307      * Default implementation does nothing and returns @c true.
308      */
309     virtual bool doGrabKeyboard();
310     /**
311      * Default implementation does nothing.
312      */
313     virtual void doUngrabKeyboard();
314 
315     /**
316      * Default implementation sets Effects override cursor on the PointerInputRedirection.
317      */
318     virtual void doStartMouseInterception(Qt::CursorShape shape);
319 
320     /**
321      * Default implementation removes the Effects override cursor on the PointerInputRedirection.
322      */
323     virtual void doStopMouseInterception();
324 
325     /**
326      * Default implementation does nothing
327      */
328     virtual void doCheckInputWindowStacking();
329 
330     Effect* keyboard_grab_effect;
331     Effect* fullscreen_effect;
332     QList<EffectWindow*> elevated_windows;
333     QMultiMap< int, EffectPair > effect_order;
334     QHash< long, int > registered_atoms;
335 
336 private:
337     void registerPropertyType(long atom, bool reg);
338     void destroyEffect(Effect *effect);
339 
340     typedef QVector< Effect*> EffectsList;
341     typedef EffectsList::const_iterator EffectsIterator;
342     EffectsList m_activeEffects;
343     EffectsIterator m_currentDrawWindowIterator;
344     EffectsIterator m_currentPaintWindowIterator;
345     EffectsIterator m_currentPaintEffectFrameIterator;
346     EffectsIterator m_currentPaintScreenIterator;
347     typedef QHash< QByteArray, QList< Effect*> > PropertyEffectMap;
348     PropertyEffectMap m_propertiesForEffects;
349     QHash<QByteArray, qulonglong> m_managedProperties;
350     Compositor *m_compositor;
351     Scene *m_scene;
352     bool m_desktopRendering;
353     int m_currentRenderedDesktop;
354     QList<Effect*> m_grabbedMouseEffects;
355     EffectLoader *m_effectLoader;
356     int m_trackingCursorChanges;
357     std::unique_ptr<WindowPropertyNotifyX11Filter> m_x11WindowPropertyNotify;
358     QList<EffectScreen *> m_effectScreens;
359 };
360 
361 class EffectScreenImpl : public EffectScreen
362 {
363     Q_OBJECT
364 
365 public:
366     explicit EffectScreenImpl(AbstractOutput *output, QObject *parent = nullptr);
367 
368     AbstractOutput *platformOutput() const;
369 
370     QString name() const override;
371     qreal devicePixelRatio() const override;
372     QRect geometry() const override;
373     Transform transform() const override;
374 
375 private:
376     AbstractOutput *m_platformOutput;
377 };
378 
379 class EffectWindowImpl : public EffectWindow
380 {
381     Q_OBJECT
382 public:
383     explicit EffectWindowImpl(Toplevel *toplevel);
384     ~EffectWindowImpl() override;
385 
386     void enablePainting(int reason) override;
387     void disablePainting(int reason) override;
388     bool isPaintingEnabled() override;
389 
390     void addRepaint(const QRect &r) override;
391     void addRepaint(int x, int y, int w, int h) override;
392     void addRepaintFull() override;
393     void addLayerRepaint(const QRect &r) override;
394     void addLayerRepaint(int x, int y, int w, int h) override;
395 
396     void refWindow() override;
397     void unrefWindow() override;
398 
399     const EffectWindowGroup* group() const override;
400 
401     bool isDeleted() const override;
402     bool isMinimized() const override;
403     double opacity() const override;
404     bool hasAlpha() const override;
405 
406     QStringList activities() const override;
407     int desktop() const override;
408     QVector<uint> desktops() const override;
409     int x() const override;
410     int y() const override;
411     int width() const override;
412     int height() const override;
413 
414     QSize basicUnit() const override;
415     QRect geometry() const override;
416     QRect frameGeometry() const override;
417     QRect bufferGeometry() const override;
418     QRect clientGeometry() const override;
419 
420     QString caption() const override;
421 
422     QRect expandedGeometry() const override;
423     int screen() const override;
424     QPoint pos() const override;
425     QSize size() const override;
426     QRect rect() const override;
427 
428     bool isMovable() const override;
429     bool isMovableAcrossScreens() const override;
430     bool isUserMove() const override;
431     bool isUserResize() const override;
432     QRect iconGeometry() const override;
433 
434     bool isDesktop() const override;
435     bool isDock() const override;
436     bool isToolbar() const override;
437     bool isMenu() const override;
438     bool isNormalWindow() const override;
439     bool isSpecialWindow() const override;
440     bool isDialog() const override;
441     bool isSplash() const override;
442     bool isUtility() const override;
443     bool isDropdownMenu() const override;
444     bool isPopupMenu() const override;
445     bool isTooltip() const override;
446     bool isNotification() const override;
447     bool isCriticalNotification() const override;
448     bool isOnScreenDisplay() const override;
449     bool isComboBox() const override;
450     bool isDNDIcon() const override;
451     bool skipsCloseAnimation() const override;
452 
453     bool acceptsFocus() const override;
454     bool keepAbove() const override;
455     bool keepBelow() const override;
456     bool isModal() const override;
457     bool isPopupWindow() const override;
458     bool isOutline() const override;
459     bool isLockScreen() const override;
460 
461     KWaylandServer::SurfaceInterface *surface() const override;
462     bool isFullScreen() const override;
463     bool isUnresponsive() const override;
464 
465     QRect contentsRect() const override;
466     bool decorationHasAlpha() const override;
467     QIcon icon() const override;
468     QString windowClass() const override;
469     NET::WindowType windowType() const override;
470     bool isSkipSwitcher() const override;
471     bool isCurrentTab() const override;
472     QString windowRole() const override;
473 
474     bool isManaged() const override;
475     bool isWaylandClient() const override;
476     bool isX11Client() const override;
477 
478     pid_t pid() const override;
479     qlonglong windowId() const override;
480 
481     QRect decorationInnerRect() const override;
482     QByteArray readProperty(long atom, long type, int format) const override;
483     void deleteProperty(long atom) const override;
484 
485     EffectWindow* findModal() override;
486     EffectWindow* transientFor() override;
487     EffectWindowList mainWindows() const override;
488 
489     void minimize() override;
490     void unminimize() override;
491     void closeWindow() override;
492 
493     void referencePreviousWindowPixmap() override;
494     void unreferencePreviousWindowPixmap() override;
495 
496     QWindow *internalWindow() const override;
497 
498     const Toplevel* window() const;
499     Toplevel* window();
500 
501     void setWindow(Toplevel* w);   // internal
502     void setSceneWindow(Scene::Window* w);   // internal
503     const Scene::Window* sceneWindow() const; // internal
504     Scene::Window* sceneWindow(); // internal
505 
506     void elevate(bool elevate);
507 
508     void setData(int role, const QVariant &data) override;
509     QVariant data(int role) const override;
510 
511 private:
512     Toplevel* toplevel;
513     Scene::Window* sw; // This one is used only during paint pass.
514     QHash<int, QVariant> dataMap;
515     bool managed = false;
516     bool waylandClient;
517     bool x11Client;
518 };
519 
520 class EffectWindowGroupImpl
521     : public EffectWindowGroup
522 {
523 public:
524     explicit EffectWindowGroupImpl(Group* g);
525     EffectWindowList members() const override;
526 private:
527     Group* group;
528 };
529 
530 class KWIN_EXPORT EffectFrameImpl
531     : public QObject, public EffectFrame
532 {
533     Q_OBJECT
534 public:
535     explicit EffectFrameImpl(EffectFrameStyle style, bool staticSize = true, QPoint position = QPoint(-1, -1),
536                              Qt::Alignment alignment = Qt::AlignCenter);
537     ~EffectFrameImpl() override;
538 
539     void free() override;
540     void render(const QRegion &region = infiniteRegion(), double opacity = 1.0, double frameOpacity = 1.0) override;
541     Qt::Alignment alignment() const override;
542     void setAlignment(Qt::Alignment alignment) override;
543     const QFont& font() const override;
544     void setFont(const QFont& font) override;
545     const QRect& geometry() const override;
546     void setGeometry(const QRect& geometry, bool force = false) override;
547     const QIcon& icon() const override;
548     void setIcon(const QIcon& icon) override;
549     const QSize& iconSize() const override;
550     void setIconSize(const QSize& size) override;
551     void setPosition(const QPoint& point) override;
552     const QString& text() const override;
553     void setText(const QString& text) override;
style()554     EffectFrameStyle style() const override {
555         return m_style;
556     }
frame()557     Plasma::FrameSvg& frame() {
558         return m_frame;
559     }
isStatic()560     bool isStatic() const {
561         return m_static;
562     }
563     void finalRender(QRegion region, double opacity, double frameOpacity) const;
setShader(GLShader * shader)564     void setShader(GLShader* shader) override {
565         m_shader = shader;
566     }
shader()567     GLShader* shader() const override {
568         return m_shader;
569     }
570     void setSelection(const QRect& selection) override;
selection()571     const QRect& selection() const {
572         return m_selectionGeometry;
573     }
selectionFrame()574     Plasma::FrameSvg& selectionFrame() {
575         return m_selection;
576     }
577     /**
578      * The foreground text color as specified by the default Plasma theme.
579      */
580     QColor styledTextColor();
581 
582 private Q_SLOTS:
583     void plasmaThemeChanged();
584 
585 private:
586     Q_DISABLE_COPY(EffectFrameImpl)   // As we need to use Qt slots we cannot copy this class
587     void align(QRect &geometry);   // positions geometry around m_point respecting m_alignment
588     void autoResize(); // Auto-resize if not a static size
589 
590     EffectFrameStyle m_style;
591     Plasma::FrameSvg m_frame; // TODO: share between all EffectFrames
592     Plasma::FrameSvg m_selection;
593 
594     // Position
595     bool m_static;
596     QPoint m_point;
597     Qt::Alignment m_alignment;
598     QRect m_geometry;
599 
600     // Contents
601     QString m_text;
602     QFont m_font;
603     QIcon m_icon;
604     QSize m_iconSize;
605     QRect m_selectionGeometry;
606 
607     Scene::EffectFrame* m_sceneFrame;
608     GLShader* m_shader;
609 
610     Plasma::Theme *m_theme;
611 };
612 
613 inline
elevatedWindows()614 QList<EffectWindow*> EffectsHandlerImpl::elevatedWindows() const
615 {
616     if (isScreenLocked())
617         return QList<EffectWindow*>();
618     return elevated_windows;
619 }
620 
621 inline
x11RootWindow()622 xcb_window_t EffectsHandlerImpl::x11RootWindow() const
623 {
624     return rootWindow();
625 }
626 
627 inline
xcbConnection()628 xcb_connection_t *EffectsHandlerImpl::xcbConnection() const
629 {
630     return connection();
631 }
632 
633 inline
EffectWindowGroupImpl(Group * g)634 EffectWindowGroupImpl::EffectWindowGroupImpl(Group* g)
635     : group(g)
636 {
637 }
638 
639 EffectWindow* effectWindow(Toplevel* w);
640 EffectWindow* effectWindow(Scene::Window* w);
641 
642 inline
sceneWindow()643 const Scene::Window* EffectWindowImpl::sceneWindow() const
644 {
645     return sw;
646 }
647 
648 inline
sceneWindow()649 Scene::Window* EffectWindowImpl::sceneWindow()
650 {
651     return sw;
652 }
653 
654 inline
window()655 const Toplevel* EffectWindowImpl::window() const
656 {
657     return toplevel;
658 }
659 
660 inline
window()661 Toplevel* EffectWindowImpl::window()
662 {
663     return toplevel;
664 }
665 
666 
667 } // namespace
668 
669 #endif
670