ScreenView.qml 10.2 KB
Newer Older
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
1
2
3
4
5
6
7
/*
    SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>

    SPDX-License-Identifier: GPL-2.0-or-later
*/

import QtQuick 2.12
8
import QtGraphicalEffects 1.12
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
9
import org.kde.kwin 3.0 as KWinComponents
10
import org.kde.kwin.private.effects 1.0
11
import org.kde.milou 0.3 as Milou
12
import org.kde.plasma.components 3.0 as PC3
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
13
import org.kde.plasma.core 2.0 as PlasmaCore
14
import org.kde.plasma.extras 2.0 as PlasmaExtras
15
import org.kde.kirigami 2.12 as Kirigami
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
16
17
18
19
20

FocusScope {
    id: container
    focus: true

21
22
23
    required property QtObject effect
    required property QtObject targetScreen

24
25
26
27
    readonly property bool lightBackground: Math.max(PlasmaCore.ColorScope.backgroundColor.r,
                                                     PlasmaCore.ColorScope.backgroundColor.g,
                                                     PlasmaCore.ColorScope.backgroundColor.b) > 0.5

28
    property bool animationEnabled: false
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
29
30
    property bool organized: false

31
    function start() {
32
        container.animationEnabled = true;
33
        container.organized = true;
34
        searchField.text = "";
35
36
    }

Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
37
38
39
40
    function stop() {
        container.organized = false;
    }

41
42
    Keys.onEscapePressed: effect.deactivate();

43
44
    Keys.priority: Keys.AfterItem
    Keys.forwardTo: searchField
45
46
47
48
49
50
    Keys.onEnterPressed: {
        heap.forceActiveFocus();
        if (heap.count === 1) {
            heap.activateCurrentClient();
        }
    }
51

52
    KWinComponents.DesktopBackgroundItem {
53
        id: backgroundItem
54
55
56
        activity: KWinComponents.Workspace.currentActivity
        desktop: KWinComponents.Workspace.currentVirtualDesktop
        outputName: targetScreen.name
57
        property real blurRadius: 0
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
58

59
60
        layer.enabled: effect.blurBackground
        layer.effect: FastBlur {
61
62
63
64
65
66
67
68
69
70
71
72
73
            radius: backgroundItem.blurRadius
        }
    }

    state: {
        if (effect.gestureInProgress) {
            return "partial";
        } else if (container.organized) {
            return "active";
        } else {
            return "initial";
        }
    }
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
    states: [
        State {
            name: "initial"
            PropertyChanges {
                target: underlay
                opacity: 0
            }
            PropertyChanges {
                target: topBar
                opacity: 0
            }
            PropertyChanges {
                target: backgroundItem
                blurRadius: 0
            }
        },
        State {
            name: "partial"
            PropertyChanges {
                target: underlay
                opacity: 0.75 * effect.partialActivationFactor
            }
            PropertyChanges {
                target: topBar
                opacity: effect.partialActivationFactor
100
            }
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
            PropertyChanges {
                target: backgroundItem
                blurRadius: 64 * effect.partialActivationFactor
            }
        },
        State {
            name: "active"
            PropertyChanges {
                target: underlay
                opacity: 0.75
            }
            PropertyChanges {
                target: topBar
                opacity: 1
            }
            PropertyChanges {
                target: backgroundItem
                blurRadius: 64
            }
        }
    ]
    transitions: Transition {
        to: "initial, active"
        NumberAnimation {
            duration: effect.animationDuration
            properties: "opacity, blurRadius"
            easing.type: Easing.OutCubic
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
128
129
130
131
132
133
134
        }
    }

    Rectangle {
        id: underlay
        anchors.fill: parent
        color: PlasmaCore.ColorScope.backgroundColor
135
136
137
138

        TapHandler {
            onTapped: effect.deactivate();
        }
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
139
140
    }

141
    Column {
Marco Martin's avatar
Marco Martin committed
142
        anchors.fill: parent
143
144

        Item {
145
146
147
148
149
150
151
152
            id: topBar
            width: parent.width
            height: searchBar.height + desktopBar.height

            Rectangle {
                id: desktopBar
                width: parent.width
                implicitHeight: bar.implicitHeight + 2 * PlasmaCore.Units.smallSpacing
153
154
155
156
                color: container.lightBackground ? Qt.rgba(PlasmaCore.ColorScope.backgroundColor.r,
                                                           PlasmaCore.ColorScope.backgroundColor.g,
                                                           PlasmaCore.ColorScope.backgroundColor.b, 0.75)
                                                 : Qt.rgba(0, 0, 0, 0.25)
157
158
159
160
161
162
163
164
165

                DesktopBar {
                    id: bar
                    anchors.fill: parent
                    clientModel: stackModel
                    desktopModel: desktopModel
                    selectedDesktop: KWinComponents.Workspace.currentVirtualDesktop
                }
            }
166

167
168
169
170
171
172
173
174
175
176
177
            Item {
                id: searchBar
                anchors.top: desktopBar.bottom
                width: parent.width
                height: searchField.height + 2 * PlasmaCore.Units.largeSpacing

                PC3.TextField {
                    id: searchField
                    anchors.centerIn: parent
                    width: Math.min(parent.width, 20 * PlasmaCore.Units.gridUnit)
                    focus: true
178
                    placeholderText: i18nd("kwin_effects", "Search...")
179
                    clearButtonShown: true
180
181
182
183
184
185
186
187
188
189
190
191
                    Keys.priority: Keys.BeforeItem
                    Keys.forwardTo: text && heap.count === 0 ? searchResults : heap
                    onTextChanged: {
                        effect.searchText = text;
                        heap.resetSelected();
                        heap.selectNextItem(WindowHeap.Direction.Down);
                    }
                     Binding {
                        target: searchField
                        property: "text"
                        value: effect.searchText
                    }
192
                }
193
194
195
            }
        }

196
        Item {
197
            width: parent.width
198
            height: parent.height - topBar.height
199

200
201
            PlasmaExtras.PlaceholderMessage {
                id: placeholderMessage
202
                anchors.top: parent.top
203
204
205
206
207
                anchors.horizontalCenter: parent.horizontalCenter
                visible: container.organized && searchField.text && heap.count === 0
                text: i18nd("kwin_effects", "No matching windows")
            }

208
209
            WindowHeap {
                id: heap
210
                visible: !(container.organized && searchField.text) || heap.count !== 0
211
                anchors.fill: parent
212
                layout.mode: effect.layout
213
                focus: true
214
                padding: PlasmaCore.Units.largeSpacing
215
                animationDuration: effect.animationDuration
216
217
                animationEnabled: container.animationEnabled
                organized: container.organized
218
219
220
221
222
223
                onWindowClicked: {
                    if (eventPoint.event.button !== Qt.MiddleButton) {
                        return;
                    }
                    window.closeWindow();
                }
224
225
                Keys.priority: Keys.AfterItem
                Keys.forwardTo: searchResults
226
227
228
229
230
                model: KWinComponents.ClientFilterModel {
                    activity: KWinComponents.Workspace.currentActivity
                    desktop: KWinComponents.Workspace.currentVirtualDesktop
                    screenName: targetScreen.name
                    clientModel: stackModel
231
                    filter: searchField.text
232
                    minimizedWindows: !effect.ignoreMinimized
233
234
235
236
                    windowType: ~KWinComponents.ClientFilterModel.Dock &
                            ~KWinComponents.ClientFilterModel.Desktop &
                            ~KWinComponents.ClientFilterModel.Notification;
                }
237
                onActivated: effect.deactivate();
238
239
240
241
                delegate: WindowHeapDelegate {
                    windowHeap: heap

                    targetScale: {
242
                        var localPressPosition = dragHandler.centroid.scenePressPosition.y - heap.layout.Kirigami.ScenePosition.y;
243
244
245
                        if (localPressPosition == 0) {
                            return 0.1
                        } else {
246
                            var localPosition = dragHandler.centroid.scenePosition.y - heap.layout.Kirigami.ScenePosition.y;
247
248
249
250
251
252
253
                            return Math.max(0.1, Math.min(localPosition / localPressPosition, 1))
                        }
                    }

                    opacity: 1 - downGestureProgress
                    onDownGestureTriggered: client.closeWindow()
                }
254
255
256
257
            }

            Milou.ResultsView {
                id: searchResults
258
                anchors.bottom: parent.bottom
259
260
                anchors.horizontalCenter: parent.horizontalCenter
                width: parent.width / 2
261
                height: parent.height - placeholderMessage.height - PlasmaCore.Units.largeSpacing
262
                queryString: searchField.text
263
                visible: container.organized && searchField.text && heap.count === 0
264
265
266
267

                onActivated: {
                    effect.deactivate();
                }
268
            }
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
269
270
271
272
273
        }
    }

    Repeater {
        model: KWinComponents.ClientFilterModel {
274
            desktop: KWinComponents.Workspace.currentVirtualDesktop
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
275
276
277
278
279
280
281
            screenName: targetScreen.name
            clientModel: stackModel
            windowType: KWinComponents.ClientFilterModel.Dock
        }

        KWinComponents.WindowThumbnailItem {
            id: windowThumbnail
Marco Martin's avatar
Marco Martin committed
282
            visible: !model.client.hidden && opacity > 0
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
283
284
285
286
287
            wId: model.client.internalId
            x: model.client.x - targetScreen.geometry.x
            y: model.client.y - targetScreen.geometry.y
            width: model.client.width
            height: model.client.height
Marco Martin's avatar
Marco Martin committed
288
289
290
            opacity: container.effect.gestureInProgress
                ? 1 - container.effect.partialActivationFactor
                : (model.client.hidden || container.organized) ? 0 : 1
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
291

Marco Martin's avatar
Marco Martin committed
292
293
            Behavior on opacity {
                enabled: !container.effect.gestureInProgress
294
                NumberAnimation { duration: effect.animationDuration; easing.type: Easing.OutCubic }
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
295
296
297
298
299
300
301
302
            }
        }
    }

    KWinComponents.ClientModel {
        id: stackModel
    }

303
304
305
306
    KWinComponents.VirtualDesktopModel {
        id: desktopModel
    }

307
    Component.onCompleted: start();
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
308
}