Add Peek at Desktop to the convergence dock

Place a desktop toggle next to Home in the convergence dock and
shift the pager and task focus flow around it. This brings the
upstream show-desktop affordance into SHIFT without adding a new
panel surface.
This commit is contained in:
Marco Allegretti 2026-05-09 10:46:32 +02:00
parent c23d756596
commit 76da62dae9

View file

@ -13,6 +13,7 @@ import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
import org.kde.taskmanager as TaskManager
import plasma.applet.org.kde.plasma.mobile.homescreen.folio as Folio
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.windowplugin as WindowPlugin
import org.kde.kirigami as Kirigami
import QtQuick.Controls as Controls
import QtQuick.Templates as T
@ -93,14 +94,16 @@ MouseArea {
property real pagerButtonWidth: showPager ? Math.min(root.height, Kirigami.Units.gridUnit * 2.5) : 0
readonly property int pagerLeftCount: showPager ? Math.ceil(virtualDesktopInfo.numberOfDesktops / 2) : 0
readonly property int pagerRightCount: showPager ? virtualDesktopInfo.numberOfDesktops - pagerLeftCount : 0
property real desktopButtonWidth: convergenceMode ? root.height : 0
property real trashButtonWidth: convergenceMode ? root.height : 0
property real searchButtonWidth: convergenceMode ? root.height : 0
readonly property real leftControlsWidth: convergenceMode ? navButtonWidth + pagerLeftCount * pagerButtonWidth : 0
readonly property real leftControlsWidth: convergenceMode ? navButtonWidth + desktopButtonWidth + pagerLeftCount * pagerButtonWidth : 0
readonly property real rightControlsWidth: convergenceMode ? navButtonWidth + searchButtonWidth + trashButtonWidth + pagerRightCount * pagerButtonWidth : 0
readonly property real dockCenterX: convergenceMode
? leftControlsWidth + (root.width - leftControlsWidth - rightControlsWidth) / 2
: root.width / 2
Behavior on pagerButtonWidth { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic } }
Behavior on desktopButtonWidth { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic } }
Behavior on trashButtonWidth { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic } }
Behavior on searchButtonWidth { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic } }
@ -144,7 +147,7 @@ MouseArea {
if (!showPager) return ""
let ids = virtualDesktopInfo.desktopIds
for (let i = 0; i < pagerLeftCount; ++i) {
let bx = navButtonWidth + i * pagerButtonWidth
let bx = navButtonWidth + desktopButtonWidth + i * pagerButtonWidth
if (x >= bx && x < bx + pagerButtonWidth)
return (ids && i < ids.length) ? String(ids[i]) : ""
}
@ -235,11 +238,7 @@ MouseArea {
Keys.onEnterPressed: MobileShellState.ShellDBusClient.openHomeScreen()
Keys.onSpacePressed: MobileShellState.ShellDBusClient.openHomeScreen()
Keys.onRightPressed: {
let first = repeater.itemAt(0)
if (first) { first.keyboardFocus(); return }
let firstTask = taskRepeater.itemAt(0)
if (firstTask) { firstTask.forceActiveFocus(); return }
searchButton.forceActiveFocus()
desktopButton.forceActiveFocus()
}
KeyboardHighlight {
@ -275,6 +274,81 @@ MouseArea {
}
}
// Peek at Desktop button (convergence mode, next to Home)
Rectangle {
id: desktopButton
visible: root.convergenceMode || opacity > 0
enabled: root.convergenceMode
opacity: root.convergenceMode ? 1 : 0
activeFocusOnTab: root.convergenceMode
x: root.navButtonWidth
y: 0
width: root.desktopButtonWidth
height: root.height
color: "transparent"
function toggleDesktop() {
WindowPlugin.WindowUtil.requestShowingDesktop(!WindowPlugin.WindowUtil.isShowingDesktop)
}
Behavior on opacity {
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.InOutQuad }
}
Accessible.role: Accessible.Button
Accessible.name: WindowPlugin.WindowUtil.isShowingDesktop ? i18n("Stop Peeking at Desktop") : i18n("Peek at Desktop")
Accessible.onPressAction: desktopButton.toggleDesktop()
Keys.onReturnPressed: desktopButton.toggleDesktop()
Keys.onEnterPressed: desktopButton.toggleDesktop()
Keys.onSpacePressed: desktopButton.toggleDesktop()
Keys.onLeftPressed: homeButton.forceActiveFocus()
Keys.onRightPressed: {
let first = repeater.itemAt(0)
if (first) { first.keyboardFocus(); return }
let firstTask = taskRepeater.itemAt(0)
if (firstTask) { firstTask.forceActiveFocus(); return }
searchButton.forceActiveFocus()
}
KeyboardHighlight {
anchors.fill: parent
visible: desktopButton.activeFocus
}
Rectangle {
anchors.fill: parent
anchors.margins: root.dockItemInset
radius: Kirigami.Units.cornerRadius
color: root.dockItemColor(desktopMouseArea.containsPress, desktopMouseArea.containsMouse, WindowPlugin.WindowUtil.isShowingDesktop)
Behavior on color {
ColorAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
}
}
Kirigami.Icon {
anchors.centerIn: parent
width: root.dockIconSize
height: width
source: "user-desktop"
active: desktopMouseArea.containsMouse || WindowPlugin.WindowUtil.isShowingDesktop
}
PC3.ToolTip {
visible: desktopMouseArea.containsMouse
text: desktopButton.Accessible.name
}
MouseArea {
id: desktopMouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: root.convergenceMode ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: desktopButton.toggleDesktop()
}
}
// Overview button (convergence mode, right end)
Rectangle {
id: overviewButton
@ -365,7 +439,7 @@ MouseArea {
if (lastTask) { lastTask.forceActiveFocus(); return }
let lastFav = repeater.itemAt(repeater.count - 1)
if (lastFav) { lastFav.keyboardFocus(); return }
homeButton.forceActiveFocus()
desktopButton.forceActiveFocus()
}
Keys.onRightPressed: overviewButton.forceActiveFocus()
@ -427,7 +501,7 @@ MouseArea {
return root.pagerButtonDesktopAt(cx) === desktopId
}
x: root.navButtonWidth + index * root.pagerButtonWidth
x: root.navButtonWidth + root.desktopButtonWidth + index * root.pagerButtonWidth
y: 0
width: root.pagerButtonWidth
height: root.height
@ -800,7 +874,7 @@ MouseArea {
prevDelegate.keyboardFocus();
event.accepted = true;
} else if (root.convergenceMode) {
homeButton.forceActiveFocus();
desktopButton.forceActiveFocus();
event.accepted = true;
}
}
@ -1385,7 +1459,7 @@ MouseArea {
if (prev) { prev.forceActiveFocus(); return }
let lastFav = repeater.itemAt(repeater.count - 1)
if (lastFav) { lastFav.keyboardFocus(); return }
homeButton.forceActiveFocus()
desktopButton.forceActiveFocus()
}
Keys.onRightPressed: {
let next = taskRepeater.itemAt(taskDelegate.index + 1)