From c92f3b5574197a3a904c729263ae2f751ff15d80 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Fri, 27 May 2022 20:16:09 +0200 Subject: [PATCH] :tada: Add some initial kwin files --- kwin/README.md | 0 kwin/build.sh | 42 +++++ kwin/kwin4_effect_tv/contents/config/main.xml | 15 ++ kwin/kwin4_effect_tv/contents/ui/config.ui | 80 ++++++++ kwin/main.js.in | 172 ++++++++++++++++++ kwin/metadata.desktop.in | 21 +++ 6 files changed, 330 insertions(+) create mode 100644 kwin/README.md create mode 100755 kwin/build.sh create mode 100755 kwin/kwin4_effect_tv/contents/config/main.xml create mode 100755 kwin/kwin4_effect_tv/contents/ui/config.ui create mode 100755 kwin/main.js.in create mode 100755 kwin/metadata.desktop.in diff --git a/kwin/README.md b/kwin/README.md new file mode 100644 index 0000000..e69de29 diff --git a/kwin/build.sh b/kwin/build.sh new file mode 100755 index 0000000..15c0fde --- /dev/null +++ b/kwin/build.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# -------------------------------------------------------------------------------------- # +# ) ( # +# ( /( ( ( ) ( ( ( ( )\ ) ( ( # +# )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( # +# ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ # +# | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) # +# | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< # +# |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ # +# |__/ # +# Copyright (c) 2021 Simon Schneegans # +# Released under the GPLv3 or later. See LICENSE file for details. # +# -------------------------------------------------------------------------------------- # + +# Exit the script when one command fails. +set -e + +# Go to the script's directory. +cd "$( cd "$( dirname "$0" )" && pwd )" || \ + { echo "ERROR: Could not find kwin directory."; exit 1; } + +BUILD_DIR="_build" + +mkdir -p "${BUILD_DIR}" + +generate() { + cp -r "kwin4_effect_$1" "${BUILD_DIR}" + + mkdir -p "${BUILD_DIR}/kwin4_effect_$1/contents/shaders" + mkdir -p "${BUILD_DIR}/kwin4_effect_$1/contents/code" + + sed -e "s;%NICK%;$1;g" -e "s;%NAME%;$2;g" -e "s;%DESCRIPTION%;$3;g" \ + metadata.desktop.in > "${BUILD_DIR}/kwin4_effect_$1/metadata.desktop" + + sed -e "s;%NICK%;$1;g" -e "s;%NAME%;$2;g" -e "s;%DESCRIPTION%;$3;g" \ + main.js.in > "${BUILD_DIR}/kwin4_effect_$1/contents/code/main.js" + +} + +generate "tv" "TV" "Make windows close like turning off a TV" +# generate "fire" "Fire" "Make windows burn" \ No newline at end of file diff --git a/kwin/kwin4_effect_tv/contents/config/main.xml b/kwin/kwin4_effect_tv/contents/config/main.xml new file mode 100755 index 0000000..c0f6524 --- /dev/null +++ b/kwin/kwin4_effect_tv/contents/config/main.xml @@ -0,0 +1,15 @@ + + + + + + 0 + + + 128,128,128 + + + diff --git a/kwin/kwin4_effect_tv/contents/ui/config.ui b/kwin/kwin4_effect_tv/contents/ui/config.ui new file mode 100755 index 0000000..8c55fdf --- /dev/null +++ b/kwin/kwin4_effect_tv/contents/ui/config.ui @@ -0,0 +1,80 @@ + + + TvEffectConfigForm + + + + 0 + 0 + 498 + 451 + + + + + + + Duration: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + &Color: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_Color + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + Default + + + milliseconds + + + 9999 + + + 5 + + + + + + + + KColorCombo + QComboBox +
kcolorcombo.h
+
+
+ + +
diff --git a/kwin/main.js.in b/kwin/main.js.in new file mode 100755 index 0000000..a0d96c6 --- /dev/null +++ b/kwin/main.js.in @@ -0,0 +1,172 @@ +/* + KWin - the KDE window manager + This file is part of the KDE project. + + SPDX-FileCopyrightText: 2018, 2021, 2022 Vlad Zahorodnii , Martin Flöser , Simon Schneegans + + SPDX-License-Identifier: GPL-3.0-or-later +*/ + +"use strict"; + +const 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" +]; + +class Effect { + constructor() { + effect.configChanged.connect(this.loadConfig.bind(this)); + effect.animationEnded.connect(this.cleanupForcedRoles.bind(this)); + effects.windowAdded.connect(this.slotWindowAdded.bind(this)); + effects.windowClosed.connect(this.slotWindowClosed.bind(this)); + effects.windowDataChanged.connect(this.slotWindowDataChanged.bind(this)); + + this.shader = effect.addShader(Effect.MapTexture, "%NICK%.frag"); + + this.loadConfig(); + } + + loadConfig() { + const defaultDuration = 1000; + const duration = effect.readConfig("Duration", defaultDuration) || defaultDuration; + this.duration = animationTime(duration); + + effect.setUniform(this.shader, "uEffectColor", effect.readConfig("Color", "white")); + } + + static isScaleWindow(window) { + // 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.popupWindow) { + return false; + } + + // Dont't animate the outline and the screenlocker as it looks bad. + if (window.lockScreen || window.outline) { + return false; + } + + // Override-redirect windows are usually used for user interface + // concepts that are not expected to be animated by this effect. + if (!window.managed) { + return false; + } + + return window.normalWindow || window.dialog; + } + + setupForcedRoles(window) { + window.setData(Effect.WindowForceBackgroundContrastRole, true); + window.setData(Effect.WindowForceBlurRole, true); + } + + cleanupForcedRoles(window) { + window.setData(Effect.WindowForceBackgroundContrastRole, null); + window.setData(Effect.WindowForceBlurRole, null); + } + + slotWindowAdded(window) { + if (effects.hasActiveFullScreenEffect) { + return; + } + if (!Effect.isScaleWindow(window)) { + return; + } + if (!window.visible) { + return; + } + if (effect.isGrabbed(window, Effect.WindowAddedGrabRole)) { + return; + } + this.setupForcedRoles(window); + window.scaleInAnimation = animate({ + window: window, + curve: QEasingCurve.Linear, + duration: this.duration, + animations: [ + { + type: Effect.ShaderUniform, + shader: this.shader, + uniform: "uForOpening", + from: 1.0, + to: 1.0 + } + ] + }); + } + + slotWindowClosed(window) { + if (effects.hasActiveFullScreenEffect) { + return; + } + if (!Effect.isScaleWindow(window)) { + return; + } + if (!window.visible || window.skipsCloseAnimation) { + return; + } + if (effect.isGrabbed(window, Effect.WindowClosedGrabRole)) { + return; + } + if (window.scaleInAnimation) { + cancel(window.scaleInAnimation); + delete window.scaleInAnimation; + } + this.setupForcedRoles(window); + window.scaleOutAnimation = animate({ + window: window, + curve: QEasingCurve.Linear, + duration: this.duration, + animations: [ + { + type: Effect.ShaderUniform, + shader: this.shader, + uniform: "uForOpening", + from: 0.0, + to: 0.0 + } + ] + }); + } + + slotWindowDataChanged(window, role) { + if (role == Effect.WindowAddedGrabRole) { + if (window.scaleInAnimation && effect.isGrabbed(window, role)) { + cancel(window.scaleInAnimation); + delete window.scaleInAnimation; + this.cleanupForcedRoles(window); + } + } else if (role == Effect.WindowClosedGrabRole) { + if (window.scaleOutAnimation && effect.isGrabbed(window, role)) { + cancel(window.scaleOutAnimation); + delete window.scaleOutAnimation; + this.cleanupForcedRoles(window); + } + } + } +} + +new Effect(); diff --git a/kwin/metadata.desktop.in b/kwin/metadata.desktop.in new file mode 100755 index 0000000..c975bed --- /dev/null +++ b/kwin/metadata.desktop.in @@ -0,0 +1,21 @@ +[Desktop Entry] +Name=%NAME% +Icon=preferences-system-windows-effect-%NICK% +Comment=%DESCRIPTION% + +Type=Service +X-KDE-ServiceTypes=KWin/Effect,KCModule +X-KDE-PluginInfo-Author=Vlad Zahorodnii, Martin Flöser, Simon Schneegans +X-KDE-PluginInfo-Email=vlad.zahorodnii@kde.org, mgraesslin@kde.org +X-KDE-PluginInfo-Name=kwin4_effect_%NICK% +X-KDE-PluginInfo-Version=1 +X-KDE-PluginInfo-Category=Window Open/Close Animation +X-KDE-PluginInfo-License=GPLv3 +X-KDE-PluginInfo-EnabledByDefault=false +X-KDE-Ordering=60 +X-Plasma-API=javascript +X-Plasma-MainScript=code/main.js +X-KDE-PluginKeyword=kwin4_effect_%NICK% +X-KDE-Library=kcm_kwin4_genericscripted +X-KWin-Config-TranslationDomain=kwin_effects +X-KWin-Exclusive-Category=toplevel-open-close-animation