diff --git a/autotests/test_builtin_effectloader.cpp b/autotests/test_builtin_effectloader.cpp --- a/autotests/test_builtin_effectloader.cpp +++ b/autotests/test_builtin_effectloader.cpp @@ -89,7 +89,6 @@ QTest::newRow("CubeSlide") << QStringLiteral("cubeslide") << true; QTest::newRow("DesktopGrid") << QStringLiteral("desktopgrid") << true; QTest::newRow("DimInactive") << QStringLiteral("diminactive") << true; - QTest::newRow("DimScreen") << QStringLiteral("dimscreen") << true; QTest::newRow("FallApart") << QStringLiteral("fallapart") << true; QTest::newRow("FlipSwitch") << QStringLiteral("flipswitch") << true; QTest::newRow("Glide") << QStringLiteral("glide") << true; @@ -145,7 +144,6 @@ << QStringLiteral("cubeslide") << QStringLiteral("desktopgrid") << QStringLiteral("diminactive") - << QStringLiteral("dimscreen") << QStringLiteral("fallapart") << QStringLiteral("flipswitch") << QStringLiteral("glide") @@ -214,7 +212,6 @@ QTest::newRow("CubeSlide-GL-no-anim") << QStringLiteral("cubeslide") << false << oc << false; QTest::newRow("DesktopGrid") << QStringLiteral("desktopgrid") << true << xc << true; QTest::newRow("DimInactive") << QStringLiteral("diminactive") << true << xc << true; - QTest::newRow("DimScreen") << QStringLiteral("dimscreen") << true << xc << true; QTest::newRow("FallApart") << QStringLiteral("fallapart") << false << xc << true; QTest::newRow("FallApart-GL") << QStringLiteral("fallapart") << true << oc << true; QTest::newRow("FlipSwitch") << QStringLiteral("flipswitch") << false << xc << true; @@ -305,7 +302,6 @@ QTest::newRow("CubeSlide-GL") << QStringLiteral("cubeslide") << true << oc; QTest::newRow("DesktopGrid") << QStringLiteral("desktopgrid") << true << xc; QTest::newRow("DimInactive") << QStringLiteral("diminactive") << true << xc; - QTest::newRow("DimScreen") << QStringLiteral("dimScreen") << true << xc; QTest::newRow("FallApart") << QStringLiteral("fallapart") << false << xc; QTest::newRow("FallApart-GL") << QStringLiteral("fallapart") << true << oc; QTest::newRow("FlipSwitch") << QStringLiteral("flipswitch") << false << xc; diff --git a/autotests/test_plugin_effectloader.cpp b/autotests/test_plugin_effectloader.cpp --- a/autotests/test_plugin_effectloader.cpp +++ b/autotests/test_plugin_effectloader.cpp @@ -80,7 +80,6 @@ QTest::newRow("CubeSlide") << QStringLiteral("cubeslide") << false; QTest::newRow("DesktopGrid") << QStringLiteral("desktopgrid") << false; QTest::newRow("DimInactive") << QStringLiteral("diminactive") << false; - QTest::newRow("DimScreen") << QStringLiteral("dimscreen") << false; QTest::newRow("FallApart") << QStringLiteral("fallapart") << false; QTest::newRow("FlipSwitch") << QStringLiteral("flipswitch") << false; QTest::newRow("Glide") << QStringLiteral("glide") << false; @@ -112,6 +111,7 @@ QTest::newRow("Zoom") << QStringLiteral("zoom") << false; QTest::newRow("Non Existing") << QStringLiteral("InvalidName") << false; // all the scripted effects should fail + QTest::newRow("DimScreen") << QStringLiteral("kwin4_effect_dimscreen") << false; QTest::newRow("Fade") << QStringLiteral("kwin4_effect_fade") << false; QTest::newRow("FadeDesktop") << QStringLiteral("kwin4_effect_fadedesktop") << false; QTest::newRow("DialogParent") << QStringLiteral("kwin4_effect_dialogparent") << false; diff --git a/autotests/test_scripted_effectloader.cpp b/autotests/test_scripted_effectloader.cpp --- a/autotests/test_scripted_effectloader.cpp +++ b/autotests/test_scripted_effectloader.cpp @@ -109,7 +109,6 @@ QTest::newRow("CubeSlide") << QStringLiteral("cubeslide") << false; QTest::newRow("DesktopGrid") << QStringLiteral("desktopgrid") << false; QTest::newRow("DimInactive") << QStringLiteral("diminactive") << false; - QTest::newRow("DimScreen") << QStringLiteral("dimscreen") << false; QTest::newRow("FallApart") << QStringLiteral("fallapart") << false; QTest::newRow("FlipSwitch") << QStringLiteral("flipswitch") << false; QTest::newRow("Glide") << QStringLiteral("glide") << false; @@ -147,6 +146,7 @@ QTest::newRow("FadeDesktop") << QStringLiteral("kwin4_effect_fadedesktop") << true; QTest::newRow("FrozenApp") << QStringLiteral("kwin4_effect_frozenapp") << true; QTest::newRow("DialogParent") << QStringLiteral("kwin4_effect_dialogparent") << true; + QTest::newRow("DimScreen") << QStringLiteral("kwin4_effect_dimscreen") << true; QTest::newRow("Login") << QStringLiteral("kwin4_effect_login") << true; QTest::newRow("Logout") << QStringLiteral("kwin4_effect_logout") << true; QTest::newRow("Maximize") << QStringLiteral("kwin4_effect_maximize") << true; @@ -176,6 +176,7 @@ { QStringList expectedEffects; expectedEffects << QStringLiteral("kwin4_effect_dialogparent") + << QStringLiteral("kwin4_effect_dimscreen") << QStringLiteral("kwin4_effect_fade") << QStringLiteral("kwin4_effect_fadedesktop") << QStringLiteral("kwin4_effect_frozenapp") @@ -206,6 +207,7 @@ QTest::newRow("FadeDesktop") << QStringLiteral("kwin4_effect_fadedesktop") << true; QTest::newRow("FrozenApp") << QStringLiteral("kwin4_effect_frozenapp") << true; QTest::newRow("DialogParent") << QStringLiteral("kwin4_effect_dialogparent") << true; + QTest::newRow("DimScreen") << QStringLiteral("kwin4_effect_dimscreen") << true; QTest::newRow("Login") << QStringLiteral("kwin4_effect_login") << true; QTest::newRow("Logout") << QStringLiteral("kwin4_effect_logout") << true; QTest::newRow("Maximize") << QStringLiteral("kwin4_effect_maximize") << true; @@ -355,6 +357,7 @@ // prepare the configuration to hard enable/disable the effects we want to load KConfigGroup plugins = config->group("Plugins"); plugins.writeEntry(kwin4 + QStringLiteral("dialogparentEnabled"), false); + plugins.writeEntry(kwin4 + QStringLiteral("dimscreenEnabled"), false); plugins.writeEntry(kwin4 + QStringLiteral("fadeEnabled"), false); plugins.writeEntry(kwin4 + QStringLiteral("fadedesktopEnabled"), false); plugins.writeEntry(kwin4 + QStringLiteral("frozenappEnabled"), false); diff --git a/effects/CMakeLists.txt b/effects/CMakeLists.txt --- a/effects/CMakeLists.txt +++ b/effects/CMakeLists.txt @@ -134,6 +134,7 @@ # scripted effects add_subdirectory( dialogparent ) +add_subdirectory( dimscreen ) add_subdirectory( eyeonscreen ) add_subdirectory( fade ) add_subdirectory( fadedesktop ) @@ -152,7 +153,6 @@ # Common effects add_subdirectory( desktopgrid ) add_subdirectory( diminactive ) -include( dimscreen/CMakeLists.txt ) include( fallapart/CMakeLists.txt ) include( highlightwindow/CMakeLists.txt ) include( kscreen/CMakeLists.txt ) diff --git a/effects/dimscreen/CMakeLists.txt b/effects/dimscreen/CMakeLists.txt --- a/effects/dimscreen/CMakeLists.txt +++ b/effects/dimscreen/CMakeLists.txt @@ -1,7 +1 @@ -####################################### -# Effect - -# Source files -set( kwin4_effect_builtins_sources ${kwin4_effect_builtins_sources} - dimscreen/dimscreen.cpp - ) +add_subdirectory(package) diff --git a/effects/dimscreen/dimscreen.h b/effects/dimscreen/dimscreen.h deleted file mode 100644 --- a/effects/dimscreen/dimscreen.h +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************** - KWin - the KDE window manager - This file is part of the KDE project. - - Copyright (C) 2008, 2009 Martin Gräßlin - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*********************************************************************/ - -#ifndef KWIN_DIMSCREEN_H -#define KWIN_DIMSCREEN_H - -#include -#include - -namespace KWin -{ - -class DimScreenEffect - : public Effect -{ - Q_OBJECT -public: - DimScreenEffect(); - ~DimScreenEffect(); - - virtual void reconfigure(ReconfigureFlags); - virtual void prePaintScreen(ScreenPrePaintData& data, int time); - virtual void postPaintScreen(); - virtual void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data); - virtual bool isActive() const; - -public Q_SLOTS: - void slotWindowActivated(KWin::EffectWindow *w); - -private: - bool mActivated; - bool activateAnimation; - bool deactivateAnimation; - QTimeLine timeline; - EffectWindow* window; -}; - -} // namespace - -#endif diff --git a/effects/dimscreen/dimscreen.cpp b/effects/dimscreen/dimscreen.cpp deleted file mode 100644 --- a/effects/dimscreen/dimscreen.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/******************************************************************** - KWin - the KDE window manager - This file is part of the KDE project. - - Copyright (C) 2008, 2009 Martin Gräßlin - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*********************************************************************/ -#include "dimscreen.h" - -#include - -#include - -namespace KWin -{ - -static const QSet s_authWindows { - QStringLiteral("kdesu kdesu"), - QStringLiteral("kdesudo kdesudo"), - QStringLiteral("pinentry pinentry"), - QStringLiteral("polkit-kde-authentication-agent-1 polkit-kde-authentication-agent-1"), - QStringLiteral("polkit-kde-manager polkit-kde-manager"), - - // On Wayland, the resource name is filename of executable. It's empty for - // authentication agents because KWayland can't get their executable paths. - QStringLiteral(" org.kde.kdesu"), - QStringLiteral(" org.kde.polkit-kde-authentication-agent-1") -}; - -DimScreenEffect::DimScreenEffect() - : mActivated(false) - , activateAnimation(false) - , deactivateAnimation(false) -{ - reconfigure(ReconfigureAll); - connect(effects, SIGNAL(windowActivated(KWin::EffectWindow*)), this, SLOT(slotWindowActivated(KWin::EffectWindow*))); -} - -DimScreenEffect::~DimScreenEffect() -{ -} - -void DimScreenEffect::reconfigure(ReconfigureFlags) -{ - timeline.setDuration(animationTime(250)); -} - -void DimScreenEffect::prePaintScreen(ScreenPrePaintData& data, int time) -{ - if (mActivated && activateAnimation && !effects->activeFullScreenEffect()) - timeline.setCurrentTime(timeline.currentTime() + time); - if (mActivated && deactivateAnimation) - timeline.setCurrentTime(timeline.currentTime() - time); - if (mActivated && effects->activeFullScreenEffect()) - timeline.setCurrentTime(timeline.currentTime() - time); - if (mActivated && !activateAnimation && !deactivateAnimation && !effects->activeFullScreenEffect() && timeline.currentValue() != 1.0) - timeline.setCurrentTime(timeline.currentTime() + time); - effects->prePaintScreen(data, time); -} - -void DimScreenEffect::postPaintScreen() -{ - if (mActivated) { - if (activateAnimation && timeline.currentValue() == 1.0) { - activateAnimation = false; - effects->addRepaintFull(); - } - if (deactivateAnimation && timeline.currentValue() == 0.0) { - deactivateAnimation = false; - mActivated = false; - effects->addRepaintFull(); - } - // still animating - if (timeline.currentValue() > 0.0 && timeline.currentValue() < 1.0) - effects->addRepaintFull(); - } - effects->postPaintScreen(); -} - -static inline bool isDimWindow(const EffectWindow *w) -{ - if (w->isPopupWindow()) { - return false; - } - - if (w->isX11Client() && !w->isManaged()) { - return false; - } - - return true; -} - -void DimScreenEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) -{ - if (mActivated && (w != window) && isDimWindow(w)) { - data.multiplyBrightness((1.0 - 0.33 * timeline.currentValue())); - data.multiplySaturation((1.0 - 0.33 * timeline.currentValue())); - } - effects->paintWindow(w, mask, region, data); -} - -void DimScreenEffect::slotWindowActivated(EffectWindow *w) -{ - if (!w) return; - if (s_authWindows.contains(w->windowClass())) { - mActivated = true; - activateAnimation = true; - deactivateAnimation = false; - window = w; - effects->addRepaintFull(); - } else { - if (mActivated) { - activateAnimation = false; - deactivateAnimation = true; - effects->addRepaintFull(); - } - } -} - -bool DimScreenEffect::isActive() const -{ - return mActivated; -} - -} // namespace diff --git a/effects/dimscreen/package/CMakeLists.txt b/effects/dimscreen/package/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/effects/dimscreen/package/CMakeLists.txt @@ -0,0 +1,9 @@ +install(DIRECTORY contents + DESTINATION ${DATA_INSTALL_DIR}/${KWIN_NAME}/effects/kwin4_effect_dimscreen) + +install(FILES metadata.desktop + DESTINATION ${DATA_INSTALL_DIR}/${KWIN_NAME}/effects/kwin4_effect_dimscreen) + +install(FILES metadata.desktop + DESTINATION ${SERVICES_INSTALL_DIR}/${KWIN_NAME} + RENAME kwin4_effect_dimscreen.desktop) diff --git a/effects/dimscreen/package/contents/code/main.js b/effects/dimscreen/package/contents/code/main.js new file mode 100644 --- /dev/null +++ b/effects/dimscreen/package/contents/code/main.js @@ -0,0 +1,255 @@ +/******************************************************************** + This file is part of the KDE project. + +Copyright (C) 2018 Vlad Zagorodniy + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ + +var authenticationAgents = [ + "kdesu kdesu", + "kdesudo kdesudo", + "pinentry pinentry", + "polkit-kde-authentication-agent-1 polkit-kde-authentication-agent-1", + "polkit-kde-manager polkit-kde-manager", + + // On Wayland, the resource name is filename of executable. It's empty for + // authentication agents because KWayland can't get their executable paths. + " org.kde.kdesu", + " org.kde.polkit-kde-authentication-agent-1" +]; + +function activeAuthenticationAgent() { + "use strict"; + var activeWindow = effects.activeWindow; + if (!activeWindow) { + return null; + } + + if (authenticationAgents.indexOf(activeWindow.windowClass) == -1) { + return null; + } + + return activeWindow; +} + +var dimScreenEffect = { + duration: animationTime(250), + saturation: 0.77, + brightness: 0.77, + loadConfig: function () { + "use strict"; + dimScreenEffect.duration = animationTime(250); + }, + startAnimation: function (window) { + "use strict"; + if (!window.visible) { + return; + } + if (window.popup) { + return; + } + if (window.x11Client && !window.managed) { + return; + } + if (window.dimAnimation) { + if (redirect(window.dimAnimation, Effect.Forward)) { + return; + } + cancel(window.dimAnimation); + } + window.dimAnimation = set({ + window: window, + curve: QEasingCurve.InOutSine, + duration: dimScreenEffect.duration, + keepAlive: false, + animations: [ + { + type: Effect.Saturation, + to: dimScreenEffect.saturation + }, + { + type: Effect.Brightness, + to: dimScreenEffect.brightness + } + ] + }); + }, + startAnimationSmooth: function (window) { + "use strict"; + dimScreenEffect.startAnimation(window); + }, + startAnimationInstant: function (window) { + "use strict"; + dimScreenEffect.startAnimation(window); + + if (window.dimAnimation) { + rewind(window.dimAnimation, dimScreenEffect.duration); + } + }, + cancelAnimationSmooth: function (window) { + "use strict"; + if (!window.dimAnimation) { + return; + } + if (redirect(window.dimAnimation, Effect.Backward)) { + return; + } + cancel(window.dimAnimation); + delete window.dimAnimation; + }, + cancelAnimationInstant: function (window) { + "use strict"; + if (!window.dimAnimation) { + return; + } + cancel(window.dimAnimation); + delete window.dimAnimation; + }, + dimScreen: function (agent, animationFunc, cancelFunc) { + "use strict"; + // Keep track of currently active authentication agent so we don't have + // to re-scan the stacking order in brightenScreen each time when some + // window is activated. + dimScreenEffect.authenticationAgent = agent; + + var windows = effects.stackingOrder; + for (var i = 0; i < windows.length; ++i) { + var window = windows[i]; + if (window == agent) { + // The agent might have been dimmed before (because there are + // several authentication agents on the screen), so we need to + // cancel previous animations for it if there are any. + cancelFunc(agent); + continue; + } + animationFunc(window); + } + }, + dimScreenSmooth: function (agent) { + "use strict"; + dimScreenEffect.dimScreen( + agent, + dimScreenEffect.startAnimationSmooth, + dimScreenEffect.cancelAnimationSmooth + ); + }, + dimScreenInstant: function (agent) { + "use strict"; + dimScreenEffect.dimScreen( + agent, + dimScreenEffect.startAnimationInstant, + dimScreenEffect.cancelAnimationInstant + ); + }, + brightenScreen: function (cancelFunc) { + "use agent"; + if (!dimScreenEffect.authenticationAgent) { + return; + } + dimScreenEffect.authenticationAgent = null; + + var windows = effects.stackingOrder; + for (var i = 0; i < windows.length; ++i) { + cancelFunc(windows[i]); + } + }, + brightenScreenSmooth: function () { + "use strict"; + dimScreenEffect.brightenScreen(dimScreenEffect.cancelAnimationSmooth); + }, + brightenScreenInstant: function () { + "use strict"; + dimScreenEffect.brightenScreen(dimScreenEffect.cancelAnimationInstant); + }, + slotWindowActivated: function (window) { + "use strict"; + if (!window) { + return; + } + if (authenticationAgents.indexOf(window.windowClass) != -1) { + dimScreenEffect.dimScreenSmooth(window); + } else { + dimScreenEffect.brightenScreenSmooth(); + } + }, + slotWindowAdded: function (window) { + "use agent"; + // Don't dim authentication agents that just opened. + var agent = activeAuthenticationAgent(); + if (agent == window) { + return; + } + + // If a window appeared while the screen is dimmed, dim the window too. + if (agent) { + dimScreenEffect.startAnimationInstant(window); + } + }, + slotActiveFullScreenEffectChanged: function () { + "use strict"; + // If some full screen effect has been activated, for example the desktop + // cube effect, then brighten screen back. We need to do that because the + // full screen effect can dim windows on its own. + if (effects.hasActiveFullScreenEffect) { + dimScreenEffect.brightenScreenSmooth(); + return; + } + + // If user left the full screen effect, try to dim screen back. + var agent = activeAuthenticationAgent(); + if (agent) { + dimScreenEffect.dimScreenSmooth(agent); + } + }, + slotDesktopChanged: function () { + "use agent"; + // If there is an active full screen effect, then try smoothly dim/brighten + // the screen. Keep in mind that in order for this to work properly, this + // effect has to come after the full screen effect in the effect chain, + // otherwise this slot will be invoked before the full screen effect can mark + // itself as a full screen effect. + if (effects.hasActiveFullScreenEffect) { + return; + } + + // Try to brighten windows on the previous virtual desktop. + dimScreenEffect.brightenScreenInstant(); + + // Try to dim windows on the current virtual desktop. + var agent = activeAuthenticationAgent(); + if (agent) { + dimScreenEffect.dimScreenInstant(agent); + } + }, + restartAnimation: function (window) { + "use agent"; + if (activeAuthenticationAgent()) { + dimScreenEffect.startAnimationInstant(window); + } + }, + init: function () { + "use strict"; + effect.configChanged.connect(dimScreenEffect.loadConfig); + effects.windowActivated.connect(dimScreenEffect.slotWindowActivated); + effects.windowAdded.connect(dimScreenEffect.slotWindowAdded); + effects.windowMinimized.connect(dimScreenEffect.cancelAnimationInstant); + effects.windowUnminimized.connect(dimScreenEffect.restartAnimation); + effects.activeFullScreenEffectChanged.connect( + dimScreenEffect.slotActiveFullScreenEffectChanged); + effects['desktopChanged(int,int)'].connect(dimScreenEffect.slotDesktopChanged); + } +}; + +dimScreenEffect.init(); diff --git a/effects/dimscreen/package/metadata.desktop b/effects/dimscreen/package/metadata.desktop new file mode 100644 --- /dev/null +++ b/effects/dimscreen/package/metadata.desktop @@ -0,0 +1,20 @@ +[Desktop Entry] +Comment=Darkens the entire screen when requesting root privileges +Icon=preferences-system-windows-effect-dimscreen +Name=Dim Screen for Administrator Mode + +Type=Service +X-KDE-ParentApp= +X-KDE-PluginInfo-Author=Martin Flöser, Vlad Zagorodniy +X-KDE-PluginInfo-Category=Focus +X-KDE-PluginInfo-Email=mgraesslin@kde.org, vladzzag@gmail.com +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-Name=kwin4_effect_dimscreen +X-KDE-PluginInfo-Version=1 +X-KDE-PluginInfo-Website= +X-KDE-ServiceTypes=KWin/Effect +X-KDE-PluginInfo-EnabledByDefault=false +X-KDE-Ordering=60 +X-Plasma-API=javascript +X-Plasma-MainScript=code/main.js +X-KWin-Video-Url=http://files.kde.org/plasma/kwin/effect-videos/dim_administration.mp4 diff --git a/effects/effect_builtins.h b/effects/effect_builtins.h --- a/effects/effect_builtins.h +++ b/effects/effect_builtins.h @@ -42,7 +42,6 @@ CubeSlide, DesktopGrid, DimInactive, - DimScreen, FallApart, FlipSwitch, Glide, diff --git a/effects/effect_builtins.cpp b/effects/effect_builtins.cpp --- a/effects/effect_builtins.cpp +++ b/effects/effect_builtins.cpp @@ -31,7 +31,6 @@ // Common effects only relevant to desktop #include "desktopgrid/desktopgrid.h" #include "diminactive/diminactive.h" -#include "dimscreen/dimscreen.h" #include "fallapart/fallapart.h" #include "highlightwindow/highlightwindow.h" #include "magiclamp/magiclamp.h" @@ -218,21 +217,6 @@ nullptr, nullptr #endif -EFFECT_FALLBACK - }, { - QStringLiteral("dimscreen"), - i18ndc("kwin_effects", "Name of a KWin Effect", "Dim Screen for Administrator Mode"), - i18ndc("kwin_effects", "Comment describing the KWin Effect", "Darkens the entire screen when requesting root privileges"), - QStringLiteral("Focus"), - QString(), - QUrl(QStringLiteral("http://files.kde.org/plasma/kwin/effect-videos/dim_administration.mp4")), - false, - false, -#ifdef EFFECT_BUILTINS - &createHelper, - nullptr, - nullptr -#endif EFFECT_FALLBACK }, { QStringLiteral("fallapart"),