File indexing completed on 2024-05-19 05:31:41

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2006 Lubos Lunak <l.lunak@kde.org>
0006     SPDX-FileCopyrightText: 2009 Lucas Murray <lmurray@undefinedfire.com>
0007     SPDX-FileCopyrightText: 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
0008     SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0009 
0010     SPDX-License-Identifier: GPL-2.0-or-later
0011 */
0012 
0013 #pragma once
0014 
0015 #include "effect/effect.h"
0016 #include "effect/effectwindow.h"
0017 
0018 #include <QEasingCurve>
0019 #include <QIcon>
0020 #include <QPair>
0021 #include <QRect>
0022 #include <QRegion>
0023 #include <QSet>
0024 
0025 #include <QHash>
0026 #include <QList>
0027 #include <QLoggingCategory>
0028 #include <QStack>
0029 
0030 #include <netwm.h>
0031 
0032 #include <functional>
0033 
0034 class KConfigGroup;
0035 class QFont;
0036 class QKeyEvent;
0037 class QMatrix4x4;
0038 class QMouseEvent;
0039 class QWheelEvent;
0040 class QAction;
0041 class QTabletEvent;
0042 class QQmlEngine;
0043 
0044 /**
0045  * Logging category to be used inside the KWin effects.
0046  * Do not use in this library.
0047  */
0048 Q_DECLARE_LOGGING_CATEGORY(KWINEFFECTS)
0049 
0050 namespace KDecoration2
0051 {
0052 class Decoration;
0053 }
0054 
0055 namespace KWin
0056 {
0057 
0058 class SurfaceInterface;
0059 class Display;
0060 class PaintDataPrivate;
0061 class WindowPaintDataPrivate;
0062 
0063 class Compositor;
0064 class EffectLoader;
0065 class EffectWindow;
0066 class EffectWindowGroup;
0067 class OffscreenQuickView;
0068 class Group;
0069 class Output;
0070 class Effect;
0071 class TabletEvent;
0072 class TabletPadId;
0073 class TabletToolId;
0074 class Window;
0075 class WindowItem;
0076 class WindowPropertyNotifyX11Filter;
0077 class WorkspaceScene;
0078 class VirtualDesktop;
0079 
0080 typedef QPair<QString, Effect *> EffectPair;
0081 
0082 /**
0083  * EffectWindow::setData() and EffectWindow::data() global roles.
0084  * All values between 0 and 999 are reserved for global roles.
0085  */
0086 enum DataRole {
0087     // Grab roles are used to force all other animations to ignore the window.
0088     // The value of the data is set to the Effect's `this` value.
0089     WindowAddedGrabRole = 1,
0090     WindowClosedGrabRole,
0091     WindowMinimizedGrabRole,
0092     WindowUnminimizedGrabRole,
0093     WindowForceBlurRole, ///< For fullscreen effects to enforce blurring of windows,
0094     WindowForceBackgroundContrastRole, ///< For fullscreen effects to enforce the background contrast,
0095 };
0096 
0097 /**
0098  * @short Manager class that handles all the effects.
0099  *
0100  * This class creates Effect objects and calls it's appropriate methods.
0101  *
0102  * Effect objects can call methods of this class to interact with the
0103  *  workspace, e.g. to activate or move a specific window, change current
0104  *  desktop or create a special input window to receive mouse and keyboard
0105  *  events.
0106  */
0107 class KWIN_EXPORT EffectsHandler : public QObject
0108 {
0109     Q_OBJECT
0110     Q_CLASSINFO("D-Bus Interface", "org.kde.kwin.Effects")
0111 
0112     Q_PROPERTY(QStringList activeEffects READ activeEffects)
0113     Q_PROPERTY(QStringList loadedEffects READ loadedEffects)
0114     Q_PROPERTY(QStringList listOfEffects READ listOfEffects)
0115 
0116     Q_PROPERTY(KWin::VirtualDesktop *currentDesktop READ currentDesktop WRITE setCurrentDesktop NOTIFY desktopChanged)
0117     Q_PROPERTY(QString currentActivity READ currentActivity NOTIFY currentActivityChanged)
0118     Q_PROPERTY(KWin::EffectWindow *activeWindow READ activeWindow WRITE activateWindow NOTIFY windowActivated)
0119     Q_PROPERTY(QSize desktopGridSize READ desktopGridSize NOTIFY desktopGridSizeChanged)
0120     Q_PROPERTY(int desktopGridWidth READ desktopGridWidth NOTIFY desktopGridWidthChanged)
0121     Q_PROPERTY(int desktopGridHeight READ desktopGridHeight NOTIFY desktopGridHeightChanged)
0122     Q_PROPERTY(int workspaceWidth READ workspaceWidth)
0123     Q_PROPERTY(int workspaceHeight READ workspaceHeight)
0124     Q_PROPERTY(QList<KWin::VirtualDesktop *> desktops READ desktops)
0125     Q_PROPERTY(bool optionRollOverDesktops READ optionRollOverDesktops)
0126     Q_PROPERTY(KWin::Output *activeScreen READ activeScreen)
0127     /**
0128      * Factor by which animation speed in the effect should be modified (multiplied).
0129      * If configurable in the effect itself, the option should have also 'default'
0130      * animation speed. The actual value should be determined using animationTime().
0131      * Note: The factor can be also 0, so make sure your code can cope with 0ms time
0132      * if used manually.
0133      */
0134     Q_PROPERTY(qreal animationTimeFactor READ animationTimeFactor)
0135     Q_PROPERTY(QList<EffectWindow *> stackingOrder READ stackingOrder)
0136     /**
0137      * Whether window decorations use the alpha channel.
0138      */
0139     Q_PROPERTY(bool decorationsHaveAlpha READ decorationsHaveAlpha)
0140     Q_PROPERTY(CompositingType compositingType READ compositingType CONSTANT)
0141     Q_PROPERTY(QPointF cursorPos READ cursorPos)
0142     Q_PROPERTY(QSize virtualScreenSize READ virtualScreenSize NOTIFY virtualScreenSizeChanged)
0143     Q_PROPERTY(QRect virtualScreenGeometry READ virtualScreenGeometry NOTIFY virtualScreenGeometryChanged)
0144     Q_PROPERTY(bool hasActiveFullScreenEffect READ hasActiveFullScreenEffect NOTIFY hasActiveFullScreenEffectChanged)
0145 
0146     /**
0147      * The status of the session i.e if the user is logging out
0148      * @since 5.18
0149      */
0150     Q_PROPERTY(KWin::SessionState sessionState READ sessionState NOTIFY sessionStateChanged)
0151 
0152     Q_PROPERTY(KWin::EffectWindow *inputPanel READ inputPanel NOTIFY inputPanelChanged)
0153 
0154     friend class Effect;
0155 
0156 public:
0157     using TouchBorderCallback = std::function<void(ElectricBorder border, const QPointF &, Output *screen)>;
0158 
0159     EffectsHandler(Compositor *compositor, WorkspaceScene *scene);
0160     ~EffectsHandler() override;
0161 
0162     // internal (used by kwin core or compositing code)
0163     void startPaint();
0164 
0165     // for use by effects
0166     void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime);
0167     void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, Output *screen);
0168     void postPaintScreen();
0169     void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime);
0170     void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data);
0171     void postPaintWindow(EffectWindow *w);
0172     void drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data);
0173     void renderWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data);
0174     QVariant kwinOption(KWinOption kwopt);
0175     /**
0176      * Sets the cursor while the mouse is intercepted.
0177      * @see startMouseInterception
0178      * @since 4.11
0179      */
0180     virtual void defineCursor(Qt::CursorShape shape);
0181     QPointF cursorPos() const;
0182     bool grabKeyboard(Effect *effect);
0183     void ungrabKeyboard();
0184     /**
0185      * Ensures that all mouse events are sent to the @p effect.
0186      * No window will get the mouse events. Only fullscreen effects providing a custom user interface should
0187      * be using this method. The input events are delivered to Effect::windowInputMouseEvent.
0188      *
0189      * @note This method does not perform an X11 mouse grab. On X11 a fullscreen input window is raised above
0190      * all other windows, but no grab is performed.
0191      *
0192      * @param effect The effect
0193      * @param shape Sets the cursor to be used while the mouse is intercepted
0194      * @see stopMouseInterception
0195      * @see Effect::windowInputMouseEvent
0196      * @since 4.11
0197      */
0198     void startMouseInterception(Effect *effect, Qt::CursorShape shape);
0199     /**
0200      * Releases the hold mouse interception for @p effect
0201      * @see startMouseInterception
0202      * @since 4.11
0203      */
0204     void stopMouseInterception(Effect *effect);
0205     bool isMouseInterception() const;
0206 
0207     bool checkInputWindowEvent(QMouseEvent *e);
0208     bool checkInputWindowEvent(QWheelEvent *e);
0209     void checkInputWindowStacking();
0210 
0211     void grabbedKeyboardEvent(QKeyEvent *e);
0212     bool hasKeyboardGrab() const;
0213 
0214     /**
0215      * @brief Registers a global pointer shortcut with the provided @p action.
0216      *
0217      * @param modifiers The keyboard modifiers which need to be holded
0218      * @param pointerButtons The pointer buttons which need to be pressed
0219      * @param action The action which gets triggered when the shortcut matches
0220      */
0221     void registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action);
0222     /**
0223      * @brief Registers a global axis shortcut with the provided @p action.
0224      *
0225      * @param modifiers The keyboard modifiers which need to be holded
0226      * @param axis The direction in which the axis needs to be moved
0227      * @param action The action which gets triggered when the shortcut matches
0228      */
0229     void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action);
0230 
0231     /**
0232      * @brief Registers a global touchpad swipe gesture shortcut with the provided @p action.
0233      *
0234      * @param direction The direction for the swipe
0235      * @param action The action which gets triggered when the gesture triggers
0236      * @since 5.10
0237      */
0238     void registerTouchpadSwipeShortcut(SwipeDirection dir, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback = {});
0239 
0240     void registerTouchpadPinchShortcut(PinchDirection dir, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback = {});
0241 
0242     /**
0243      * @brief Registers a global touchscreen swipe gesture shortcut with the provided @p action.
0244      *
0245      * @param direction The direction for the swipe
0246      * @param action The action which gets triggered when the gesture triggers
0247      * @since 5.25
0248      */
0249     void registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function<void(qreal)> progressCallback);
0250 
0251     // Mouse polling
0252     void startMousePolling();
0253     void stopMousePolling();
0254 
0255     void reserveElectricBorder(ElectricBorder border, Effect *effect);
0256     void unreserveElectricBorder(ElectricBorder border, Effect *effect);
0257 
0258     /**
0259      * Registers the given @p action for the given @p border to be activated through
0260      * a touch swipe gesture.
0261      *
0262      * If the @p border gets triggered through a touch swipe gesture the QAction::triggered
0263      * signal gets invoked.
0264      *
0265      * To unregister the touch screen action either delete the @p action or
0266      * invoke unregisterTouchBorder.
0267      *
0268      * @see unregisterTouchBorder
0269      * @since 5.10
0270      */
0271     void registerTouchBorder(ElectricBorder border, QAction *action);
0272 
0273     /**
0274      * Registers the given @p action for the given @p border to be activated through
0275      * a touch swipe gesture.
0276      *
0277      * If the @p border gets triggered through a touch swipe gesture the QAction::triggered
0278      * signal gets invoked.
0279      *
0280      * progressCallback will be dinamically called each time the touch position is updated
0281      * to show the effect "partially" activated
0282      *
0283      * To unregister the touch screen action either delete the @p action or
0284      * invoke unregisterTouchBorder.
0285      *
0286      * @see unregisterTouchBorder
0287      * @since 5.25
0288      */
0289     void registerRealtimeTouchBorder(ElectricBorder border, QAction *action, TouchBorderCallback progressCallback);
0290 
0291     /**
0292      * Unregisters the given @p action for the given touch @p border.
0293      *
0294      * @see registerTouchBorder
0295      * @since 5.10
0296      */
0297     void unregisterTouchBorder(ElectricBorder border, QAction *action);
0298 
0299     // functions that allow controlling windows/desktop
0300     void activateWindow(KWin::EffectWindow *c);
0301     KWin::EffectWindow *activeWindow() const;
0302     Q_SCRIPTABLE void moveWindow(KWin::EffectWindow *w, const QPoint &pos, bool snap = false, double snapAdjust = 1.0);
0303 
0304     /**
0305      * Moves a window to the given desktops
0306      * On X11, the window will end up on the last window in the list
0307      * Setting this to an empty list will set the window on all desktops
0308      */
0309     Q_SCRIPTABLE void windowToDesktops(KWin::EffectWindow *w, const QList<KWin::VirtualDesktop *> &desktops);
0310 
0311     Q_SCRIPTABLE void windowToScreen(KWin::EffectWindow *w, Output *screen);
0312     void setShowingDesktop(bool showing);
0313 
0314     // Activities
0315     /**
0316      * @returns The ID of the current activity.
0317      */
0318     QString currentActivity() const;
0319     // Desktops
0320     /**
0321      * @returns The current desktop.
0322      */
0323     VirtualDesktop *currentDesktop() const;
0324     /**
0325      * @returns Total number of desktops currently in existence.
0326      */
0327     QList<VirtualDesktop *> desktops() const;
0328     /**
0329      * Set the current desktop to @a desktop.
0330      */
0331     void setCurrentDesktop(KWin::VirtualDesktop *desktop);
0332     /**
0333      * @returns The size of desktop layout in grid units.
0334      */
0335     QSize desktopGridSize() const;
0336     /**
0337      * @returns The width of desktop layout in grid units.
0338      */
0339     int desktopGridWidth() const;
0340     /**
0341      * @returns The height of desktop layout in grid units.
0342      */
0343     int desktopGridHeight() const;
0344     /**
0345      * @returns The width of desktop layout in pixels.
0346      */
0347     int workspaceWidth() const;
0348     /**
0349      * @returns The height of desktop layout in pixels.
0350      */
0351     int workspaceHeight() const;
0352     /**
0353      * @returns The desktop at the point @a coords or 0 if no desktop exists at that
0354      * point. @a coords is to be in grid units.
0355      */
0356     VirtualDesktop *desktopAtCoords(QPoint coords) const;
0357     /**
0358      * @returns The coords of the specified @a desktop in grid units.
0359      */
0360     QPoint desktopGridCoords(VirtualDesktop *desktop) const;
0361     /**
0362      * @returns The coords of the top-left corner of @a desktop in pixels.
0363      */
0364     QPoint desktopCoords(VirtualDesktop *desktop) const;
0365     /**
0366      * @returns The desktop above the given @a desktop. Wraps around to the bottom of
0367      * the layout if @a wrap is set. If @a id is not set use the current one.
0368      */
0369     Q_SCRIPTABLE KWin::VirtualDesktop *desktopAbove(KWin::VirtualDesktop *desktop = nullptr, bool wrap = true) const;
0370     /**
0371      * @returns The desktop to the right of the given @a desktop. Wraps around to the
0372      * left of the layout if @a wrap is set. If @a id is not set use the current one.
0373      */
0374     Q_SCRIPTABLE KWin::VirtualDesktop *desktopToRight(KWin::VirtualDesktop *desktop = nullptr, bool wrap = true) const;
0375     /**
0376      * @returns The desktop below the given @a desktop. Wraps around to the top of the
0377      * layout if @a wrap is set. If @a id is not set use the current one.
0378      */
0379     Q_SCRIPTABLE KWin::VirtualDesktop *desktopBelow(KWin::VirtualDesktop *desktop = nullptr, bool wrap = true) const;
0380     /**
0381      * @returns The desktop to the left of the given @a desktop. Wraps around to the
0382      * right of the layout if @a wrap is set. If @a id is not set use the current one.
0383      */
0384     Q_SCRIPTABLE KWin::VirtualDesktop *desktopToLeft(KWin::VirtualDesktop *desktop = nullptr, bool wrap = true) const;
0385     Q_SCRIPTABLE QString desktopName(KWin::VirtualDesktop *desktop) const;
0386     bool optionRollOverDesktops() const;
0387 
0388     Output *activeScreen() const; // Xinerama
0389     QRectF clientArea(clientAreaOption, const Output *screen, const VirtualDesktop *desktop) const;
0390     QRectF clientArea(clientAreaOption, const EffectWindow *c) const;
0391     QRectF clientArea(clientAreaOption, const QPoint &p, const VirtualDesktop *desktop) const;
0392 
0393     /**
0394      * The bounding size of all screens combined. Overlapping areas
0395      * are not counted multiple times.
0396      *
0397      * @see virtualScreenGeometry()
0398      * @see virtualScreenSizeChanged()
0399      * @since 5.0
0400      */
0401     QSize virtualScreenSize() const;
0402     /**
0403      * The bounding geometry of all outputs combined. Always starts at (0,0) and has
0404      * virtualScreenSize as it's size.
0405      *
0406      * @see virtualScreenSize()
0407      * @see virtualScreenGeometryChanged()
0408      * @since 5.0
0409      */
0410     QRect virtualScreenGeometry() const;
0411     /**
0412      * Factor by which animation speed in the effect should be modified (multiplied).
0413      * If configurable in the effect itself, the option should have also 'default'
0414      * animation speed. The actual value should be determined using animationTime().
0415      * Note: The factor can be also 0, so make sure your code can cope with 0ms time
0416      * if used manually.
0417      */
0418     double animationTimeFactor() const;
0419 
0420     Q_SCRIPTABLE KWin::EffectWindow *findWindow(WId id) const;
0421     Q_SCRIPTABLE KWin::EffectWindow *findWindow(SurfaceInterface *surf) const;
0422     /**
0423      * Finds the EffectWindow for the internal window @p w.
0424      * If there is no such window @c null is returned.
0425      *
0426      * On Wayland this returns the internal window. On X11 it returns an Unamanged with the
0427      * window id matching that of the provided window @p w.
0428      *
0429      * @since 5.16
0430      */
0431     Q_SCRIPTABLE KWin::EffectWindow *findWindow(QWindow *w) const;
0432     /**
0433      * Finds the EffectWindow for the Window with KWin internal @p id.
0434      * If there is no such window @c null is returned.
0435      *
0436      * @since 5.16
0437      */
0438     Q_SCRIPTABLE KWin::EffectWindow *findWindow(const QUuid &id) const;
0439     QList<EffectWindow *> stackingOrder() const;
0440     // window will be temporarily painted as if being at the top of the stack
0441     Q_SCRIPTABLE void setElevatedWindow(KWin::EffectWindow *w, bool set);
0442 
0443     void setTabBoxWindow(EffectWindow *);
0444     QList<EffectWindow *> currentTabBoxWindowList() const;
0445     void refTabBox();
0446     void unrefTabBox();
0447     void closeTabBox();
0448     EffectWindow *currentTabBoxWindow() const;
0449 
0450     void setActiveFullScreenEffect(Effect *e);
0451     Effect *activeFullScreenEffect() const;
0452 
0453     /**
0454      * Schedules the entire workspace to be repainted next time.
0455      * If you call it during painting (including prepaint) then it does not
0456      *  affect the current painting.
0457      */
0458     Q_SCRIPTABLE void addRepaintFull();
0459     Q_SCRIPTABLE void addRepaint(const QRectF &r);
0460     Q_SCRIPTABLE void addRepaint(const QRect &r);
0461     Q_SCRIPTABLE void addRepaint(const QRegion &r);
0462     Q_SCRIPTABLE void addRepaint(int x, int y, int w, int h);
0463 
0464     CompositingType compositingType() const;
0465     /**
0466      * @brief Whether the Compositor is OpenGL based (either GL 1 or 2).
0467      *
0468      * @return bool @c true in case of OpenGL based Compositor, @c false otherwise
0469      */
0470     bool isOpenGLCompositing() const;
0471     /**
0472      * @brief Provides access to the QPainter which is rendering to the back buffer.
0473      *
0474      * Only relevant for CompositingType QPainterCompositing. For all other compositing types
0475      * @c null is returned.
0476      *
0477      * @return QPainter* The Scene's QPainter or @c null.
0478      */
0479     QPainter *scenePainter();
0480     void reconfigure();
0481 
0482     QByteArray readRootProperty(long atom, long type, int format) const;
0483     /**
0484      * @brief Announces support for the feature with the given name. If no other Effect
0485      * has announced support for this feature yet, an X11 property will be installed on
0486      * the root window.
0487      *
0488      * The Effect will be notified for events through the signal propertyNotify().
0489      *
0490      * To remove the support again use removeSupportProperty. When an Effect is
0491      * destroyed it is automatically taken care of removing the support. It is not
0492      * required to call removeSupportProperty in the Effect's cleanup handling.
0493      *
0494      * @param propertyName The name of the property to announce support for
0495      * @param effect The effect which announces support
0496      * @return xcb_atom_t The created X11 atom
0497      * @see removeSupportProperty
0498      * @since 4.11
0499      */
0500     xcb_atom_t announceSupportProperty(const QByteArray &propertyName, Effect *effect);
0501     /**
0502      * @brief Removes support for the feature with the given name. If there is no other Effect left
0503      * which has announced support for the given property, the property will be removed from the
0504      * root window.
0505      *
0506      * In case the Effect had not registered support, calling this function does not change anything.
0507      *
0508      * @param propertyName The name of the property to remove support for
0509      * @param effect The effect which had registered the property.
0510      * @see announceSupportProperty
0511      * @since 4.11
0512      */
0513     void removeSupportProperty(const QByteArray &propertyName, Effect *effect);
0514 
0515     /**
0516      * Returns @a true if the active window decoration has shadow API hooks.
0517      */
0518     bool hasDecorationShadows() const;
0519 
0520     /**
0521      * Returns @a true if the window decorations use the alpha channel, and @a false otherwise.
0522      * @since 4.5
0523      */
0524     bool decorationsHaveAlpha() const;
0525 
0526     /**
0527      * Allows an effect to trigger a reload of itself.
0528      * This can be used by an effect which needs to be reloaded when screen geometry changes.
0529      * It is possible that the effect cannot be loaded again as it's supported method does no longer
0530      * hold.
0531      * @param effect The effect to reload
0532      * @since 4.8
0533      */
0534     void reloadEffect(Effect *effect);
0535     Effect *provides(Effect::Feature ef);
0536     Effect *findEffect(const QString &name) const;
0537     QStringList loadedEffects() const;
0538     QStringList listOfEffects() const;
0539     void unloadAllEffects();
0540     QStringList activeEffects() const;
0541     bool isEffectActive(const QString &pluginId) const;
0542 
0543     /**
0544      * Whether the screen is currently considered as locked.
0545      * Note for technical reasons this is not always possible to detect. The screen will only
0546      * be considered as locked if the screen locking process implements the
0547      * org.freedesktop.ScreenSaver interface.
0548      *
0549      * @returns @c true if the screen is currently locked, @c false otherwise
0550      * @see screenLockingChanged
0551      * @since 4.11
0552      */
0553     bool isScreenLocked() const;
0554 
0555     /**
0556      * @brief Makes the OpenGL compositing context current.
0557      *
0558      * If the compositing backend is not using OpenGL, this method returns @c false.
0559      *
0560      * @return bool @c true if the context became current, @c false otherwise.
0561      */
0562     bool makeOpenGLContextCurrent();
0563     /**
0564      * @brief Makes a null OpenGL context current resulting in no context
0565      * being current.
0566      *
0567      * If the compositing backend is not OpenGL based, this method is a noop.
0568      *
0569      * There is normally no reason for an Effect to call this method.
0570      */
0571     void doneOpenGLContextCurrent();
0572 
0573     xcb_connection_t *xcbConnection() const;
0574     xcb_window_t x11RootWindow() const;
0575 
0576     /**
0577      * Interface to the Wayland display: this is relevant only
0578      * on Wayland, on X11 it will be nullptr
0579      * @since 5.5
0580      */
0581     Display *waylandDisplay() const;
0582 
0583     /**
0584      * Whether animations are supported by the Scene.
0585      * If this method returns @c false Effects are supposed to not
0586      * animate transitions.
0587      *
0588      * @returns Whether the Scene can drive animations
0589      * @since 5.8
0590      */
0591     bool animationsSupported() const;
0592 
0593     /**
0594      * The current cursor image of the Platform.
0595      * @see cursorPos
0596      * @since 5.9
0597      */
0598     PlatformCursorImage cursorImage() const;
0599 
0600     /**
0601      * The cursor image should be hidden.
0602      * @see showCursor
0603      * @since 5.9
0604      */
0605     void hideCursor();
0606 
0607     /**
0608      * The cursor image should be shown again after having been hidden.
0609      * @see hideCursor
0610      * @since 5.9
0611      */
0612     void showCursor();
0613 
0614     /**
0615      * @returns Whether or not the cursor is currently hidden
0616      */
0617     bool isCursorHidden() const;
0618 
0619     /**
0620      * Starts an interactive window selection process.
0621      *
0622      * Once the user selected a window the @p callback is invoked with the selected EffectWindow as
0623      * argument. In case the user cancels the interactive window selection or selecting a window is currently
0624      * not possible (e.g. screen locked) the @p callback is invoked with a @c nullptr argument.
0625      *
0626      * During the interactive window selection the cursor is turned into a crosshair cursor.
0627      *
0628      * @param callback The function to invoke once the interactive window selection ends
0629      * @since 5.9
0630      */
0631     void startInteractiveWindowSelection(std::function<void(KWin::EffectWindow *)> callback);
0632 
0633     /**
0634      * Starts an interactive position selection process.
0635      *
0636      * Once the user selected a position on the screen the @p callback is invoked with
0637      * the selected point as argument. In case the user cancels the interactive position selection
0638      * or selecting a position is currently not possible (e.g. screen locked) the @p callback
0639      * is invoked with a point at @c -1 as x and y argument.
0640      *
0641      * During the interactive window selection the cursor is turned into a crosshair cursor.
0642      *
0643      * @param callback The function to invoke once the interactive position selection ends
0644      * @since 5.9
0645      */
0646     void startInteractivePositionSelection(std::function<void(const QPointF &)> callback);
0647 
0648     /**
0649      * Shows an on-screen-message. To hide it again use hideOnScreenMessage.
0650      *
0651      * @param message The message to show
0652      * @param iconName The optional themed icon name
0653      * @see hideOnScreenMessage
0654      * @since 5.9
0655      */
0656     void showOnScreenMessage(const QString &message, const QString &iconName = QString());
0657 
0658     /**
0659      * Flags for how to hide a shown on-screen-message
0660      * @see hideOnScreenMessage
0661      * @since 5.9
0662      */
0663     enum class OnScreenMessageHideFlag {
0664         /**
0665          * The on-screen-message should skip the close window animation.
0666          * @see EffectWindow::skipsCloseAnimation
0667          */
0668         SkipsCloseAnimation = 1
0669     };
0670     Q_DECLARE_FLAGS(OnScreenMessageHideFlags, OnScreenMessageHideFlag)
0671     /**
0672      * Hides a previously shown on-screen-message again.
0673      * @param flags The flags for how to hide the message
0674      * @see showOnScreenMessage
0675      * @since 5.9
0676      */
0677     void hideOnScreenMessage(OnScreenMessageHideFlags flags = OnScreenMessageHideFlags());
0678 
0679     /*
0680      * @returns The configuration used by the EffectsHandler.
0681      * @since 5.10
0682      */
0683     KSharedConfigPtr config() const;
0684 
0685     /**
0686      * @returns The global input configuration (kcminputrc)
0687      * @since 5.10
0688      */
0689     KSharedConfigPtr inputConfig() const;
0690 
0691     /**
0692      * Returns if activeFullScreenEffect is set
0693      */
0694     bool hasActiveFullScreenEffect() const;
0695 
0696     /**
0697      * Render the supplied OffscreenQuickView onto the scene
0698      * It can be called at any point during the scene rendering
0699      * @since 5.18
0700      */
0701     void renderOffscreenQuickView(const RenderTarget &renderTarget, const RenderViewport &viewport, OffscreenQuickView *effectQuickView) const;
0702 
0703     /**
0704      * The status of the session i.e if the user is logging out
0705      * @since 5.18
0706      */
0707     SessionState sessionState() const;
0708 
0709     /**
0710      * Returns the list of all the screens connected to the system.
0711      */
0712     QList<Output *> screens() const;
0713     Output *screenAt(const QPoint &point) const;
0714     Output *findScreen(const QString &name) const;
0715     Output *findScreen(int screenId) const;
0716 
0717     KWin::EffectWindow *inputPanel() const;
0718     bool isInputPanelOverlay() const;
0719 
0720     QQmlEngine *qmlEngine() const;
0721 
0722     /**
0723      * @returns whether or not any effect is currently active where KWin should not use direct scanout
0724      */
0725     bool blocksDirectScanout() const;
0726 
0727     WorkspaceScene *scene() const
0728     {
0729         return m_scene;
0730     }
0731 
0732     bool touchDown(qint32 id, const QPointF &pos, std::chrono::microseconds time);
0733     bool touchMotion(qint32 id, const QPointF &pos, std::chrono::microseconds time);
0734     bool touchUp(qint32 id, std::chrono::microseconds time);
0735 
0736     bool tabletToolEvent(KWin::TabletEvent *event);
0737     bool tabletToolButtonEvent(uint button, bool pressed, const KWin::TabletToolId &tabletToolId, std::chrono::microseconds time);
0738     bool tabletPadButtonEvent(uint button, bool pressed, const KWin::TabletPadId &tabletPadId, std::chrono::microseconds time);
0739     bool tabletPadStripEvent(int number, int position, bool isFinger, const KWin::TabletPadId &tabletPadId, std::chrono::microseconds time);
0740     bool tabletPadRingEvent(int number, int position, bool isFinger, const KWin::TabletPadId &tabletPadId, std::chrono::microseconds time);
0741 
0742     void highlightWindows(const QList<EffectWindow *> &windows);
0743 
0744     bool isPropertyTypeRegistered(xcb_atom_t atom) const
0745     {
0746         return registered_atoms.contains(atom);
0747     }
0748 
0749 Q_SIGNALS:
0750     /**
0751      * This signal is emitted whenever a new @a screen is added to the system.
0752      */
0753     void screenAdded(KWin::Output *screen);
0754     /**
0755      * This signal is emitted whenever a @a screen is removed from the system.
0756      */
0757     void screenRemoved(KWin::Output *screen);
0758     /**
0759      * Signal emitted when the current desktop changed.
0760      * @param oldDesktop The previously current desktop
0761      * @param newDesktop The new current desktop
0762      * @param with The window which is taken over to the new desktop, can be NULL
0763      * @since 4.9
0764      */
0765     void desktopChanged(KWin::VirtualDesktop *oldDesktop, KWin::VirtualDesktop *newDesktop, KWin::EffectWindow *with);
0766 
0767     /**
0768      * Signal emmitted while desktop is changing for animation.
0769      * @param currentDesktop The current desktop untiotherwise.
0770      * @param offset The current desktop offset.
0771      * offset.x() = .6 means 60% of the way to the desktop to the right.
0772      * Positive Values means Up and Right.
0773      */
0774     void desktopChanging(KWin::VirtualDesktop *currentDesktop, QPointF offset, KWin::EffectWindow *with);
0775     void desktopChangingCancelled();
0776     void desktopAdded(KWin::VirtualDesktop *desktop);
0777     void desktopRemoved(KWin::VirtualDesktop *desktop);
0778 
0779     /**
0780      * Emitted when the virtual desktop grid layout changes
0781      * @param size new size
0782      * @since 5.25
0783      */
0784     void desktopGridSizeChanged(const QSize &size);
0785     /**
0786      * Emitted when the virtual desktop grid layout changes
0787      * @param width new width
0788      * @since 5.25
0789      */
0790     void desktopGridWidthChanged(int width);
0791     /**
0792      * Emitted when the virtual desktop grid layout changes
0793      * @param height new height
0794      * @since 5.25
0795      */
0796     void desktopGridHeightChanged(int height);
0797     /**
0798      * Signal emitted when the desktop showing ("dashboard") state changed
0799      * The desktop is risen to the keepAbove layer, you may want to elevate
0800      * windows or such.
0801      * @since 5.3
0802      */
0803     void showingDesktopChanged(bool);
0804     /**
0805      * Signal emitted when a new window has been added to the Workspace.
0806      * @param w The added window
0807      * @since 4.7
0808      */
0809     void windowAdded(KWin::EffectWindow *w);
0810     /**
0811      * Signal emitted when a window is being removed from the Workspace.
0812      * An effect which wants to animate the window closing should connect
0813      * to this signal and reference the window by using
0814      * refWindow
0815      * @param w The window which is being closed
0816      * @since 4.7
0817      */
0818     void windowClosed(KWin::EffectWindow *w);
0819     /**
0820      * Signal emitted when a window get's activated.
0821      * @param w The new active window, or @c NULL if there is no active window.
0822      * @since 4.7
0823      */
0824     void windowActivated(KWin::EffectWindow *w);
0825     /**
0826      * Signal emitted when a window is deleted.
0827      * This means that a closed window is not referenced any more.
0828      * An effect bookkeeping the closed windows should connect to this
0829      * signal to clean up the internal references.
0830      * @param w The window which is going to be deleted.
0831      * @see EffectWindow::refWindow
0832      * @see EffectWindow::unrefWindow
0833      * @see windowClosed
0834      * @since 4.7
0835      */
0836     void windowDeleted(KWin::EffectWindow *w);
0837     /**
0838      * Signal emitted when a tabbox is added.
0839      * An effect who wants to replace the tabbox with itself should use refTabBox.
0840      * @param mode The TabBoxMode.
0841      * @see refTabBox
0842      * @see tabBoxClosed
0843      * @see tabBoxUpdated
0844      * @see tabBoxKeyEvent
0845      * @since 4.7
0846      */
0847     void tabBoxAdded(int mode);
0848     /**
0849      * Signal emitted when the TabBox was closed by KWin core.
0850      * An effect which referenced the TabBox should use unrefTabBox to unref again.
0851      * @see unrefTabBox
0852      * @see tabBoxAdded
0853      * @since 4.7
0854      */
0855     void tabBoxClosed();
0856     /**
0857      * Signal emitted when the selected TabBox window changed or the TabBox List changed.
0858      * An effect should only response to this signal if it referenced the TabBox with refTabBox.
0859      * @see refTabBox
0860      * @see currentTabBoxWindowList
0861      * @see currentTabBoxDesktopList
0862      * @see currentTabBoxWindow
0863      * @see currentTabBoxDesktop
0864      * @since 4.7
0865      */
0866     void tabBoxUpdated();
0867     /**
0868      * Signal emitted when a key event, which is not handled by TabBox directly is, happens while
0869      * TabBox is active. An effect might use the key event to e.g. change the selected window.
0870      * An effect should only response to this signal if it referenced the TabBox with refTabBox.
0871      * @param event The key event not handled by TabBox directly
0872      * @see refTabBox
0873      * @since 4.7
0874      */
0875     void tabBoxKeyEvent(QKeyEvent *event);
0876     /**
0877      * Signal emitted when mouse changed.
0878      * If an effect needs to get updated mouse positions, it needs to first call startMousePolling.
0879      * For a fullscreen effect it is better to use an input window and react on windowInputMouseEvent.
0880      * @param pos The new mouse position
0881      * @param oldpos The previously mouse position
0882      * @param buttons The pressed mouse buttons
0883      * @param oldbuttons The previously pressed mouse buttons
0884      * @param modifiers Pressed keyboard modifiers
0885      * @param oldmodifiers Previously pressed keyboard modifiers.
0886      * @see startMousePolling
0887      * @since 4.7
0888      */
0889     void mouseChanged(const QPointF &pos, const QPointF &oldpos,
0890                       Qt::MouseButtons buttons, Qt::MouseButtons oldbuttons,
0891                       Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers oldmodifiers);
0892     /**
0893      * Signal emitted when the cursor shape changed.
0894      * You'll likely want to query the current cursor as reaction: xcb_xfixes_get_cursor_image_unchecked
0895      * Connection to this signal is tracked, so if you don't need it anymore, disconnect from it to stop cursor event filtering
0896      */
0897     void cursorShapeChanged();
0898     /**
0899      * Receives events registered for using registerPropertyType.
0900      * Use readProperty() to get the property data.
0901      * Note that the property may be already set on the window, so doing the same
0902      * processing from windowAdded() (e.g. simply calling propertyNotify() from it)
0903      * is usually needed.
0904      * @param w The window whose property changed, is @c null if it is a root window property
0905      * @param atom The property
0906      * @since 4.7
0907      */
0908     void propertyNotify(KWin::EffectWindow *w, long atom);
0909 
0910     /**
0911      * This signal is emitted when the global
0912      * activity is changed
0913      * @param id id of the new current activity
0914      * @since 4.9
0915      */
0916     void currentActivityChanged(const QString &id);
0917     /**
0918      * This signal is emitted when a new activity is added
0919      * @param id id of the new activity
0920      * @since 4.9
0921      */
0922     void activityAdded(const QString &id);
0923     /**
0924      * This signal is emitted when the activity
0925      * is removed
0926      * @param id id of the removed activity
0927      * @since 4.9
0928      */
0929     void activityRemoved(const QString &id);
0930     /**
0931      * This signal is emitted when the screen got locked or unlocked.
0932      * @param locked @c true if the screen is now locked, @c false if it is now unlocked
0933      * @since 4.11
0934      */
0935     void screenLockingChanged(bool locked);
0936 
0937     /**
0938      * This signal is emitted just before the screen locker tries to grab keys and lock the screen
0939      * Effects should release any grabs immediately
0940      * @since 5.17
0941      */
0942     void screenAboutToLock();
0943 
0944     /**
0945      * This signels is emitted when ever the stacking order is change, ie. a window is risen
0946      * or lowered
0947      * @since 4.10
0948      */
0949     void stackingOrderChanged();
0950     /**
0951      * This signal is emitted when the user starts to approach the @p border with the mouse.
0952      * The @p factor describes how far away the mouse is in a relative mean. The values are in
0953      * [0.0, 1.0] with 0.0 being emitted when first entered and on leaving. The value 1.0 means that
0954      * the @p border is reached with the mouse. So the values are well suited for animations.
0955      * The signal is always emitted when the mouse cursor position changes.
0956      * @param border The screen edge which is being approached
0957      * @param factor Value in range [0.0,1.0] to describe how close the mouse is to the border
0958      * @param geometry The geometry of the edge which is being approached
0959      * @since 4.11
0960      */
0961     void screenEdgeApproaching(ElectricBorder border, qreal factor, const QRect &geometry);
0962     /**
0963      * Emitted whenever the virtualScreenSize changes.
0964      * @see virtualScreenSize()
0965      * @since 5.0
0966      */
0967     void virtualScreenSizeChanged();
0968     /**
0969      * Emitted whenever the virtualScreenGeometry changes.
0970      * @see virtualScreenGeometry()
0971      * @since 5.0
0972      */
0973     void virtualScreenGeometryChanged();
0974 
0975     /**
0976      * This signal gets emitted when the data on EffectWindow @p w for @p role changed.
0977      *
0978      * An Effect can connect to this signal to read the new value and react on it.
0979      * E.g. an Effect which does not operate on windows grabbed by another Effect wants
0980      * to cancel the already scheduled animation if another Effect adds a grab.
0981      *
0982      * @param w The EffectWindow for which the data changed
0983      * @param role The data role which changed
0984      * @see EffectWindow::setData
0985      * @see EffectWindow::data
0986      * @since 5.8.4
0987      */
0988     void windowDataChanged(KWin::EffectWindow *w, int role);
0989 
0990     /**
0991      * The xcb connection changed, either a new xcbConnection got created or the existing one
0992      * got destroyed.
0993      * Effects can use this to refetch the properties they want to set.
0994      *
0995      * When the xcbConnection changes also the x11RootWindow becomes invalid.
0996      * @see xcbConnection
0997      * @see x11RootWindow
0998      * @since 5.11
0999      */
1000     void xcbConnectionChanged();
1001 
1002     /**
1003      * This signal is emitted when active fullscreen effect changed.
1004      *
1005      * @see activeFullScreenEffect
1006      * @see setActiveFullScreenEffect
1007      * @since 5.14
1008      */
1009     void activeFullScreenEffectChanged();
1010 
1011     /**
1012      * This signal is emitted when active fullscreen effect changed to being
1013      * set or unset
1014      *
1015      * @see activeFullScreenEffect
1016      * @see setActiveFullScreenEffect
1017      * @since 5.15
1018      */
1019     void hasActiveFullScreenEffectChanged();
1020 
1021     /**
1022      * This signal is emitted when the session state was changed
1023      * @since 5.18
1024      */
1025     void sessionStateChanged();
1026 
1027     void startupAdded(const QString &id, const QIcon &icon);
1028     void startupChanged(const QString &id, const QIcon &icon);
1029     void startupRemoved(const QString &id);
1030 
1031     void inputPanelChanged();
1032 
1033 public Q_SLOTS:
1034     // slots for D-Bus interface
1035     Q_SCRIPTABLE void reconfigureEffect(const QString &name);
1036     Q_SCRIPTABLE bool loadEffect(const QString &name);
1037     Q_SCRIPTABLE void toggleEffect(const QString &name);
1038     Q_SCRIPTABLE void unloadEffect(const QString &name);
1039     Q_SCRIPTABLE bool isEffectLoaded(const QString &name) const;
1040     Q_SCRIPTABLE bool isEffectSupported(const QString &name);
1041     Q_SCRIPTABLE QList<bool> areEffectsSupported(const QStringList &names);
1042     Q_SCRIPTABLE QString supportInformation(const QString &name) const;
1043     Q_SCRIPTABLE QString debug(const QString &name, const QString &parameter = QString()) const;
1044 
1045 protected:
1046     void connectNotify(const QMetaMethod &signal) override;
1047     void disconnectNotify(const QMetaMethod &signal) override;
1048     void effectsChanged();
1049     void setupWindowConnections(KWin::Window *window);
1050 
1051     /**
1052      * Default implementation does nothing and returns @c true.
1053      */
1054     virtual bool doGrabKeyboard();
1055     /**
1056      * Default implementation does nothing.
1057      */
1058     virtual void doUngrabKeyboard();
1059 
1060     /**
1061      * Default implementation sets Effects override cursor on the PointerInputRedirection.
1062      */
1063     virtual void doStartMouseInterception(Qt::CursorShape shape);
1064 
1065     /**
1066      * Default implementation removes the Effects override cursor on the PointerInputRedirection.
1067      */
1068     virtual void doStopMouseInterception();
1069 
1070     /**
1071      * Default implementation does nothing
1072      */
1073     virtual void doCheckInputWindowStacking();
1074 
1075     void registerPropertyType(long atom, bool reg);
1076     void destroyEffect(Effect *effect);
1077     void reconfigureEffects();
1078 
1079     typedef QList<Effect *> EffectsList;
1080     typedef EffectsList::const_iterator EffectsIterator;
1081 
1082     Effect *keyboard_grab_effect;
1083     Effect *fullscreen_effect;
1084     QMultiMap<int, EffectPair> effect_order;
1085     QHash<long, int> registered_atoms;
1086     QList<EffectPair> loaded_effects;
1087     CompositingType compositing_type;
1088     EffectsList m_activeEffects;
1089     EffectsIterator m_currentDrawWindowIterator;
1090     EffectsIterator m_currentPaintWindowIterator;
1091     EffectsIterator m_currentPaintScreenIterator;
1092     typedef QHash<QByteArray, QList<Effect *>> PropertyEffectMap;
1093     PropertyEffectMap m_propertiesForEffects;
1094     QHash<QByteArray, qulonglong> m_managedProperties;
1095     Compositor *m_compositor;
1096     WorkspaceScene *m_scene;
1097     QList<Effect *> m_grabbedMouseEffects;
1098     EffectLoader *m_effectLoader;
1099     int m_trackingCursorChanges;
1100     std::unique_ptr<WindowPropertyNotifyX11Filter> m_x11WindowPropertyNotify;
1101 };
1102 
1103 /**
1104  * Pointer to the global EffectsHandler object.
1105  */
1106 extern KWIN_EXPORT EffectsHandler *effects;
1107 
1108 } // namespace
1109 
1110 /** @} */