Last active
December 2, 2025 04:57
-
-
Save Schneegans/72af6738f8c1cf7f03a7941a7dac15a1 to your computer and use it in GitHub Desktop.
Test-Effect
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| KWin - the KDE window manager | |
| This file is part of the KDE project. | |
| SPDX-FileCopyrightText: 2018, 2021, 2022 Vlad Zahorodnii <[email protected]>, Martin Flöser <[email protected]>, 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 TestEffect { | |
| 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.addFragmentShader(Effect.MapTexture, "test.frag"); | |
| this.loadConfig(); | |
| } | |
| loadConfig() { | |
| const defaultDuration = 500; | |
| 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 (!TestEffect.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, | |
| shader: this.shader, | |
| type: Effect.Shader, | |
| animations: [ | |
| { | |
| type: Effect.ShaderUniform, | |
| uniform: "uForOpening", | |
| shader: this.shader, | |
| from: 1.0, | |
| to: 1.0 | |
| }, | |
| { | |
| type: Effect.Scale, | |
| shader: this.shader, | |
| from: { | |
| value1: 1.0, | |
| value2: 0.0 | |
| }, | |
| to: { | |
| value1: 1.0, | |
| value2: 1.0 | |
| } | |
| } | |
| ] | |
| }); | |
| } | |
| slotWindowClosed(window) { | |
| if (effects.hasActiveFullScreenEffect) { | |
| return; | |
| } | |
| if (!TestEffect.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, | |
| shader: this.shader, | |
| type: Effect.Shader, | |
| animations: [ | |
| { | |
| type: Effect.ShaderUniform, | |
| uniform: "uForOpening", | |
| shader: this.shader, | |
| from: 0.0, | |
| to: 0.0 | |
| }, | |
| { | |
| type: Effect.Scale, | |
| shader: this.shader, | |
| from: { | |
| value1: 1.0, | |
| value2: 1.0 | |
| }, | |
| to: { | |
| value1: 1.0, | |
| value2: 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 TestEffect(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [Desktop Entry] | |
| Name=Test | |
| Icon=preferences-system-windows-effect-test | |
| Comment=Foo Bar | |
| Type=Service | |
| X-KDE-ServiceTypes=KWin/Effect,KCModule | |
| X-KDE-PluginInfo-Author=Vlad Zahorodnii, Martin Flöser, Simon Schneegans | |
| [email protected], [email protected] | |
| X-KDE-PluginInfo-Name=kwin4_effect_test | |
| 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_test | |
| X-KDE-Library=kcm_kwin4_genericscripted | |
| X-KWin-Config-TranslationDomain=kwin_effects | |
| X-KWin-Exclusive-Category=toplevel-open-close-animation |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| uniform float uForOpening; | |
| uniform float textureWidth; | |
| uniform float textureHeight; | |
| void main() { | |
| gl_FragColor = vec4(1, uForOpening, 0, 1); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #version 140 | |
| uniform float uForOpening; | |
| uniform float textureWidth; | |
| uniform float textureHeight; | |
| out vec4 fragColor; | |
| void main() { | |
| fragColor = vec4(1, uForOpening, 0, 1); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment