KWin::Effect Class

Base class for all KWin effects. More...

Header: #include <effect/effect.h>
CMake: find_package(KWin REQUIRED)
target_link_libraries(mytarget PRIVATE KWin::kwin)
Inherited By:

KWin::QuickSceneEffect

Public Types

enum Feature { Nothing, ScreenInversion, Blur, Contrast, HighlightWindows, SystemBell }
enum ReconfigureFlag { ReconfigureAll }
flags ReconfigureFlags
enum { PAINT_WINDOW_OPAQUE, PAINT_WINDOW_TRANSLUCENT, PAINT_WINDOW_TRANSFORMED, PAINT_SCREEN_REGION, PAINT_SCREEN_TRANSFORMED, …, PAINT_SCREEN_BACKGROUND_FIRST }

Public Functions

Effect(QObject *parent = nullptr)
virtual ~Effect() override
int animationTime(std::chrono::milliseconds defaultDuration)
virtual bool blocksDirectScanout() const
virtual QString debug(const QString &parameter) const
virtual void drawWindow(const KWin::RenderTarget &renderTarget, const KWin::RenderViewport &viewport, KWin::EffectWindow *w, int mask, const KWin::Region &deviceRegion, KWin::WindowPaintData &data)
virtual void grabbedKeyboardEvent(QKeyEvent *e)
virtual bool isActive() const
virtual void paintScreen(const KWin::RenderTarget &renderTarget, const KWin::RenderViewport &viewport, int mask, const KWin::Region &deviceRegion, KWin::LogicalOutput *screen)
virtual void paintWindow(const KWin::RenderTarget &renderTarget, const KWin::RenderViewport &viewport, KWin::EffectWindow *w, int mask, const KWin::Region &deviceRegion, KWin::WindowPaintData &data)
virtual bool perform(KWin::Effect::Feature feature, const QVariantList &arguments)
(since 6.7) virtual void pointerAxis(KWin::PointerAxisEvent *event)
(since 6.7) virtual void pointerButton(KWin::PointerButtonEvent *event)
(since 6.7) virtual void pointerMotion(KWin::PointerMotionEvent *event)
virtual void postPaintScreen()
virtual void prePaintScreen(KWin::ScreenPrePaintData &data)
virtual void prePaintWindow(KWin::RenderView *view, KWin::EffectWindow *w, KWin::WindowPrePaintData &data)
virtual bool provides(KWin::Effect::Feature)
virtual void reconfigure(KWin::Effect::ReconfigureFlags flags)
virtual int requestedEffectChainPosition() const
virtual bool tabletPadButtonEvent(uint button, bool pressed, void *device)
(since 6.4) virtual bool tabletPadDialEvent(int number, double delta, void *device)
virtual bool tabletPadRingEvent(int number, qreal position, bool isFinger, void *device)
virtual bool tabletPadStripEvent(int number, qreal position, bool isFinger, void *device)
virtual bool tabletToolAxis(KWin::TabletToolAxisEvent *event)
virtual bool tabletToolButtonEvent(uint button, bool pressed, quint64 toolId)
virtual bool tabletToolProximity(KWin::TabletToolProximityEvent *event)
virtual bool tabletToolTip(KWin::TabletToolTipEvent *event)
(since 6.3) virtual void touchCancel()
virtual bool touchDown(qint32 id, const QPointF &pos, std::chrono::microseconds time)
virtual bool touchMotion(qint32 id, const QPointF &pos, std::chrono::microseconds time)
virtual bool touchUp(qint32 id, std::chrono::microseconds time)

Public Slots

virtual bool borderActivated(KWin::ElectricBorder border)

Static Public Members

double animationTime(const KConfigGroup &cfg, const QString &key, std::chrono::milliseconds defaultTime)
double animationTime(std::chrono::milliseconds defaultTime)
QPointF cursorPos()
double interpolate(double x, double y, double a)
void setPositionTransformations(KWin::WindowPaintData &data, KWin::Rect &logicalRegion, KWin::EffectWindow *w, const KWin::Rect &r, Qt::AspectRatioMode aspect)

Macros

Detailed Description

This is the base class for all effects. By reimplementing virtual methods of this class, you can customize how the windows are painted.

The virtual methods are used for painting and need to be implemented for custom painting.

In order to react to state changes (e.g. a window gets closed) the effect should provide slots for the signals emitted by the EffectsHandler.

Chaining

Most methods of this class are called in chain style. This means that when effects A and B area active then first e.g. A::paintWindow() is called and then from within that method B::paintWindow() is called (although indirectly). To achieve this, you need to make sure to call corresponding method in EffectsHandler class from each such method (using effects pointer):

void MyEffect::postPaintScreen()
{
    // Do your own processing here
    ...
    // Call corresponding EffectsHandler method
    effects->postPaintScreen();
}

Effects pointer

effects pointer points to the global EffectsHandler object that you can use to interact with the windows.

Painting stages

Painting of windows is done in three stages:

  • First, the prepaint pass. Here you can specify how the windows will be painted, e.g. that they will be translucent and transformed.
  • Second, the paint pass. Here the actual painting takes place. You can change attributes such as opacity of windows as well as apply transformations to them. You can also paint something onto the screen yourself.
  • Finally, the postpaint pass. Here you can mark windows, part of windows or even the entire screen for repainting to create animations.

    For each stage there are *Screen() and *Window() methods. The window method is called for every window while the screen method is usually called just once.

    OpenGL

    Effects can use OpenGL if EffectsHandler::isOpenGLCompositing() returns true.

    The OpenGL context may not always be current when code inside the effect is executed. The framework ensures that the OpenGL context is current when the Effect gets created, destroyed or reconfigured and during the painting stages. All virtual methods which have the OpenGL context current are documented.

    If OpenGL code is going to be executed outside the painting stages, e.g. in reaction to a global shortcut, it is the task of the Effect to make the OpenGL context current:

    effects->makeOpenGLContextCurrent();

    There is in general no need to call the matching doneCurrent method.

Member Type Documentation

enum Effect::Feature

ConstantValue
KWin::Effect::Nothing0
KWin::Effect::ScreenInversion1
KWin::Effect::Blur2
KWin::Effect::Contrast3
KWin::Effect::HighlightWindows4
KWin::Effect::SystemBell5

enum Effect::ReconfigureFlag
flags Effect::ReconfigureFlags

Flags describing which parts of configuration have changed.

ConstantValueDescription
KWin::Effect::ReconfigureAll1 << 0Everything needs to be reconfigured

The ReconfigureFlags type is a typedef for QFlags<ReconfigureFlag>. It stores an OR combination of ReconfigureFlag values.

[anonymous] enum

Flags controlling how painting is done.

ConstantValueDescription
KWin::Effect::PAINT_WINDOW_OPAQUE1 << 0Window (or at least part of it) will be painted opaque
KWin::Effect::PAINT_WINDOW_TRANSLUCENT1 << 1Window (or at least part of it) will be painted translucent
KWin::Effect::PAINT_WINDOW_TRANSFORMED1 << 2Window will be painted with transformed geometry
KWin::Effect::PAINT_SCREEN_REGION1 << 3Paint only a region of the screen (can be optimized, cannot be used together with TRANSFORMED flags)
KWin::Effect::PAINT_SCREEN_TRANSFORMED1 << 4The whole screen will be painted with transformed geometry. Forces the entire screen to be painted
KWin::Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS1 << 5At least one window will be painted with transformed geometry. Forces the entire screen to be painted
KWin::Effect::PAINT_SCREEN_BACKGROUND_FIRST1 << 6Clear whole background as the very first step, without optimizing it

Member Function Documentation

Effect::Effect(QObject *parent = nullptr)

Constructs new Effect object.

In OpenGL based compositing, the frameworks ensures that the context is current when the Effect is constructed.

[override virtual noexcept] Effect::~Effect()

Destructs the Effect object.

In OpenGL based compositing, the frameworks ensures that the context is current when the Effect is destroyed.

[static] double Effect::animationTime(const KConfigGroup &cfg, const QString &key, std::chrono::milliseconds defaultTime)

Read animation time from the configuration and possibly adjust using animationTimeFactor().

The configuration value in the effect should also have special value 'default' (set using QSpinBox::setSpecialValueText()) with the value 0. This special value is adjusted using the global animation speed, otherwise the exact time configured is returned.

cfg configuration group to read value from

key configuration key to read value from

defaultTime default animation time in milliseconds

[static] double Effect::animationTime(std::chrono::milliseconds defaultTime)

in the effect itself.

This function overloads Effect::Use this variant if the animation time is hardcoded and not configurable.

template <typename T> int Effect::animationTime(std::chrono::milliseconds defaultDuration)

having a property called "duration".

This function overloads Effect::Use this variant if animation time is provided through a KConfigXT generated class.

[virtual] bool Effect::blocksDirectScanout() const

overwrite this method to return false if your effect does not need to be drawn over opaque fullscreen windows

[virtual slot] bool Effect::borderActivated(KWin::ElectricBorder border)

This function gets called when a reserved screen edge for border gets called.

[static] QPointF Effect::cursorPos()

Returns the current pointer position.

[virtual] QString Effect::debug(const QString &parameter) const

Reimplement this method to provide online debugging.

This could be as trivial as printing specific detail information about the effect state but could also be used to move the effect in and out of a special debug modes, clear bogus data, etc.

Notice that the functions is const by intent! Whenever you alter the state of the object due to random user input, you should do so with greatest care, hence const_cast<> your object - signalling "let me alone, i know what i'm doing"

parameter A freeform string user input for your effect to interpret.

[virtual] void Effect::drawWindow(const KWin::RenderTarget &renderTarget, const KWin::RenderViewport &viewport, KWin::EffectWindow *w, int mask, const KWin::Region &deviceRegion, KWin::WindowPaintData &data)

Can be called to draw multiple copies (e.g. thumbnails) of a window.

You can change window's opacity/brightness/etc here, but you can't do any transformations.

In OpenGL based compositing, the frameworks ensures that the context is current when this method is invoked.

[virtual] void Effect::grabbedKeyboardEvent(QKeyEvent *e)

This function can be overriden to handle grabbed keyboard input.

[static] double Effect::interpolate(double x, double y, double a)

Linearly interpolates between x and y.

Returns x when a = 0; returns y when a = 1.

[virtual] bool Effect::isActive() const

Overwrite this method to indicate whether your effect will be doing something in the next frame to be rendered.

If the method returns false the effect will be excluded from the chained methods in the next rendered frame.

This method is called always directly before the paint loop begins. So it is totally fine to e.g. react on a window event, issue a repaint to trigger an animation and change a flag to indicate that this method returns true.

As the method is called each frame, you should not perform complex calculations. Best use just a boolean flag.

The default implementation of this method returns true.

[virtual] void Effect::paintScreen(const KWin::RenderTarget &renderTarget, const KWin::RenderViewport &viewport, int mask, const KWin::Region &deviceRegion, KWin::LogicalOutput *screen)

In this method you can:

  • paint something on top of the windows (by painting after calling effects->paintScreen())
  • paint multiple desktops and/or multiple copies of the same desktop by calling effects->paintScreen() multiple times

In OpenGL based compositing, the frameworks ensures that the context is current when this method is invoked.

[virtual] void Effect::paintWindow(const KWin::RenderTarget &renderTarget, const KWin::RenderViewport &viewport, KWin::EffectWindow *w, int mask, const KWin::Region &deviceRegion, KWin::WindowPaintData &data)

This is the main method for painting windows.

In this method you can:

  • do various transformations
  • change opacity of the window
  • change brightness and/or saturation, if it's supported

In OpenGL based compositing, the frameworks ensures that the context is current when this method is invoked.

[virtual] bool Effect::perform(KWin::Effect::Feature feature, const QVariantList &arguments)

Performs the feature with the arguments.

This allows to have specific protocols between KWin core and an Effect.

The method is supposed to return true if it performed the features, false otherwise.

The default implementation returns false.

[virtual, since 6.7] void Effect::pointerAxis(KWin::PointerAxisEvent *event)

A pointer axis was scrolled

event The PointerAxisEvent for the event

This function was introduced in 6.7.

[virtual, since 6.7] void Effect::pointerButton(KWin::PointerButtonEvent *event)

A pointer button was moved

event The PointerButtonEvent for the event

This function was introduced in 6.7.

[virtual, since 6.7] void Effect::pointerMotion(KWin::PointerMotionEvent *event)

A pointer was moved

event The PointerMotionEvent for the event

This function was introduced in 6.7.

[virtual] void Effect::postPaintScreen()

Called after all the painting has been finished.

In this method you can:

  • schedule next repaint in case of animations

You shouldn't paint anything here.

In OpenGL based compositing, the frameworks ensures that the context is current when this method is invoked.

[virtual] void Effect::prePaintScreen(KWin::ScreenPrePaintData &data)

Called before starting to paint the screen. In this method you can:

  • set whether the windows or the entire screen will be transformed
  • change the region of the screen that will be painted
  • do various housekeeping tasks such as initing your effect's variables for the upcoming paint pass or updating animation's progress

[virtual] void Effect::prePaintWindow(KWin::RenderView *view, KWin::EffectWindow *w, KWin::WindowPrePaintData &data)

Called for every window before the actual paint pass

In this method you can:

  • enable or disable painting of the window (e.g. enable painting of minimized window)
  • set window to be painted with translucency
  • set window to be transformed
  • request the window to be divided into multiple parts

In OpenGL based compositing, the frameworks ensures that the context is current when this method is invoked.

[virtual] bool Effect::provides(KWin::Effect::Feature)

Called on Transparent resizes.

return true if your effect substitutes questioned feature

[virtual] void Effect::reconfigure(KWin::Effect::ReconfigureFlags flags)

Called when configuration changes (either the effect's or KWin's global).

In OpenGL based compositing, the frameworks ensures that the context is current when the Effect is reconfigured. If this method is called from within the Effect it is required to ensure that the context is current if the implementation does OpenGL calls.

[virtual] int Effect::requestedEffectChainPosition() const

Reimplement this method to indicate where in the Effect chain the Effect should be placed.

A low number indicates early chain position, thus before other Effects got called, a high number indicates a late position. The returned number should be in the interval [0, 100]. The default value is 0.

In KWin4 this information was provided in the Effect's desktop file as property X-KDE-Ordering. In the case of Scripted Effects this property is still used.

[static] void Effect::setPositionTransformations(KWin::WindowPaintData &data, KWin::Rect &logicalRegion, KWin::EffectWindow *w, const KWin::Rect &r, Qt::AspectRatioMode aspect)

Helper to set WindowPaintData and Region to necessary transformations so that a following drawWindow() would put the window at the requested geometry (useful for thumbnails)

[virtual] bool Effect::tabletPadButtonEvent(uint button, bool pressed, void *device)

There has been an event from a button on a drawing tablet pad

button which button

pressed true if pressed, false when released

device the identifier of the tool id

[virtual, since 6.4] bool Effect::tabletPadDialEvent(int number, double delta, void *device)

There has been an event from a input dial on a drawing tablet pad

number which dial

delta the delta value

device the identifier of the tool id

This function was introduced in 6.4.

[virtual] bool Effect::tabletPadRingEvent(int number, qreal position, bool isFinger, void *device)

There has been an event from a input ring on a drawing tablet pad

number which ring

position the value within the ring that was selected

isFinger if it was activated with a finger

device the identifier of the tool id

[virtual] bool Effect::tabletPadStripEvent(int number, qreal position, bool isFinger, void *device)

There has been an event from a input strip on a drawing tablet pad

number which strip

position the value within the strip that was selected

isFinger if it was activated with a finger

device the identifier of the tool id

[virtual] bool Effect::tabletToolAxis(KWin::TabletToolAxisEvent *event)

There has been an axis tablet tool event.

[virtual] bool Effect::tabletToolButtonEvent(uint button, bool pressed, quint64 toolId)

There has been an event from a button on a drawing tablet tool

button which button

pressed true if pressed, false when released

toolId the identifier of the tool id

[virtual] bool Effect::tabletToolProximity(KWin::TabletToolProximityEvent *event)

There has been a proximity tablet tool event.

[virtual] bool Effect::tabletToolTip(KWin::TabletToolTipEvent *event)

There has been a tip tablet tool event.

[virtual, since 6.3] void Effect::touchCancel()

All touch points were canceled

This function was introduced in 6.3.

[virtual] bool Effect::touchDown(qint32 id, const QPointF &pos, std::chrono::microseconds time)

A touch point was pressed.

If the effect wants to exclusively use the touch event it should return true. If false is returned the touch event is passed to further effects.

In general an Effect should only return true if it is the exclusive effect getting input events. E.g. has grabbed mouse events.

Default implementation returns false.

id The unique id of the touch point

pos The position of the touch point in global coordinates

time Timestamp

See also touchMotion and touchUp.

[virtual] bool Effect::touchMotion(qint32 id, const QPointF &pos, std::chrono::microseconds time)

A touch point moved.

If the effect wants to exclusively use the touch event it should return true. If false is returned the touch event is passed to further effects.

In general an Effect should only return true if it is the exclusive effect getting input events. E.g. has grabbed mouse events.

Default implementation returns false.

id The unique id of the touch point

pos The position of the touch point in global coordinates

time Timestamp

See also touchDown and touchUp.

[virtual] bool Effect::touchUp(qint32 id, std::chrono::microseconds time)

A touch point was released.

If the effect wants to exclusively use the touch event it should return true. If false is returned the touch event is passed to further effects.

In general an Effect should only return true if it is the exclusive effect getting input events. E.g. has grabbed mouse events.

Default implementation returns false.

id The unique id of the touch point

time Timestamp

See also touchDown and touchMotion.

Macro Documentation

KWIN_EFFECT_FACTORY

KWIN_EFFECT_FACTORY_ENABLED

KWIN_EFFECT_FACTORY_SUPPORTED

KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED

Defines an EffectPluginFactory sub class with customized isSupported and enabledByDefault methods.

If the Effect to be created does not need the isSupported or enabledByDefault methods prefer the simplified KWIN_EFFECT_FACTORY, KWIN_EFFECT_FACTORY_SUPPORTED or KWIN_EFFECT_FACTORY_ENABLED macros which create an EffectPluginFactory with a usable default value.

This API is not providing binary compatibility and thus the effect plugin must be compiled against the same kwineffects library version as KWin.

factoryName The name to be used for the EffectPluginFactory

className The class name of the Effect sub class which is to be created by the factory

jsonFile Name of the json file to be compiled into the plugin as metadata

supported Source code to go into the isSupported() method, must return a boolean

enabled Source code to go into the enabledByDefault() method, must return a boolean