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

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 "use strict";
0011 
0012 var blacklist = [
0013     // ignore black background behind lockscreen
0014     "ksmserver ksmserver",
0015     // The logout screen has to be animated only by the logout effect.
0016     "ksmserver-logout-greeter ksmserver-logout-greeter",
0017     // The lockscreen isn't a popup window
0018     "kscreenlocker_greet kscreenlocker_greet",
0019     // KDE Plasma splash screen has to be animated only by the login effect.
0020     "ksplashqml ksplashqml"
0021 ];
0022 
0023 function isPopupWindow(window) {
0024     // If the window is blacklisted, don't animate it.
0025     if (blacklist.indexOf(window.windowClass) != -1) {
0026         return false;
0027     }
0028 
0029     // Animate combo box popups, tooltips, popup menus, etc.
0030     if (window.popupWindow) {
0031         return true;
0032     }
0033 
0034     // Maybe the outline deserves its own effect.
0035     if (window.outline) {
0036         return true;
0037     }
0038 
0039     // Override-redirect windows are usually used for user interface
0040     // concepts that are expected to be animated by this effect, e.g.
0041     // popups that contain window thumbnails on X11, etc.
0042     if (!window.managed) {
0043         // Some utility windows can look like popup windows (e.g. the
0044         // address bar dropdown in Firefox), but we don't want to fade
0045         // them because the fade effect didn't do that.
0046         if (window.utility) {
0047             return false;
0048         }
0049 
0050         return true;
0051     }
0052 
0053     // Previously, there was a "monolithic" fade effect, which tried to
0054     // animate almost every window that was shown or hidden. Then it was
0055     // split into two effects: one that animates toplevel windows and
0056     // this one. In addition to popups, this effect also animates some
0057     // special windows(e.g. notifications) because the monolithic version
0058     // was doing that.
0059     if (window.dock || window.splash || window.toolbar
0060             || window.notification || window.onScreenDisplay
0061             || window.criticalNotification
0062             || window.appletPopup) {
0063         return true;
0064     }
0065 
0066     return false;
0067 }
0068 
0069 var fadingPopupsEffect = {
0070     loadConfig: function () {
0071         fadingPopupsEffect.fadeInDuration = animationTime(150);
0072         fadingPopupsEffect.fadeOutDuration = animationTime(150) * 4;
0073     },
0074     slotWindowAdded: function (window) {
0075         if (effects.hasActiveFullScreenEffect) {
0076             return;
0077         }
0078         if (!isPopupWindow(window)) {
0079             return;
0080         }
0081         if (!window.visible) {
0082             return;
0083         }
0084         if (!effect.grab(window, Effect.WindowAddedGrabRole)) {
0085             return;
0086         }
0087         window.fadeInAnimation = animate({
0088             window: window,
0089             curve: QEasingCurve.Linear,
0090             duration: fadingPopupsEffect.fadeInDuration,
0091             type: Effect.Opacity,
0092             from: 0.0,
0093             to: 1.0
0094         });
0095     },
0096     slotWindowClosed: function (window) {
0097         if (effects.hasActiveFullScreenEffect) {
0098             return;
0099         }
0100         if (!isPopupWindow(window)) {
0101             return;
0102         }
0103         if (!window.visible || window.skipsCloseAnimation) {
0104             return;
0105         }
0106         if (!effect.grab(window, Effect.WindowClosedGrabRole)) {
0107             return;
0108         }
0109         window.fadeOutAnimation = animate({
0110             window: window,
0111             curve: QEasingCurve.OutQuart,
0112             duration: fadingPopupsEffect.fadeOutDuration,
0113             type: Effect.Opacity,
0114             from: 1.0,
0115             to: 0.0
0116         });
0117     },
0118     slotWindowDataChanged: function (window, role) {
0119         if (role == Effect.WindowAddedGrabRole) {
0120             if (window.fadeInAnimation && effect.isGrabbed(window, role)) {
0121                 cancel(window.fadeInAnimation);
0122                 delete window.fadeInAnimation;
0123             }
0124         } else if (role == Effect.WindowClosedGrabRole) {
0125             if (window.fadeOutAnimation && effect.isGrabbed(window, role)) {
0126                 cancel(window.fadeOutAnimation);
0127                 delete window.fadeOutAnimation;
0128             }
0129         }
0130     },
0131     init: function () {
0132         fadingPopupsEffect.loadConfig();
0133 
0134         effect.configChanged.connect(fadingPopupsEffect.loadConfig);
0135         effects.windowAdded.connect(fadingPopupsEffect.slotWindowAdded);
0136         effects.windowClosed.connect(fadingPopupsEffect.slotWindowClosed);
0137         effects.windowDataChanged.connect(fadingPopupsEffect.slotWindowDataChanged);
0138     }
0139 };
0140 
0141 fadingPopupsEffect.init();