Frame convergence work area

This commit is contained in:
Marco Allegretti 2026-05-19 09:13:00 +02:00
parent 8dd3bfbb07
commit ae3319b120
4 changed files with 101 additions and 4 deletions

View file

@ -33,6 +33,8 @@ QtObject {
readonly property real defaultGesturePanelThickness: Kirigami.Units.gridUnit
readonly property real convergenceDockHeight: Kirigami.Units.gridUnit * 3
readonly property real convergenceDockRevealHeight: Kirigami.Units.gridUnit
readonly property real convergenceWorkspaceFrameThickness: Math.max(Kirigami.Units.smallSpacing, Math.round(Kirigami.Units.gridUnit * 0.35))
readonly property real convergenceWorkspaceFrameRadius: Math.max(Kirigami.Units.cornerRadius * 2, Kirigami.Units.largeSpacing)
readonly property real navigationPanelThickness: {
if (!ShellSettings.Settings.navigationPanelEnabled) {

View file

@ -5,6 +5,7 @@ import QtQuick
import QtQuick.Window
import QtQuick.Layouts
import QtQuick.Effects
import QtQuick.Shapes 1.8
import Qt5Compat.GraphicalEffects
import org.kde.kirigami as Kirigami
@ -869,6 +870,64 @@ ContainmentItem {
onHomeTriggered: root.homeAction()
contentItem: Item {
Item {
id: workspaceFrame
anchors.fill: parent
visible: ShellSettings.Settings.convergenceModeEnabled && !ShellSettings.Settings.gamingModeEnabled
z: -1
readonly property real frameThickness: MobileShell.Constants.convergenceWorkspaceFrameThickness
readonly property real frameRadius: Math.min(MobileShell.Constants.convergenceWorkspaceFrameRadius, Math.max(0, Math.min(workAreaWidth, workAreaHeight) / 2))
readonly property real topReservedHeight: MobileShell.Constants.topPanelHeight
readonly property real bottomReservedHeight: MobileShell.Constants.convergenceDockHeight
readonly property real workAreaX: frameThickness
readonly property real workAreaY: topReservedHeight + frameThickness
readonly property real workAreaWidth: Math.max(0, width - frameThickness * 2)
readonly property real workAreaHeight: Math.max(0, height - topReservedHeight - bottomReservedHeight - frameThickness * 2)
readonly property color frameColor: Kirigami.Theme.backgroundColor
readonly property color edgeColor: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1)
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
Shape {
anchors.fill: parent
ShapePath {
fillColor: workspaceFrame.frameColor
fillRule: ShapePath.OddEvenFill
strokeWidth: 0
startX: 0
startY: workspaceFrame.topReservedHeight
PathLine { x: workspaceFrame.width; y: workspaceFrame.topReservedHeight }
PathLine { x: workspaceFrame.width; y: workspaceFrame.height - workspaceFrame.bottomReservedHeight }
PathLine { x: 0; y: workspaceFrame.height - workspaceFrame.bottomReservedHeight }
PathLine { x: 0; y: workspaceFrame.topReservedHeight }
PathMove { x: workspaceFrame.workAreaX + workspaceFrame.frameRadius; y: workspaceFrame.workAreaY }
PathLine { x: workspaceFrame.workAreaX + workspaceFrame.workAreaWidth - workspaceFrame.frameRadius; y: workspaceFrame.workAreaY }
PathArc { x: workspaceFrame.workAreaX + workspaceFrame.workAreaWidth; y: workspaceFrame.workAreaY + workspaceFrame.frameRadius; radiusX: workspaceFrame.frameRadius; radiusY: workspaceFrame.frameRadius }
PathLine { x: workspaceFrame.workAreaX + workspaceFrame.workAreaWidth; y: workspaceFrame.workAreaY + workspaceFrame.workAreaHeight - workspaceFrame.frameRadius }
PathArc { x: workspaceFrame.workAreaX + workspaceFrame.workAreaWidth - workspaceFrame.frameRadius; y: workspaceFrame.workAreaY + workspaceFrame.workAreaHeight; radiusX: workspaceFrame.frameRadius; radiusY: workspaceFrame.frameRadius }
PathLine { x: workspaceFrame.workAreaX + workspaceFrame.frameRadius; y: workspaceFrame.workAreaY + workspaceFrame.workAreaHeight }
PathArc { x: workspaceFrame.workAreaX; y: workspaceFrame.workAreaY + workspaceFrame.workAreaHeight - workspaceFrame.frameRadius; radiusX: workspaceFrame.frameRadius; radiusY: workspaceFrame.frameRadius }
PathLine { x: workspaceFrame.workAreaX; y: workspaceFrame.workAreaY + workspaceFrame.frameRadius }
PathArc { x: workspaceFrame.workAreaX + workspaceFrame.frameRadius; y: workspaceFrame.workAreaY; radiusX: workspaceFrame.frameRadius; radiusY: workspaceFrame.frameRadius }
}
}
Rectangle {
x: workspaceFrame.workAreaX
y: workspaceFrame.workAreaY
width: workspaceFrame.workAreaWidth
height: workspaceFrame.workAreaHeight
radius: workspaceFrame.frameRadius
color: "transparent"
border.width: 1
border.color: workspaceFrame.edgeColor
}
}
// homescreen component
FolioHomeScreen {

View file

@ -76,6 +76,9 @@ ContainmentItem {
}
readonly property real panelHeight: gamingMode ? 0 : MobileShell.Constants.topPanelHeight
readonly property real convergenceWorkspaceFrameThickness: ShellSettings.Settings.convergenceModeEnabled && !gamingMode
? MobileShell.Constants.convergenceWorkspaceFrameThickness
: 0
onPanelHeightChanged: setWindowProperties()
function setWindowProperties() {
@ -150,13 +153,13 @@ ContainmentItem {
visible: ShellSettings.Settings.convergenceModeEnabled && !ShellSettings.Settings.gamingModeEnabled
color: "transparent"
flags: Qt.FramelessWindowHint | Qt.WindowTransparentForInput
height: Math.max(1, root.panelHeight)
height: Math.max(1, root.panelHeight + root.convergenceWorkspaceFrameThickness)
width: 1
LayerShell.Window.scope: "topbar-space"
LayerShell.Window.layer: LayerShell.Window.LayerBottom
LayerShell.Window.anchors: LayerShell.Window.AnchorTop | LayerShell.Window.AnchorLeft | LayerShell.Window.AnchorRight
LayerShell.Window.exclusionZone: Math.max(1, root.panelHeight)
LayerShell.Window.exclusionZone: Math.max(1, root.panelHeight + root.convergenceWorkspaceFrameThickness)
LayerShell.Window.keyboardInteractivity: LayerShell.Window.KeyboardInteractivityNone
}

View file

@ -41,6 +41,9 @@ ContainmentItem {
readonly property bool gamingMode: ShellSettings.Settings.gamingModeEnabled
readonly property real navigationPanelHeight: gamingMode ? 0 : MobileShell.Constants.navigationPanelThickness
readonly property real convergenceWorkspaceFrameThickness: ShellSettings.Settings.convergenceModeEnabled && !gamingMode
? MobileShell.Constants.convergenceWorkspaceFrameThickness
: 0
onNavigationPanelHeightChanged: setWindowProperties()
readonly property real intendedWindowThickness: navigationPanelHeight
@ -166,13 +169,43 @@ ContainmentItem {
color: "transparent"
flags: Qt.FramelessWindowHint | Qt.WindowTransparentForInput
// height is set by layer-shell anchoring; provide a fallback.
height: MobileShell.Constants.convergenceDockHeight
height: MobileShell.Constants.convergenceDockHeight + root.convergenceWorkspaceFrameThickness
width: 1 // layer-shell stretches it via AnchorLeft|AnchorRight
LayerShell.Window.scope: "dock-space"
LayerShell.Window.layer: LayerShell.Window.LayerBottom
LayerShell.Window.anchors: LayerShell.Window.AnchorBottom | LayerShell.Window.AnchorLeft | LayerShell.Window.AnchorRight
LayerShell.Window.exclusionZone: MobileShell.Constants.convergenceDockHeight
LayerShell.Window.exclusionZone: MobileShell.Constants.convergenceDockHeight + root.convergenceWorkspaceFrameThickness
LayerShell.Window.keyboardInteractivity: LayerShell.Window.KeyboardInteractivityNone
}
Window {
id: leftWorkspaceFrameReserver
visible: root.convergenceWorkspaceFrameThickness > 0
color: "transparent"
flags: Qt.FramelessWindowHint | Qt.WindowTransparentForInput
width: Math.max(1, root.convergenceWorkspaceFrameThickness)
height: 1
LayerShell.Window.scope: "workspace-frame-left"
LayerShell.Window.layer: LayerShell.Window.LayerBottom
LayerShell.Window.anchors: LayerShell.Window.AnchorLeft | LayerShell.Window.AnchorTop | LayerShell.Window.AnchorBottom
LayerShell.Window.exclusionZone: Math.max(1, root.convergenceWorkspaceFrameThickness)
LayerShell.Window.keyboardInteractivity: LayerShell.Window.KeyboardInteractivityNone
}
Window {
id: rightWorkspaceFrameReserver
visible: root.convergenceWorkspaceFrameThickness > 0
color: "transparent"
flags: Qt.FramelessWindowHint | Qt.WindowTransparentForInput
width: Math.max(1, root.convergenceWorkspaceFrameThickness)
height: 1
LayerShell.Window.scope: "workspace-frame-right"
LayerShell.Window.layer: LayerShell.Window.LayerBottom
LayerShell.Window.anchors: LayerShell.Window.AnchorRight | LayerShell.Window.AnchorTop | LayerShell.Window.AnchorBottom
LayerShell.Window.exclusionZone: Math.max(1, root.convergenceWorkspaceFrameThickness)
LayerShell.Window.keyboardInteractivity: LayerShell.Window.KeyboardInteractivityNone
}