mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-08-04 10:44:46 +00:00
taskswitcher: Move component to homescreen and remove popup window
This commit is contained in:
parent
e407e76233
commit
4057122fb0
10 changed files with 235 additions and 202 deletions
|
|
@ -13,12 +13,12 @@ pragma Singleton
|
||||||
QtObject {
|
QtObject {
|
||||||
id: delegate
|
id: delegate
|
||||||
|
|
||||||
|
signal openHomeScreen()
|
||||||
signal resetHomeScreenPosition()
|
signal resetHomeScreenPosition()
|
||||||
signal snapHomeScreenPosition()
|
signal snapHomeScreenPosition()
|
||||||
signal requestRelativeScroll(point pos)
|
signal requestRelativeScroll(point pos)
|
||||||
signal hideHomeScreen(bool animate)
|
|
||||||
signal showHomeScreen(bool animate)
|
property var taskSwitcher
|
||||||
property Item homeScreen
|
|
||||||
property QtObject homeScreenWindow
|
property QtObject homeScreenWindow
|
||||||
property bool homeScreenVisible: true
|
property bool homeScreenVisible: true
|
||||||
property bool taskSwitcherVisible: false
|
property bool taskSwitcherVisible: false
|
||||||
|
|
|
||||||
21
components/mobileshell/qml/TaskPanelControls.qml
Normal file
21
components/mobileshell/qml/TaskPanelControls.qml
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -82,7 +82,7 @@ Item {
|
||||||
|
|
||||||
opening = oldMouseY > mouse.y;
|
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
|
// start task switcher gesture
|
||||||
activeButton = null;
|
activeButton = null;
|
||||||
root.taskSwitcher.show(false);
|
root.taskSwitcher.show(false);
|
||||||
|
|
|
||||||
|
|
@ -37,4 +37,5 @@ NotificationsWidget 1.0 widgets/NotificationsWidget.qml
|
||||||
|
|
||||||
# /
|
# /
|
||||||
singleton HomeScreenControls 1.0 HomeScreenControls.qml
|
singleton HomeScreenControls 1.0 HomeScreenControls.qml
|
||||||
|
singleton TaskPanelControls 1.0 TaskPanelControls.qml
|
||||||
singleton TopPanelControls 1.0 TopPanelControls.qml
|
singleton TopPanelControls 1.0 TopPanelControls.qml
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||||
Item {
|
Item {
|
||||||
id: delegate
|
id: delegate
|
||||||
|
|
||||||
|
required property var taskSwitcher
|
||||||
|
|
||||||
required property var model
|
required property var model
|
||||||
required property var displaysModel
|
required property var displaysModel
|
||||||
|
|
||||||
|
|
@ -29,12 +31,12 @@ Item {
|
||||||
required property real previewWidth
|
required property real previewWidth
|
||||||
property real scale: 1
|
property real scale: 1
|
||||||
|
|
||||||
opacity: 1 - dragOffset / window.height
|
opacity: 1 - dragOffset / taskSwitcher.height
|
||||||
|
|
||||||
//BEGIN functions
|
//BEGIN functions
|
||||||
function syncDelegateGeometry() {
|
function syncDelegateGeometry() {
|
||||||
let pos = pipeWireLoader.mapToItem(tasksView, 0, 0);
|
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);
|
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() {
|
function activateApp() {
|
||||||
window.activateWindow(model.index);
|
taskSwitcher.activateWindow(model.index);
|
||||||
}
|
}
|
||||||
//END functions
|
//END functions
|
||||||
|
|
||||||
Component.onCompleted: syncDelegateGeometry();
|
Component.onCompleted: syncDelegateGeometry();
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: window
|
target: taskSwitcher
|
||||||
function onVisibleChanged() {
|
function onVisibleChanged() {
|
||||||
syncDelegateGeometry();
|
syncDelegateGeometry();
|
||||||
}
|
}
|
||||||
|
|
@ -78,7 +80,7 @@ Item {
|
||||||
yAnimator.stop();
|
yAnimator.stop();
|
||||||
|
|
||||||
if (parent.y < -PlasmaCore.Units.gridUnit * 2) {
|
if (parent.y < -PlasmaCore.Units.gridUnit * 2) {
|
||||||
yAnimator.to = -window.height;
|
yAnimator.to = -root.height;
|
||||||
} else {
|
} else {
|
||||||
yAnimator.to = 0;
|
yAnimator.to = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.nanoshell 2.0 as NanoShell
|
||||||
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||||
|
|
||||||
NanoShell.FullScreenOverlay {
|
Item {
|
||||||
id: window
|
id: root
|
||||||
|
|
||||||
visible: false
|
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
|
// dimensions of a window on the screen
|
||||||
readonly property real windowHeight: window.height - (navPanel.isPortrait ? window.taskPanelHeight : 0) - MobileShell.TopPanelControls.panelHeight
|
readonly property real windowHeight: root.height - (root.isPortrait ? root.taskPanelHeight : 0) - MobileShell.TopPanelControls.panelHeight
|
||||||
readonly property real windowWidth: window.width - (navPanel.isPortrait ? 0 : window.taskPanelHeight)
|
readonly property real windowWidth: root.width - (root.isPortrait ? 0 : root.taskPanelWidth)
|
||||||
|
|
||||||
property int tasksCount: window.model.count
|
readonly property int tasksCount: root.model.count
|
||||||
property int currentTaskIndex: tasksView.currentIndex
|
readonly property int currentTaskIndex: tasksView.currentIndex
|
||||||
property TaskManager.TasksModel model
|
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 oldYOffset: 0
|
||||||
property real yOffset: 0
|
property real yOffset: 0
|
||||||
|
|
||||||
// offset constants
|
// set from NavigationPanel in taskpanel containment
|
||||||
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
|
|
||||||
property bool wasInActiveTask: false // whether we were in an app before opening the task switcher
|
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
|
property bool currentlyDragging: false // whether we are in a swipe up gesture
|
||||||
|
|
||||||
|
|
@ -52,18 +51,7 @@ NanoShell.FullScreenOverlay {
|
||||||
Right
|
Right
|
||||||
}
|
}
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: MobileShell.HomeScreenControls.taskSwitcherVisible = visible;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
onTasksCountChanged: {
|
onTasksCountChanged: {
|
||||||
if (tasksCount == 0) {
|
if (tasksCount == 0) {
|
||||||
|
|
@ -71,52 +59,51 @@ NanoShell.FullScreenOverlay {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// background
|
|
||||||
color: "transparent"
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: backgroundRect
|
id: backgroundRect
|
||||||
anchors.fill: parent
|
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 {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: hide()
|
onClicked: root.hide()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//BEGIN functions
|
//BEGIN functions
|
||||||
|
|
||||||
function show(animation) {
|
function show(animation) {
|
||||||
window.yOffset = 0;
|
root.yOffset = 0;
|
||||||
window.wasInActiveTask = window.model.activeTask.row >= 0;
|
root.wasInActiveTask = root.model.activeTask.row >= 0;
|
||||||
|
|
||||||
// skip to first active task
|
// skip to first active task
|
||||||
if (window.wasInActiveTask) {
|
if (root.wasInActiveTask) {
|
||||||
tasksView.currentIndex = window.model.activeTask.row;
|
tasksView.currentIndex = root.model.activeTask.row;
|
||||||
tasksView.positionViewAtIndex(window.model.activeTask.row, ListView.SnapPosition);
|
tasksView.positionViewAtIndex(root.model.activeTask.row, ListView.SnapPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.visible = true;
|
root.visible = true;
|
||||||
root.minimizeAll();
|
minimizeAll();
|
||||||
|
|
||||||
// animate app shrink
|
// animate app shrink
|
||||||
if (animation) {
|
if (animation) {
|
||||||
offsetAnimator.to = window.targetYOffsetDist;
|
offsetAnimator.to = root.targetYOffsetDist;
|
||||||
offsetAnimator.restart();
|
offsetAnimator.restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function hide() {
|
function hide() {
|
||||||
if (!window.visible) return;
|
if (!root.visible) return;
|
||||||
window.visible = false;
|
root.visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function snapOffset() {
|
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
|
if (movingUp || root.yOffset >= root.targetYOffsetDist) { // open task switcher and stay
|
||||||
offsetAnimator.to = window.targetYOffsetDist;
|
offsetAnimator.to = root.targetYOffsetDist;
|
||||||
offsetAnimator.restart();
|
offsetAnimator.restart();
|
||||||
} else { // close task switcher and return to app
|
} 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.activateApp = false;
|
||||||
}
|
}
|
||||||
offsetAnimator.to = 0;
|
offsetAnimator.to = 0;
|
||||||
|
|
@ -135,12 +122,12 @@ NanoShell.FullScreenOverlay {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newActiveIdx = window.model.index(id, 0)
|
var newActiveIdx = root.model.index(id, 0)
|
||||||
var newActiveGeo = tasksModel.data(newActiveIdx, TaskManager.AbstractTasksModel.ScreenGeometry)
|
var newActiveGeo = tasksModel.data(newActiveIdx, TaskManager.AbstractTasksModel.ScreenGeometry)
|
||||||
for (var i = 0 ; i < tasksModel.count; i++) {
|
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) {
|
if (i == id) {
|
||||||
window.model.requestActivate(idx);
|
root.model.requestActivate(idx);
|
||||||
} else if (!tasksModel.data(idx, TaskManager.AbstractTasksModel.IsMinimized)) {
|
} else if (!tasksModel.data(idx, TaskManager.AbstractTasksModel.IsMinimized)) {
|
||||||
var geo = tasksModel.data(idx, TaskManager.AbstractTasksModel.ScreenGeometry)
|
var geo = tasksModel.data(idx, TaskManager.AbstractTasksModel.ScreenGeometry)
|
||||||
// Only minimize the other windows in the same screen
|
// 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
|
//END functions
|
||||||
|
|
||||||
// animate app grow and shrink
|
// animate app grow and shrink
|
||||||
|
|
@ -164,19 +170,19 @@ NanoShell.FullScreenOverlay {
|
||||||
|
|
||||||
// states of to:
|
// states of to:
|
||||||
// 0 - open/resume app (zoom up the thumbnail)
|
// 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
|
to: 0
|
||||||
onFinished: {
|
onFinished: {
|
||||||
if (to === 0) { // close task switcher, and switch to current app
|
if (to === 0) { // close task switcher, and switch to current app
|
||||||
if (!window.visible) return;
|
if (!root.visible) return;
|
||||||
window.visible = false;
|
root.visible = false;
|
||||||
|
|
||||||
if (activateApp) {
|
if (activateApp) {
|
||||||
setSingleActiveWindow(window.currentTaskIndex);
|
setSingleActiveWindow(root.currentTaskIndex);
|
||||||
}
|
}
|
||||||
activateApp = true;
|
activateApp = true;
|
||||||
} else if (to == window.dismissYOffsetDist) {
|
} else if (to == root.dismissYOffsetDist) {
|
||||||
window.hide();
|
root.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -186,23 +192,23 @@ NanoShell.FullScreenOverlay {
|
||||||
|
|
||||||
// provide shell margins
|
// provide shell margins
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.rightMargin: navPanel.isPortrait ? 0 : window.taskPanelHeight
|
anchors.rightMargin: root.isPortrait ? 0 : root.taskPanelWidth
|
||||||
anchors.bottomMargin: navPanel.isPortrait ? window.taskPanelHeight : 0
|
anchors.bottomMargin: root.isPortrait ? root.taskPanelHeight : 0
|
||||||
anchors.topMargin: MobileShell.TopPanelControls.panelHeight
|
anchors.topMargin: MobileShell.TopPanelControls.panelHeight
|
||||||
|
|
||||||
// applications list
|
// applications list
|
||||||
ListView {
|
ListView {
|
||||||
id: tasksView
|
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
|
anchors.centerIn: parent
|
||||||
|
|
||||||
readonly property real sizeFactor: 0.75
|
readonly property real sizeFactor: 0.75
|
||||||
readonly property real taskHeaderHeight: PlasmaCore.Units.gridUnit * 2 + PlasmaCore.Units.smallSpacing * 2
|
readonly property real taskHeaderHeight: PlasmaCore.Units.gridUnit * 2 + PlasmaCore.Units.smallSpacing * 2
|
||||||
|
|
||||||
width: window.windowWidth * sizeFactor
|
width: root.windowWidth * sizeFactor
|
||||||
height: window.windowHeight * sizeFactor + taskHeaderHeight
|
height: root.windowHeight * sizeFactor + taskHeaderHeight
|
||||||
|
|
||||||
model: window.model
|
model: root.model
|
||||||
orientation: ListView.Horizontal
|
orientation: ListView.Horizontal
|
||||||
|
|
||||||
highlightRangeMode: ListView.StrictlyEnforceRange // ensures currentIndex is updated
|
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
|
// ensure that window previews are exactly to the scale of the device screen
|
||||||
property real scalingFactor: {
|
property real scalingFactor: {
|
||||||
let candidateHeight = (tasksView.width / window.windowWidth) * window.windowHeight;
|
let candidateHeight = (tasksView.width / root.windowWidth) * root.windowHeight;
|
||||||
if (candidateHeight > tasksView.height) {
|
if (candidateHeight > tasksView.height) {
|
||||||
return tasksView.height / window.windowHeight;
|
return tasksView.height / root.windowHeight;
|
||||||
} else {
|
} else {
|
||||||
return tasksView.width / window.windowWidth;
|
return tasksView.width / root.windowWidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: Task {
|
delegate: Task {
|
||||||
id: task
|
id: task
|
||||||
property int curIndex: model.index
|
property int curIndex: model.index
|
||||||
z: window.currentTaskIndex === curIndex ? 1 : 0
|
z: root.currentTaskIndex === curIndex ? 1 : 0
|
||||||
width: tasksView.width
|
width: tasksView.width
|
||||||
height: tasksView.height
|
height: tasksView.height
|
||||||
|
|
||||||
displaysModel: window.displaysModel
|
taskSwitcher: root
|
||||||
|
displaysModel: root.displaysModel
|
||||||
|
|
||||||
// account for header offset (center the preview)
|
// account for header offset (center the preview)
|
||||||
y: -tasksView.taskHeaderHeight / 2
|
y: -tasksView.taskHeaderHeight / 2
|
||||||
|
|
@ -240,18 +247,18 @@ NanoShell.FullScreenOverlay {
|
||||||
// scale gesture
|
// scale gesture
|
||||||
scale: {
|
scale: {
|
||||||
let maxScale = 1 / tasksView.scalingFactor;
|
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));
|
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 finalScale;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure that window previews are exactly to the scale of the device screen
|
// ensure that window previews are exactly to the scale of the device screen
|
||||||
previewWidth: tasksView.scalingFactor * window.windowWidth
|
previewWidth: tasksView.scalingFactor * root.windowWidth
|
||||||
previewHeight: tasksView.scalingFactor * window.windowHeight
|
previewHeight: tasksView.scalingFactor * root.windowHeight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -274,57 +281,4 @@ NanoShell.FullScreenOverlay {
|
||||||
}
|
}
|
||||||
onReleased: MobileShell.TopPanelControls.endSwipe();
|
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,9 @@ TaskManager.PipeWireSourceItem {
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (visible && waylandItem.uuid.length === 0) {
|
if (visible && waylandItem.uuid.length === 0) {
|
||||||
waylandItem.uuid = model.WinIdList[0]
|
if (model.WinIdList) {
|
||||||
|
waylandItem.uuid = model.WinIdList[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ Item {
|
||||||
readonly property real headerHeight: Math.round(PlasmaCore.Units.gridUnit * 3)
|
readonly property real headerHeight: Math.round(PlasmaCore.Units.gridUnit * 3)
|
||||||
|
|
||||||
//BEGIN functions
|
//BEGIN functions
|
||||||
|
|
||||||
function activate() {
|
function activate() {
|
||||||
// there's a couple of steps:
|
// there's a couple of steps:
|
||||||
// - minimize windows
|
// - minimize windows
|
||||||
|
|
@ -44,6 +45,7 @@ Item {
|
||||||
root.appDrawer.close()
|
root.appDrawer.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//END functions
|
//END functions
|
||||||
|
|
||||||
HomeScreenComponents.FlickablePages {
|
HomeScreenComponents.FlickablePages {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import QtQuick 2.15
|
||||||
import QtQuick.Window 2.15
|
import QtQuick.Window 2.15
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
|
import org.kde.taskmanager 0.1 as TaskManager
|
||||||
import org.kde.plasma.plasmoid 2.0
|
import org.kde.plasma.plasmoid 2.0
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
import org.kde.plasma.components 3.0 as PlasmaComponents
|
import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||||
|
|
@ -30,6 +31,12 @@ FocusScope {
|
||||||
HomeScreenComponents.ApplicationListModel.maxFavoriteCount = Math.max(4, Math.floor(Math.min(width, height) / homescreen.homeScreenContents.appletsLayout.cellWidth));
|
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
|
//END functions
|
||||||
|
|
||||||
//BEGIN API implementation
|
//BEGIN API implementation
|
||||||
|
|
@ -38,6 +45,10 @@ FocusScope {
|
||||||
|
|
||||||
property real lastRequestedPosition: 0
|
property real lastRequestedPosition: 0
|
||||||
|
|
||||||
|
function onOpenHomeScreen() {
|
||||||
|
root.triggerHomeScreen();
|
||||||
|
}
|
||||||
|
|
||||||
function onResetHomeScreenPosition() {
|
function onResetHomeScreenPosition() {
|
||||||
homescreen.flickablePages.scrollToPage(0);
|
homescreen.flickablePages.scrollToPage(0);
|
||||||
homescreen.appDrawer.close();
|
homescreen.appDrawer.close();
|
||||||
|
|
@ -55,35 +66,17 @@ FocusScope {
|
||||||
homescreen.appDrawer.offset -= pos.y;
|
homescreen.appDrawer.offset -= pos.y;
|
||||||
lastRequestedPosition = 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: {
|
Plasmoid.onScreenChanged: {
|
||||||
if (plasmoid.screen == 0) {
|
if (plasmoid.screen == 0) {
|
||||||
MobileShell.HomeScreenControls.homeScreen = root
|
MobileShell.HomeScreenControls.taskSwitcher = taskSwitcher;
|
||||||
MobileShell.HomeScreenControls.homeScreenWindow = root.Window.window
|
MobileShell.HomeScreenControls.homeScreenWindow = root.Window.window;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Window.onWindowChanged: {
|
Window.onWindowChanged: {
|
||||||
if (plasmoid.screen == 0) {
|
if (plasmoid.screen == 0) {
|
||||||
MobileShell.HomeScreenControls.homeScreenWindow = root.Window.window
|
MobileShell.HomeScreenControls.homeScreenWindow = root.Window.window;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,7 +94,7 @@ FocusScope {
|
||||||
|
|
||||||
// set API variables
|
// set API variables
|
||||||
if (plasmoid.screen == 0) {
|
if (plasmoid.screen == 0) {
|
||||||
MobileShell.HomeScreenControls.homeScreen = root;
|
MobileShell.HomeScreenControls.taskSwitcher = taskSwitcher;
|
||||||
MobileShell.HomeScreenControls.homeScreenWindow = root.Window.window;
|
MobileShell.HomeScreenControls.homeScreenWindow = root.Window.window;
|
||||||
}
|
}
|
||||||
componentComplete = true;
|
componentComplete = true;
|
||||||
|
|
@ -116,6 +109,7 @@ FocusScope {
|
||||||
homescreen.activate();
|
homescreen.activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// homescreen component
|
||||||
HomeScreen {
|
HomeScreen {
|
||||||
id: homescreen
|
id: homescreen
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
@ -126,5 +120,49 @@ FocusScope {
|
||||||
duration: PlasmaCore.Units.longDuration
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,34 +30,27 @@ PlasmaCore.ColorScope {
|
||||||
|
|
||||||
readonly property bool hasTasks: tasksModel.count > 0
|
readonly property bool hasTasks: tasksModel.count > 0
|
||||||
|
|
||||||
property QtObject taskSwitcher: taskSwitcherLoader.item ? taskSwitcherLoader.item : null
|
property var taskSwitcher: MobileShell.HomeScreenControls.taskSwitcher
|
||||||
|
|
||||||
//BEGIN functions
|
//BEGIN API implementation
|
||||||
function minimizeAll() {
|
|
||||||
for (var i = 0 ; i < tasksModel.count; i++) {
|
Binding {
|
||||||
var idx = tasksModel.makeModelIndex(i);
|
target: MobileShell.TaskPanelControls
|
||||||
if (!tasksModel.data(idx, TaskManager.AbstractTasksModel.IsMinimized)) {
|
property: "isPortrait"
|
||||||
tasksModel.requestToggleMinimized(idx);
|
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() {
|
//END API implementation
|
||||||
for (var i = 0 ; i < tasksModel.count; i++) {
|
|
||||||
var idx = tasksModel.makeModelIndex(i);
|
|
||||||
if (tasksModel.data(idx, TaskManager.AbstractTasksModel.IsMinimized)) {
|
|
||||||
tasksModel.requestToggleMinimized(idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function triggerHomescreen() {
|
|
||||||
root.minimizeAll();
|
|
||||||
MobileShell.HomeScreenControls.resetHomeScreenPosition();
|
|
||||||
MobileShell.HomeScreenControls.showHomeScreen(true);
|
|
||||||
plasmoid.nativeInterface.allMinimizedChanged();
|
|
||||||
}
|
|
||||||
//END functions
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: plasmoid.nativeInterface
|
target: plasmoid.nativeInterface
|
||||||
|
|
@ -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
|
// bottom navigation panel
|
||||||
MobileShell.NavigationPanel {
|
MobileShell.NavigationPanel {
|
||||||
id: panel
|
id: panel
|
||||||
anchors.fill: parent
|
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
|
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 {
|
leftAction: MobileShell.NavigationPanelAction {
|
||||||
enabled: hasTasks
|
enabled: hasTasks || taskSwitcher.visible
|
||||||
iconSource: "mobile-task-switcher"
|
iconSource: "mobile-task-switcher"
|
||||||
iconSizeFactor: 0.75
|
iconSizeFactor: 0.75
|
||||||
|
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
plasmoid.nativeInterface.showDesktop = false;
|
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
|
enabled: true
|
||||||
iconSource: "start-here-kde"
|
iconSource: "start-here-kde"
|
||||||
iconSizeFactor: 1
|
iconSizeFactor: 1
|
||||||
onTriggered: root.triggerHomescreen()
|
onTriggered: {
|
||||||
|
MobileShell.HomeScreenControls.openHomeScreen();
|
||||||
|
plasmoid.nativeInterface.allMinimizedChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rightAction: MobileShell.NavigationPanelAction {
|
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
|
// mobile-close-app (from plasma-frameworks) seems to have less margins than icons from breeze-icons
|
||||||
iconSizeFactor: MobileShell.KWinVirtualKeyboard.visible ? 1 : 0.75
|
iconSizeFactor: MobileShell.KWinVirtualKeyboard.visible ? 1 : 0.75
|
||||||
iconSource: MobileShell.KWinVirtualKeyboard.visible ? "go-down-symbolic" : "mobile-close-app"
|
iconSource: MobileShell.KWinVirtualKeyboard.visible ? "go-down-symbolic" : "mobile-close-app"
|
||||||
|
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (MobileShell.KWinVirtualKeyboard.active) {
|
if (MobileShell.KWinVirtualKeyboard.active) {
|
||||||
|
// close keyboard if it is open
|
||||||
MobileShell.KWinVirtualKeyboard.active = false;
|
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) {
|
} else if (plasmoid.nativeInterface.hasCloseableActiveWindow) {
|
||||||
|
|
||||||
|
// if task switcher is closed, but there is an active window
|
||||||
var index = taskSwitcher.model.activeTask;
|
var index = taskSwitcher.model.activeTask;
|
||||||
if (index) {
|
if (index) {
|
||||||
taskSwitcher.model.requestClose(index);
|
taskSwitcher.model.requestClose(index);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue