diff --git a/components/mobileshell/qml/HomeScreenControls.qml b/components/mobileshell/qml/HomeScreenControls.qml index 148121ba..2bde6a5d 100644 --- a/components/mobileshell/qml/HomeScreenControls.qml +++ b/components/mobileshell/qml/HomeScreenControls.qml @@ -13,12 +13,12 @@ pragma Singleton QtObject { id: delegate + signal openHomeScreen() signal resetHomeScreenPosition() signal snapHomeScreenPosition() signal requestRelativeScroll(point pos) - signal hideHomeScreen(bool animate) - signal showHomeScreen(bool animate) - property Item homeScreen + + property var taskSwitcher property QtObject homeScreenWindow property bool homeScreenVisible: true property bool taskSwitcherVisible: false diff --git a/components/mobileshell/qml/TaskPanelControls.qml b/components/mobileshell/qml/TaskPanelControls.qml new file mode 100644 index 00000000..e5869207 --- /dev/null +++ b/components/mobileshell/qml/TaskPanelControls.qml @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2021 Devin Lin + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +import QtQuick 2.12 +import org.kde.plasma.core 2.0 as PlasmaCore + +pragma Singleton + +/** + * Properties exposed by the taskpanel containment. + */ +QtObject { + id: root + property bool isPortrait + property real panelHeight + property real panelWidth +} + diff --git a/components/mobileshell/qml/navigationpanel/NavigationPanel.qml b/components/mobileshell/qml/navigationpanel/NavigationPanel.qml index 7f9f9ed8..f993bdb6 100644 --- a/components/mobileshell/qml/navigationpanel/NavigationPanel.qml +++ b/components/mobileshell/qml/navigationpanel/NavigationPanel.qml @@ -82,7 +82,7 @@ Item { opening = oldMouseY > mouse.y; - if (root.taskSwitcher.visibility == Window.Hidden && Math.abs(startMouseY - mouse.y) > PlasmaCore.Units.gridUnit && root.taskSwitcher.tasksCount) { + if (!root.taskSwitcher.visible && Math.abs(startMouseY - mouse.y) > PlasmaCore.Units.gridUnit && root.taskSwitcher.tasksCount) { // start task switcher gesture activeButton = null; root.taskSwitcher.show(false); diff --git a/components/mobileshell/qml/qmldir b/components/mobileshell/qml/qmldir index e27c8ef7..4a5dfd35 100644 --- a/components/mobileshell/qml/qmldir +++ b/components/mobileshell/qml/qmldir @@ -37,4 +37,5 @@ NotificationsWidget 1.0 widgets/NotificationsWidget.qml # / singleton HomeScreenControls 1.0 HomeScreenControls.qml +singleton TaskPanelControls 1.0 TaskPanelControls.qml singleton TopPanelControls 1.0 TopPanelControls.qml diff --git a/components/mobileshell/qml/taskswitcher/Task.qml b/components/mobileshell/qml/taskswitcher/Task.qml index e09b6b28..daa8b392 100644 --- a/components/mobileshell/qml/taskswitcher/Task.qml +++ b/components/mobileshell/qml/taskswitcher/Task.qml @@ -17,6 +17,8 @@ import org.kde.plasma.components 3.0 as PlasmaComponents Item { id: delegate + required property var taskSwitcher + required property var model required property var displaysModel @@ -29,12 +31,12 @@ Item { required property real previewWidth property real scale: 1 - opacity: 1 - dragOffset / window.height + opacity: 1 - dragOffset / taskSwitcher.height //BEGIN functions function syncDelegateGeometry() { let pos = pipeWireLoader.mapToItem(tasksView, 0, 0); - if (window.visible) { + if (taskSwitcher.visible) { tasksModel.requestPublishDelegateGeometry(tasksModel.index(model.index, 0), Qt.rect(pos.x, pos.y, pipeWireLoader.width, pipeWireLoader.height), pipeWireLoader); } } @@ -44,14 +46,14 @@ Item { } function activateApp() { - window.activateWindow(model.index); + taskSwitcher.activateWindow(model.index); } //END functions Component.onCompleted: syncDelegateGeometry(); Connections { - target: window + target: taskSwitcher function onVisibleChanged() { syncDelegateGeometry(); } @@ -78,7 +80,7 @@ Item { yAnimator.stop(); if (parent.y < -PlasmaCore.Units.gridUnit * 2) { - yAnimator.to = -window.height; + yAnimator.to = -root.height; } else { yAnimator.to = 0; } diff --git a/components/mobileshell/qml/taskswitcher/TaskSwitcher.qml b/components/mobileshell/qml/taskswitcher/TaskSwitcher.qml index f8f23fc4..f2fa550f 100644 --- a/components/mobileshell/qml/taskswitcher/TaskSwitcher.qml +++ b/components/mobileshell/qml/taskswitcher/TaskSwitcher.qml @@ -15,32 +15,31 @@ import org.kde.plasma.components 3.0 as PlasmaComponents import org.kde.plasma.private.nanoshell 2.0 as NanoShell import org.kde.plasma.private.mobileshell 1.0 as MobileShell -NanoShell.FullScreenOverlay { - id: window - +Item { + id: root visible: false - width: Screen.width - height: Screen.height - required property real taskPanelHeight // height of task panel, provided by main.qml + readonly property real taskPanelHeight: MobileShell.TaskPanelControls.panelHeight + readonly property real taskPanelWidth: MobileShell.TaskPanelControls.panelWidth + readonly property bool isPortrait: MobileShell.TaskPanelControls.isPortrait // dimensions of a window on the screen - readonly property real windowHeight: window.height - (navPanel.isPortrait ? window.taskPanelHeight : 0) - MobileShell.TopPanelControls.panelHeight - readonly property real windowWidth: window.width - (navPanel.isPortrait ? 0 : window.taskPanelHeight) + readonly property real windowHeight: root.height - (root.isPortrait ? root.taskPanelHeight : 0) - MobileShell.TopPanelControls.panelHeight + readonly property real windowWidth: root.width - (root.isPortrait ? 0 : root.taskPanelWidth) - property int tasksCount: window.model.count - property int currentTaskIndex: tasksView.currentIndex + readonly property int tasksCount: root.model.count + readonly property int currentTaskIndex: tasksView.currentIndex property TaskManager.TasksModel model - // properties controlled from main.qml MouseArea (swipe to open gesture) + // offset constants + readonly property real targetYOffsetDist: root.height - tasksView.height // offset distance to perfect opening + readonly property real dismissYOffsetDist: root.height + + // properties controlled from NavigationPanel (swipe to open gesture) property real oldYOffset: 0 property real yOffset: 0 - // offset constants - readonly property real targetYOffsetDist: window.height - tasksView.height // offset distance to perfect opening - readonly property real dismissYOffsetDist: window.height - - // set from NavigationPanel in main.qml + // set from NavigationPanel in taskpanel containment property bool wasInActiveTask: false // whether we were in an app before opening the task switcher property bool currentlyDragging: false // whether we are in a swipe up gesture @@ -52,18 +51,7 @@ NanoShell.FullScreenOverlay { Right } - onVisibleChanged: { - if (!visible) { - window.contentItem.opacity = 1; - } - // hide homescreen elements to make use of wallpaper - if (visible) { - MobileShell.HomeScreenControls.hideHomeScreen(!window.wasInActiveTask); // only animate if going from homescreen - } else { - MobileShell.HomeScreenControls.showHomeScreen(true); - } - MobileShell.HomeScreenControls.taskSwitcherVisible = visible; - } + onVisibleChanged: MobileShell.HomeScreenControls.taskSwitcherVisible = visible; onTasksCountChanged: { if (tasksCount == 0) { @@ -71,52 +59,51 @@ NanoShell.FullScreenOverlay { } } - // background - color: "transparent" Rectangle { id: backgroundRect anchors.fill: parent - color: Qt.rgba(0, 0, 0, 0.6 * (window.wasInActiveTask ? 1 : Math.min(1, window.yOffset / window.targetYOffsetDist))) + color: Qt.rgba(0, 0, 0, 0.6 * (root.wasInActiveTask ? 1 : Math.min(1, root.yOffset / root.targetYOffsetDist))) MouseArea { anchors.fill: parent - onClicked: hide() + onClicked: root.hide() } } //BEGIN functions + function show(animation) { - window.yOffset = 0; - window.wasInActiveTask = window.model.activeTask.row >= 0; + root.yOffset = 0; + root.wasInActiveTask = root.model.activeTask.row >= 0; // skip to first active task - if (window.wasInActiveTask) { - tasksView.currentIndex = window.model.activeTask.row; - tasksView.positionViewAtIndex(window.model.activeTask.row, ListView.SnapPosition); + if (root.wasInActiveTask) { + tasksView.currentIndex = root.model.activeTask.row; + tasksView.positionViewAtIndex(root.model.activeTask.row, ListView.SnapPosition); } - window.visible = true; - root.minimizeAll(); + root.visible = true; + minimizeAll(); // animate app shrink if (animation) { - offsetAnimator.to = window.targetYOffsetDist; + offsetAnimator.to = root.targetYOffsetDist; offsetAnimator.restart(); } } function hide() { - if (!window.visible) return; - window.visible = false; + if (!root.visible) return; + root.visible = false; } function snapOffset() { - let movingUp = window.yOffset > window.oldYOffset; + let movingUp = root.yOffset > root.oldYOffset; - if (movingUp || window.yOffset >= window.targetYOffsetDist) { // open task switcher and stay - offsetAnimator.to = window.targetYOffsetDist; + if (movingUp || root.yOffset >= root.targetYOffsetDist) { // open task switcher and stay + offsetAnimator.to = root.targetYOffsetDist; offsetAnimator.restart(); } else { // close task switcher and return to app - if (!window.wasInActiveTask) { // if pulled up from homescreen, don't activate app + if (!root.wasInActiveTask) { // if pulled up from homescreen, don't activate app offsetAnimator.activateApp = false; } offsetAnimator.to = 0; @@ -135,12 +122,12 @@ NanoShell.FullScreenOverlay { return; } - var newActiveIdx = window.model.index(id, 0) + var newActiveIdx = root.model.index(id, 0) var newActiveGeo = tasksModel.data(newActiveIdx, TaskManager.AbstractTasksModel.ScreenGeometry) for (var i = 0 ; i < tasksModel.count; i++) { - var idx = window.model.index(i, 0) + var idx = root.model.index(i, 0) if (i == id) { - window.model.requestActivate(idx); + root.model.requestActivate(idx); } else if (!tasksModel.data(idx, TaskManager.AbstractTasksModel.IsMinimized)) { var geo = tasksModel.data(idx, TaskManager.AbstractTasksModel.ScreenGeometry) // Only minimize the other windows in the same screen @@ -150,8 +137,27 @@ NanoShell.FullScreenOverlay { } } - window.visible = false; + root.visible = false; } + + function minimizeAll() { + for (var i = 0 ; i < tasksModel.count; i++) { + var idx = tasksModel.makeModelIndex(i); + if (!tasksModel.data(idx, TaskManager.AbstractTasksModel.IsMinimized)) { + tasksModel.requestToggleMinimized(idx); + } + } + } + + function restoreAll() { + for (var i = 0 ; i < tasksModel.count; i++) { + var idx = tasksModel.makeModelIndex(i); + if (tasksModel.data(idx, TaskManager.AbstractTasksModel.IsMinimized)) { + tasksModel.requestToggleMinimized(idx); + } + } + } + //END functions // animate app grow and shrink @@ -164,19 +170,19 @@ NanoShell.FullScreenOverlay { // states of to: // 0 - open/resume app (zoom up the thumbnail) - // window.targetYOffsetDist - animate shrinking of thumbnail, to listview (open task switcher) + // root.targetYOffsetDist - animate shrinking of thumbnail, to listview (open task switcher) to: 0 onFinished: { if (to === 0) { // close task switcher, and switch to current app - if (!window.visible) return; - window.visible = false; + if (!root.visible) return; + root.visible = false; if (activateApp) { - setSingleActiveWindow(window.currentTaskIndex); + setSingleActiveWindow(root.currentTaskIndex); } activateApp = true; - } else if (to == window.dismissYOffsetDist) { - window.hide(); + } else if (to == root.dismissYOffsetDist) { + root.hide(); } } } @@ -186,23 +192,23 @@ NanoShell.FullScreenOverlay { // provide shell margins anchors.fill: parent - anchors.rightMargin: navPanel.isPortrait ? 0 : window.taskPanelHeight - anchors.bottomMargin: navPanel.isPortrait ? window.taskPanelHeight : 0 + anchors.rightMargin: root.isPortrait ? 0 : root.taskPanelWidth + anchors.bottomMargin: root.isPortrait ? root.taskPanelHeight : 0 anchors.topMargin: MobileShell.TopPanelControls.panelHeight // applications list ListView { id: tasksView - opacity: window.wasInActiveTask ? 1 : Math.min(1, window.yOffset / window.targetYOffsetDist) + opacity: root.wasInActiveTask ? 1 : Math.min(1, root.yOffset / root.targetYOffsetDist) anchors.centerIn: parent readonly property real sizeFactor: 0.75 readonly property real taskHeaderHeight: PlasmaCore.Units.gridUnit * 2 + PlasmaCore.Units.smallSpacing * 2 - width: window.windowWidth * sizeFactor - height: window.windowHeight * sizeFactor + taskHeaderHeight + width: root.windowWidth * sizeFactor + height: root.windowHeight * sizeFactor + taskHeaderHeight - model: window.model + model: root.model orientation: ListView.Horizontal highlightRangeMode: ListView.StrictlyEnforceRange // ensures currentIndex is updated @@ -217,22 +223,23 @@ NanoShell.FullScreenOverlay { // ensure that window previews are exactly to the scale of the device screen property real scalingFactor: { - let candidateHeight = (tasksView.width / window.windowWidth) * window.windowHeight; + let candidateHeight = (tasksView.width / root.windowWidth) * root.windowHeight; if (candidateHeight > tasksView.height) { - return tasksView.height / window.windowHeight; + return tasksView.height / root.windowHeight; } else { - return tasksView.width / window.windowWidth; + return tasksView.width / root.windowWidth; } } delegate: Task { id: task property int curIndex: model.index - z: window.currentTaskIndex === curIndex ? 1 : 0 + z: root.currentTaskIndex === curIndex ? 1 : 0 width: tasksView.width height: tasksView.height - displaysModel: window.displaysModel + taskSwitcher: root + displaysModel: root.displaysModel // account for header offset (center the preview) y: -tasksView.taskHeaderHeight / 2 @@ -240,18 +247,18 @@ NanoShell.FullScreenOverlay { // scale gesture scale: { let maxScale = 1 / tasksView.scalingFactor; - let subtract = (maxScale - 1) * (window.yOffset / window.targetYOffsetDist); + let subtract = (maxScale - 1) * (root.yOffset / root.targetYOffsetDist); let finalScale = Math.max(0, Math.min(maxScale, maxScale - subtract)); - if ((window.wasInActiveTask || !taskSwitcher.currentlyDragging) && window.currentTaskIndex === task.curIndex) { + if ((root.wasInActiveTask || !taskSwitcher.currentlyDragging) && root.currentTaskIndex === task.curIndex) { return finalScale; } return 1; } // ensure that window previews are exactly to the scale of the device screen - previewWidth: tasksView.scalingFactor * window.windowWidth - previewHeight: tasksView.scalingFactor * window.windowHeight + previewWidth: tasksView.scalingFactor * root.windowWidth + previewHeight: tasksView.scalingFactor * root.windowHeight } } } @@ -274,57 +281,4 @@ NanoShell.FullScreenOverlay { } onReleased: MobileShell.TopPanelControls.endSwipe(); } - - // task panel - MobileShell.NavigationPanel { - id: navPanel - - property bool isPortrait: Screen.width <= Screen.height - width: isPortrait ? implicitWidth : window.taskPanelHeight - height: isPortrait ? window.taskPanelHeight : implicitWidth - - anchors.left: isPortrait ? parent.left : undefined - anchors.right: parent.right - anchors.top: isPortrait ? undefined: parent.top - anchors.bottom: parent.bottom - - taskSwitcher: window - backgroundColor: window.visible ? Qt.rgba(0, 0, 0, 0.1) : "transparent" - foregroundColorGroup: PlasmaCore.Theme.ComplementaryColorGroup - dragGestureEnabled: false - - Behavior on backgroundColor { ColorAnimation {} } - - leftAction: MobileShell.NavigationPanelAction { - enabled: true - iconSource: "mobile-task-switcher" - iconSizeFactor: 0.75 - onTriggered: { - if (window.wasInActiveTask) { - window.activateWindow(window.currentTaskIndex); - } else { - window.hide(); - } - } - } - - middleAction: MobileShell.NavigationPanelAction { - enabled: true - iconSource: "start-here-kde" - iconSizeFactor: 1 - onTriggered: { - window.hide(); - root.triggerHomescreen(); - } - } - - rightAction: MobileShell.NavigationPanelAction { - enabled: true - iconSource: "mobile-close-app" - iconSizeFactor: 0.75 - onTriggered: { - tasksModel.requestClose(tasksModel.index(window.currentTaskIndex, 0)); - } - } - } } diff --git a/components/mobileshell/qml/taskswitcher/Thumbnail.qml b/components/mobileshell/qml/taskswitcher/Thumbnail.qml index 2cbc1289..5dd3139e 100644 --- a/components/mobileshell/qml/taskswitcher/Thumbnail.qml +++ b/components/mobileshell/qml/taskswitcher/Thumbnail.qml @@ -16,7 +16,9 @@ TaskManager.PipeWireSourceItem { onVisibleChanged: { if (visible && waylandItem.uuid.length === 0) { - waylandItem.uuid = model.WinIdList[0] + if (model.WinIdList) { + waylandItem.uuid = model.WinIdList[0]; + } } } diff --git a/containments/homescreen/package/contents/ui/HomeScreen.qml b/containments/homescreen/package/contents/ui/HomeScreen.qml index 5e302e48..a6946107 100644 --- a/containments/homescreen/package/contents/ui/HomeScreen.qml +++ b/containments/homescreen/package/contents/ui/HomeScreen.qml @@ -29,6 +29,7 @@ Item { readonly property real headerHeight: Math.round(PlasmaCore.Units.gridUnit * 3) //BEGIN functions + function activate() { // there's a couple of steps: // - minimize windows @@ -44,6 +45,7 @@ Item { root.appDrawer.close() } } + //END functions HomeScreenComponents.FlickablePages { diff --git a/containments/homescreen/package/contents/ui/main.qml b/containments/homescreen/package/contents/ui/main.qml index 8b2011b2..ebfbc458 100644 --- a/containments/homescreen/package/contents/ui/main.qml +++ b/containments/homescreen/package/contents/ui/main.qml @@ -9,6 +9,7 @@ import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Layouts 1.1 +import org.kde.taskmanager 0.1 as TaskManager import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 3.0 as PlasmaComponents @@ -29,6 +30,12 @@ FocusScope { } HomeScreenComponents.ApplicationListModel.maxFavoriteCount = Math.max(4, Math.floor(Math.min(width, height) / homescreen.homeScreenContents.appletsLayout.cellWidth)); } + + function triggerHomeScreen() { + taskSwitcher.minimizeAll(); + MobileShell.HomeScreenControls.resetHomeScreenPosition(); + taskSwitcher.visible = false; // will trigger homescreen open + } //END functions @@ -38,6 +45,10 @@ FocusScope { property real lastRequestedPosition: 0 + function onOpenHomeScreen() { + root.triggerHomeScreen(); + } + function onResetHomeScreenPosition() { homescreen.flickablePages.scrollToPage(0); homescreen.appDrawer.close(); @@ -55,35 +66,17 @@ FocusScope { homescreen.appDrawer.offset -= pos.y; lastRequestedPosition = pos.y; } - - function onHideHomeScreen(animate) { - if (animate) { - opacityAnimation.to = 0; - opacityAnimation.restart(); - } else { - homescreen.opacity = 0; - } - } - - function onShowHomeScreen(animate) { - if (animate) { - opacityAnimation.to = 1; - opacityAnimation.restart(); - } else { - homescreen.opacity = 1; - } - } } Plasmoid.onScreenChanged: { if (plasmoid.screen == 0) { - MobileShell.HomeScreenControls.homeScreen = root - MobileShell.HomeScreenControls.homeScreenWindow = root.Window.window + MobileShell.HomeScreenControls.taskSwitcher = taskSwitcher; + MobileShell.HomeScreenControls.homeScreenWindow = root.Window.window; } } Window.onWindowChanged: { if (plasmoid.screen == 0) { - MobileShell.HomeScreenControls.homeScreenWindow = root.Window.window + MobileShell.HomeScreenControls.homeScreenWindow = root.Window.window; } } @@ -101,7 +94,7 @@ FocusScope { // set API variables if (plasmoid.screen == 0) { - MobileShell.HomeScreenControls.homeScreen = root; + MobileShell.HomeScreenControls.taskSwitcher = taskSwitcher; MobileShell.HomeScreenControls.homeScreenWindow = root.Window.window; } componentComplete = true; @@ -116,6 +109,7 @@ FocusScope { homescreen.activate(); } + // homescreen component HomeScreen { id: homescreen anchors.fill: parent @@ -126,5 +120,49 @@ FocusScope { duration: PlasmaCore.Units.longDuration } } + + // task switcher component + TaskManager.TasksModel { + id: tasksModel + groupMode: TaskManager.TasksModel.GroupDisabled + + screenGeometry: plasmoid.screenGeometry + sortMode: TaskManager.TasksModel.SortAlpha + + virtualDesktop: virtualDesktopInfo.currentDesktop + activity: activityInfo.currentActivity + } + + TaskManager.VirtualDesktopInfo { + id: virtualDesktopInfo + } + + TaskManager.ActivityInfo { + id: activityInfo + } + + MobileShell.TaskSwitcher { + id: taskSwitcher + model: tasksModel + + anchors.fill: parent + + // hide homescreen elements to make use of wallpaper + onVisibleChanged: { + if (visible) { + // only animate if going from homescreen + if (taskSwitcher.wasInActiveTask) { + opacityAnimation.to = 0; + opacityAnimation.restart(); + } else { + homescreen.opacity = 0; + } + + } else { + opacityAnimation.to = 1; + opacityAnimation.restart(); + } + } + } } diff --git a/containments/taskpanel/package/contents/ui/main.qml b/containments/taskpanel/package/contents/ui/main.qml index b2bb5068..5cd93915 100644 --- a/containments/taskpanel/package/contents/ui/main.qml +++ b/containments/taskpanel/package/contents/ui/main.qml @@ -22,7 +22,7 @@ import org.kde.plasma.phone.taskpanel 1.0 as TaskPanel PlasmaCore.ColorScope { id: root colorGroup: showingApp ? PlasmaCore.Theme.HeaderColorGroup : PlasmaCore.Theme.ComplementaryColorGroup - + Plasmoid.backgroundHints: PlasmaCore.Types.NoBackground readonly property color backgroundColor: NanoShell.StartupFeedback.visible ? NanoShell.StartupFeedback.backgroundColor : PlasmaCore.ColorScope.backgroundColor @@ -30,35 +30,28 @@ PlasmaCore.ColorScope { readonly property bool hasTasks: tasksModel.count > 0 - property QtObject taskSwitcher: taskSwitcherLoader.item ? taskSwitcherLoader.item : null + property var taskSwitcher: MobileShell.HomeScreenControls.taskSwitcher -//BEGIN functions - function minimizeAll() { - for (var i = 0 ; i < tasksModel.count; i++) { - var idx = tasksModel.makeModelIndex(i); - if (!tasksModel.data(idx, TaskManager.AbstractTasksModel.IsMinimized)) { - tasksModel.requestToggleMinimized(idx); - } - } +//BEGIN API implementation + + Binding { + target: MobileShell.TaskPanelControls + property: "isPortrait" + value: Screen.width <= Screen.height + } + Binding { + target: MobileShell.TaskPanelControls + property: "panelHeight" + value: root.height + } + Binding { + target: MobileShell.TaskPanelControls + property: "panelWidth" + value: root.width } - function restoreAll() { - for (var i = 0 ; i < tasksModel.count; i++) { - var idx = tasksModel.makeModelIndex(i); - if (tasksModel.data(idx, TaskManager.AbstractTasksModel.IsMinimized)) { - tasksModel.requestToggleMinimized(idx); - } - } - } +//END API implementation - function triggerHomescreen() { - root.minimizeAll(); - MobileShell.HomeScreenControls.resetHomeScreenPosition(); - MobileShell.HomeScreenControls.showHomeScreen(true); - plasmoid.nativeInterface.allMinimizedChanged(); - } -//END functions - Connections { target: plasmoid.nativeInterface function onAllMinimizedChanged() { @@ -94,35 +87,44 @@ PlasmaCore.ColorScope { }); } - // task switcher - Loader { - id: taskSwitcherLoader - sourceComponent: MobileShell.TaskSwitcher { - model: tasksModel - taskPanelHeight: root.state === "portrait" ? root.height : root.width - } - } - // bottom navigation panel MobileShell.NavigationPanel { id: panel anchors.fill: parent - opacity: (root.taskSwitcher && root.taskSwitcher.visible) ? 0 : 1 // hide bar when task switcher is open - - backgroundColor: root.showingApp ? root.backgroundColor : "transparent" - foregroundColorGroup: root.showingApp ? PlasmaCore.Theme.NormalColorGroup : PlasmaCore.Theme.ComplementaryColorGroup - - dragGestureEnabled: true taskSwitcher: root.taskSwitcher - + + backgroundColor: { + if (taskSwitcher.visible) { + return Qt.rgba(0, 0, 0, 0.1); + } else { + return root.showingApp ? root.backgroundColor : "transparent"; + } + } + foregroundColorGroup: (!taskSwitcher.visible && root.showingApp) ? PlasmaCore.Theme.NormalColorGroup : PlasmaCore.Theme.ComplementaryColorGroup + + // do not enable drag gesture when task switcher is already open + // also don't disable drag gesture mid-drag + dragGestureEnabled: !taskSwitcher.visible || taskSwitcher.currentlyDragging + leftAction: MobileShell.NavigationPanelAction { - enabled: hasTasks + enabled: hasTasks || taskSwitcher.visible iconSource: "mobile-task-switcher" iconSizeFactor: 0.75 onTriggered: { plasmoid.nativeInterface.showDesktop = false; - taskSwitcher.visible ? taskSwitcher.hide() : taskSwitcher.show(true); + + if (!taskSwitcher.visible) { + taskSwitcher.show(true); + } else { + // when task switcher is open + if (taskSwitcher.wasInActiveTask) { + // restore active window + taskSwitcher.activateWindow(root.currentTaskIndex); + } else { + taskSwitcher.hide(); + } + } } } @@ -130,19 +132,30 @@ PlasmaCore.ColorScope { enabled: true iconSource: "start-here-kde" iconSizeFactor: 1 - onTriggered: root.triggerHomescreen() + onTriggered: { + MobileShell.HomeScreenControls.openHomeScreen(); + plasmoid.nativeInterface.allMinimizedChanged(); + } } rightAction: MobileShell.NavigationPanelAction { - enabled: MobileShell.KWinVirtualKeyboard.visible || (plasmoid.nativeInterface.hasCloseableActiveWindow && !taskSwitcher.visible) + enabled: MobileShell.KWinVirtualKeyboard.visible || taskSwitcher.visible || plasmoid.nativeInterface.hasCloseableActiveWindow // mobile-close-app (from plasma-frameworks) seems to have less margins than icons from breeze-icons iconSizeFactor: MobileShell.KWinVirtualKeyboard.visible ? 1 : 0.75 iconSource: MobileShell.KWinVirtualKeyboard.visible ? "go-down-symbolic" : "mobile-close-app" onTriggered: { if (MobileShell.KWinVirtualKeyboard.active) { + // close keyboard if it is open MobileShell.KWinVirtualKeyboard.active = false; + } else if (taskSwitcher.visible) { + + // if task switcher is open, close the current window shown + taskSwitcher.model.requestClose(taskSwitcher.model.index(taskSwitcher.currentTaskIndex, 0)); + } else if (plasmoid.nativeInterface.hasCloseableActiveWindow) { + + // if task switcher is closed, but there is an active window var index = taskSwitcher.model.activeTask; if (index) { taskSwitcher.model.requestClose(index);