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();