File indexing completed on 2024-11-10 04:56:58

0001 /*
0002     This file is part of the KDE project.
0003 
0004     SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 "use strict";
0010 
0011 var authenticationAgents = [
0012     "kdesu kdesu",
0013     "kdesudo kdesudo",
0014     "pinentry pinentry",
0015     "polkit-kde-authentication-agent-1 polkit-kde-authentication-agent-1",
0016     "polkit-kde-manager polkit-kde-manager",
0017 
0018     // On Wayland, the resource name is filename of executable. It's empty for
0019     // authentication agents because KWayland can't get their executable paths.
0020     " org.kde.kdesu",
0021     " org.kde.polkit-kde-authentication-agent-1"
0022 ];
0023 
0024 function activeAuthenticationAgent() {
0025     var activeWindow = effects.activeWindow;
0026     if (!activeWindow) {
0027         return null;
0028     }
0029 
0030     if (authenticationAgents.indexOf(activeWindow.windowClass) == -1) {
0031         return null;
0032     }
0033 
0034     return activeWindow;
0035 }
0036 
0037 var dimScreenEffect = {
0038     loadConfig: function () {
0039         dimScreenEffect.duration = animationTime(250);
0040         dimScreenEffect.brightness = 0.67;
0041         dimScreenEffect.saturation = 0.67;
0042     },
0043     startAnimation: function (window) {
0044         if (!window.visible) {
0045             return;
0046         }
0047         if (window.popupWindow) {
0048             return;
0049         }
0050         if (!window.managed) {
0051             return;
0052         }
0053         if (window.dimAnimation) {
0054             if (redirect(window.dimAnimation, Effect.Forward)) {
0055                 return;
0056             }
0057             cancel(window.dimAnimation);
0058         }
0059         window.dimAnimation = set({
0060             window: window,
0061             curve: QEasingCurve.InOutSine,
0062             duration: dimScreenEffect.duration,
0063             keepAlive: false,
0064             animations: [
0065                 {
0066                     type: Effect.Saturation,
0067                     to: dimScreenEffect.saturation
0068                 },
0069                 {
0070                     type: Effect.Brightness,
0071                     to: dimScreenEffect.brightness
0072                 }
0073             ]
0074         });
0075     },
0076     startAnimationSmooth: function (window) {
0077         dimScreenEffect.startAnimation(window);
0078     },
0079     startAnimationInstant: function (window) {
0080         dimScreenEffect.startAnimation(window);
0081 
0082         if (window.dimAnimation) {
0083             complete(window.dimAnimation);
0084         }
0085     },
0086     cancelAnimationSmooth: function (window) {
0087         if (!window.dimAnimation) {
0088             return;
0089         }
0090         if (redirect(window.dimAnimation, Effect.Backward)) {
0091             return;
0092         }
0093         cancel(window.dimAnimation);
0094         delete window.dimAnimation;
0095     },
0096     cancelAnimationInstant: function (window) {
0097         if (window.dimAnimation) {
0098             cancel(window.dimAnimation);
0099             delete window.dimAnimation;
0100         }
0101     },
0102     dimScreen: function (agent, animationFunc, cancelFunc) {
0103         // Keep track of currently active authentication agent so we don't have
0104         // to re-scan the stacking order in brightenScreen each time when some
0105         // window is activated.
0106         dimScreenEffect.authenticationAgent = agent;
0107 
0108         var windows = effects.stackingOrder;
0109         for (var i = 0; i < windows.length; ++i) {
0110             var window = windows[i];
0111             if (window == agent) {
0112                 // The agent might have been dimmed before (because there are
0113                 // several authentication agents on the screen), so we need to
0114                 // cancel previous animations for it if there are any.
0115                 cancelFunc(agent);
0116                 continue;
0117             }
0118             animationFunc(window);
0119         }
0120     },
0121     dimScreenSmooth: function (agent) {
0122         dimScreenEffect.dimScreen(
0123             agent,
0124             dimScreenEffect.startAnimationSmooth,
0125             dimScreenEffect.cancelAnimationSmooth
0126         );
0127     },
0128     dimScreenInstant: function (agent) {
0129         dimScreenEffect.dimScreen(
0130             agent,
0131             dimScreenEffect.startAnimationInstant,
0132             dimScreenEffect.cancelAnimationInstant
0133         );
0134     },
0135     brightenScreen: function (cancelFunc) {
0136         if (!dimScreenEffect.authenticationAgent) {
0137             return;
0138         }
0139         dimScreenEffect.authenticationAgent = null;
0140 
0141         var windows = effects.stackingOrder;
0142         for (var i = 0; i < windows.length; ++i) {
0143             cancelFunc(windows[i]);
0144         }
0145     },
0146     brightenScreenSmooth: function () {
0147         dimScreenEffect.brightenScreen(dimScreenEffect.cancelAnimationSmooth);
0148     },
0149     brightenScreenInstant: function () {
0150         dimScreenEffect.brightenScreen(dimScreenEffect.cancelAnimationInstant);
0151     },
0152     slotWindowActivated: function (window) {
0153         if (!window) {
0154             return;
0155         }
0156         if (authenticationAgents.indexOf(window.windowClass) != -1) {
0157             dimScreenEffect.dimScreenSmooth(window);
0158         } else {
0159             dimScreenEffect.brightenScreenSmooth();
0160         }
0161     },
0162     slotWindowAdded: function (window) {
0163         window.minimizedChanged.connect(() => {
0164             if (window.minimized) {
0165                 dimScreenEffect.cancelAnimationInstant(window);
0166             } else {
0167                 dimScreenEffect.restartAnimation(window);
0168             }
0169         });
0170 
0171         // Don't dim authentication agents that just opened.
0172         var agent = activeAuthenticationAgent();
0173         if (agent == window) {
0174             return;
0175         }
0176 
0177         // If a window appeared while the screen is dimmed, dim the window too.
0178         if (agent) {
0179             dimScreenEffect.startAnimationInstant(window);
0180         }
0181     },
0182     slotActiveFullScreenEffectChanged: function () {
0183         // If some full screen effect has been activated, for example the desktop
0184         // cube effect, then brighten screen back. We need to do that because the
0185         // full screen effect can dim windows on its own.
0186         if (effects.hasActiveFullScreenEffect) {
0187             dimScreenEffect.brightenScreenSmooth();
0188             return;
0189         }
0190 
0191         // If user left the full screen effect, try to dim screen back.
0192         var agent = activeAuthenticationAgent();
0193         if (agent) {
0194             dimScreenEffect.dimScreenSmooth(agent);
0195         }
0196     },
0197     slotDesktopChanged: function () {
0198         // If there is an active full screen effect, then try smoothly dim/brighten
0199         // the screen. Keep in mind that in order for this to work properly, this
0200         // effect has to come after the full screen effect in the effect chain,
0201         // otherwise this slot will be invoked before the full screen effect can mark
0202         // itself as a full screen effect.
0203         if (effects.hasActiveFullScreenEffect) {
0204             return;
0205         }
0206 
0207         // Try to brighten windows on the previous virtual desktop.
0208         dimScreenEffect.brightenScreenInstant();
0209 
0210         // Try to dim windows on the current virtual desktop.
0211         var agent = activeAuthenticationAgent();
0212         if (agent) {
0213             dimScreenEffect.dimScreenInstant(agent);
0214         }
0215     },
0216     restartAnimation: function (window) {
0217         if (activeAuthenticationAgent()) {
0218             dimScreenEffect.startAnimationInstant(window);
0219         }
0220     },
0221     init: function () {
0222         dimScreenEffect.loadConfig();
0223 
0224         effect.configChanged.connect(dimScreenEffect.loadConfig);
0225         effects.windowActivated.connect(dimScreenEffect.slotWindowActivated);
0226         effects.windowAdded.connect(dimScreenEffect.slotWindowAdded);
0227         effects.activeFullScreenEffectChanged.connect(
0228             dimScreenEffect.slotActiveFullScreenEffectChanged);
0229         effects.desktopChanged.connect(dimScreenEffect.slotDesktopChanged);
0230 
0231         for (const window of effects.stackingOrder) {
0232             dimScreenEffect.slotWindowAdded(window);
0233         }
0234     }
0235 };
0236 
0237 dimScreenEffect.init();