From eb78b1ca3af8dc644b57d447aa927283ba19fd4f Mon Sep 17 00:00:00 2001 From: Vlad Zagorodniy Date: Sun, 23 Sep 2018 20:07:48 +0300 Subject: [PATCH] [effects] Re-implement the Minimize Animation effect in JavaScript Summary: There were several reasons to rewrite the Minimize Animation effect in JavaScript: to simplify code and to get rid of full repaints. One could say that nothing prevents us from calculating the dirty region in postPaintScreen or postPaintWindow and it is correct, but with the scripting effects API the dirty region will be calculated for us, so we can focus more on "what we want" instead of "how". Visually, the "old" effect and the rewritten one look quite the same. Except one tiny bit: if a window doesn't have an icon in the task manager, it won't be animated. The reason for that is the purpose of this effect is to show where the window will be after it's minimized, if the window doesn't have icon in the task manager, one can't click at the center of the screen to unminimize the window. There is one significant change, the name of the effect was changed to "Squash". If we put this effect and the Magic lamp effect under "Window Minimize Animation" category (or if we add some "heading" label), then the old name and the name of the category would "conflict". The new name was suggested by Nate Graham and it very closely describes what the effect does. "Scale" doesn't fit this effect because while a window is being animated, its aspect ratio is not preserved. Reviewers: #kwin, #plasma, davidedmundson Reviewed By: #kwin, #plasma, davidedmundson Subscribers: davidedmundson, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D16372 --- autotests/test_builtin_effectloader.cpp | 5 - autotests/test_plugin_effectloader.cpp | 2 +- autotests/test_scripted_effectloader.cpp | 6 +- effects/CMakeLists.txt | 2 +- effects/effect_builtins.cpp | 16 -- effects/effect_builtins.h | 1 - effects/minimizeanimation/CMakeLists.txt | 7 - .../minimizeanimation/minimizeanimation.cpp | 165 ------------------ effects/minimizeanimation/minimizeanimation.h | 66 ------- effects/squash/CMakeLists.txt | 1 + effects/squash/package/CMakeLists.txt | 9 + effects/squash/package/contents/code/main.js | 150 ++++++++++++++++ effects/squash/package/metadata.desktop | 21 +++ kconf_update/kwin.upd | 6 + 14 files changed, 193 insertions(+), 264 deletions(-) delete mode 100644 effects/minimizeanimation/CMakeLists.txt delete mode 100644 effects/minimizeanimation/minimizeanimation.cpp delete mode 100644 effects/minimizeanimation/minimizeanimation.h create mode 100644 effects/squash/CMakeLists.txt create mode 100644 effects/squash/package/CMakeLists.txt create mode 100644 effects/squash/package/contents/code/main.js create mode 100644 effects/squash/package/metadata.desktop diff --git a/autotests/test_builtin_effectloader.cpp b/autotests/test_builtin_effectloader.cpp index ce5e3079f4..3d514e1863 100644 --- a/autotests/test_builtin_effectloader.cpp +++ b/autotests/test_builtin_effectloader.cpp @@ -99,7 +99,6 @@ void TestBuiltInEffectLoader::testHasEffect_data() QTest::newRow("LookingGlass") << QStringLiteral("lookingglass") << true; QTest::newRow("MagicLamp") << QStringLiteral("magiclamp") << true; QTest::newRow("Magnifier") << QStringLiteral("magnifier") << true; - QTest::newRow("MinimizeAnimation") << QStringLiteral("minimizeanimation") << true; QTest::newRow("MouseClick") << QStringLiteral("mouseclick") << true; QTest::newRow("MouseMark") << QStringLiteral("mousemark") << true; QTest::newRow("PresentWindows") << QStringLiteral("presentwindows") << true; @@ -156,7 +155,6 @@ void TestBuiltInEffectLoader::testKnownEffects() << QStringLiteral("lookingglass") << QStringLiteral("magiclamp") << QStringLiteral("magnifier") - << QStringLiteral("minimizeanimation") << QStringLiteral("mouseclick") << QStringLiteral("mousemark") << QStringLiteral("presentwindows") @@ -235,7 +233,6 @@ void TestBuiltInEffectLoader::testSupported_data() QTest::newRow("MagicLamp-GL") << QStringLiteral("magiclamp") << true << oc << true; QTest::newRow("MagicLamp-GL-no-anim") << QStringLiteral("magiclamp") << false << oc << false; QTest::newRow("Magnifier") << QStringLiteral("magnifier") << true << xc << true; - QTest::newRow("MinimizeAnimation") << QStringLiteral("minimizeanimation") << true << xc << true; QTest::newRow("MouseClick") << QStringLiteral("mouseclick") << true << xc << true; QTest::newRow("MouseMark") << QStringLiteral("mousemark") << true << xc << true; QTest::newRow("PresentWindows") << QStringLiteral("presentwindows") << true << xc << true; @@ -324,7 +321,6 @@ void TestBuiltInEffectLoader::testLoadEffect_data() QTest::newRow("MagicLamp") << QStringLiteral("magiclamp") << false << xc; QTest::newRow("MagicLamp-GL") << QStringLiteral("magiclamp") << true << oc; QTest::newRow("Magnifier") << QStringLiteral("magnifier") << true << xc; - QTest::newRow("MinimizeAnimation") << QStringLiteral("minimizeanimation") << true << xc; QTest::newRow("MouseClick") << QStringLiteral("mouseclick") << true << xc; QTest::newRow("MouseMark") << QStringLiteral("mousemark") << true << xc; QTest::newRow("PresentWindows") << QStringLiteral("presentwindows") << true << xc; @@ -509,7 +505,6 @@ void TestBuiltInEffectLoader::testLoadAllEffects() plugins.writeEntry(QStringLiteral("desktopgridEnabled"), false); plugins.writeEntry(QStringLiteral("highlightwindowEnabled"), false); plugins.writeEntry(QStringLiteral("kscreenEnabled"), false); - plugins.writeEntry(QStringLiteral("minimizeanimationEnabled"), false); plugins.writeEntry(QStringLiteral("presentwindowsEnabled"), false); plugins.writeEntry(QStringLiteral("screenedgeEnabled"), false); plugins.writeEntry(QStringLiteral("screenshotEnabled"), false); diff --git a/autotests/test_plugin_effectloader.cpp b/autotests/test_plugin_effectloader.cpp index 05752449a5..1cbf5b9049 100644 --- a/autotests/test_plugin_effectloader.cpp +++ b/autotests/test_plugin_effectloader.cpp @@ -90,7 +90,6 @@ void TestPluginEffectLoader::testHasEffect_data() QTest::newRow("LookingGlass") << QStringLiteral("lookingglass") << false; QTest::newRow("MagicLamp") << QStringLiteral("magiclamp") << false; QTest::newRow("Magnifier") << QStringLiteral("magnifier") << false; - QTest::newRow("MinimizeAnimation") << QStringLiteral("minimizeanimation") << false; QTest::newRow("MouseClick") << QStringLiteral("mouseclick") << false; QTest::newRow("MouseMark") << QStringLiteral("mousemark") << false; QTest::newRow("PresentWindows") << QStringLiteral("presentwindows") << false; @@ -119,6 +118,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("Squash") << QStringLiteral("kwin4_effect_squash") << false; QTest::newRow("Translucency") << QStringLiteral("kwin4_effect_translucency") << false; // and the fake effects we use here QTest::newRow("fakeeffectplugin") << QStringLiteral("fakeeffectplugin") << true; diff --git a/autotests/test_scripted_effectloader.cpp b/autotests/test_scripted_effectloader.cpp index f1a729d98b..79821a8f3d 100644 --- a/autotests/test_scripted_effectloader.cpp +++ b/autotests/test_scripted_effectloader.cpp @@ -120,7 +120,6 @@ void TestScriptedEffectLoader::testHasEffect_data() QTest::newRow("LookingGlass") << QStringLiteral("lookingglass") << false; QTest::newRow("MagicLamp") << QStringLiteral("magiclamp") << false; QTest::newRow("Magnifier") << QStringLiteral("magnifier") << false; - QTest::newRow("MinimizeAnimation") << QStringLiteral("minimizeanimation") << false; QTest::newRow("MouseClick") << QStringLiteral("mouseclick") << false; QTest::newRow("MouseMark") << QStringLiteral("mousemark") << false; QTest::newRow("PresentWindows") << QStringLiteral("presentwindows") << false; @@ -151,6 +150,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("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_squash") << QStringLiteral("kwin4_effect_translucency"); KWin::ScriptedEffectLoader loader; @@ -208,6 +209,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("Squash") << QStringLiteral("kwin4_effect_squash") << true; QTest::newRow("Translucency") << QStringLiteral("kwin4_effect_translucency") << true; } @@ -359,7 +361,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("minimizeanimationEnabled"), false); + plugins.writeEntry(kwin4 + QStringLiteral("squashEnabled"), false); plugins.writeEntry(kwin4 + QStringLiteral("translucencyEnabled"), false); plugins.writeEntry(kwin4 + QStringLiteral("eyeonscreenEnabled"), false); plugins.writeEntry(kwin4 + QStringLiteral("windowapertureEnabled"), false); diff --git a/effects/CMakeLists.txt b/effects/CMakeLists.txt index 23e157d8e1..71f8fa2113 100644 --- a/effects/CMakeLists.txt +++ b/effects/CMakeLists.txt @@ -142,6 +142,7 @@ add_subdirectory( login ) add_subdirectory( logout ) add_subdirectory( maximize ) add_subdirectory( morphingpopups ) +add_subdirectory( squash ) add_subdirectory( translucency ) add_subdirectory( windowaperture ) @@ -156,7 +157,6 @@ include( fallapart/CMakeLists.txt ) include( highlightwindow/CMakeLists.txt ) include( kscreen/CMakeLists.txt ) add_subdirectory( magiclamp ) -include( minimizeanimation/CMakeLists.txt ) add_subdirectory( presentwindows ) add_subdirectory( resize ) include( screenedge/CMakeLists.txt ) diff --git a/effects/effect_builtins.cpp b/effects/effect_builtins.cpp index 92f64c87e5..1eaa2e37a6 100644 --- a/effects/effect_builtins.cpp +++ b/effects/effect_builtins.cpp @@ -35,7 +35,6 @@ along with this program. If not, see . #include "fallapart/fallapart.h" #include "highlightwindow/highlightwindow.h" #include "magiclamp/magiclamp.h" -#include "minimizeanimation/minimizeanimation.h" #include "resize/resize.h" #include "scale/scale.h" #include "showfps/showfps.h" @@ -369,21 +368,6 @@ EFFECT_FALLBACK &MagnifierEffect::supported, nullptr #endif -EFFECT_FALLBACK - }, { - QStringLiteral("minimizeanimation"), - i18ndc("kwin_effects", "Name of a KWin Effect", "Minimize Animation"), - i18ndc("kwin_effects", "Comment describing the KWin Effect", "Animate the minimizing of windows"), - QStringLiteral("Appearance"), - QStringLiteral("minimize"), - QUrl(QStringLiteral("http://files.kde.org/plasma/kwin/effect-videos/minimize.ogv")), - true, - false, -#ifdef EFFECT_BUILTINS - &createHelper, - &MinimizeAnimationEffect::supported, - nullptr -#endif EFFECT_FALLBACK }, { QStringLiteral("mouseclick"), diff --git a/effects/effect_builtins.h b/effects/effect_builtins.h index 7abf4ac3cb..30c0e43ad4 100644 --- a/effects/effect_builtins.h +++ b/effects/effect_builtins.h @@ -52,7 +52,6 @@ enum class BuiltInEffect LookingGlass, MagicLamp, Magnifier, - MinimizeAnimation, MouseClick, MouseMark, PresentWindows, diff --git a/effects/minimizeanimation/CMakeLists.txt b/effects/minimizeanimation/CMakeLists.txt deleted file mode 100644 index 043a527177..0000000000 --- a/effects/minimizeanimation/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -####################################### -# Effect - -# Source files -set( kwin4_effect_builtins_sources ${kwin4_effect_builtins_sources} - minimizeanimation/minimizeanimation.cpp - ) diff --git a/effects/minimizeanimation/minimizeanimation.cpp b/effects/minimizeanimation/minimizeanimation.cpp deleted file mode 100644 index dbb9c6cb0a..0000000000 --- a/effects/minimizeanimation/minimizeanimation.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/******************************************************************** - KWin - the KDE window manager - This file is part of the KDE project. - -Copyright (C) 2007 Rivo Laks - -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 "minimizeanimation.h" - -#include - -namespace KWin -{ - -MinimizeAnimationEffect::MinimizeAnimationEffect() -{ - reconfigure(ReconfigureAll); - - connect(effects, &EffectsHandler::windowDeleted, this, &MinimizeAnimationEffect::windowDeleted); - connect(effects, &EffectsHandler::windowMinimized, this, &MinimizeAnimationEffect::windowMinimized); - connect(effects, &EffectsHandler::windowUnminimized, this, &MinimizeAnimationEffect::windowUnminimized); -} - -void MinimizeAnimationEffect::reconfigure(ReconfigureFlags flags) -{ - Q_UNUSED(flags) - - m_duration = std::chrono::milliseconds(static_cast(animationTime(250))); -} - -bool MinimizeAnimationEffect::supported() -{ - return effects->animationsSupported(); -} - -void MinimizeAnimationEffect::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; - } - - // We need to mark the screen windows as transformed. Otherwise the - // whole screen won't be repainted, resulting in artefacts. - data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; - - effects->prePaintScreen(data, time); -} - -void MinimizeAnimationEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) -{ - if (m_animations.contains(w)) { - data.setTransformed(); - w->enablePainting(EffectWindow::PAINT_DISABLED_BY_MINIMIZE); - } - - effects->prePaintWindow(w, data, time); -} - -void MinimizeAnimationEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) -{ - const auto animationIt = m_animations.constFind(w); - if (animationIt != m_animations.constEnd()) { - // 0 = not minimized, 1 = fully minimized - const qreal progress = (*animationIt).value(); - - QRect geo = w->geometry(); - QRect icon = w->iconGeometry(); - // If there's no icon geometry, minimize to the center of the screen - if (!icon.isValid()) { - icon = QRect(effects->virtualScreenGeometry().center(), QSize(0, 0)); - } - - data *= QVector2D(interpolate(1.0, icon.width() / (double)geo.width(), progress), - interpolate(1.0, icon.height() / (double)geo.height(), progress)); - data.setXTranslation(interpolate(data.xTranslation(), icon.x() - geo.x(), progress)); - data.setYTranslation(interpolate(data.yTranslation(), icon.y() - geo.y(), progress)); - data.multiplyOpacity(interpolate(1.0, 0.1, progress)); - } - - effects->paintWindow(w, mask, region, data); -} - -void MinimizeAnimationEffect::postPaintScreen() -{ - auto animationIt = m_animations.begin(); - while (animationIt != m_animations.end()) { - if ((*animationIt).done()) { - animationIt = m_animations.erase(animationIt); - } else { - ++animationIt; - } - } - - effects->addRepaintFull(); - - effects->postPaintScreen(); -} - -void MinimizeAnimationEffect::windowDeleted(EffectWindow *w) -{ - m_animations.remove(w); -} - -void MinimizeAnimationEffect::windowMinimized(EffectWindow *w) -{ - if (effects->activeFullScreenEffect()) { - return; - } - - TimeLine &timeLine = m_animations[w]; - - if (timeLine.running()) { - timeLine.toggleDirection(); - } else { - timeLine.setDirection(TimeLine::Forward); - timeLine.setDuration(m_duration); - timeLine.setEasingCurve(QEasingCurve::InOutSine); - } - - effects->addRepaintFull(); -} - -void MinimizeAnimationEffect::windowUnminimized(EffectWindow *w) -{ - if (effects->activeFullScreenEffect()) { - return; - } - - TimeLine &timeLine = m_animations[w]; - - if (timeLine.running()) { - timeLine.toggleDirection(); - } else { - timeLine.setDirection(TimeLine::Backward); - timeLine.setDuration(m_duration); - timeLine.setEasingCurve(QEasingCurve::InOutSine); - } - - effects->addRepaintFull(); -} - -bool MinimizeAnimationEffect::isActive() const -{ - return !m_animations.isEmpty(); -} - -} // namespace - diff --git a/effects/minimizeanimation/minimizeanimation.h b/effects/minimizeanimation/minimizeanimation.h deleted file mode 100644 index 4549bc7c20..0000000000 --- a/effects/minimizeanimation/minimizeanimation.h +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************** - KWin - the KDE window manager - This file is part of the KDE project. - -Copyright (C) 2007 Rivo Laks - -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_MINIMIZEANIMATION_H -#define KWIN_MINIMIZEANIMATION_H - -// Include with base class for effects. -#include - -namespace KWin -{ - -/** - * Animates minimize/unminimize - **/ -class MinimizeAnimationEffect : public Effect -{ - Q_OBJECT - -public: - MinimizeAnimationEffect(); - - 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 { - return 50; - } - - static bool supported(); - -private Q_SLOTS: - void windowDeleted(EffectWindow *w); - void windowMinimized(EffectWindow *w); - void windowUnminimized(EffectWindow *w); - -private: - std::chrono::milliseconds m_duration; - QHash m_animations; -}; - -} // namespace - -#endif diff --git a/effects/squash/CMakeLists.txt b/effects/squash/CMakeLists.txt new file mode 100644 index 0000000000..1242620d48 --- /dev/null +++ b/effects/squash/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(package) diff --git a/effects/squash/package/CMakeLists.txt b/effects/squash/package/CMakeLists.txt new file mode 100644 index 0000000000..99be93cbf8 --- /dev/null +++ b/effects/squash/package/CMakeLists.txt @@ -0,0 +1,9 @@ +install(DIRECTORY contents + DESTINATION ${DATA_INSTALL_DIR}/${KWIN_NAME}/effects/kwin4_effect_squash) + +install(FILES metadata.desktop + DESTINATION ${DATA_INSTALL_DIR}/${KWIN_NAME}/effects/kwin4_effect_squash) + +install(FILES metadata.desktop + DESTINATION ${SERVICES_INSTALL_DIR}/${KWIN_NAME} + RENAME kwin4_effect_squash.desktop) diff --git a/effects/squash/package/contents/code/main.js b/effects/squash/package/contents/code/main.js new file mode 100644 index 0000000000..506df7108c --- /dev/null +++ b/effects/squash/package/contents/code/main.js @@ -0,0 +1,150 @@ +/******************************************************************** + 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 squashEffect = { + duration: animationTime(250), + loadConfig: function () { + "use strict"; + squashEffect.duration = animationTime(250); + }, + slotWindowMinimized: function (window) { + "use strict"; + if (effects.hasActiveFullScreenEffect) { + return; + } + + // If the window doesn't have an icon in the task manager, + // don't animate it. + var iconRect = window.iconGeometry; + if (iconRect.width == 0 || iconRect.height == 0) { + return; + } + + if (window.unminimizeAnimation) { + // TODO: Try to reverse it instead. + cancel(window.unminimizeAnimation); + delete window.unminimizeAnimation; + } + + var windowRect = window.geometry; + + window.minimizeAnimation = animate({ + window: window, + curve: QEasingCurve.InOutSine, + duration: squashEffect.duration, + animations: [ + { + type: Effect.Size, + from: { + value1: windowRect.width, + value2: windowRect.height + }, + to: { + value1: iconRect.width, + value2: iconRect.height + } + }, + { + type: Effect.Translation, + from: { + value1: 0.0, + value2: 0.0 + }, + to: { + value1: iconRect.x - windowRect.x - + (windowRect.width - iconRect.width) / 2, + value2: iconRect.y - windowRect.y - + (windowRect.height - iconRect.height) / 2, + } + }, + { + type: Effect.Opacity, + from: 1.0, + to: 0.0 + } + ] + }); + }, + slotWindowUnminimized: function (window) { + "use strict"; + if (effects.hasActiveFullScreenEffect) { + return; + } + + // If the window doesn't have an icon in the task manager, + // don't animate it. + var iconRect = window.iconGeometry; + if (iconRect.width == 0 || iconRect.height == 0) { + return; + } + + if (window.minimizeAnimation) { + // TODO: Try to reverse it instead. + cancel(window.minimizeAnimation); + delete window.minimizeAnimation; + } + + var windowRect = window.geometry; + + window.unminimizeAnimation = animate({ + window: window, + curve: QEasingCurve.InOutSine, + duration: squashEffect.duration, + animations: [ + { + type: Effect.Size, + from: { + value1: iconRect.width, + value2: iconRect.height + }, + to: { + value1: windowRect.width, + value2: windowRect.height + } + }, + { + type: Effect.Translation, + from: { + value1: iconRect.x - windowRect.x - + (windowRect.width - iconRect.width) / 2, + value2: iconRect.y - windowRect.y - + (windowRect.height - iconRect.height) / 2, + }, + to: { + value1: 0.0, + value2: 0.0 + } + }, + { + type: Effect.Opacity, + from: 0.0, + to: 1.0 + } + ] + }); + }, + init: function () { + "use strict"; + effect.configChanged.connect(squashEffect.loadConfig); + effects.windowMinimized.connect(squashEffect.slotWindowMinimized); + effects.windowUnminimized.connect(squashEffect.slotWindowUnminimized); + } +}; + +squashEffect.init(); diff --git a/effects/squash/package/metadata.desktop b/effects/squash/package/metadata.desktop new file mode 100644 index 0000000000..17da642aa2 --- /dev/null +++ b/effects/squash/package/metadata.desktop @@ -0,0 +1,21 @@ +[Desktop Entry] +Comment=Squash windows when they are minimized +Icon=preferences-system-windows-effect-squash +Name=Squash + +Type=Service +X-KDE-ParentApp= +X-KDE-PluginInfo-Author=Rivo Laks, Vlad Zagorodniy +X-KDE-PluginInfo-Category=Appearance +X-KDE-PluginInfo-Email=rivolaks@hot.ee, vladzzag@gmail.com +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-Name=kwin4_effect_squash +X-KDE-PluginInfo-Version=1 +X-KDE-PluginInfo-Website= +X-KDE-ServiceTypes=KWin/Effect +X-KDE-PluginInfo-EnabledByDefault=true +X-KDE-Ordering=60 +X-Plasma-API=javascript +X-Plasma-MainScript=code/main.js +X-KWin-Exclusive-Category=minimize +X-KWin-Video-Url=http://files.kde.org/plasma/kwin/effect-videos/minimize.ogv diff --git a/kconf_update/kwin.upd b/kconf_update/kwin.upd index b179ca1f76..164079c71f 100644 --- a/kconf_update/kwin.upd +++ b/kconf_update/kwin.upd @@ -5,3 +5,9 @@ Id=replace-scalein-with-scale File=kwinrc Group=Plugins Key=kwin4_effect_scaleinEnabled,scaleEnabled + +# Port the Minimize Animation effect to JavaScript. +Id=port-minimizeanimation-effect-to-js +File=kwinrc +Group=Plugins +Key=minimizeanimationEnabled,kwin4_effect_squashEnabled