You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

1114 lines
40 KiB

/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2006 Lubos Lunak <l.lunak@kde.org>
SPDX-FileCopyrightText: 2009 Lucas Murray <lmurray@undefinedfire.com>
SPDX-FileCopyrightText: 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "effect/effect.h"
#include "effect/effectwindow.h"
#include <QEasingCurve>
#include <QIcon>
#include <QPair>
#include <QRect>
#include <QRegion>
#include <QSet>
#include <QHash>
#include <QList>
#include <QLoggingCategory>
#include <QStack>
#include <netwm.h>
#include <climits>
#include <cmath>
#include <functional>
#include <optional>
#include <span>
class KConfigGroup;
class QFont;
class QKeyEvent;
class QMatrix4x4;
class QMouseEvent;
class QWheelEvent;
class QAction;
class QTabletEvent;
class QQmlEngine;
/**
* Logging category to be used inside the KWin effects.
* Do not use in this library.
*/
Q_DECLARE_LOGGING_CATEGORY(KWINEFFECTS)
namespace KDecoration2
{
class Decoration;
}
namespace KWin
{
class SurfaceInterface;
class Display;
class PaintDataPrivate;
class WindowPaintDataPrivate;
class Compositor;
class EffectLoader;
class EffectWindow;
class EffectWindowGroup;
class OffscreenQuickView;
class Group;
class Output;
class Effect;
class TabletEvent;
class TabletPadId;
class TabletToolId;
class Window;
class WindowItem;
class WindowPropertyNotifyX11Filter;
class WorkspaceScene;
class VirtualDesktop;
typedef QPair<QString, Effect *> EffectPair;
/**
* EffectWindow::setData() and EffectWindow::data() global roles.
* All values between 0 and 999 are reserved for global roles.
*/
enum DataRole {
// Grab roles are used to force all other animations to ignore the window.
// The value of the data is set to the Effect's `this` value.
WindowAddedGrabRole = 1,
WindowClosedGrabRole,
WindowMinimizedGrabRole,
WindowUnminimizedGrabRole,
WindowForceBlurRole, ///< For fullscreen effects to enforce blurring of windows,
WindowForceBackgroundContrastRole, ///< For fullscreen effects to enforce the background contrast,
};
/**
* @short Manager class that handles all the effects.
*
* This class creates Effect objects and calls it's appropriate methods.
*
* Effect objects can call methods of this class to interact with the
* workspace, e.g. to activate or move a specific window, change current
* desktop or create a special input window to receive mouse and keyboard
* events.
*/
class KWIN_EXPORT EffectsHandler : public QObject
{
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)
Q_PROPERTY(KWin::VirtualDesktop *currentDesktop READ currentDesktop WRITE setCurrentDesktop NOTIFY desktopChanged)
Q_PROPERTY(QString currentActivity READ currentActivity NOTIFY currentActivityChanged)
Q_PROPERTY(KWin::EffectWindow *activeWindow READ activeWindow WRITE activateWindow NOTIFY windowActivated)
Q_PROPERTY(QSize desktopGridSize READ desktopGridSize NOTIFY desktopGridSizeChanged)
Q_PROPERTY(int desktopGridWidth READ desktopGridWidth NOTIFY desktopGridWidthChanged)
Q_PROPERTY(int desktopGridHeight READ desktopGridHeight NOTIFY desktopGridHeightChanged)
Q_PROPERTY(int workspaceWidth READ workspaceWidth)
Q_PROPERTY(int workspaceHeight READ workspaceHeight)
Q_PROPERTY(QList<KWin::VirtualDesktop *> desktops READ desktops)
Q_PROPERTY(bool optionRollOverDesktops READ optionRollOverDesktops)
Q_PROPERTY(KWin::Output *activeScreen READ activeScreen)
/**
* Factor by which animation speed in the effect should be modified (multiplied).
* If configurable in the effect itself, the option should have also 'default'
* animation speed. The actual value should be determined using animationTime().
* Note: The factor can be also 0, so make sure your code can cope with 0ms time
* if used manually.
*/
Q_PROPERTY(qreal animationTimeFactor READ animationTimeFactor)
Q_PROPERTY(QList<EffectWindow *> stackingOrder READ stackingOrder)
/**
* Whether window decorations use the alpha channel.
*/
Q_PROPERTY(bool decorationsHaveAlpha READ decorationsHaveAlpha)
Q_PROPERTY(CompositingType compositingType READ compositingType CONSTANT)
Q_PROPERTY(QPointF cursorPos READ cursorPos)
Q_PROPERTY(QSize virtualScreenSize READ virtualScreenSize NOTIFY virtualScreenSizeChanged)
Q_PROPERTY(QRect virtualScreenGeometry READ virtualScreenGeometry NOTIFY virtualScreenGeometryChanged)
Q_PROPERTY(bool hasActiveFullScreenEffect READ hasActiveFullScreenEffect NOTIFY hasActiveFullScreenEffectChanged)
/**
* The status of the session i.e if the user is logging out
* @since 5.18
*/
Q_PROPERTY(KWin::SessionState sessionState READ sessionState NOTIFY sessionStateChanged)
Q_PROPERTY(KWin::EffectWindow *inputPanel READ inputPanel NOTIFY inputPanelChanged)
friend class Effect;
public:
using TouchBorderCallback = std::function<void(ElectricBorder border, const QPointF &, Output *screen)>;
EffectsHandler(Compositor *compositor, WorkspaceScene *scene);
~EffectsHandler() override;
// internal (used by kwin core or compositing code)
void startPaint();
// for use by effects
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime);
void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, Output *screen);
void postPaintScreen();
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime);
void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data);
void postPaintWindow(EffectWindow *w);
void drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data);
void renderWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data);
QVariant kwinOption(KWinOption kwopt);
/**
* Sets the cursor while the mouse is intercepted.
* @see startMouseInterception
* @since 4.11
*/
virtual void defineCursor(Qt::CursorShape shape);
QPointF cursorPos() const;
bool grabKeyboard(Effect *effect);
void ungrabKeyboard();
/**
* Ensures that all mouse events are sent to the @p effect.
* No window will get the mouse events. Only fullscreen effects providing a custom user interface should
* be using this method. The input events are delivered to Effect::windowInputMouseEvent.
*
* @note This method does not perform an X11 mouse grab. On X11 a fullscreen input window is raised above
* all other windows, but no grab is performed.
*
* @param effect The effect
* @param shape Sets the cursor to be used while the mouse is intercepted
* @see stopMouseInterception
* @see Effect::windowInputMouseEvent
* @since 4.11
*/
void startMouseInterception(Effect *effect, Qt::CursorShape shape);
/**
* Releases the hold mouse interception for @p effect
* @see startMouseInterception
* @since 4.11
*/
void stopMouseInterception(Effect *effect);
bool isMouseInterception() const;
bool checkInputWindowEvent(QMouseEvent *e);
bool checkInputWindowEvent(QWheelEvent *e);
void checkInputWindowStacking();
void grabbedKeyboardEvent(QKeyEvent *e);
bool hasKeyboardGrab() const;
/**
* @brief Registers a global pointer shortcut with the provided @p action.
*
* @param modifiers The keyboard modifiers which need to be holded
* @param pointerButtons The pointer buttons which need to be pressed
* @param action The action which gets triggered when the shortcut matches
*/
void registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action);
/**
* @brief Registers a global axis shortcut with the provided @p action.
*
* @param modifiers The keyboard modifiers which need to be holded
* @param axis The direction in which the axis needs to be moved
* @param action The action which gets triggered when the shortcut matches
*/
void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action);
/**
* @brief Registers a global touchpad swipe gesture shortcut with the provided @p action.
*
* @param direction The direction for the swipe
* @param action The action which gets triggered when the gesture triggers
* @since 5.10
*/
void registerTouchpadSwipeShortcut(SwipeDirection dir, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback = {});
void registerTouchpadPinchShortcut(PinchDirection dir, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback = {});
/**
* @brief Registers a global touchscreen swipe gesture shortcut with the provided @p action.
*
* @param direction The direction for the swipe
* @param action The action which gets triggered when the gesture triggers
* @since 5.25
*/
void registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function<void(qreal)> progressCallback);
// Mouse polling
void startMousePolling();
void stopMousePolling();
void reserveElectricBorder(ElectricBorder border, Effect *effect);
void unreserveElectricBorder(ElectricBorder border, Effect *effect);
/**
* Registers the given @p action for the given @p border to be activated through
* a touch swipe gesture.
*
* If the @p border gets triggered through a touch swipe gesture the QAction::triggered
* signal gets invoked.
*
* To unregister the touch screen action either delete the @p action or
* invoke unregisterTouchBorder.
*
* @see unregisterTouchBorder
* @since 5.10
*/
void registerTouchBorder(ElectricBorder border, QAction *action);
/**
* Registers the given @p action for the given @p border to be activated through
* a touch swipe gesture.
*
* If the @p border gets triggered through a touch swipe gesture the QAction::triggered
* signal gets invoked.
*
* progressCallback will be dinamically called each time the touch position is updated
* to show the effect "partially" activated
*
* To unregister the touch screen action either delete the @p action or
* invoke unregisterTouchBorder.
*
* @see unregisterTouchBorder
* @since 5.25
*/
void registerRealtimeTouchBorder(ElectricBorder border, QAction *action, TouchBorderCallback progressCallback);
/**
* Unregisters the given @p action for the given touch @p border.
*
* @see registerTouchBorder
* @since 5.10
*/
void unregisterTouchBorder(ElectricBorder border, QAction *action);
// functions that allow controlling windows/desktop
void activateWindow(KWin::EffectWindow *c);
KWin::EffectWindow *activeWindow() const;
Q_SCRIPTABLE void moveWindow(KWin::EffectWindow *w, const QPoint &pos, bool snap = false, double snapAdjust = 1.0);
/**
* Moves a window to the given desktops
* On X11, the window will end up on the last window in the list
* Setting this to an empty list will set the window on all desktops
*/
Q_SCRIPTABLE void windowToDesktops(KWin::EffectWindow *w, const QList<KWin::VirtualDesktop *> &desktops);
Q_SCRIPTABLE void windowToScreen(KWin::EffectWindow *w, Output *screen);
void setShowingDesktop(bool showing);
// Activities
/**
* @returns The ID of the current activity.
*/
QString currentActivity() const;
// Desktops
/**
* @returns The current desktop.
*/
VirtualDesktop *currentDesktop() const;
/**
* @returns Total number of desktops currently in existence.
*/
QList<VirtualDesktop *> desktops() const;
/**
* Set the current desktop to @a desktop.
*/
void setCurrentDesktop(KWin::VirtualDesktop *desktop);
/**
* @returns The size of desktop layout in grid units.
*/
QSize desktopGridSize() const;
/**
* @returns The width of desktop layout in grid units.
*/
int desktopGridWidth() const;
/**
* @returns The height of desktop layout in grid units.
*/
int desktopGridHeight() const;
/**
* @returns The width of desktop layout in pixels.
*/
int workspaceWidth() const;
/**
* @returns The height of desktop layout in pixels.
*/
int workspaceHeight() const;
/**
* @returns The desktop at the point @a coords or 0 if no desktop exists at that
* point. @a coords is to be in grid units.
*/
VirtualDesktop *desktopAtCoords(QPoint coords) const;
/**
* @returns The coords of the specified @a desktop in grid units.
*/
QPoint desktopGridCoords(VirtualDesktop *desktop) const;
/**
* @returns The coords of the top-left corner of @a desktop in pixels.
*/
QPoint desktopCoords(VirtualDesktop *desktop) const;
/**
* @returns The desktop above the given @a desktop. Wraps around to the bottom of
* the layout if @a wrap is set. If @a id is not set use the current one.
*/
Q_SCRIPTABLE KWin::VirtualDesktop *desktopAbove(KWin::VirtualDesktop *desktop = nullptr, bool wrap = true) const;
/**
* @returns The desktop to the right of the given @a desktop. Wraps around to the
* left of the layout if @a wrap is set. If @a id is not set use the current one.
*/
Q_SCRIPTABLE KWin::VirtualDesktop *desktopToRight(KWin::VirtualDesktop *desktop = nullptr, bool wrap = true) const;
/**
* @returns The desktop below the given @a desktop. Wraps around to the top of the
* layout if @a wrap is set. If @a id is not set use the current one.
*/
Q_SCRIPTABLE KWin::VirtualDesktop *desktopBelow(KWin::VirtualDesktop *desktop = nullptr, bool wrap = true) const;
/**
* @returns The desktop to the left of the given @a desktop. Wraps around to the
* right of the layout if @a wrap is set. If @a id is not set use the current one.
*/
Q_SCRIPTABLE KWin::VirtualDesktop *desktopToLeft(KWin::VirtualDesktop *desktop = nullptr, bool wrap = true) const;
Q_SCRIPTABLE QString desktopName(KWin::VirtualDesktop *desktop) const;
bool optionRollOverDesktops() const;
Output *activeScreen() const; // Xinerama
QRectF clientArea(clientAreaOption, const Output *screen, const VirtualDesktop *desktop) const;
QRectF clientArea(clientAreaOption, const EffectWindow *c) const;
QRectF clientArea(clientAreaOption, const QPoint &p, const VirtualDesktop *desktop) const;
/**
* The bounding size of all screens combined. Overlapping areas
* are not counted multiple times.
*
* @see virtualScreenGeometry()
* @see virtualScreenSizeChanged()
* @since 5.0
*/
QSize virtualScreenSize() const;
/**
* The bounding geometry of all outputs combined. Always starts at (0,0) and has
* virtualScreenSize as it's size.
*
* @see virtualScreenSize()
* @see virtualScreenGeometryChanged()
* @since 5.0
*/
QRect virtualScreenGeometry() const;
/**
* Factor by which animation speed in the effect should be modified (multiplied).
* If configurable in the effect itself, the option should have also 'default'
* animation speed. The actual value should be determined using animationTime().
* Note: The factor can be also 0, so make sure your code can cope with 0ms time
* if used manually.
*/
double animationTimeFactor() const;
Q_SCRIPTABLE KWin::EffectWindow *findWindow(WId id) const;
Q_SCRIPTABLE KWin::EffectWindow *findWindow(SurfaceInterface *surf) const;
/**
* Finds the EffectWindow for the internal window @p w.
* If there is no such window @c null is returned.
*
* On Wayland this returns the internal window. On X11 it returns an Unamanged with the
* window id matching that of the provided window @p w.
*
* @since 5.16
*/
Q_SCRIPTABLE KWin::EffectWindow *findWindow(QWindow *w) const;
/**
* Finds the EffectWindow for the Window with KWin internal @p id.
* If there is no such window @c null is returned.
*
* @since 5.16
*/
Q_SCRIPTABLE KWin::EffectWindow *findWindow(const QUuid &id) const;
QList<EffectWindow *> stackingOrder() const;
// window will be temporarily painted as if being at the top of the stack
Q_SCRIPTABLE void setElevatedWindow(KWin::EffectWindow *w, bool set);
void setTabBoxWindow(EffectWindow *);
QList<EffectWindow *> currentTabBoxWindowList() const;
void refTabBox();
void unrefTabBox();
void closeTabBox();
EffectWindow *currentTabBoxWindow() const;
void setActiveFullScreenEffect(Effect *e);
Effect *activeFullScreenEffect() const;
/**
* Schedules the entire workspace to be repainted next time.
* If you call it during painting (including prepaint) then it does not
* affect the current painting.
*/
Q_SCRIPTABLE void addRepaintFull();
Q_SCRIPTABLE void addRepaint(const QRectF &r);
Q_SCRIPTABLE void addRepaint(const QRect &r);
Q_SCRIPTABLE void addRepaint(const QRegion &r);
Q_SCRIPTABLE void addRepaint(int x, int y, int w, int h);
CompositingType compositingType() const;
/**
* @brief Whether the Compositor is OpenGL based (either GL 1 or 2).
*
* @return bool @c true in case of OpenGL based Compositor, @c false otherwise
*/
bool isOpenGLCompositing() const;
/**
* @brief Provides access to the QPainter which is rendering to the back buffer.
*
* Only relevant for CompositingType QPainterCompositing. For all other compositing types
* @c null is returned.
*
* @return QPainter* The Scene's QPainter or @c null.
*/
QPainter *scenePainter();
void reconfigure();
QByteArray readRootProperty(long atom, long type, int format) const;
/**
* @brief Announces support for the feature with the given name. If no other Effect
* has announced support for this feature yet, an X11 property will be installed on
* the root window.
*
* The Effect will be notified for events through the signal propertyNotify().
*
* To remove the support again use removeSupportProperty. When an Effect is
* destroyed it is automatically taken care of removing the support. It is not
* required to call removeSupportProperty in the Effect's cleanup handling.
*
* @param propertyName The name of the property to announce support for
* @param effect The effect which announces support
* @return xcb_atom_t The created X11 atom
* @see removeSupportProperty
* @since 4.11
*/
xcb_atom_t announceSupportProperty(const QByteArray &propertyName, Effect *effect);
/**
* @brief Removes support for the feature with the given name. If there is no other Effect left
* which has announced support for the given property, the property will be removed from the
* root window.
*
* In case the Effect had not registered support, calling this function does not change anything.
*
* @param propertyName The name of the property to remove support for
* @param effect The effect which had registered the property.
* @see announceSupportProperty
* @since 4.11
*/
void removeSupportProperty(const QByteArray &propertyName, Effect *effect);
/**
* Returns @a true if the active window decoration has shadow API hooks.
*/
bool hasDecorationShadows() const;
/**
* Returns @a true if the window decorations use the alpha channel, and @a false otherwise.
* @since 4.5
*/
bool decorationsHaveAlpha() const;
/**
* Allows an effect to trigger a reload of itself.
* This can be used by an effect which needs to be reloaded when screen geometry changes.
* It is possible that the effect cannot be loaded again as it's supported method does no longer
* hold.
* @param effect The effect to reload
* @since 4.8
*/
void reloadEffect(Effect *effect);
Effect *provides(Effect::Feature ef);
Effect *findEffect(const QString &name) const;
QStringList loadedEffects() const;
QStringList listOfEffects() const;
void unloadAllEffects();
QStringList activeEffects() const;
bool isEffectActive(const QString &pluginId) const;
/**
* Whether the screen is currently considered as locked.
* Note for technical reasons this is not always possible to detect. The screen will only
* be considered as locked if the screen locking process implements the
* org.freedesktop.ScreenSaver interface.
*
* @returns @c true if the screen is currently locked, @c false otherwise
* @see screenLockingChanged
* @since 4.11
*/
bool isScreenLocked() const;
/**
* @brief Makes the OpenGL compositing context current.
*
* If the compositing backend is not using OpenGL, this method returns @c false.
*
* @return bool @c true if the context became current, @c false otherwise.
*/
bool makeOpenGLContextCurrent();
/**
* @brief Makes a null OpenGL context current resulting in no context
* being current.
*
* If the compositing backend is not OpenGL based, this method is a noop.
*
* There is normally no reason for an Effect to call this method.
*/
void doneOpenGLContextCurrent();
xcb_connection_t *xcbConnection() const;
xcb_window_t x11RootWindow() const;
/**
* Interface to the Wayland display: this is relevant only
* on Wayland, on X11 it will be nullptr
* @since 5.5
*/
Display *waylandDisplay() const;
/**
* Whether animations are supported by the Scene.
* If this method returns @c false Effects are supposed to not
* animate transitions.
*
* @returns Whether the Scene can drive animations
* @since 5.8
*/
bool animationsSupported() const;
/**
* The current cursor image of the Platform.
* @see cursorPos
* @since 5.9
*/
PlatformCursorImage cursorImage() const;
/**
* The cursor image should be hidden.
* @see showCursor
* @since 5.9
*/
void hideCursor();
/**
* The cursor image should be shown again after having been hidden.
* @see hideCursor
* @since 5.9
*/
void showCursor();
/**
* @returns Whether or not the cursor is currently hidden
*/
bool isCursorHidden() const;
/**
* Starts an interactive window selection process.
*
* Once the user selected a window the @p callback is invoked with the selected EffectWindow as
* argument. In case the user cancels the interactive window selection or selecting a window is currently
* not possible (e.g. screen locked) the @p callback is invoked with a @c nullptr argument.
*
* During the interactive window selection the cursor is turned into a crosshair cursor.
*
* @param callback The function to invoke once the interactive window selection ends
* @since 5.9
*/
void startInteractiveWindowSelection(std::function<void(KWin::EffectWindow *)> callback);
/**
* Starts an interactive position selection process.
*
* Once the user selected a position on the screen the @p callback is invoked with
* the selected point as argument. In case the user cancels the interactive position selection
* or selecting a position is currently not possible (e.g. screen locked) the @p callback
* is invoked with a point at @c -1 as x and y argument.
*
* During the interactive window selection the cursor is turned into a crosshair cursor.
*
* @param callback The function to invoke once the interactive position selection ends
* @since 5.9
*/
void startInteractivePositionSelection(std::function<void(const QPointF &)> callback);
/**
* Shows an on-screen-message. To hide it again use hideOnScreenMessage.
*
* @param message The message to show
* @param iconName The optional themed icon name
* @see hideOnScreenMessage
* @since 5.9
*/
void showOnScreenMessage(const QString &message, const QString &iconName = QString());
/**
* Flags for how to hide a shown on-screen-message
* @see hideOnScreenMessage
* @since 5.9
*/
enum class OnScreenMessageHideFlag {
/**
* The on-screen-message should skip the close window animation.
* @see EffectWindow::skipsCloseAnimation
*/
SkipsCloseAnimation = 1
};
Q_DECLARE_FLAGS(OnScreenMessageHideFlags, OnScreenMessageHideFlag)
/**
* Hides a previously shown on-screen-message again.
* @param flags The flags for how to hide the message
* @see showOnScreenMessage
* @since 5.9
*/
void hideOnScreenMessage(OnScreenMessageHideFlags flags = OnScreenMessageHideFlags());
/*
* @returns The configuration used by the EffectsHandler.
* @since 5.10
*/
KSharedConfigPtr config() const;
/**
* @returns The global input configuration (kcminputrc)
* @since 5.10
*/
KSharedConfigPtr inputConfig() const;
/**
* Returns if activeFullScreenEffect is set
*/
bool hasActiveFullScreenEffect() const;
/**
* Render the supplied OffscreenQuickView onto the scene
* It can be called at any point during the scene rendering
* @since 5.18
*/
void renderOffscreenQuickView(const RenderTarget &renderTarget, const RenderViewport &viewport, OffscreenQuickView *effectQuickView) const;
/**
* The status of the session i.e if the user is logging out
* @since 5.18
*/
SessionState sessionState() const;
/**
* Returns the list of all the screens connected to the system.
*/
QList<Output *> screens() const;
Output *screenAt(const QPoint &point) const;
Output *findScreen(const QString &name) const;
Output *findScreen(int screenId) const;
KWin::EffectWindow *inputPanel() const;
bool isInputPanelOverlay() const;
QQmlEngine *qmlEngine() const;
/**
* @returns whether or not any effect is currently active where KWin should not use direct scanout
*/
bool blocksDirectScanout() const;
WorkspaceScene *scene() const
{
return m_scene;
}
bool touchDown(qint32 id, const QPointF &pos, std::chrono::microseconds time);
bool touchMotion(qint32 id, const QPointF &pos, std::chrono::microseconds time);
bool touchUp(qint32 id, std::chrono::microseconds time);
bool tabletToolEvent(KWin::TabletEvent *event);
bool tabletToolButtonEvent(uint button, bool pressed, const KWin::TabletToolId &tabletToolId, std::chrono::microseconds time);
bool tabletPadButtonEvent(uint button, bool pressed, const KWin::TabletPadId &tabletPadId, std::chrono::microseconds time);
bool tabletPadStripEvent(int number, int position, bool isFinger, const KWin::TabletPadId &tabletPadId, std::chrono::microseconds time);
bool tabletPadRingEvent(int number, int position, bool isFinger, const KWin::TabletPadId &tabletPadId, std::chrono::microseconds time);
void highlightWindows(const QList<EffectWindow *> &windows);
bool isPropertyTypeRegistered(xcb_atom_t atom) const
{
return registered_atoms.contains(atom);
}
Q_SIGNALS:
/**
* This signal is emitted whenever a new @a screen is added to the system.
*/
void screenAdded(KWin::Output *screen);
/**
* This signal is emitted whenever a @a screen is removed from the system.
*/
void screenRemoved(KWin::Output *screen);
/**
* Signal emitted when the current desktop changed.
* @param oldDesktop The previously current desktop
* @param newDesktop The new current desktop
* @param with The window which is taken over to the new desktop, can be NULL
* @since 4.9
*/
void desktopChanged(KWin::VirtualDesktop *oldDesktop, KWin::VirtualDesktop *newDesktop, KWin::EffectWindow *with);
/**
* Signal emmitted while desktop is changing for animation.
* @param currentDesktop The current desktop untiotherwise.
* @param offset The current desktop offset.
* offset.x() = .6 means 60% of the way to the desktop to the right.
* Positive Values means Up and Right.
*/
void desktopChanging(KWin::VirtualDesktop *currentDesktop, QPointF offset, KWin::EffectWindow *with);
void desktopChangingCancelled();
void desktopAdded(KWin::VirtualDesktop *desktop);
void desktopRemoved(KWin::VirtualDesktop *desktop);
/**
* Emitted when the virtual desktop grid layout changes
* @param size new size
* @since 5.25
*/
void desktopGridSizeChanged(const QSize &size);
/**
* Emitted when the virtual desktop grid layout changes
* @param width new width
* @since 5.25
*/
void desktopGridWidthChanged(int width);
/**
* Emitted when the virtual desktop grid layout changes
* @param height new height
* @since 5.25
*/
void desktopGridHeightChanged(int height);
/**
* Signal emitted when the desktop showing ("dashboard") state changed
* The desktop is risen to the keepAbove layer, you may want to elevate
* windows or such.
* @since 5.3
*/
void showingDesktopChanged(bool);
/**
* Signal emitted when a new window has been added to the Workspace.
* @param w The added window
* @since 4.7
*/
void windowAdded(KWin::EffectWindow *w);
/**
* Signal emitted when a window is being removed from the Workspace.
* An effect which wants to animate the window closing should connect
* to this signal and reference the window by using
* refWindow
* @param w The window which is being closed
* @since 4.7
*/
void windowClosed(KWin::EffectWindow *w);
/**
* Signal emitted when a window get's activated.
* @param w The new active window, or @c NULL if there is no active window.
* @since 4.7
*/
void windowActivated(KWin::EffectWindow *w);
/**
* Signal emitted when a window is deleted.
* This means that a closed window is not referenced any more.
* An effect bookkeeping the closed windows should connect to this
* signal to clean up the internal references.
* @param w The window which is going to be deleted.
* @see EffectWindow::refWindow
* @see EffectWindow::unrefWindow
* @see windowClosed
* @since 4.7
*/
void windowDeleted(KWin::EffectWindow *w);
/**
* Signal emitted when a tabbox is added.
* An effect who wants to replace the tabbox with itself should use refTabBox.
* @param mode The TabBoxMode.
* @see refTabBox
* @see tabBoxClosed
* @see tabBoxUpdated
* @see tabBoxKeyEvent
* @since 4.7
*/
void tabBoxAdded(int mode);
/**
* Signal emitted when the TabBox was closed by KWin core.
* An effect which referenced the TabBox should use unrefTabBox to unref again.
* @see unrefTabBox
* @see tabBoxAdded
* @since 4.7
*/
void tabBoxClosed();
/**
* Signal emitted when the selected TabBox window changed or the TabBox List changed.
* An effect should only response to this signal if it referenced the TabBox with refTabBox.
* @see refTabBox
* @see currentTabBoxWindowList
* @see currentTabBoxDesktopList
* @see currentTabBoxWindow
* @see currentTabBoxDesktop
* @since 4.7
*/
void tabBoxUpdated();
/**
* Signal emitted when a key event, which is not handled by TabBox directly is, happens while
* TabBox is active. An effect might use the key event to e.g. change the selected window.
* An effect should only response to this signal if it referenced the TabBox with refTabBox.
* @param event The key event not handled by TabBox directly
* @see refTabBox
* @since 4.7
*/
void tabBoxKeyEvent(QKeyEvent *event);
/**
* Signal emitted when mouse changed.
* If an effect needs to get updated mouse positions, it needs to first call startMousePolling.
* For a fullscreen effect it is better to use an input window and react on windowInputMouseEvent.
* @param pos The new mouse position
* @param oldpos The previously mouse position
* @param buttons The pressed mouse buttons
* @param oldbuttons The previously pressed mouse buttons
* @param modifiers Pressed keyboard modifiers
* @param oldmodifiers Previously pressed keyboard modifiers.
* @see startMousePolling
* @since 4.7
*/
void mouseChanged(const QPointF &pos, const QPointF &oldpos,
Qt::MouseButtons buttons, Qt::MouseButtons oldbuttons,
Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers oldmodifiers);
/**
* Signal emitted when the cursor shape changed.
* You'll likely want to query the current cursor as reaction: xcb_xfixes_get_cursor_image_unchecked
* Connection to this signal is tracked, so if you don't need it anymore, disconnect from it to stop cursor event filtering
*/
void cursorShapeChanged();
/**
* Receives events registered for using registerPropertyType.
* Use readProperty() to get the property data.
* Note that the property may be already set on the window, so doing the same
* processing from windowAdded() (e.g. simply calling propertyNotify() from it)
* is usually needed.
* @param w The window whose property changed, is @c null if it is a root window property
* @param atom The property
* @since 4.7
*/
void propertyNotify(KWin::EffectWindow *w, long atom);
/**
* This signal is emitted when the global
* activity is changed
* @param id id of the new current activity
* @since 4.9
*/
void currentActivityChanged(const QString &id);
/**
* This signal is emitted when a new activity is added
* @param id id of the new activity
* @since 4.9
*/
void activityAdded(const QString &id);
/**
* This signal is emitted when the activity
* is removed
* @param id id of the removed activity
* @since 4.9
*/
void activityRemoved(const QString &id);
/**
* This signal is emitted when the screen got locked or unlocked.
* @param locked @c true if the screen is now locked, @c false if it is now unlocked
* @since 4.11
*/
void screenLockingChanged(bool locked);
/**
* This signal is emitted just before the screen locker tries to grab keys and lock the screen
* Effects should release any grabs immediately
* @since 5.17
*/
void screenAboutToLock();
/**
* This signels is emitted when ever the stacking order is change, ie. a window is risen
* or lowered
* @since 4.10
*/
void stackingOrderChanged();
/**
* This signal is emitted when the user starts to approach the @p border with the mouse.
* The @p factor describes how far away the mouse is in a relative mean. The values are in
* [0.0, 1.0] with 0.0 being emitted when first entered and on leaving. The value 1.0 means that
* the @p border is reached with the mouse. So the values are well suited for animations.
* The signal is always emitted when the mouse cursor position changes.
* @param border The screen edge which is being approached
* @param factor Value in range [0.0,1.0] to describe how close the mouse is to the border
* @param geometry The geometry of the edge which is being approached
* @since 4.11
*/
void screenEdgeApproaching(ElectricBorder border, qreal factor, const QRect &geometry);
/**
* Emitted whenever the virtualScreenSize changes.
* @see virtualScreenSize()
* @since 5.0
*/
void virtualScreenSizeChanged();
/**
* Emitted whenever the virtualScreenGeometry changes.
* @see virtualScreenGeometry()
* @since 5.0
*/
void virtualScreenGeometryChanged();
/**
* This signal gets emitted when the data on EffectWindow @p w for @p role changed.
*
* An Effect can connect to this signal to read the new value and react on it.
* E.g. an Effect which does not operate on windows grabbed by another Effect wants
* to cancel the already scheduled animation if another Effect adds a grab.
*
* @param w The EffectWindow for which the data changed
* @param role The data role which changed
* @see EffectWindow::setData
* @see EffectWindow::data
* @since 5.8.4
*/
void windowDataChanged(KWin::EffectWindow *w, int role);
/**
* The xcb connection changed, either a new xcbConnection got created or the existing one
* got destroyed.
* Effects can use this to refetch the properties they want to set.
*
* When the xcbConnection changes also the x11RootWindow becomes invalid.
* @see xcbConnection
* @see x11RootWindow
* @since 5.11
*/
void xcbConnectionChanged();
/**
* This signal is emitted when active fullscreen effect changed.
*
* @see activeFullScreenEffect
* @see setActiveFullScreenEffect
* @since 5.14
*/
void activeFullScreenEffectChanged();
/**
* This signal is emitted when active fullscreen effect changed to being
* set or unset
*
* @see activeFullScreenEffect
* @see setActiveFullScreenEffect
* @since 5.15
*/
void hasActiveFullScreenEffectChanged();
/**
* This signal is emitted when the session state was changed
* @since 5.18
*/
void sessionStateChanged();
void startupAdded(const QString &id, const QIcon &icon);
void startupChanged(const QString &id, const QIcon &icon);
void startupRemoved(const QString &id);
void inputPanelChanged();
public Q_SLOTS:
// slots for D-Bus interface
Q_SCRIPTABLE void reconfigureEffect(const QString &name);
Q_SCRIPTABLE bool loadEffect(const QString &name);
Q_SCRIPTABLE void toggleEffect(const QString &name);
Q_SCRIPTABLE void unloadEffect(const QString &name);
Q_SCRIPTABLE bool isEffectLoaded(const QString &name) const;
Q_SCRIPTABLE bool isEffectSupported(const QString &name);
Q_SCRIPTABLE QList<bool> areEffectsSupported(const QStringList &names);
Q_SCRIPTABLE QString supportInformation(const QString &name) const;
Q_SCRIPTABLE QString debug(const QString &name, const QString &parameter = QString()) const;
protected:
void connectNotify(const QMetaMethod &signal) override;
void disconnectNotify(const QMetaMethod &signal) override;
void effectsChanged();
void setupWindowConnections(KWin::Window *window);
/**
* Default implementation does nothing and returns @c true.
*/
virtual bool doGrabKeyboard();
/**
* Default implementation does nothing.
*/
virtual void doUngrabKeyboard();
/**
* Default implementation sets Effects override cursor on the PointerInputRedirection.
*/
virtual void doStartMouseInterception(Qt::CursorShape shape);
/**
* Default implementation removes the Effects override cursor on the PointerInputRedirection.
*/
virtual void doStopMouseInterception();
/**
* Default implementation does nothing
*/
virtual void doCheckInputWindowStacking();
void registerPropertyType(long atom, bool reg);
void destroyEffect(Effect *effect);
void reconfigureEffects();
typedef QList<Effect *> EffectsList;
typedef EffectsList::const_iterator EffectsIterator;
Effect *keyboard_grab_effect;
Effect *fullscreen_effect;
QMultiMap<int, EffectPair> effect_order;
QHash<long, int> registered_atoms;
QList<EffectPair> loaded_effects;
CompositingType compositing_type;
EffectsList m_activeEffects;
EffectsIterator m_currentDrawWindowIterator;
EffectsIterator m_currentPaintWindowIterator;
EffectsIterator m_currentPaintScreenIterator;
typedef QHash<QByteArray, QList<Effect *>> PropertyEffectMap;
PropertyEffectMap m_propertiesForEffects;
QHash<QByteArray, qulonglong> m_managedProperties;
Compositor *m_compositor;
WorkspaceScene *m_scene;
QList<Effect *> m_grabbedMouseEffects;
EffectLoader *m_effectLoader;
int m_trackingCursorChanges;
std::unique_ptr<WindowPropertyNotifyX11Filter> m_x11WindowPropertyNotify;
};
/**
* Pointer to the global EffectsHandler object.
*/
extern KWIN_EXPORT EffectsHandler *effects;
} // namespace
/** @} */