diff --git a/autotests/integration/effects/slidingpopups_test.cpp b/autotests/integration/effects/slidingpopups_test.cpp
index 0bdbe9d61a..ded4baa1cd 100644
--- a/autotests/integration/effects/slidingpopups_test.cpp
+++ b/autotests/integration/effects/slidingpopups_test.cpp
@@ -125,8 +125,8 @@ void SlidingPopupsTest::testWithOtherEffect_data()
QTest::newRow("fade, slide") << QStringList{QStringLiteral("kwin4_effect_fade"), QStringLiteral("slidingpopups")};
QTest::newRow("slide, fade") << QStringList{QStringLiteral("slidingpopups"), QStringLiteral("kwin4_effect_fade")};
- QTest::newRow("scale, slide") << QStringList{QStringLiteral("scale"), QStringLiteral("slidingpopups")};
- QTest::newRow("slide, scale") << QStringList{QStringLiteral("slidingpopups"), QStringLiteral("scale")};
+ QTest::newRow("scale, slide") << QStringList{QStringLiteral("kwin4_effect_scale"), QStringLiteral("slidingpopups")};
+ QTest::newRow("slide, scale") << QStringList{QStringLiteral("slidingpopups"), QStringLiteral("kwin4_effect_scale")};
if (effects->compositingType() & KWin::OpenGLCompositing) {
QTest::newRow("glide, slide") << QStringList{QStringLiteral("glide"), QStringLiteral("slidingpopups")};
@@ -262,8 +262,8 @@ void SlidingPopupsTest::testWithOtherEffectWayland_data()
QTest::newRow("fade, slide") << QStringList{QStringLiteral("kwin4_effect_fade"), QStringLiteral("slidingpopups")};
QTest::newRow("slide, fade") << QStringList{QStringLiteral("slidingpopups"), QStringLiteral("kwin4_effect_fade")};
- QTest::newRow("scale, slide") << QStringList{QStringLiteral("scale"), QStringLiteral("slidingpopups")};
- QTest::newRow("slide, scale") << QStringList{QStringLiteral("slidingpopups"), QStringLiteral("scale")};
+ QTest::newRow("scale, slide") << QStringList{QStringLiteral("kwin4_effect_scale"), QStringLiteral("slidingpopups")};
+ QTest::newRow("slide, scale") << QStringList{QStringLiteral("slidingpopups"), QStringLiteral("kwin4_effect_scale")};
if (effects->compositingType() & KWin::OpenGLCompositing) {
QTest::newRow("glide, slide") << QStringList{QStringLiteral("glide"), QStringLiteral("slidingpopups")};
diff --git a/autotests/test_builtin_effectloader.cpp b/autotests/test_builtin_effectloader.cpp
index 3d514e1863..2f9ab1bef3 100644
--- a/autotests/test_builtin_effectloader.cpp
+++ b/autotests/test_builtin_effectloader.cpp
@@ -103,7 +103,6 @@ void TestBuiltInEffectLoader::testHasEffect_data()
QTest::newRow("MouseMark") << QStringLiteral("mousemark") << true;
QTest::newRow("PresentWindows") << QStringLiteral("presentwindows") << true;
QTest::newRow("Resize") << QStringLiteral("resize") << true;
- QTest::newRow("Scale") << QStringLiteral("scale") << true;
QTest::newRow("ScreenEdge") << QStringLiteral("screenedge") << true;
QTest::newRow("ScreenShot") << QStringLiteral("screenshot") << true;
QTest::newRow("Sheet") << QStringLiteral("sheet") << true;
@@ -159,7 +158,6 @@ void TestBuiltInEffectLoader::testKnownEffects()
<< QStringLiteral("mousemark")
<< QStringLiteral("presentwindows")
<< QStringLiteral("resize")
- << QStringLiteral("scale")
<< QStringLiteral("screenedge")
<< QStringLiteral("screenshot")
<< QStringLiteral("sheet")
@@ -237,7 +235,6 @@ void TestBuiltInEffectLoader::testSupported_data()
QTest::newRow("MouseMark") << QStringLiteral("mousemark") << true << xc << true;
QTest::newRow("PresentWindows") << QStringLiteral("presentwindows") << true << xc << true;
QTest::newRow("Resize") << QStringLiteral("resize") << true << xc << true;
- QTest::newRow("Scale") << QStringLiteral("scale") << true << xc << true;
QTest::newRow("ScreenEdge") << QStringLiteral("screenedge") << true << xc << true;
QTest::newRow("ScreenShot") << QStringLiteral("screenshot") << true << xc << true;
QTest::newRow("Sheet") << QStringLiteral("sheet") << false << xc << true;
@@ -325,7 +322,6 @@ void TestBuiltInEffectLoader::testLoadEffect_data()
QTest::newRow("MouseMark") << QStringLiteral("mousemark") << true << xc;
QTest::newRow("PresentWindows") << QStringLiteral("presentwindows") << true << xc;
QTest::newRow("Resize") << QStringLiteral("resize") << true << xc;
- QTest::newRow("Scale") << QStringLiteral("scale") << true << xc;
QTest::newRow("ScreenEdge") << QStringLiteral("screenedge") << true << xc;
QTest::newRow("ScreenShot") << QStringLiteral("screenshot") << true << xc;
QTest::newRow("Sheet") << QStringLiteral("sheet") << false << xc;
diff --git a/autotests/test_plugin_effectloader.cpp b/autotests/test_plugin_effectloader.cpp
index 1cbf5b9049..7da8cc90fb 100644
--- a/autotests/test_plugin_effectloader.cpp
+++ b/autotests/test_plugin_effectloader.cpp
@@ -94,7 +94,6 @@ void TestPluginEffectLoader::testHasEffect_data()
QTest::newRow("MouseMark") << QStringLiteral("mousemark") << false;
QTest::newRow("PresentWindows") << QStringLiteral("presentwindows") << false;
QTest::newRow("Resize") << QStringLiteral("resize") << false;
- QTest::newRow("Scale") << QStringLiteral("scale") << false;
QTest::newRow("ScreenEdge") << QStringLiteral("screenedge") << false;
QTest::newRow("ScreenShot") << QStringLiteral("screenshot") << false;
QTest::newRow("Sheet") << QStringLiteral("sheet") << false;
@@ -118,6 +117,7 @@ void TestPluginEffectLoader::testHasEffect_data()
QTest::newRow("Login") << QStringLiteral("kwin4_effect_login") << false;
QTest::newRow("Logout") << QStringLiteral("kwin4_effect_logout") << false;
QTest::newRow("Maximize") << QStringLiteral("kwin4_effect_maximize") << false;
+ QTest::newRow("Scale") << QStringLiteral("kwin4_effect_scale") << false;
QTest::newRow("Squash") << QStringLiteral("kwin4_effect_squash") << false;
QTest::newRow("Translucency") << QStringLiteral("kwin4_effect_translucency") << false;
// and the fake effects we use here
diff --git a/autotests/test_scripted_effectloader.cpp b/autotests/test_scripted_effectloader.cpp
index 79821a8f3d..210db6c06b 100644
--- a/autotests/test_scripted_effectloader.cpp
+++ b/autotests/test_scripted_effectloader.cpp
@@ -124,7 +124,6 @@ void TestScriptedEffectLoader::testHasEffect_data()
QTest::newRow("MouseMark") << QStringLiteral("mousemark") << false;
QTest::newRow("PresentWindows") << QStringLiteral("presentwindows") << false;
QTest::newRow("Resize") << QStringLiteral("resize") << false;
- QTest::newRow("Scale") << QStringLiteral("scale") << false;
QTest::newRow("ScreenEdge") << QStringLiteral("screenedge") << false;
QTest::newRow("ScreenShot") << QStringLiteral("screenshot") << false;
QTest::newRow("Sheet") << QStringLiteral("sheet") << false;
@@ -150,6 +149,7 @@ void TestScriptedEffectLoader::testHasEffect_data()
QTest::newRow("Login") << QStringLiteral("kwin4_effect_login") << true;
QTest::newRow("Logout") << QStringLiteral("kwin4_effect_logout") << true;
QTest::newRow("Maximize") << QStringLiteral("kwin4_effect_maximize") << true;
+ QTest::newRow("Scale") << QStringLiteral("kwin4_effect_scale") << true;
QTest::newRow("Squash") << QStringLiteral("kwin4_effect_squash") << true;
QTest::newRow("Translucency") << QStringLiteral("kwin4_effect_translucency") << true;
}
@@ -182,6 +182,7 @@ void TestScriptedEffectLoader::testKnownEffects()
<< QStringLiteral("kwin4_effect_login")
<< QStringLiteral("kwin4_effect_logout")
<< QStringLiteral("kwin4_effect_maximize")
+ << QStringLiteral("kwin4_effect_scale")
<< QStringLiteral("kwin4_effect_squash")
<< QStringLiteral("kwin4_effect_translucency");
@@ -209,6 +210,7 @@ void TestScriptedEffectLoader::testLoadEffect_data()
QTest::newRow("Login") << QStringLiteral("kwin4_effect_login") << true;
QTest::newRow("Logout") << QStringLiteral("kwin4_effect_logout") << true;
QTest::newRow("Maximize") << QStringLiteral("kwin4_effect_maximize") << true;
+ QTest::newRow("Scale") << QStringLiteral("kwin4_effect_scale") << true;
QTest::newRow("Squash") << QStringLiteral("kwin4_effect_squash") << true;
QTest::newRow("Translucency") << QStringLiteral("kwin4_effect_translucency") << true;
}
@@ -361,6 +363,7 @@ void TestScriptedEffectLoader::testLoadAllEffects()
plugins.writeEntry(kwin4 + QStringLiteral("loginEnabled"), false);
plugins.writeEntry(kwin4 + QStringLiteral("logoutEnabled"), false);
plugins.writeEntry(kwin4 + QStringLiteral("maximizeEnabled"), false);
+ plugins.writeEntry(kwin4 + QStringLiteral("scaleEnabled"), false);
plugins.writeEntry(kwin4 + QStringLiteral("squashEnabled"), false);
plugins.writeEntry(kwin4 + QStringLiteral("translucencyEnabled"), false);
plugins.writeEntry(kwin4 + QStringLiteral("eyeonscreenEnabled"), false);
diff --git a/effects/CMakeLists.txt b/effects/CMakeLists.txt
index 71f8fa2113..9b6f180834 100644
--- a/effects/CMakeLists.txt
+++ b/effects/CMakeLists.txt
@@ -90,7 +90,6 @@ set( kwin4_effect_builtins_sources
presentwindows/presentwindows.cpp
presentwindows/presentwindows_proxy.cpp
resize/resize.cpp
- scale/scale.cpp
showfps/showfps.cpp
showpaint/showpaint.cpp
slide/slide.cpp
@@ -121,7 +120,6 @@ kconfig_add_kcfg_files(kwin4_effect_builtins_sources
mousemark/mousemarkconfig.kcfgc
presentwindows/presentwindowsconfig.kcfgc
resize/resizeconfig.kcfgc
- scale/scaleconfig.kcfgc
showfps/showfpsconfig.kcfgc
slide/slideconfig.kcfgc
slidingpopups/slidingpopupsconfig.kcfgc
@@ -142,6 +140,7 @@ add_subdirectory( login )
add_subdirectory( logout )
add_subdirectory( maximize )
add_subdirectory( morphingpopups )
+add_subdirectory( scale )
add_subdirectory( squash )
add_subdirectory( translucency )
add_subdirectory( windowaperture )
@@ -182,7 +181,6 @@ add_subdirectory( lookingglass )
add_subdirectory( magnifier )
add_subdirectory( mouseclick )
add_subdirectory( mousemark )
-add_subdirectory( scale )
include( screenshot/CMakeLists.txt )
include( sheet/CMakeLists.txt )
include( snaphelper/CMakeLists.txt )
diff --git a/effects/effect_builtins.cpp b/effects/effect_builtins.cpp
index 1eaa2e37a6..6306bece9d 100644
--- a/effects/effect_builtins.cpp
+++ b/effects/effect_builtins.cpp
@@ -36,7 +36,6 @@ along with this program. If not, see .
#include "highlightwindow/highlightwindow.h"
#include "magiclamp/magiclamp.h"
#include "resize/resize.h"
-#include "scale/scale.h"
#include "showfps/showfps.h"
#include "showpaint/showpaint.h"
#include "slide/slide.h"
@@ -428,21 +427,6 @@ EFFECT_FALLBACK
nullptr,
nullptr
#endif
-EFFECT_FALLBACK
- }, {
- QStringLiteral("scale"),
- i18ndc("kwin_effects", "Name of a KWin Effect", "Scale"),
- i18ndc("kwin_effects", "Comment describing the KWin Effect", "Make windows smoothly scale in and out when they are shown or hidden"),
- QStringLiteral("Appearance"),
- QString(),
- QUrl(),
- false,
- false,
-#ifdef EFFECT_BUILTINS
- &createHelper,
- &ScaleEffect::supported,
- nullptr
-#endif
EFFECT_FALLBACK
}, {
QStringLiteral("screenedge"),
diff --git a/effects/effect_builtins.h b/effects/effect_builtins.h
index 30c0e43ad4..a98bb630d7 100644
--- a/effects/effect_builtins.h
+++ b/effects/effect_builtins.h
@@ -56,7 +56,6 @@ enum class BuiltInEffect
MouseMark,
PresentWindows,
Resize,
- Scale,
ScreenEdge,
ScreenShot,
Sheet,
diff --git a/effects/scale/CMakeLists.txt b/effects/scale/CMakeLists.txt
index 016b2f6fc6..1242620d48 100644
--- a/effects/scale/CMakeLists.txt
+++ b/effects/scale/CMakeLists.txt
@@ -1,25 +1 @@
-#######################################
-# Config
-set(kwin_scale_config_SRCS scale_config.cpp)
-ki18n_wrap_ui(kwin_scale_config_SRCS scale_config.ui)
-qt5_add_dbus_interface(kwin_scale_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
-kconfig_add_kcfg_files(kwin_scale_config_SRCS scaleconfig.kcfgc)
-
-add_library(kwin_scale_config MODULE ${kwin_scale_config_SRCS})
-
-target_link_libraries(kwin_scale_config
- Qt5::DBus
- KF5::ConfigWidgets
- KF5::I18n
- KF5::Service
-)
-
-kcoreaddons_desktop_to_json(kwin_scale_config scale_config.desktop SERVICE_TYPES kcmodule.desktop)
-
-install(
- TARGETS
- kwin_scale_config
- DESTINATION
- ${PLUGIN_INSTALL_DIR}/kwin/effects/configs
-)
-
+add_subdirectory(package)
diff --git a/effects/scale/package/CMakeLists.txt b/effects/scale/package/CMakeLists.txt
new file mode 100644
index 0000000000..38efbd346f
--- /dev/null
+++ b/effects/scale/package/CMakeLists.txt
@@ -0,0 +1,9 @@
+install(DIRECTORY contents
+ DESTINATION ${DATA_INSTALL_DIR}/${KWIN_NAME}/effects/kwin4_effect_scale)
+
+install(FILES metadata.desktop
+ DESTINATION ${DATA_INSTALL_DIR}/${KWIN_NAME}/effects/kwin4_effect_scale)
+
+install(FILES metadata.desktop
+ DESTINATION ${SERVICES_INSTALL_DIR}/${KWIN_NAME}
+ RENAME kwin4_effect_scale.desktop)
diff --git a/effects/scale/package/contents/code/main.js b/effects/scale/package/contents/code/main.js
new file mode 100644
index 0000000000..11b58c78a5
--- /dev/null
+++ b/effects/scale/package/contents/code/main.js
@@ -0,0 +1,181 @@
+/********************************************************************
+ KWin - the KDE window manager
+ 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 blacklist = [
+ // The logout screen has to be animated only by the logout effect.
+ "ksmserver ksmserver",
+ "ksmserver-logout-greeter ksmserver-logout-greeter",
+
+ // KDE Plasma splash screen has to be animated only by the login effect.
+ "ksplashqml ksplashqml",
+ "ksplashsimple ksplashsimple",
+ "ksplashx ksplashx"
+];
+
+var scaleEffect = {
+ loadConfig: function (window) {
+ "use strict";
+ var defaultDuration = 160;
+ var duration = effect.readConfig("Duration", defaultDuration) || defaultDuration;
+ scaleEffect.duration = animationTime(duration);
+ scaleEffect.inScale = effect.readConfig("InScale", 0.96);
+ scaleEffect.inOpacity = effect.readConfig("InOpacity", 0.4);
+ scaleEffect.outScale = effect.readConfig("OutScale", 0.96);
+ scaleEffect.outOpacity = effect.readConfig("OutOpacity", 0.0);
+ },
+ isScaleWindow: function (window) {
+ "use strict";
+ // We don't want to animate most of plasmashell's windows, yet, some
+ // of them we want to, for example, Task Manager Settings window.
+ // The problem is that all those window share single window class.
+ // So, the only way to decide whether a window should be animated is
+ // to use a heuristic: if a window has decoration, then it's most
+ // likely a dialog or a settings window so we have to animate it.
+ if (window.windowClass == "plasmashell plasmashell"
+ || window.windowClass == "plasmashell org.kde.plasmashell") {
+ return window.hasDecoration;
+ }
+
+ if (blacklist.indexOf(window.windowClass) != -1) {
+ return false;
+ }
+
+ if (window.hasDecoration) {
+ return true;
+ }
+
+ // Don't animate combobox popups, tooltips, popup menus, etc.
+ if (window.popup) {
+ return false;
+ }
+
+ // Override-redirect windows are usually used for user interface
+ // concepts that are not expected to be animated by this effect.
+ if (window.x11Client && !window.managed) {
+ return false;
+ }
+
+ return window.normalWindow || window.dialog;
+ },
+ setupForcedRoles: function (window) {
+ "use strict";
+ window.setData(Effect.WindowForceBackgroundContrastRole, true);
+ window.setData(Effect.WindowForceBlurRole, true);
+ },
+ cleanupForcedRoles: function (window) {
+ "use strict";
+ window.setData(Effect.WindowForceBackgroundContrastRole, null);
+ window.setData(Effect.WindowForceBlurRole, null);
+ },
+ slotWindowAdded: function (window) {
+ "use strict";
+ if (effects.hasActiveFullScreenEffect) {
+ return;
+ }
+ if (!scaleEffect.isScaleWindow(window)) {
+ return;
+ }
+ if (!window.visible) {
+ return;
+ }
+ if (!effect.grab(window, Effect.WindowAddedGrabRole)) {
+ return;
+ }
+ scaleEffect.setupForcedRoles(window);
+ window.scaleInAnimation = animate({
+ window: window,
+ curve: QEasingCurve.InOutSine,
+ duration: scaleEffect.duration,
+ animations: [
+ {
+ type: Effect.Scale,
+ from: scaleEffect.inScale
+ },
+ {
+ type: Effect.Opacity,
+ from: scaleEffect.inOpacity
+ }
+ ]
+ });
+ },
+ slotWindowClosed: function (window) {
+ "use strict";
+ if (effects.hasActiveFullScreenEffect) {
+ return;
+ }
+ if (!scaleEffect.isScaleWindow(window)) {
+ return;
+ }
+ if (!window.visible) {
+ return;
+ }
+ if (!effect.grab(window, Effect.WindowClosedGrabRole)) {
+ return;
+ }
+ if (window.scaleInAnimation) {
+ cancel(window.scaleInAnimation);
+ delete window.scaleInAnimation;
+ }
+ scaleEffect.setupForcedRoles(window);
+ window.scaleOutAnimation = animate({
+ window: window,
+ curve: QEasingCurve.InOutSine,
+ duration: scaleEffect.duration,
+ animations: [
+ {
+ type: Effect.Scale,
+ to: scaleEffect.outScale
+ },
+ {
+ type: Effect.Opacity,
+ to: scaleEffect.outOpacity
+ }
+ ]
+ });
+ },
+ slotWindowDataChanged: function (window, role) {
+ "use strict";
+ if (role == Effect.WindowAddedGrabRole) {
+ if (window.scaleInAnimation && effect.isGrabbed(window, role)) {
+ cancel(window.scaleInAnimation);
+ delete window.scaleInAnimation;
+ scaleEffect.cleanupForcedRoles(window);
+ }
+ } else if (role == Effect.WindowClosedGrabRole) {
+ if (window.scaleOutAnimation && effect.isGrabbed(window, role)) {
+ cancel(window.scaleOutAnimation);
+ delete window.scaleOutAnimation;
+ scaleEffect.cleanupForcedRoles(window);
+ }
+ }
+ },
+ init: function () {
+ "use strict";
+ scaleEffect.loadConfig();
+
+ effect.configChanged.connect(scaleEffect.loadConfig);
+ effect.animationEnded.connect(scaleEffect.cleanupForcedRoles);
+ effects.windowAdded.connect(scaleEffect.slotWindowAdded);
+ effects.windowClosed.connect(scaleEffect.slotWindowClosed);
+ effects.windowDataChanged.connect(scaleEffect.slotWindowDataChanged);
+ }
+};
+
+scaleEffect.init();
diff --git a/effects/scale/scale.kcfg b/effects/scale/package/contents/config/main.xml
similarity index 93%
rename from effects/scale/scale.kcfg
rename to effects/scale/package/contents/config/main.xml
index 2b77c303c4..4f9152a087 100644
--- a/effects/scale/scale.kcfg
+++ b/effects/scale/package/contents/config/main.xml
@@ -3,8 +3,8 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
-
-
+
+
0
diff --git a/effects/scale/scale_config.ui b/effects/scale/package/contents/ui/config.ui
similarity index 100%
rename from effects/scale/scale_config.ui
rename to effects/scale/package/contents/ui/config.ui
diff --git a/effects/scale/package/metadata.desktop b/effects/scale/package/metadata.desktop
new file mode 100644
index 0000000000..28bf83cb27
--- /dev/null
+++ b/effects/scale/package/metadata.desktop
@@ -0,0 +1,22 @@
+[Desktop Entry]
+Name=Scale
+Icon=preferences-system-windows-effect-scale
+Comment=Make windows smoothly scale in and out when they are shown or hidden
+
+Type=Service
+X-KDE-ServiceTypes=KWin/Effect,KCModule
+X-KDE-PluginInfo-Author=Vlad Zagorodniy
+X-KDE-PluginInfo-Email=vladzzag@gmail.com
+X-KDE-PluginInfo-Name=kwin4_effect_scale
+X-KDE-PluginInfo-Version=1
+X-KDE-PluginInfo-Category=Appearance
+X-KDE-PluginInfo-Depends=
+X-KDE-PluginInfo-License=GPL
+X-KDE-PluginInfo-EnabledByDefault=false
+X-KDE-Ordering=60
+X-Plasma-API=javascript
+X-Plasma-MainScript=code/main.js
+X-KDE-PluginKeyword=kwin4_effect_scale
+X-KDE-Library=kcm_kwin4_genericscripted
+X-KDE-ParentComponents=kwin4_effect_scale
+X-KWin-Config-TranslationDomain=kwin_effects
diff --git a/effects/scale/scale.cpp b/effects/scale/scale.cpp
deleted file mode 100644
index 530f8de364..0000000000
--- a/effects/scale/scale.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-/********************************************************************
- KWin - the KDE window manager
- 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 .
-*********************************************************************/
-
-// own
-#include "scale.h"
-
-// KConfigSkeleton
-#include "scaleconfig.h"
-
-// Qt
-#include
-
-namespace KWin
-{
-
-static const QSet s_blacklist {
- // The logout screen has to be animated only by the logout effect.
- QStringLiteral("ksmserver ksmserver"),
- QStringLiteral("ksmserver-logout-greeter ksmserver-logout-greeter"),
-
- // KDE Plasma splash screen has to be animated only by the login effect.
- QStringLiteral("ksplashqml ksplashqml"),
- QStringLiteral("ksplashsimple ksplashsimple"),
- QStringLiteral("ksplashx ksplashx")
-};
-
-ScaleEffect::ScaleEffect()
-{
- initConfig();
- reconfigure(ReconfigureAll);
-
- connect(effects, &EffectsHandler::windowAdded, this, &ScaleEffect::windowAdded);
- connect(effects, &EffectsHandler::windowClosed, this, &ScaleEffect::windowClosed);
- connect(effects, &EffectsHandler::windowDeleted, this, &ScaleEffect::windowDeleted);
- connect(effects, &EffectsHandler::windowDataChanged, this, &ScaleEffect::windowDataChanged);
-}
-
-ScaleEffect::~ScaleEffect()
-{
-}
-
-void ScaleEffect::reconfigure(ReconfigureFlags flags)
-{
- Q_UNUSED(flags)
-
- ScaleConfig::self()->read();
- m_duration = std::chrono::milliseconds(animationTime(160));
-
- m_inParams.scale.from = ScaleConfig::inScale();
- m_inParams.scale.to = 1.0;
- m_inParams.opacity.from = ScaleConfig::inOpacity();
- m_inParams.opacity.to = 1.0;
-
- m_outParams.scale.from = 1.0;
- m_outParams.scale.to = ScaleConfig::outScale();
- m_outParams.opacity.from = 1.0;
- m_outParams.opacity.to = ScaleConfig::outOpacity();
-}
-
-void ScaleEffect::prePaintScreen(ScreenPrePaintData &data, int time)
-{
- const std::chrono::milliseconds delta(time);
-
- auto animationIt = m_animations.begin();
- while (animationIt != m_animations.end()) {
- (*animationIt).update(delta);
- ++animationIt;
- }
-
- effects->prePaintScreen(data, time);
-}
-
-void ScaleEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time)
-{
- if (m_animations.contains(w)) {
- data.setTransformed();
- w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE);
- }
-
- effects->prePaintWindow(w, data, time);
-}
-
-void ScaleEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
-{
- auto animationIt = m_animations.constFind(w);
- if (animationIt == m_animations.constEnd()) {
- effects->paintWindow(w, mask, region, data);
- return;
- }
-
- const ScaleParams params = w->isDeleted() ? m_outParams : m_inParams;
- const qreal t = (*animationIt).value();
- const qreal scale = interpolate(params.scale.from, params.scale.to, t);
-
- data.setXScale(scale);
- data.setYScale(scale);
- data.setXTranslation(0.5 * (1.0 - scale) * w->width());
- data.setYTranslation(0.5 * (1.0 - scale) * w->height());
- data.multiplyOpacity(interpolate(params.opacity.from, params.opacity.to, t));
-
- effects->paintWindow(w, mask, region, data);
-}
-
-void ScaleEffect::postPaintScreen()
-{
- auto animationIt = m_animations.begin();
- while (animationIt != m_animations.end()) {
- EffectWindow *w = animationIt.key();
-
- const QRect geo = w->expandedGeometry();
- const ScaleParams params = w->isDeleted() ? m_outParams : m_inParams;
- const qreal scale = qMax(params.scale.from, params.scale.to);
- const QRect repaintRect(
- geo.topLeft() + 0.5 * (1.0 - scale) * QPoint(geo.width(), geo.height()),
- geo.size() * scale);
- effects->addRepaint(repaintRect);
-
- if ((*animationIt).done()) {
- if (w->isDeleted()) {
- w->unrefWindow();
- } else {
- w->setData(WindowForceBackgroundContrastRole, QVariant());
- w->setData(WindowForceBlurRole, QVariant());
- }
- animationIt = m_animations.erase(animationIt);
- } else {
- ++animationIt;
- }
- }
-
- effects->postPaintScreen();
-}
-
-bool ScaleEffect::isActive() const
-{
- return !m_animations.isEmpty();
-}
-
-bool ScaleEffect::supported()
-{
- return effects->animationsSupported();
-}
-
-void ScaleEffect::windowAdded(EffectWindow *w)
-{
- if (effects->activeFullScreenEffect()) {
- return;
- }
-
- if (!isScaleWindow(w)) {
- return;
- }
-
- if (!w->isVisible()) {
- return;
- }
-
- const void *addGrab = w->data(WindowAddedGrabRole).value();
- if (addGrab && addGrab != this) {
- return;
- }
-
- TimeLine &timeLine = m_animations[w];
- timeLine.reset();
- timeLine.setDirection(TimeLine::Forward);
- timeLine.setDuration(m_duration);
- timeLine.setEasingCurve(QEasingCurve::InCurve);
-
- w->setData(WindowAddedGrabRole, QVariant::fromValue(static_cast(this)));
- w->setData(WindowForceBackgroundContrastRole, QVariant(true));
- w->setData(WindowForceBlurRole, QVariant(true));
-
- w->addRepaintFull();
-}
-
-void ScaleEffect::windowClosed(EffectWindow *w)
-{
- if (effects->activeFullScreenEffect()) {
- return;
- }
-
- if (!isScaleWindow(w)) {
- return;
- }
-
- if (!w->isVisible()) {
- return;
- }
-
- const void *closeGrab = w->data(WindowClosedGrabRole).value();
- if (closeGrab && closeGrab != this) {
- return;
- }
-
- w->refWindow();
-
- TimeLine &timeLine = m_animations[w];
- timeLine.reset();
- timeLine.setDirection(TimeLine::Forward);
- timeLine.setDuration(m_duration);
- timeLine.setEasingCurve(QEasingCurve::OutCurve);
-
- w->setData(WindowClosedGrabRole, QVariant::fromValue(static_cast(this)));
- w->setData(WindowForceBackgroundContrastRole, QVariant(true));
- w->setData(WindowForceBlurRole, QVariant(true));
-
- w->addRepaintFull();
-}
-
-void ScaleEffect::windowDeleted(EffectWindow *w)
-{
- m_animations.remove(w);
-}
-
-void ScaleEffect::windowDataChanged(EffectWindow *w, int role)
-{
- if (role != WindowAddedGrabRole && role != WindowClosedGrabRole) {
- return;
- }
-
- if (w->data(role).value() == this) {
- return;
- }
-
- auto animationIt = m_animations.find(w);
- if (animationIt == m_animations.end()) {
- return;
- }
-
- if (w->isDeleted() && role == WindowClosedGrabRole) {
- w->unrefWindow();
- }
-
- m_animations.erase(animationIt);
-
- w->setData(WindowForceBackgroundContrastRole, QVariant());
- w->setData(WindowForceBlurRole, QVariant());
-}
-
-bool ScaleEffect::isScaleWindow(EffectWindow *w) const
-{
- // We don't want to animate most of plasmashell's windows, yet, some
- // of them we want to, for example, Task Manager Settings window.
- // The problem is that all those window share single window class.
- // So, the only way to decide whether a window should be animated is
- // to use a heuristic: if a window has decoration, then it's most
- // likely a dialog or a settings window so we have to animate it.
- if (w->windowClass() == QLatin1String("plasmashell plasmashell")
- || w->windowClass() == QLatin1String("plasmashell org.kde.plasmashell")) {
- return w->hasDecoration();
- }
-
- if (s_blacklist.contains(w->windowClass())) {
- return false;
- }
-
- if (w->hasDecoration()) {
- return true;
- }
-
- // Don't animate combobox popups, tooltips, popup menus, etc.
- if (w->isPopupWindow()) {
- return false;
- }
-
- // Override-redirect windows are usually used for user interface
- // concepts that are not expected to be animated by this effect.
- if (w->isX11Client() && !w->isManaged()) {
- return false;
- }
-
- return w->isNormalWindow()
- || w->isDialog();
-}
-
-} // namespace KWin
diff --git a/effects/scale/scale.h b/effects/scale/scale.h
deleted file mode 100644
index 68f3cff118..0000000000
--- a/effects/scale/scale.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/********************************************************************
- KWin - the KDE window manager
- 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 .
-*********************************************************************/
-
-#ifndef KWIN_SCALE_H
-#define KWIN_SCALE_H
-
-// kwineffects
-#include
-
-namespace KWin
-{
-
-class ScaleEffect : public Effect
-{
- Q_OBJECT
- Q_PROPERTY(int duration READ duration)
- Q_PROPERTY(qreal inScale READ inScale)
- Q_PROPERTY(qreal inOpacity READ inOpacity)
- Q_PROPERTY(qreal outScale READ outScale)
- Q_PROPERTY(qreal outOpacity READ outOpacity)
-
-public:
- ScaleEffect();
- ~ScaleEffect() override;
-
- void reconfigure(ReconfigureFlags flags) override;
-
- void prePaintScreen(ScreenPrePaintData &data, int time) override;
- void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) override;
- void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
- void postPaintScreen() override;
-
- bool isActive() const override;
- int requestedEffectChainPosition() const override;
-
- static bool supported();
-
- int duration() const;
- qreal inScale() const;
- qreal inOpacity() const;
- qreal outScale() const;
- qreal outOpacity() const;
-
-private Q_SLOTS:
- void windowAdded(EffectWindow *w);
- void windowClosed(EffectWindow *w);
- void windowDeleted(EffectWindow *w);
- void windowDataChanged(EffectWindow *w, int role);
-
-private:
- bool isScaleWindow(EffectWindow *w) const;
-
- std::chrono::milliseconds m_duration;
- QHash m_animations;
-
- struct ScaleParams {
- struct {
- qreal from;
- qreal to;
- } scale, opacity;
- };
-
- ScaleParams m_inParams;
- ScaleParams m_outParams;
-};
-
-inline int ScaleEffect::requestedEffectChainPosition() const
-{
- return 50;
-}
-
-inline int ScaleEffect::duration() const
-{
- return m_duration.count();
-}
-
-inline qreal ScaleEffect::inScale() const
-{
- return m_inParams.scale.from;
-}
-
-inline qreal ScaleEffect::inOpacity() const
-{
- return m_inParams.opacity.from;
-}
-
-inline qreal ScaleEffect::outScale() const
-{
- return m_outParams.scale.to;
-}
-
-inline qreal ScaleEffect::outOpacity() const
-{
- return m_outParams.opacity.to;
-}
-
-} // namespace KWin
-
-#endif
diff --git a/effects/scale/scale_config.cpp b/effects/scale/scale_config.cpp
deleted file mode 100644
index 8b078add80..0000000000
--- a/effects/scale/scale_config.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/********************************************************************
- KWin - the KDE window manager
- 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 .
-*********************************************************************/
-
-#include "scale_config.h"
-
-// KConfigSkeleton
-#include "scaleconfig.h"
-#include
-
-#include
-#include
-#include
-
-K_PLUGIN_FACTORY_WITH_JSON(ScaleEffectConfigFactory,
- "scale_config.json",
- registerPlugin();)
-
-namespace KWin
-{
-
-ScaleEffectConfig::ScaleEffectConfig(QWidget *parent, const QVariantList &args)
- : KCModule(KAboutData::pluginData(QStringLiteral("scale")), parent, args)
-{
- ui.setupUi(this);
- ScaleConfig::instance(KWIN_CONFIG);
- addConfig(ScaleConfig::self(), this);
- load();
-}
-
-ScaleEffectConfig::~ScaleEffectConfig()
-{
-}
-
-void ScaleEffectConfig::save()
-{
- KCModule::save();
- OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"),
- QStringLiteral("/Effects"),
- QDBusConnection::sessionBus());
- interface.reconfigureEffect(QStringLiteral("scale"));
-}
-
-} // namespace KWin
-
-#include "scale_config.moc"
diff --git a/effects/scale/scale_config.desktop b/effects/scale/scale_config.desktop
deleted file mode 100644
index 8c9f733e35..0000000000
--- a/effects/scale/scale_config.desktop
+++ /dev/null
@@ -1,34 +0,0 @@
-[Desktop Entry]
-Type=Service
-X-KDE-ServiceTypes=KCModule
-
-X-KDE-Library=kwin_scale_config
-X-KDE-ParentComponents=scale
-
-Name=Scale
-Name[ca]=Escala
-Name[ca@valencia]=Escala
-Name[cs]=Měřítko
-Name[de]=Skalieren
-Name[el]=Κλιμάκωση
-Name[en_GB]=Scale
-Name[es]=Escalar
-Name[eu]=Eskalatu
-Name[fi]=Skaalaa
-Name[fr]=Échelle
-Name[gl]=Cambiar as dimensións
-Name[id]=Scale
-Name[it]=Scala
-Name[ko]=크기 조정
-Name[nl]=Schalen
-Name[nn]=Skalering
-Name[pl]=Skala
-Name[pt]=Escala
-Name[pt_BR]=Escala
-Name[ru]=Масштабирование
-Name[sk]=Škálovať
-Name[sv]=Skala
-Name[uk]=Масштабування
-Name[x-test]=xxScalexx
-Name[zh_CN]=缩放
-Name[zh_TW]=縮放
diff --git a/effects/scale/scale_config.h b/effects/scale/scale_config.h
deleted file mode 100644
index d26f361f13..0000000000
--- a/effects/scale/scale_config.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/********************************************************************
- KWin - the KDE window manager
- 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 .
-*********************************************************************/
-
-#ifndef SCALE_CONFIG_H
-#define SCALE_CONFIG_H
-
-#include "ui_scale_config.h"
-
-#include
-
-namespace KWin
-{
-
-class ScaleEffectConfig : public KCModule
-{
- Q_OBJECT
-
-public:
- explicit ScaleEffectConfig(QWidget *parent = nullptr, const QVariantList &args = QVariantList());
- ~ScaleEffectConfig() override;
-
- void save() override;
-
-private:
- ::Ui::ScaleEffectConfig ui;
-};
-
-} // namespace KWin
-
-#endif
-
diff --git a/effects/scale/scaleconfig.kcfgc b/effects/scale/scaleconfig.kcfgc
deleted file mode 100644
index 2b9bc99119..0000000000
--- a/effects/scale/scaleconfig.kcfgc
+++ /dev/null
@@ -1,5 +0,0 @@
-File=scale.kcfg
-ClassName=ScaleConfig
-NameSpace=KWin
-Singleton=true
-Mutators=true
diff --git a/kconf_update/kwin.upd b/kconf_update/kwin.upd
index 164079c71f..19062a50b0 100644
--- a/kconf_update/kwin.upd
+++ b/kconf_update/kwin.upd
@@ -11,3 +11,11 @@ Id=port-minimizeanimation-effect-to-js
File=kwinrc
Group=Plugins
Key=minimizeanimationEnabled,kwin4_effect_squashEnabled
+
+# Port the Scale effect to JavaScript.
+Id=port-scale-effect-to-js
+File=kwinrc
+Group=Effect-Scale,Effect-kwin4_effect_scale
+AllKeys
+Group=Plugins
+Key=scaleEnabled,kwin4_effect_scaleEnabled