Unify convergence dock geometry and add invariant test

Introduce shared dock height/reveal constants and use them in folio and taskpanel to keep overlay and exclusion zone aligned. Keep dock backing stationary while only content slides, and add a CTest invariant script to prevent regressions.
This commit is contained in:
Marco Allegretti 2026-05-04 08:43:10 +02:00
parent 709304c99c
commit e72165ec98
6 changed files with 60 additions and 11 deletions

View file

@ -31,6 +31,8 @@ QtObject {
? 0 ? 0
: Kirigami.Units.gridUnit * 2 : Kirigami.Units.gridUnit * 2
readonly property real defaultGesturePanelThickness: Kirigami.Units.gridUnit 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 navigationPanelThickness: { readonly property real navigationPanelThickness: {
if (!ShellSettings.Settings.navigationPanelEnabled) { if (!ShellSettings.Settings.navigationPanelEnabled) {

View file

@ -382,8 +382,8 @@ Item {
visible: opacity > 0 && !ShellSettings.Settings.convergenceModeEnabled visible: opacity > 0 && !ShellSettings.Settings.convergenceModeEnabled
// one is ignored as anchors are set // one is ignored as anchors are set
height: ShellSettings.Settings.convergenceModeEnabled ? Kirigami.Units.gridUnit * 3 : Kirigami.Units.gridUnit * 6 height: ShellSettings.Settings.convergenceModeEnabled ? MobileShell.Constants.convergenceDockHeight : Kirigami.Units.gridUnit * 6
width: ShellSettings.Settings.convergenceModeEnabled ? Kirigami.Units.gridUnit * 3 : Kirigami.Units.gridUnit * 6 width: ShellSettings.Settings.convergenceModeEnabled ? MobileShell.Constants.convergenceDockHeight : Kirigami.Units.gridUnit * 6
anchors.topMargin: root.topMargin anchors.topMargin: root.topMargin
anchors.bottomMargin: ShellSettings.Settings.convergenceModeEnabled ? 0 : root.bottomMargin anchors.bottomMargin: ShellSettings.Settings.convergenceModeEnabled ? 0 : root.bottomMargin
@ -439,7 +439,7 @@ Item {
} }
PropertyChanges { PropertyChanges {
target: favouritesBar target: favouritesBar
height: ShellSettings.Settings.convergenceModeEnabled ? Kirigami.Units.gridUnit * 3 : Kirigami.Units.gridUnit * 6 height: ShellSettings.Settings.convergenceModeEnabled ? MobileShell.Constants.convergenceDockHeight : Kirigami.Units.gridUnit * 6
} }
}, State { }, State {
name: "left" name: "left"

View file

@ -279,7 +279,7 @@ ContainmentItem {
visible: ShellSettings.Settings.convergenceModeEnabled && !ShellSettings.Settings.gamingModeEnabled visible: ShellSettings.Settings.convergenceModeEnabled && !ShellSettings.Settings.gamingModeEnabled
color: "transparent" color: "transparent"
width: Screen.width width: Screen.width
height: Kirigami.Units.gridUnit * 3 height: MobileShell.Constants.convergenceDockHeight
LayerShell.Window.scope: "dock-overlay" LayerShell.Window.scope: "dock-overlay"
LayerShell.Window.layer: LayerShell.Window.LayerTop LayerShell.Window.layer: LayerShell.Window.LayerTop
@ -290,11 +290,11 @@ ContainmentItem {
// Auto-hide: slide dock content off-screen when a window is // Auto-hide: slide dock content off-screen when a window is
// maximized. The reveal strip at the screen edge brings it back. // maximized. The reveal strip at the screen edge brings it back.
property real dockOffset: 0 property real dockOffset: 0
readonly property real dockHeight: Kirigami.Units.gridUnit * 3 readonly property real dockHeight: MobileShell.Constants.convergenceDockHeight
// Height of the input-receive strip kept at the screen edge when // Height of the input-receive strip kept at the screen edge when
// the dock is hidden. Matches the navigation panel convention. // the dock is hidden. Matches the navigation panel convention.
readonly property real revealStripHeight: Kirigami.Units.gridUnit readonly property real revealStripHeight: MobileShell.Constants.convergenceDockRevealHeight
// True once the hover-reveal timer fires; cleared on hover-exit. // True once the hover-reveal timer fires; cleared on hover-exit.
property bool hoverRevealing: false property bool hoverRevealing: false
@ -353,10 +353,10 @@ ContainmentItem {
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
visible: !dockOverlay.shouldHide || dockOverlay.dockOffset < dockOverlay.dockHeight
Kirigami.Theme.inherit: false Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window Kirigami.Theme.colorSet: Kirigami.Theme.Window
color: Kirigami.Theme.backgroundColor color: Kirigami.Theme.backgroundColor
transform: Translate { y: dockOverlay.dockOffset }
} }
FavouritesBar { FavouritesBar {
@ -408,7 +408,7 @@ ContainmentItem {
readonly property real popupWidth: Math.min(Kirigami.Units.gridUnit * 28, parent.width * 0.5) readonly property real popupWidth: Math.min(Kirigami.Units.gridUnit * 28, parent.width * 0.5)
readonly property real popupHeight: Math.min(Kirigami.Units.gridUnit * 32, parent.height * 0.7) readonly property real popupHeight: Math.min(Kirigami.Units.gridUnit * 32, parent.height * 0.7)
readonly property real dockHeight: Kirigami.Units.gridUnit * 3 readonly property real dockHeight: MobileShell.Constants.convergenceDockHeight
width: popupWidth width: popupWidth
height: popupHeight height: popupHeight

View file

@ -166,13 +166,13 @@ ContainmentItem {
color: "transparent" color: "transparent"
flags: Qt.FramelessWindowHint | Qt.WindowTransparentForInput flags: Qt.FramelessWindowHint | Qt.WindowTransparentForInput
// height is set by layer-shell anchoring; provide a fallback. // height is set by layer-shell anchoring; provide a fallback.
height: Kirigami.Units.gridUnit * 3 height: MobileShell.Constants.convergenceDockHeight
width: 1 // layer-shell stretches it via AnchorLeft|AnchorRight width: 1 // layer-shell stretches it via AnchorLeft|AnchorRight
LayerShell.Window.scope: "dock-space" LayerShell.Window.scope: "dock-space"
LayerShell.Window.layer: LayerShell.Window.LayerBottom LayerShell.Window.layer: LayerShell.Window.LayerBottom
LayerShell.Window.anchors: LayerShell.Window.AnchorBottom | LayerShell.Window.AnchorLeft | LayerShell.Window.AnchorRight LayerShell.Window.anchors: LayerShell.Window.AnchorBottom | LayerShell.Window.AnchorLeft | LayerShell.Window.AnchorRight
LayerShell.Window.exclusionZone: Kirigami.Units.gridUnit * 3 LayerShell.Window.exclusionZone: MobileShell.Constants.convergenceDockHeight
LayerShell.Window.keyboardInteractivity: LayerShell.Window.KeyboardInteractivityNone LayerShell.Window.keyboardInteractivity: LayerShell.Window.KeyboardInteractivityNone
} }

View file

@ -2,3 +2,11 @@
# SPDX-License-Identifier: GPL-2.0-or-later # SPDX-License-Identifier: GPL-2.0-or-later
add_subdirectory(notificationtest) add_subdirectory(notificationtest)
find_program(BASH_EXECUTABLE bash)
if(BASH_EXECUTABLE)
add_test(
NAME convergence-dock-invariant
COMMAND ${BASH_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/check-convergence-dock-invariant.sh
)
endif()

View file

@ -0,0 +1,39 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2026 Marco Allegretti <mightymarco4@gmail.com>
# SPDX-License-Identifier: GPL-2.0-or-later
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
constants="$repo_root/components/mobileshell/qml/components/Constants.qml"
taskpanel="$repo_root/containments/taskpanel/qml/main.qml"
folio_main="$repo_root/containments/homescreens/folio/qml/main.qml"
folio_home="$repo_root/containments/homescreens/folio/qml/FolioHomeScreen.qml"
require_line() {
local file="$1"
local needle="$2"
if ! grep -Fq "$needle" "$file"; then
echo "Missing invariant in ${file#$repo_root/}: $needle" >&2
exit 1
fi
}
require_line "$constants" "readonly property real convergenceDockHeight: Kirigami.Units.gridUnit * 3"
require_line "$constants" "readonly property real convergenceDockRevealHeight: Kirigami.Units.gridUnit"
require_line "$taskpanel" "height: MobileShell.Constants.convergenceDockHeight"
require_line "$taskpanel" "LayerShell.Window.exclusionZone: MobileShell.Constants.convergenceDockHeight"
require_line "$folio_main" "height: MobileShell.Constants.convergenceDockHeight"
require_line "$folio_main" "readonly property real dockHeight: MobileShell.Constants.convergenceDockHeight"
require_line "$folio_main" "readonly property real revealStripHeight: MobileShell.Constants.convergenceDockRevealHeight"
require_line "$folio_home" "height: ShellSettings.Settings.convergenceModeEnabled ? MobileShell.Constants.convergenceDockHeight : Kirigami.Units.gridUnit * 6"
dock_offset_transforms="$(grep -F "transform: Translate { y: dockOverlay.dockOffset }" "$folio_main" | wc -l)"
if [[ "$dock_offset_transforms" -ne 1 ]]; then
echo "Expected only dock contents to slide with dockOverlay.dockOffset; found $dock_offset_transforms transforms" >&2
exit 1
fi