From 862bf0f153255d4e3c36d862e718f3328d683d3e Mon Sep 17 00:00:00 2001 From: Vlad Zagorodniy Date: Sun, 28 Oct 2018 00:27:25 +0300 Subject: [PATCH] [effects/scale] Port to JavaScript Summary: Now, when the scripting effects API has all required ingredients to port the Scale effect to JavaScript we finally can do it. The main rationale for porting this effect to JavaScript is that scripted effects API lets us focus more on what we want instead of "how". Visually, the ported version doesn't deviate from the C++ version. Test Plan: * Enable the Scale effect; * Open/close a window. Reviewers: #kwin, graesslin Reviewed By: #kwin, graesslin Subscribers: graesslin, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D16478 --- .../effects/slidingpopups_test.cpp | 8 +- autotests/test_builtin_effectloader.cpp | 4 - autotests/test_plugin_effectloader.cpp | 2 +- autotests/test_scripted_effectloader.cpp | 5 +- effects/CMakeLists.txt | 4 +- effects/effect_builtins.cpp | 16 - effects/effect_builtins.h | 1 - effects/scale/CMakeLists.txt | 26 +- effects/scale/package/CMakeLists.txt | 9 + effects/scale/package/contents/code/main.js | 181 +++++++++++ .../contents/config/main.xml} | 4 +- .../contents/ui/config.ui} | 0 effects/scale/package/metadata.desktop | 22 ++ effects/scale/scale.cpp | 293 ------------------ effects/scale/scale.h | 116 ------- effects/scale/scale_config.cpp | 62 ---- effects/scale/scale_config.desktop | 34 -- effects/scale/scale_config.h | 48 --- effects/scale/scaleconfig.kcfgc | 5 - kconf_update/kwin.upd | 8 + 20 files changed, 233 insertions(+), 615 deletions(-) create mode 100644 effects/scale/package/CMakeLists.txt create mode 100644 effects/scale/package/contents/code/main.js rename effects/scale/{scale.kcfg => package/contents/config/main.xml} (93%) rename effects/scale/{scale_config.ui => package/contents/ui/config.ui} (100%) create mode 100644 effects/scale/package/metadata.desktop delete mode 100644 effects/scale/scale.cpp delete mode 100644 effects/scale/scale.h delete mode 100644 effects/scale/scale_config.cpp delete mode 100644 effects/scale/scale_config.desktop delete mode 100644 effects/scale/scale_config.h delete mode 100644 effects/scale/scaleconfig.kcfgc 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