Add desktop switcher and task context menus

Show numbered desktop indicator buttons between the nav buttons and
the keyboard toggle corner button. Each button highlights the current
desktop and switches on click via VirtualDesktopInfo.requestActivate.
Only visible in convergence mode when multiple desktops exist.

Add Minimize and Maximize/Restore actions to the task strip
right-click context menu alongside the existing Close action.
This commit is contained in:
Marco Allegretti 2026-04-08 20:12:38 +02:00
parent 32a9b04864
commit 00a9ac1c4d
2 changed files with 66 additions and 0 deletions

View file

@ -38,6 +38,7 @@ Item {
// Convergence mode: show running-app task strip
property bool convergenceMode: false
property var taskModel: null
property var virtualDesktopInfo: null
// drop shadow for icons
MultiEffect {
@ -175,6 +176,17 @@ Item {
Controls.Menu {
id: taskContextMenu
Controls.MenuItem {
text: taskDelegate.model.IsMinimized ? i18n("Restore") : i18n("Minimize")
icon.name: taskDelegate.model.IsMinimized ? "window-restore" : "window-minimize"
onTriggered: root.taskModel.requestToggleMinimized(root.taskModel.makeModelIndex(taskDelegate.index))
}
Controls.MenuItem {
text: taskDelegate.model.IsMaximized ? i18n("Restore") : i18n("Maximize")
icon.name: taskDelegate.model.IsMaximized ? "window-restore" : "window-maximize"
onTriggered: root.taskModel.requestToggleMaximized(root.taskModel.makeModelIndex(taskDelegate.index))
}
Controls.MenuSeparator {}
Controls.MenuItem {
text: i18n("Close")
icon.name: "window-close"
@ -195,6 +207,43 @@ Item {
}
}
}
// Virtual desktop switcher (convergence mode, multiple desktops)
Row {
id: workspaceIndicator
visible: root.convergenceMode && root.virtualDesktopInfo !== null && root.virtualDesktopInfo.numberOfDesktops > 1
spacing: Kirigami.Units.smallSpacing / 2
Repeater {
model: root.virtualDesktopInfo ? root.virtualDesktopInfo.desktopIds : []
delegate: Rectangle {
required property int index
required property var modelData
width: Kirigami.Units.gridUnit * 1.5
height: width
radius: Kirigami.Units.smallSpacing
color: modelData === root.virtualDesktopInfo.currentDesktop
? Kirigami.Theme.highlightColor
: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.2)
Text {
anchors.centerIn: parent
text: index + 1
color: parent.modelData === root.virtualDesktopInfo.currentDesktop
? Kirigami.Theme.highlightedTextColor
: Kirigami.Theme.textColor
font.pixelSize: parent.height * 0.6
}
MouseArea {
anchors.fill: parent
onClicked: root.virtualDesktopInfo.requestActivate(parent.modelData)
}
}
}
}
}
states: [
@ -277,6 +326,14 @@ Item {
// Fill space between leftCorner (bottom) and the nav button group
height: taskStrip.visible ? (leftButton.y - leftCornerButton.y - leftCornerButton.height - Kirigami.Units.smallSpacing * 2) : 0
}
// Workspace indicator: vertical above rightCornerButton (top)
AnchorChanges {
target: workspaceIndicator
anchors {
horizontalCenter: parent.horizontalCenter
top: rightCornerButton.bottom
}
}
}, State {
name: "horizontal"
when: !root.isVertical
@ -354,6 +411,14 @@ Item {
target: taskStrip
height: parent.height
}
// Workspace indicator: horizontal between rightButton and rightCornerButton
AnchorChanges {
target: workspaceIndicator
anchors {
verticalCenter: parent.verticalCenter
left: rightButton.right
}
}
}
]
}

View file

@ -38,6 +38,7 @@ MobileShell.NavigationPanel {
// Convergence mode: expose running-app task strip
convergenceMode: ShellSettings.Settings.convergenceModeEnabled
taskModel: tasksModel
virtualDesktopInfo: virtualDesktopInfo
MobileShellState.PanelSettingsDBusClient {
id: panelSettings