mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-06-11 16:57:43 +00:00
Add task panel to Folio drawer
Show running windows in the app drawer with previews, window actions, and virtual desktop controls. Hide dock task icons while the panel is open so the same windows are not duplicated. Use TaskManager to move windows between desktops, and expose desktop activation through the containment.
This commit is contained in:
parent
c469ad49b6
commit
4077292801
7 changed files with 803 additions and 5 deletions
|
|
@ -83,6 +83,7 @@ find_package(KF6 ${KF6_MIN_VERSION} REQUIRED COMPONENTS
|
||||||
find_package(Plasma CONFIG REQUIRED)
|
find_package(Plasma CONFIG REQUIRED)
|
||||||
find_package(PlasmaQuick CONFIG REQUIRED)
|
find_package(PlasmaQuick CONFIG REQUIRED)
|
||||||
find_package(PlasmaActivities CONFIG REQUIRED)
|
find_package(PlasmaActivities CONFIG REQUIRED)
|
||||||
|
find_package(LibTaskManager CONFIG REQUIRED)
|
||||||
find_package(KF6Screen CONFIG REQUIRED)
|
find_package(KF6Screen CONFIG REQUIRED)
|
||||||
find_package(KWayland CONFIG REQUIRED)
|
find_package(KWayland CONFIG REQUIRED)
|
||||||
find_package(KPipeWire ${PROJECT_DEP_VERSION} REQUIRED)
|
find_package(KPipeWire ${PROJECT_DEP_VERSION} REQUIRED)
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ plasma_add_applet(org.kde.plasma.mobile.homescreen.folio
|
||||||
qml/main.qml
|
qml/main.qml
|
||||||
qml/PipeWireThumbnail.qml
|
qml/PipeWireThumbnail.qml
|
||||||
qml/PlaceholderDelegate.qml
|
qml/PlaceholderDelegate.qml
|
||||||
|
qml/RunningAppsPanel.qml
|
||||||
qml/WidgetDragItem.qml
|
qml/WidgetDragItem.qml
|
||||||
qml/config.qml
|
qml/config.qml
|
||||||
CPP_SOURCES
|
CPP_SOURCES
|
||||||
|
|
@ -95,6 +96,7 @@ target_link_libraries(org.kde.plasma.mobile.homescreen.folio PRIVATE
|
||||||
KF6::Service
|
KF6::Service
|
||||||
KF6::KIOGui
|
KF6::KIOGui
|
||||||
KF6::Notifications
|
KF6::Notifications
|
||||||
|
PW::LibTaskManager
|
||||||
Plasma::KWaylandClient
|
Plasma::KWaylandClient
|
||||||
KF6::WindowSystem
|
KF6::WindowSystem
|
||||||
KF6::JobWidgets
|
KF6::JobWidgets
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include "homescreen.h"
|
#include "homescreen.h"
|
||||||
|
|
||||||
|
#include <virtualdesktopinfo.h>
|
||||||
|
|
||||||
#include <KWindowSystem>
|
#include <KWindowSystem>
|
||||||
|
|
||||||
#include <QDBusConnection>
|
#include <QDBusConnection>
|
||||||
|
|
@ -96,4 +98,14 @@ void HomeScreen::triggerOverview() const
|
||||||
QDBusConnection::sessionBus().send(message);
|
QDBusConnection::sessionBus().send(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HomeScreen::activateVirtualDesktop(const QVariant &desktop) const
|
||||||
|
{
|
||||||
|
if (!desktop.isValid() || desktop.toString().isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskManager::VirtualDesktopInfo virtualDesktopInfo;
|
||||||
|
virtualDesktopInfo.requestActivate(desktop);
|
||||||
|
}
|
||||||
|
|
||||||
#include "homescreen.moc"
|
#include "homescreen.moc"
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <Plasma/Containment>
|
#include <Plasma/Containment>
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
#include "applicationlistmodel.h"
|
#include "applicationlistmodel.h"
|
||||||
#include "delegatetoucharea.h"
|
#include "delegatetoucharea.h"
|
||||||
|
|
@ -49,6 +50,7 @@ public:
|
||||||
void configChanged() override;
|
void configChanged() override;
|
||||||
|
|
||||||
Q_INVOKABLE void triggerOverview() const;
|
Q_INVOKABLE void triggerOverview() const;
|
||||||
|
Q_INVOKABLE void activateVirtualDesktop(const QVariant &desktop) const;
|
||||||
|
|
||||||
FolioSettings *folioSettings();
|
FolioSettings *folioSettings();
|
||||||
HomeScreenState *homeScreenState();
|
HomeScreenState *homeScreenState();
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,14 @@ MouseArea {
|
||||||
property MobileShell.MaskManager maskManager
|
property MobileShell.MaskManager maskManager
|
||||||
|
|
||||||
property var homeScreen
|
property var homeScreen
|
||||||
|
property bool suppressRunningTasks: false
|
||||||
|
|
||||||
signal delegateDragRequested(var item)
|
signal delegateDragRequested(var item)
|
||||||
|
|
||||||
// Convergence mode: show running apps alongside favourites
|
// Convergence mode: show running apps alongside favourites
|
||||||
readonly property bool convergenceMode: ShellSettings.Settings.convergenceModeEnabled
|
readonly property bool convergenceMode: ShellSettings.Settings.convergenceModeEnabled
|
||||||
readonly property int totalItemCount: repeater.count + (convergenceMode ? taskRepeater.count : 0)
|
readonly property bool showRunningTasks: convergenceMode && !suppressRunningTasks
|
||||||
|
readonly property int totalItemCount: repeater.count + (showRunningTasks ? taskRepeater.count : 0)
|
||||||
|
|
||||||
// In convergence mode, size icons to fit the dock bar instead of using page grid cells
|
// In convergence mode, size icons to fit the dock bar instead of using page grid cells
|
||||||
readonly property real dockCellWidth: convergenceMode ? root.height : folio.HomeScreenState.pageCellWidth
|
readonly property real dockCellWidth: convergenceMode ? root.height : folio.HomeScreenState.pageCellWidth
|
||||||
|
|
@ -59,7 +61,7 @@ MouseArea {
|
||||||
: root.width / 2
|
: root.width / 2
|
||||||
|
|
||||||
// Visible spacer between pinned favourites and running tasks
|
// Visible spacer between pinned favourites and running tasks
|
||||||
readonly property bool showSpacer: convergenceMode && repeater.count > 0 && taskRepeater.count > 0
|
readonly property bool showSpacer: showRunningTasks && repeater.count > 0 && taskRepeater.count > 0
|
||||||
property real spacerWidth: showSpacer ? Kirigami.Units.largeSpacing * 2 : 0
|
property real spacerWidth: showSpacer ? Kirigami.Units.largeSpacing * 2 : 0
|
||||||
Behavior on spacerWidth {
|
Behavior on spacerWidth {
|
||||||
NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutQuad }
|
NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutQuad }
|
||||||
|
|
@ -936,7 +938,7 @@ MouseArea {
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: taskRepeater
|
id: taskRepeater
|
||||||
model: root.convergenceMode ? tasksModel : null
|
model: root.showRunningTasks ? tasksModel : null
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
id: taskDelegate
|
id: taskDelegate
|
||||||
|
|
|
||||||
762
containments/homescreens/folio/qml/RunningAppsPanel.qml
Normal file
762
containments/homescreens/folio/qml/RunningAppsPanel.qml
Normal file
|
|
@ -0,0 +1,762 @@
|
||||||
|
// SPDX-FileCopyrightText: 2026 Marco Allegretti
|
||||||
|
// SPDX-License-Identifier: EUPL-1.2
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import org.kde.kirigami as Kirigami
|
||||||
|
import org.kde.plasma.components 3.0 as PC3
|
||||||
|
import org.kde.taskmanager as TaskManager
|
||||||
|
|
||||||
|
import plasma.applet.org.kde.plasma.mobile.homescreen.folio as Folio
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property var folio
|
||||||
|
|
||||||
|
readonly property bool hasTasks: allTasksModel.count > 0
|
||||||
|
property bool sortByName: false
|
||||||
|
property int dragTargetDesktopIndex: -1
|
||||||
|
property string pendingMoveTaskKey: ""
|
||||||
|
property string pendingMoveTargetName: ""
|
||||||
|
|
||||||
|
signal taskActivated()
|
||||||
|
|
||||||
|
function taskStorageId(taskModel) {
|
||||||
|
var id = taskModel ? taskModel.AppId || "" : ""
|
||||||
|
if (id && !id.endsWith(".desktop")) {
|
||||||
|
id += ".desktop"
|
||||||
|
}
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
function taskKey(taskModel) {
|
||||||
|
const winIds = taskModel && taskModel.WinIdList ? taskModel.WinIdList : []
|
||||||
|
if (winIds.length > 0) {
|
||||||
|
var key = ""
|
||||||
|
for (var i = 0; i < winIds.length; ++i) {
|
||||||
|
key += String(winIds[i]) + "|"
|
||||||
|
}
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
|
||||||
|
return String(taskModel ? taskModel.AppId || "" : "") + "|" + String(taskModel ? taskModel.display || "" : "")
|
||||||
|
}
|
||||||
|
|
||||||
|
function markTaskMove(taskKey, desktopIndex) {
|
||||||
|
pendingMoveTaskKey = taskKey
|
||||||
|
pendingMoveTargetName = desktopName(desktopIndex)
|
||||||
|
pendingMoveResetTimer.restart()
|
||||||
|
}
|
||||||
|
|
||||||
|
function mixColor(base, overlay, ratio) {
|
||||||
|
return Qt.rgba(
|
||||||
|
base.r + (overlay.r - base.r) * ratio,
|
||||||
|
base.g + (overlay.g - base.g) * ratio,
|
||||||
|
base.b + (overlay.b - base.b) * ratio,
|
||||||
|
base.a + (overlay.a - base.a) * ratio)
|
||||||
|
}
|
||||||
|
|
||||||
|
function desktopName(index) {
|
||||||
|
const names = virtualDesktopInfo.desktopNames
|
||||||
|
if (names && names.length > index && String(names[index]).length > 0) {
|
||||||
|
return String(names[index])
|
||||||
|
}
|
||||||
|
return "Desktop " + (index + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isCurrentDesktop(desktopId) {
|
||||||
|
return String(desktopId) === String(virtualDesktopInfo.currentDesktop)
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: pendingMoveResetTimer
|
||||||
|
interval: 1200
|
||||||
|
onTriggered: {
|
||||||
|
root.pendingMoveTaskKey = ""
|
||||||
|
root.pendingMoveTargetName = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component PanelIconButton: MouseArea {
|
||||||
|
id: button
|
||||||
|
|
||||||
|
property string iconName
|
||||||
|
property string toolTipText
|
||||||
|
property bool checked: false
|
||||||
|
|
||||||
|
signal triggered()
|
||||||
|
|
||||||
|
width: Kirigami.Units.iconSizes.smallMedium + Kirigami.Units.smallSpacing * 2
|
||||||
|
height: width
|
||||||
|
hoverEnabled: enabled
|
||||||
|
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
|
opacity: enabled ? 1 : 0.35
|
||||||
|
|
||||||
|
onClicked: button.triggered()
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Kirigami.Units.cornerRadius
|
||||||
|
color: button.containsPress
|
||||||
|
? root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.16)
|
||||||
|
: button.checked
|
||||||
|
? root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, button.containsMouse ? 0.22 : 0.16)
|
||||||
|
: button.containsMouse
|
||||||
|
? root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.08)
|
||||||
|
: "transparent"
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Kirigami.Icon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: Kirigami.Units.iconSizes.small
|
||||||
|
height: width
|
||||||
|
source: button.iconName
|
||||||
|
active: button.containsMouse || button.checked
|
||||||
|
}
|
||||||
|
|
||||||
|
PC3.ToolTip {
|
||||||
|
text: button.toolTipText
|
||||||
|
visible: button.containsMouse && button.toolTipText.length > 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskManager.VirtualDesktopInfo { id: virtualDesktopInfo }
|
||||||
|
TaskManager.ActivityInfo { id: activityInfo }
|
||||||
|
|
||||||
|
TaskManager.TasksModel {
|
||||||
|
id: allTasksModel
|
||||||
|
filterByVirtualDesktop: false
|
||||||
|
filterByActivity: true
|
||||||
|
filterNotMaximized: false
|
||||||
|
filterByScreen: true
|
||||||
|
filterHidden: false
|
||||||
|
activity: activityInfo.currentActivity
|
||||||
|
groupMode: TaskManager.TasksModel.GroupApplications
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskManager.TasksModel {
|
||||||
|
id: tasksModel
|
||||||
|
filterByVirtualDesktop: true
|
||||||
|
filterByActivity: true
|
||||||
|
filterNotMaximized: false
|
||||||
|
filterByScreen: true
|
||||||
|
filterHidden: false
|
||||||
|
virtualDesktop: virtualDesktopInfo.currentDesktop
|
||||||
|
activity: activityInfo.currentActivity
|
||||||
|
groupMode: TaskManager.TasksModel.GroupApplications
|
||||||
|
sortMode: root.sortByName ? TaskManager.TasksModel.SortAlpha : TaskManager.TasksModel.SortLastActivated
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: panelShadow
|
||||||
|
anchors.fill: panelBackground
|
||||||
|
anchors.topMargin: 2
|
||||||
|
radius: panelBackground.radius
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.35)
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: panelBackground
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Kirigami.Units.cornerRadius
|
||||||
|
color: Kirigami.Theme.backgroundColor
|
||||||
|
border.width: 1
|
||||||
|
border.pixelAligned: false
|
||||||
|
border.color: root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.14)
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Kirigami.Units.smallSpacing
|
||||||
|
spacing: Kirigami.Units.smallSpacing
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: Kirigami.Units.smallSpacing
|
||||||
|
|
||||||
|
PC3.Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: i18n("Running")
|
||||||
|
font.weight: Font.Medium
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 1
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: [
|
||||||
|
{ label: i18n("Recent"), byName: false },
|
||||||
|
{ label: i18n("Name"), byName: true }
|
||||||
|
]
|
||||||
|
|
||||||
|
delegate: MouseArea {
|
||||||
|
id: sortButton
|
||||||
|
|
||||||
|
required property var modelData
|
||||||
|
readonly property bool checked: root.sortByName === modelData.byName
|
||||||
|
|
||||||
|
width: Math.max(Kirigami.Units.gridUnit * 3.5, label.implicitWidth + Kirigami.Units.smallSpacing * 3)
|
||||||
|
height: Kirigami.Units.gridUnit * 1.6
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: root.sortByName = modelData.byName
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Kirigami.Units.cornerRadius
|
||||||
|
color: sortButton.checked
|
||||||
|
? root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, sortButton.containsMouse ? 0.28 : 0.2)
|
||||||
|
: sortButton.containsMouse
|
||||||
|
? root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.08)
|
||||||
|
: "transparent"
|
||||||
|
}
|
||||||
|
|
||||||
|
PC3.Label {
|
||||||
|
id: label
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: sortButton.modelData.label
|
||||||
|
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.85
|
||||||
|
color: sortButton.checked ? Kirigami.Theme.highlightColor : Kirigami.Theme.textColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: desktopStrip
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
visible: virtualDesktopInfo.numberOfDesktops > 1
|
||||||
|
spacing: Kirigami.Units.smallSpacing
|
||||||
|
|
||||||
|
PC3.Label {
|
||||||
|
text: i18n("Desktops")
|
||||||
|
opacity: 0.7
|
||||||
|
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.85
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: desktopDropSurface
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: Kirigami.Units.gridUnit * 2.4
|
||||||
|
|
||||||
|
function desktopIndexAt(x) {
|
||||||
|
if (virtualDesktopInfo.numberOfDesktops <= 0) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
const localX = desktopRow.mapFromItem(desktopDropSurface, x, 0).x
|
||||||
|
var nearestIndex = -1
|
||||||
|
var nearestDistance = Number.MAX_VALUE
|
||||||
|
for (var i = 0; i < virtualDesktopInfo.numberOfDesktops; ++i) {
|
||||||
|
const item = desktopRepeater.itemAt(i)
|
||||||
|
if (!item) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localX >= item.x && localX <= item.x + item.width) {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
const center = item.x + item.width / 2
|
||||||
|
const distance = Math.abs(localX - center)
|
||||||
|
if (distance < nearestDistance) {
|
||||||
|
nearestIndex = i
|
||||||
|
nearestDistance = distance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nearestIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: desktopRow
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: Kirigami.Units.smallSpacing
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: desktopRepeater
|
||||||
|
|
||||||
|
model: virtualDesktopInfo.desktopIds
|
||||||
|
|
||||||
|
delegate: MouseArea {
|
||||||
|
id: desktopButton
|
||||||
|
|
||||||
|
required property int index
|
||||||
|
required property var modelData
|
||||||
|
|
||||||
|
readonly property bool checked: root.isCurrentDesktop(modelData)
|
||||||
|
readonly property string desktopLabel: root.desktopName(index)
|
||||||
|
readonly property bool dragHovered: desktopDropArea.containsDrag && root.dragTargetDesktopIndex === index
|
||||||
|
|
||||||
|
width: Math.max(Kirigami.Units.gridUnit * 5.5, (desktopRow.width / Math.max(1, virtualDesktopInfo.numberOfDesktops)) - Kirigami.Units.smallSpacing)
|
||||||
|
height: desktopRow.height
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
|
onClicked: root.folio.activateVirtualDesktop(modelData)
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Kirigami.Units.cornerRadius
|
||||||
|
scale: desktopButton.dragHovered ? 1.03 : 1
|
||||||
|
color: desktopButton.checked
|
||||||
|
? root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, desktopButton.containsMouse || desktopButton.dragHovered ? 0.32 : 0.24)
|
||||||
|
: desktopButton.dragHovered
|
||||||
|
? root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.18)
|
||||||
|
: desktopButton.containsMouse
|
||||||
|
? root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.08)
|
||||||
|
: root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.045)
|
||||||
|
border.width: 1
|
||||||
|
border.pixelAligned: false
|
||||||
|
border.color: desktopButton.checked || desktopButton.dragHovered
|
||||||
|
? root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.55)
|
||||||
|
: root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.14)
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.margins: Kirigami.Units.smallSpacing / 2
|
||||||
|
height: Math.max(2, Math.round(Kirigami.Units.devicePixelRatio))
|
||||||
|
radius: height / 2
|
||||||
|
visible: desktopButton.checked
|
||||||
|
color: Kirigami.Theme.highlightColor
|
||||||
|
}
|
||||||
|
|
||||||
|
PC3.Label {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: parent.width - Kirigami.Units.smallSpacing * 2
|
||||||
|
text: desktopButton.desktopLabel
|
||||||
|
elide: Text.ElideRight
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
font.weight: desktopButton.checked || desktopButton.dragHovered ? Font.Medium : Font.Normal
|
||||||
|
font.pixelSize: Math.min(Kirigami.Theme.defaultFont.pixelSize, parent.height * 0.42)
|
||||||
|
color: desktopButton.checked || desktopButton.dragHovered ? Kirigami.Theme.highlightColor : Kirigami.Theme.textColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DropArea {
|
||||||
|
id: desktopDropArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
keys: ["folio-running-task"]
|
||||||
|
|
||||||
|
onEntered: (drag) => {
|
||||||
|
root.dragTargetDesktopIndex = desktopDropSurface.desktopIndexAt(drag.x)
|
||||||
|
drag.accept(Qt.MoveAction)
|
||||||
|
}
|
||||||
|
onPositionChanged: (drag) => {
|
||||||
|
root.dragTargetDesktopIndex = desktopDropSurface.desktopIndexAt(drag.x)
|
||||||
|
drag.accept(Qt.MoveAction)
|
||||||
|
}
|
||||||
|
onExited: root.dragTargetDesktopIndex = -1
|
||||||
|
onDropped: (drop) => {
|
||||||
|
const desktopIndex = desktopDropSurface.desktopIndexAt(drop.x)
|
||||||
|
const desktopId = desktopIndex >= 0 ? virtualDesktopInfo.desktopIds[desktopIndex] : ""
|
||||||
|
if (!drop.source || !drop.source.moveToDesktop || String(desktopId).length === 0) {
|
||||||
|
root.dragTargetDesktopIndex = -1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
drop.source.moveToDesktop(desktopId, desktopIndex)
|
||||||
|
root.dragTargetDesktopIndex = -1
|
||||||
|
drop.accept(Qt.MoveAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridView {
|
||||||
|
id: taskGrid
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
clip: true
|
||||||
|
model: tasksModel
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
interactive: contentHeight > height
|
||||||
|
|
||||||
|
readonly property int columns: Math.max(1, Math.floor(width / (Kirigami.Units.gridUnit * 14)))
|
||||||
|
cellWidth: Math.floor(width / columns)
|
||||||
|
cellHeight: Kirigami.Units.gridUnit * 10
|
||||||
|
|
||||||
|
delegate: Item {
|
||||||
|
id: taskCard
|
||||||
|
|
||||||
|
required property int index
|
||||||
|
required property var model
|
||||||
|
|
||||||
|
width: taskGrid.cellWidth - Kirigami.Units.smallSpacing
|
||||||
|
height: taskGrid.cellHeight - Kirigami.Units.smallSpacing
|
||||||
|
|
||||||
|
readonly property var modelIndex: tasksModel.makeModelIndex(index)
|
||||||
|
readonly property var winIds: model.WinIdList ? model.WinIdList : []
|
||||||
|
readonly property int previewCount: Math.max(1, Math.min(2, winIds.length))
|
||||||
|
readonly property bool activeTask: model.IsActive === true
|
||||||
|
readonly property bool minimizedTask: model.IsMinimized === true
|
||||||
|
readonly property bool maximizedTask: model.IsMaximized === true
|
||||||
|
readonly property bool groupTask: model.IsGroupParent === true
|
||||||
|
readonly property bool desktopsChangeable: model.IsVirtualDesktopsChangeable === true
|
||||||
|
readonly property string storageId: root.taskStorageId(model)
|
||||||
|
readonly property string taskKey: root.taskKey(model)
|
||||||
|
readonly property bool pinned: storageId !== "" && root.folio.FavouritesModel.containsApplication(storageId)
|
||||||
|
readonly property bool pendingMove: root.pendingMoveTaskKey === taskKey
|
||||||
|
|
||||||
|
function taskIndexForPreview(previewIndex) {
|
||||||
|
return taskCard.groupTask
|
||||||
|
? tasksModel.makeModelIndex(taskCard.index, previewIndex)
|
||||||
|
: taskCard.modelIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
function titleForPreview(previewIndex) {
|
||||||
|
if (!taskCard.groupTask) {
|
||||||
|
return taskCard.model.display || ""
|
||||||
|
}
|
||||||
|
return tasksModel.data(tasksModel.makeModelIndex(taskCard.index, previewIndex), 0) || taskCard.model.display || ""
|
||||||
|
}
|
||||||
|
|
||||||
|
function activate(previewIndex) {
|
||||||
|
tasksModel.requestActivate(taskIndexForPreview(previewIndex || 0))
|
||||||
|
root.taskActivated()
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveToDesktop(desktopId, desktopIndex) {
|
||||||
|
if (!taskCard.desktopsChangeable || String(desktopId).length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
root.markTaskMove(taskCard.taskKey, desktopIndex)
|
||||||
|
tasksModel.requestVirtualDesktops(taskCard.modelIndex, [desktopId])
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: dragProxy
|
||||||
|
|
||||||
|
parent: root
|
||||||
|
width: taskCard.width
|
||||||
|
height: taskCard.height
|
||||||
|
z: 1000
|
||||||
|
visible: cardArea.drag.active
|
||||||
|
opacity: 0.9
|
||||||
|
|
||||||
|
Drag.active: cardArea.drag.active
|
||||||
|
Drag.hotSpot.x: cardArea.pressX
|
||||||
|
Drag.hotSpot.y: cardArea.pressY
|
||||||
|
Drag.keys: ["folio-running-task"]
|
||||||
|
Drag.proposedAction: Qt.MoveAction
|
||||||
|
Drag.source: taskCard
|
||||||
|
Drag.supportedActions: Qt.MoveAction
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Kirigami.Units.cornerRadius
|
||||||
|
color: root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.2)
|
||||||
|
border.width: 1
|
||||||
|
border.pixelAligned: false
|
||||||
|
border.color: root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.6)
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Kirigami.Units.smallSpacing
|
||||||
|
spacing: Kirigami.Units.smallSpacing
|
||||||
|
|
||||||
|
Kirigami.Icon {
|
||||||
|
Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium
|
||||||
|
Layout.preferredHeight: Layout.preferredWidth
|
||||||
|
source: taskCard.model.decoration
|
||||||
|
}
|
||||||
|
|
||||||
|
PC3.Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: taskCard.model.display || ""
|
||||||
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: cardArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: taskCard.desktopsChangeable ? Qt.OpenHandCursor : Qt.PointingHandCursor
|
||||||
|
enabled: !taskCard.pendingMove
|
||||||
|
property real pressX: width / 2
|
||||||
|
property real pressY: height / 2
|
||||||
|
property bool wasDragged: false
|
||||||
|
drag.target: taskCard.desktopsChangeable ? dragProxy : undefined
|
||||||
|
drag.threshold: Math.max(4, Kirigami.Units.smallSpacing)
|
||||||
|
drag.smoothed: false
|
||||||
|
|
||||||
|
onPressed: (mouse) => {
|
||||||
|
wasDragged = false
|
||||||
|
pressX = mouse.x
|
||||||
|
pressY = mouse.y
|
||||||
|
const pos = taskCard.mapToItem(root, 0, 0)
|
||||||
|
dragProxy.x = pos.x
|
||||||
|
dragProxy.y = pos.y
|
||||||
|
}
|
||||||
|
|
||||||
|
onPositionChanged: {
|
||||||
|
if (drag.active) {
|
||||||
|
wasDragged = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onReleased: {
|
||||||
|
if (wasDragged) {
|
||||||
|
dragProxy.Drag.drop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (!wasDragged) {
|
||||||
|
taskCard.activate(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Kirigami.Units.cornerRadius
|
||||||
|
color: taskCard.activeTask
|
||||||
|
? root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, cardArea.containsMouse ? 0.18 : 0.12)
|
||||||
|
: cardArea.containsMouse
|
||||||
|
? root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.08)
|
||||||
|
: root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.04)
|
||||||
|
border.width: 1
|
||||||
|
border.pixelAligned: false
|
||||||
|
border.color: taskCard.activeTask
|
||||||
|
? root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.5)
|
||||||
|
: root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.12)
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Kirigami.Units.smallSpacing
|
||||||
|
spacing: Kirigami.Units.smallSpacing
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: previewRow
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: Kirigami.Units.gridUnit * 5
|
||||||
|
spacing: Kirigami.Units.smallSpacing
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: taskCard.previewCount
|
||||||
|
|
||||||
|
delegate: MouseArea {
|
||||||
|
id: previewArea
|
||||||
|
|
||||||
|
required property int index
|
||||||
|
readonly property string childUuid: taskCard.winIds.length > index ? taskCard.winIds[index] : ""
|
||||||
|
|
||||||
|
width: (previewRow.width - previewRow.spacing * (taskCard.previewCount - 1)) / taskCard.previewCount
|
||||||
|
height: previewRow.height
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: taskCard.activate(index)
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Kirigami.Units.cornerRadius
|
||||||
|
color: root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, previewArea.containsMouse ? 0.1 : 0.06)
|
||||||
|
border.width: 1
|
||||||
|
border.pixelAligned: false
|
||||||
|
border.color: root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.14)
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: thumbnailLoader
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 1
|
||||||
|
active: previewArea.childUuid !== "" && root.visible
|
||||||
|
sourceComponent: PipeWireThumbnail {
|
||||||
|
windowUuid: previewArea.childUuid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Kirigami.Icon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: Kirigami.Units.iconSizes.large
|
||||||
|
height: width
|
||||||
|
source: taskCard.model.decoration
|
||||||
|
visible: !thumbnailLoader.item || !thumbnailLoader.item.hasThumbnail
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
height: titleLabel.implicitHeight + Kirigami.Units.smallSpacing
|
||||||
|
radius: Kirigami.Units.cornerRadius
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.48)
|
||||||
|
visible: taskCard.previewCount > 1
|
||||||
|
|
||||||
|
PC3.Label {
|
||||||
|
id: titleLabel
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.margins: Kirigami.Units.smallSpacing
|
||||||
|
text: taskCard.titleForPreview(previewArea.index)
|
||||||
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
|
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.75
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: Kirigami.Units.smallSpacing
|
||||||
|
|
||||||
|
Kirigami.Icon {
|
||||||
|
Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium
|
||||||
|
Layout.preferredHeight: Layout.preferredWidth
|
||||||
|
source: taskCard.model.decoration
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
PC3.Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: taskCard.model.display || ""
|
||||||
|
font.weight: taskCard.activeTask ? Font.Medium : Font.Normal
|
||||||
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: Kirigami.Units.smallSpacing
|
||||||
|
|
||||||
|
PC3.Label {
|
||||||
|
text: taskCard.activeTask ? i18n("Active") : taskCard.minimizedTask ? i18n("Minimized") : i18n("Open")
|
||||||
|
opacity: 0.65
|
||||||
|
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.75
|
||||||
|
}
|
||||||
|
|
||||||
|
PC3.Label {
|
||||||
|
visible: taskCard.maximizedTask
|
||||||
|
text: i18n("Maximized")
|
||||||
|
opacity: 0.65
|
||||||
|
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.75
|
||||||
|
}
|
||||||
|
|
||||||
|
PC3.Label {
|
||||||
|
visible: taskCard.winIds.length > 1
|
||||||
|
text: i18np("%1 window", "%1 windows", taskCard.winIds.length)
|
||||||
|
opacity: 0.65
|
||||||
|
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.75
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: Kirigami.Units.smallSpacing
|
||||||
|
|
||||||
|
Item { Layout.fillWidth: true }
|
||||||
|
|
||||||
|
PanelIconButton {
|
||||||
|
iconName: taskCard.pinned ? "emblem-favorite" : "window-pin"
|
||||||
|
toolTipText: taskCard.pinned ? i18n("Pinned") : i18n("Pin to Dock")
|
||||||
|
checked: taskCard.pinned
|
||||||
|
enabled: taskCard.storageId !== "" && !taskCard.pinned && !root.folio.FolioSettings.lockLayout
|
||||||
|
onTriggered: root.folio.FavouritesModel.addApplication(taskCard.storageId)
|
||||||
|
}
|
||||||
|
|
||||||
|
PanelIconButton {
|
||||||
|
iconName: taskCard.minimizedTask ? "window-restore" : "window-minimize"
|
||||||
|
toolTipText: taskCard.minimizedTask ? i18n("Restore") : i18n("Minimize")
|
||||||
|
onTriggered: tasksModel.requestToggleMinimized(taskCard.modelIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
PanelIconButton {
|
||||||
|
iconName: taskCard.maximizedTask ? "window-restore" : "window-maximize"
|
||||||
|
toolTipText: taskCard.maximizedTask ? i18n("Restore") : i18n("Maximize")
|
||||||
|
enabled: !taskCard.groupTask
|
||||||
|
onTriggered: tasksModel.requestToggleMaximized(taskCard.modelIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
PanelIconButton {
|
||||||
|
iconName: "window-close"
|
||||||
|
toolTipText: taskCard.winIds.length > 1 ? i18n("Close All") : i18n("Close")
|
||||||
|
onTriggered: tasksModel.requestClose(taskCard.modelIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Kirigami.Units.cornerRadius
|
||||||
|
visible: taskCard.pendingMove
|
||||||
|
color: root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.18)
|
||||||
|
border.width: 1
|
||||||
|
border.pixelAligned: false
|
||||||
|
border.color: root.mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.55)
|
||||||
|
|
||||||
|
PC3.Label {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: parent.width - Kirigami.Units.gridUnit
|
||||||
|
text: i18n("Moving to %1", root.pendingMoveTargetName)
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Kirigami.Theme.highlightColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PC3.ScrollBar.vertical: PC3.ScrollBar {
|
||||||
|
interactive: true
|
||||||
|
enabled: taskGrid.contentHeight > taskGrid.height
|
||||||
|
implicitWidth: Kirigami.Units.smallSpacing
|
||||||
|
}
|
||||||
|
|
||||||
|
PC3.Label {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: parent.width - Kirigami.Units.gridUnit * 2
|
||||||
|
visible: taskGrid.count === 0
|
||||||
|
text: i18n("No windows on this desktop")
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
opacity: 0.65
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -32,7 +32,7 @@ import "./private"
|
||||||
|
|
||||||
ContainmentItem {
|
ContainmentItem {
|
||||||
id: root
|
id: root
|
||||||
property Folio.HomeScreen folio: root.plasmoid
|
property var folio: root.plasmoid
|
||||||
|
|
||||||
// Tracks whether the Game Center grid is visible within gaming mode.
|
// Tracks whether the Game Center grid is visible within gaming mode.
|
||||||
// If gaming mode is already enabled at startup, open it immediately so
|
// If gaming mode is already enabled at startup, open it immediately so
|
||||||
|
|
@ -365,6 +365,7 @@ ContainmentItem {
|
||||||
folio: root.folio
|
folio: root.folio
|
||||||
maskManager: root.maskManager
|
maskManager: root.maskManager
|
||||||
homeScreen: folioHomeScreen
|
homeScreen: folioHomeScreen
|
||||||
|
suppressRunningTasks: runningAppsPanel.visible
|
||||||
transform: Translate { y: dockOverlay.dockOffset }
|
transform: Translate { y: dockOverlay.dockOffset }
|
||||||
// Dock is an opaque panel — use Window colorset so all content
|
// Dock is an opaque panel — use Window colorset so all content
|
||||||
// (labels, hover highlights, icon tints) follows the system theme
|
// (labels, hover highlights, icon tints) follows the system theme
|
||||||
|
|
@ -519,7 +520,9 @@ ContainmentItem {
|
||||||
|
|
||||||
width: tileSize
|
width: tileSize
|
||||||
height: overlayDrawer.popupHeight
|
height: overlayDrawer.popupHeight
|
||||||
x: categoryPanel.x + categoryPanel.width + Kirigami.Units.smallSpacing
|
x: runningAppsPanel.visible
|
||||||
|
? runningAppsPanel.x + runningAppsPanel.width + Kirigami.Units.smallSpacing
|
||||||
|
: categoryPanel.x + categoryPanel.width + Kirigami.Units.smallSpacing
|
||||||
y: overlayDrawer.y
|
y: overlayDrawer.y
|
||||||
opacity: overlayDrawer.opacity
|
opacity: overlayDrawer.opacity
|
||||||
radius: Kirigami.Units.cornerRadius
|
radius: Kirigami.Units.cornerRadius
|
||||||
|
|
@ -739,6 +742,20 @@ ContainmentItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RunningAppsPanel {
|
||||||
|
id: runningAppsPanel
|
||||||
|
folio: root.folio
|
||||||
|
|
||||||
|
x: categoryPanel.x + categoryPanel.width + Kirigami.Units.smallSpacing
|
||||||
|
y: overlayDrawer.y
|
||||||
|
width: Math.max(0, parent.width - x - powerPanel.width - Kirigami.Units.smallSpacing * 2)
|
||||||
|
height: overlayDrawer.popupHeight
|
||||||
|
opacity: overlayDrawer.opacity
|
||||||
|
visible: hasTasks && opacity > 0
|
||||||
|
|
||||||
|
onTaskActivated: folio.HomeScreenState.closeAppDrawer()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game Center overlay — full-screen grid of games shown when gaming mode
|
// Game Center overlay — full-screen grid of games shown when gaming mode
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue