From 785fa5c1725b660a3570069bd2f7f912ff647d0d Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Sat, 29 Apr 2023 19:44:10 +0300 Subject: [PATCH] plugins/overview: Allow switching between desktops inside effect At the moment, clicking desktop thumbnails in the desktop bar results in switching to that virtual desktop, which is not ideal because the overview effect allows sending windows to another virtual desktop by drag and dropping them to its thumbnail but you can't jump to that desktop unless you leave the overview effect. BUG: 448668 --- src/plugins/overview/overvieweffect.cpp | 5 - src/plugins/overview/overvieweffect.h | 1 - src/plugins/overview/qml/DesktopBar.qml | 39 +------ src/plugins/overview/qml/main.qml | 138 +++++++++++++++--------- 4 files changed, 89 insertions(+), 94 deletions(-) diff --git a/src/plugins/overview/overvieweffect.cpp b/src/plugins/overview/overvieweffect.cpp index 1565771e8c..b650a36b0b 100644 --- a/src/plugins/overview/overvieweffect.cpp +++ b/src/plugins/overview/overvieweffect.cpp @@ -270,11 +270,6 @@ void OverviewEffect::realDeactivate() m_status = Status::Inactive; } -void OverviewEffect::quickDeactivate() -{ - m_shutdownTimer->start(0); -} - void OverviewEffect::grabbedKeyboardEvent(QKeyEvent *keyEvent) { if (m_toggleShortcut.contains(keyEvent->key() | keyEvent->modifiers())) { diff --git a/src/plugins/overview/overvieweffect.h b/src/plugins/overview/overvieweffect.h index 9ae86ade23..e4fc349e65 100644 --- a/src/plugins/overview/overvieweffect.h +++ b/src/plugins/overview/overvieweffect.h @@ -66,7 +66,6 @@ public Q_SLOTS: void partialDeactivate(qreal factor); void cancelPartialDeactivate(); void deactivate(); - void quickDeactivate(); void toggle(); private: diff --git a/src/plugins/overview/qml/DesktopBar.qml b/src/plugins/overview/qml/DesktopBar.qml index e462c122cb..d907f45a97 100644 --- a/src/plugins/overview/qml/DesktopBar.qml +++ b/src/plugins/overview/qml/DesktopBar.qml @@ -71,7 +71,7 @@ Item { Keys.onRightPressed: nextItemInFocusChain(!LayoutMirroring.enabled).forceActiveFocus(Qt.TabFocusReason); function activate() { - thumbnail.state = "scaled"; + KWinComponents.Workspace.currentDesktop = delegate.desktop; } function remove() { @@ -95,48 +95,17 @@ Item { DesktopView { id: thumbnail - property bool scaled: state === "scaled" - width: targetScreen.geometry.width height: targetScreen.geometry.height - visible: scaled + visible: false windowModel: bar.windowModel desktop: delegate.desktop scale: bar.desktopHeight / targetScreen.geometry.height transformOrigin: Item.TopLeft // Disable the item layer while being scaled. - layer.enabled: !scaled + layer.enabled: true layer.textureSize: Qt.size(bar.desktopWidth, bar.desktopHeight) - - states: State { - name: "scaled" - ParentChange { - target: thumbnail - parent: container - x: 0 - y: 0 - scale: 1 - } - } - - transitions: Transition { - SequentialAnimation { - ParentAnimation { - NumberAnimation { - properties: "x,y,scale" - duration: effect.animationDuration - easing.type: Easing.OutCubic - } - } - ScriptAction { - script: { - KWinComponents.Workspace.currentDesktop = delegate.desktop; - effect.quickDeactivate(); - } - } - } - } } OpacityMask { @@ -151,7 +120,7 @@ Item { } Rectangle { - readonly property bool active: !thumbnail.scaled && (delegate.activeFocus || dropArea.containsDrag || mouseArea.containsPress || bar.selectedDesktop === delegate.desktop) + readonly property bool active: delegate.activeFocus || dropArea.containsDrag || mouseArea.containsPress || bar.selectedDesktop === delegate.desktop anchors.fill: parent anchors.margins: -border.width radius: 3 diff --git a/src/plugins/overview/qml/main.qml b/src/plugins/overview/qml/main.qml index 9f47efbc33..506fc4c620 100644 --- a/src/plugins/overview/qml/main.qml +++ b/src/plugins/overview/qml/main.qml @@ -6,6 +6,7 @@ */ import QtQuick +import QtQuick.Controls import Qt5Compat.GraphicalEffects import org.kde.kirigami 2.20 as Kirigami import org.kde.kwin as KWinComponents @@ -29,6 +30,8 @@ FocusScope { property bool animationEnabled: false property bool organized: false + property alias currentHeap: heapView.currentItem + function start() { animationEnabled = true; organized = true; @@ -43,9 +46,9 @@ FocusScope { Keys.forwardTo: searchField Keys.onEnterPressed: { - heap.forceActiveFocus(); - if (heap.count === 1) { - heap.activateCurrentClient(); + currentHeap.forceActiveFocus(); + if (currentHeap.count === 1) { + currentHeap.activateCurrentClient(); } } @@ -186,7 +189,7 @@ FocusScope { windowModel: stackModel desktopModel: desktopModel selectedDesktop: KWinComponents.Workspace.currentDesktop - heap: heap + heap: currentHeap } } @@ -202,12 +205,12 @@ FocusScope { width: Math.min(parent.width, 20 * PlasmaCore.Units.gridUnit) focus: true Keys.priority: Keys.BeforeItem - Keys.forwardTo: text && heap.count === 0 ? searchResults : heap + Keys.forwardTo: text && currentHeap.count === 0 ? searchResults : currentHeap text: effect.searchText onTextEdited: { effect.searchText = text; - heap.resetSelected(); - heap.selectNextItem(WindowHeap.Direction.Down); + currentHeap.resetSelected(); + currentHeap.selectNextItem(WindowHeap.Direction.Down); searchField.focus = true; } } @@ -222,60 +225,89 @@ FocusScope { id: placeholderMessage anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter - visible: container.organized && effect.searchText.length > 0 && heap.count === 0 + visible: container.organized && effect.searchText.length > 0 && currentHeap.count === 0 text: i18nd("kwin", "No matching windows") } - WindowHeap { - id: heap - visible: !(container.organized && effect.searchText.length > 0) || heap.count !== 0 + StackView { + id: heapView anchors.fill: parent - layout.mode: effect.layout - focus: true - padding: PlasmaCore.Units.largeSpacing - animationDuration: effect.animationDuration - animationEnabled: container.animationEnabled - organized: container.organized - Keys.priority: Keys.AfterItem - Keys.forwardTo: searchResults - model: KWinComponents.WindowFilterModel { - activity: KWinComponents.Workspace.currentActivity - desktop: KWinComponents.Workspace.currentDesktop - screenName: targetScreen.name - windowModel: stackModel - filter: effect.searchText - minimizedWindows: !effect.ignoreMinimized - windowType: ~KWinComponents.WindowFilterModel.Dock & - ~KWinComponents.WindowFilterModel.Desktop & - ~KWinComponents.WindowFilterModel.Notification & - ~KWinComponents.WindowFilterModel.CriticalNotification - } - delegate: WindowHeapDelegate { - windowHeap: heap - targetScale: { - if (!activeDragHandler.active) { - return targetScale; // leave it alone, so it won't affect transitions before they start + function switchTo(desktop) { + container.animationEnabled = false; + heapView.replace(heapTemplate, { desktop: desktop }); + currentItem.layout.forceLayout(); + container.animationEnabled = true; + } + + Component.onCompleted: { + push(heapTemplate, { desktop: KWinComponents.Workspace.currentDesktop }); + } + } + + Connections { + target: KWinComponents.Workspace + function onCurrentDesktopChanged() { + heapView.switchTo(KWinComponents.Workspace.currentDesktop); + } + } + + Component { + id: heapTemplate + + WindowHeap { + id: heap + + required property QtObject desktop + + visible: !(container.organized && effect.searchText.length > 0) || heap.count !== 0 + layout.mode: effect.layout + focus: true + padding: PlasmaCore.Units.largeSpacing + animationDuration: effect.animationDuration + animationEnabled: container.animationEnabled + organized: container.organized + Keys.priority: Keys.AfterItem + Keys.forwardTo: searchResults + model: KWinComponents.WindowFilterModel { + activity: KWinComponents.Workspace.currentActivity + desktop: heap.desktop + screenName: targetScreen.name + windowModel: stackModel + filter: effect.searchText + minimizedWindows: !effect.ignoreMinimized + windowType: ~KWinComponents.WindowFilterModel.Dock & + ~KWinComponents.WindowFilterModel.Desktop & + ~KWinComponents.WindowFilterModel.Notification & + ~KWinComponents.WindowFilterModel.CriticalNotification + } + delegate: WindowHeapDelegate { + windowHeap: heap + + targetScale: { + if (!activeDragHandler.active) { + return targetScale; // leave it alone, so it won't affect transitions before they start + } + var localPressPosition = activeDragHandler.centroid.scenePressPosition.y - heap.layout.Kirigami.ScenePosition.y; + if (localPressPosition === 0) { + return 0.1; + } else { + var localPosition = activeDragHandler.centroid.scenePosition.y - heap.layout.Kirigami.ScenePosition.y; + return Math.max(0.1, Math.min(localPosition / localPressPosition, 1)); + } } - var localPressPosition = activeDragHandler.centroid.scenePressPosition.y - heap.layout.Kirigami.ScenePosition.y; - if (localPressPosition === 0) { - return 0.1; - } else { - var localPosition = activeDragHandler.centroid.scenePosition.y - heap.layout.Kirigami.ScenePosition.y; - return Math.max(0.1, Math.min(localPosition / localPressPosition, 1)); + + opacity: 1 - downGestureProgress + onDownGestureTriggered: window.closeWindow() + + TapHandler { + acceptedPointerTypes: PointerDevice.GenericPointer | PointerDevice.Pen + acceptedButtons: Qt.MiddleButton + onTapped: window.closeWindow() } } - - opacity: 1 - downGestureProgress - onDownGestureTriggered: window.closeWindow() - - TapHandler { - acceptedPointerTypes: PointerDevice.GenericPointer | PointerDevice.Pen - acceptedButtons: Qt.MiddleButton - onTapped: window.closeWindow() - } + onActivated: effect.deactivate(); } - onActivated: effect.deactivate(); } Milou.ResultsView { @@ -285,7 +317,7 @@ FocusScope { width: parent.width / 2 height: parent.height - placeholderMessage.height - PlasmaCore.Units.largeSpacing queryString: effect.searchText - visible: container.organized && effect.searchText.length > 0 && heap.count === 0 + visible: container.organized && effect.searchText.length > 0 && currentHeap.count === 0 onActivated: { effect.deactivate();