Warning, /plasma/kwin/src/plugins/windowview/qml/main.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0003     SPDX-FileCopyrightText: 2022 ivan tkachenko <me@ratijas.tk>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 import QtQuick
0009 import Qt5Compat.GraphicalEffects
0010 import QtQuick.Layouts
0011 import org.kde.kwin as KWinComponents
0012 import org.kde.kwin.private.effects
0013 import org.kde.kirigami 2.20 as Kirigami
0014 import org.kde.plasma.extras as PlasmaExtras
0015 import org.kde.KWin.Effect.WindowView
0016 
0017 Item {
0018     id: container
0019 
0020     readonly property QtObject effect: KWinComponents.SceneView.effect
0021     readonly property QtObject targetScreen: KWinComponents.SceneView.screen
0022 
0023     property bool animationEnabled: false
0024     property bool organized: false
0025 
0026     function start() {
0027         animationEnabled = true;
0028         organized = true;
0029     }
0030 
0031     function stop() {
0032         organized = false;
0033     }
0034 
0035     Keys.onEscapePressed: effect.deactivate(container.effect.animationDuration);
0036 
0037     Keys.priority: Keys.AfterItem
0038     Keys.forwardTo: searchField
0039     Keys.onLeftPressed: {
0040         let view = effect.getView(Qt.LeftEdge)
0041         if (view) {
0042             effect.activateView(view)
0043         }
0044     }
0045     Keys.onRightPressed: {
0046         let view = effect.getView(Qt.RightEdge)
0047         if (view) {
0048             effect.activateView(view)
0049         }
0050     }
0051     Keys.onUpPressed: {
0052         let view = effect.getView(Qt.TopEdge)
0053         if (view) {
0054             effect.activateView(view)
0055         }
0056     }
0057     Keys.onDownPressed: {
0058         let view = effect.getView(Qt.BottomEdge)
0059         if (view) {
0060             effect.activateView(view)
0061         }
0062     }
0063 
0064     KWinComponents.DesktopBackground {
0065         activity: KWinComponents.Workspace.currentActivity
0066         desktop: KWinComponents.Workspace.currentDesktop
0067         outputName: targetScreen.name
0068 
0069         layer.enabled: true
0070         layer.effect: FastBlur {
0071             radius: container.organized ? 64 : 0
0072             Behavior on radius {
0073                 NumberAnimation { duration: container.effect.animationDuration; easing.type: Easing.OutCubic }
0074             }
0075         }
0076     }
0077 
0078     Rectangle {
0079         anchors.fill: parent
0080         color: Kirigami.Theme.backgroundColor
0081         opacity: container.organized ? 0.75 : 0
0082 
0083         TapHandler {
0084             onTapped: effect.deactivate(container.effect.animationDuration);
0085         }
0086 
0087         Behavior on opacity {
0088             OpacityAnimator { duration: container.effect.animationDuration; easing.type: Easing.OutCubic }
0089         }
0090     }
0091 
0092     Loader {
0093         anchors.centerIn: parent
0094         width: parent.width - (Kirigami.Units.gridUnit * 8)
0095 
0096         active: heap.activeEmpty
0097 
0098         // Otherwise it's always 100% opaque even while the blurry desktop background's
0099         // opacity is changing, which looks weird and is different from what Overview does.
0100         opacity: container.organized ? 1 : 0
0101         Behavior on opacity {
0102             OpacityAnimator { duration: container.effect.animationDuration; easing.type: Easing.OutCubic }
0103         }
0104 
0105         sourceComponent: PlasmaExtras.PlaceholderMessage {
0106             iconName: "edit-none"
0107             text: effect.searchText.length > 0 ? i18nd("kwin", "No Matches") : i18nd("kwin", "No Windows")
0108         }
0109     }
0110 
0111     ColumnLayout {
0112         width: targetScreen.geometry.width
0113         height: targetScreen.geometry.height
0114         PlasmaExtras.SearchField {
0115             id: searchField
0116             Layout.alignment: Qt.AlignCenter
0117             Layout.topMargin: Kirigami.Units.gridUnit
0118             Layout.preferredWidth: Math.min(parent.width, 20 * Kirigami.Units.gridUnit)
0119             focus: false
0120 
0121             // Don't confuse users into thinking it's a full search
0122             placeholderText: i18nd("kwin", "Filter windows…")
0123 
0124             // Otherwise it's always 100% opaque even while the blurry desktop background's
0125             // opacity is changing, which looks weird and is different from what Overview does.
0126             opacity: container.organized ? 1 : 0
0127             Behavior on opacity {
0128                 OpacityAnimator { duration: container.effect.animationDuration; easing.type: Easing.OutCubic }
0129             }
0130 
0131             // We can't use activeFocus because is not reliable on qml effects
0132             text: effect.searchText
0133             onTextEdited: {
0134                 effect.searchText = text;
0135                 heap.resetSelected();
0136                 heap.selectNextItem(WindowHeap.Direction.Down);
0137             }
0138             Keys.priority: Keys.AfterItem
0139             Keys.forwardTo: heap
0140             Keys.onPressed: {
0141                 switch (event.key) {
0142                 case Qt.Key_Down:
0143                     heap.forceActiveFocus();
0144                     break;
0145                 case Qt.Key_Return:
0146                 case Qt.Key_Enter:
0147                     heap.forceActiveFocus();
0148                     if (heap.count === 1) {
0149                         heap.activateIndex(0);
0150                     }
0151                     break;
0152                 default:
0153                     break;
0154                 }
0155             }
0156             Keys.onEnterPressed: {
0157                 heap.forceActiveFocus();
0158                 if (heap.count === 1) {
0159                     heap.activateCurrentClient();
0160                 }
0161             }
0162         }
0163         WindowHeap {
0164             id: heap
0165             Layout.fillWidth: true
0166             Layout.fillHeight: true
0167             focus: true
0168             padding: Kirigami.Units.gridUnit
0169             animationDuration: container.effect.animationDuration
0170             animationEnabled: container.animationEnabled
0171             organized: container.organized
0172             showOnly: {
0173                 switch (container.effect.mode) {
0174                     case WindowView.ModeWindowClass:
0175                     case WindowView.ModeWindowClassCurrentDesktop:
0176                         return "activeClass";
0177                     default:
0178                         return container.effect.selectedIds;
0179                 }
0180             }
0181             layout.mode: effect.layout
0182             model: KWinComponents.WindowFilterModel {
0183                 activity: KWinComponents.Workspace.currentActivity
0184                 desktop: {
0185                     switch (container.effect.mode) {
0186                         case WindowView.ModeCurrentDesktop:
0187                         case WindowView.ModeWindowClassCurrentDesktop:
0188                             return KWinComponents.Workspace.currentDesktop;
0189                         default:
0190                             return undefined;
0191                     }
0192                 }
0193                 screenName: targetScreen.name
0194                 windowModel: stackModel
0195                 filter: effect.searchText
0196                 minimizedWindows: !effect.ignoreMinimized
0197                 windowType: ~KWinComponents.WindowFilterModel.Dock &
0198                             ~KWinComponents.WindowFilterModel.Desktop &
0199                             ~KWinComponents.WindowFilterModel.Notification &
0200                             ~KWinComponents.WindowFilterModel.CriticalNotification
0201             }
0202             delegate: WindowHeapDelegate {
0203                 id: delegate
0204                 windowHeap: heap
0205                 partialActivationFactor: container.organized ? 1 : 0
0206                 Behavior on partialActivationFactor {
0207                     SequentialAnimation {
0208                         PropertyAction {
0209                             target: delegate
0210                             property: "gestureInProgress"
0211                             value: true
0212                         }
0213                         NumberAnimation {
0214                             duration: container.effect.animationDuration
0215                             easing.type: Easing.OutCubic
0216                         }
0217                         PropertyAction {
0218                             target: delegate
0219                             property: "gestureInProgress"
0220                             value: false
0221                         }
0222                     }
0223                 }
0224                 opacity: 1 - downGestureProgress
0225                 onDownGestureTriggered: window.closeWindow()
0226 
0227                 TapHandler {
0228                     acceptedPointerTypes: PointerDevice.GenericPointer | PointerDevice.Pen
0229                     acceptedButtons: Qt.MiddleButton
0230                     onTapped: window.closeWindow();
0231                 }
0232             }
0233             onActivated: effect.deactivate(container.effect.animationDuration);
0234         }
0235     }
0236 
0237     Instantiator {
0238         asynchronous: true
0239 
0240         model: KWinComponents.WindowFilterModel {
0241             desktop: KWinComponents.Workspace.currentDesktop
0242             screenName: targetScreen.name
0243             windowModel: stackModel
0244             windowType: KWinComponents.WindowFilterModel.Dock
0245         }
0246 
0247         KWinComponents.WindowThumbnail {
0248             id: windowThumbnail
0249             wId: model.window.internalId
0250             x: model.window.x - targetScreen.geometry.x
0251             y: model.window.y - targetScreen.geometry.y
0252             z: model.window.stackingOrder
0253             visible: opacity > 0
0254             opacity: (model.window.hidden || container.organized) ? 0 : 1
0255 
0256             Behavior on opacity {
0257                 NumberAnimation { duration: container.effect.animationDuration; easing.type: Easing.OutCubic }
0258             }
0259         }
0260 
0261         onObjectAdded: (index, object) => {
0262             object.parent = container
0263         }
0264     }
0265 
0266     KWinComponents.WindowModel {
0267         id: stackModel
0268     }
0269 
0270     Component.onCompleted: start();
0271 }