2026-05-04 06:43:10 +00:00
|
|
|
#!/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"
|
2026-05-19 07:13:34 +00:00
|
|
|
panel="$repo_root/containments/panel/qml/main.qml"
|
2026-05-25 07:00:34 +00:00
|
|
|
status_panel="$repo_root/containments/panel/qml/StatusPanel.qml"
|
2026-05-25 06:26:58 +00:00
|
|
|
status_bar_template="$repo_root/layout-templates/org.kde.plasma.mobile.defaultStatusBar/contents/layout.js"
|
2026-05-04 06:43:10 +00:00
|
|
|
taskpanel="$repo_root/containments/taskpanel/qml/main.qml"
|
|
|
|
|
folio_main="$repo_root/containments/homescreens/folio/qml/main.qml"
|
2026-05-25 06:26:58 +00:00
|
|
|
shellutil_header="$repo_root/components/mobileshell/shellutil.h"
|
|
|
|
|
shellutil_cpp="$repo_root/components/mobileshell/shellutil.cpp"
|
2026-05-25 19:59:19 +00:00
|
|
|
swipearea_header="$repo_root/components/mobileshell/components/swipearea.h"
|
|
|
|
|
swipearea_cpp="$repo_root/components/mobileshell/components/swipearea.cpp"
|
2026-05-04 06:43:10 +00:00
|
|
|
folio_home="$repo_root/containments/homescreens/folio/qml/FolioHomeScreen.qml"
|
2026-05-25 19:59:19 +00:00
|
|
|
favourites_bar="$repo_root/containments/homescreens/folio/qml/FavouritesBar.qml"
|
2026-05-23 13:33:23 +00:00
|
|
|
folio_backend="$repo_root/containments/homescreens/folio/homescreen.h"
|
|
|
|
|
folio_backend_cpp="$repo_root/containments/homescreens/folio/homescreen.cpp"
|
2026-05-19 07:13:34 +00:00
|
|
|
action_content="$repo_root/components/mobileshell/qml/actiondrawer/private/ContentContainer.qml"
|
2026-05-25 07:00:34 +00:00
|
|
|
action_open_surface="$repo_root/components/mobileshell/qml/actiondrawer/ActionDrawerOpenSurface.qml"
|
2026-05-19 07:13:34 +00:00
|
|
|
action_landscape="$repo_root/components/mobileshell/qml/actiondrawer/private/LandscapeContentContainer.qml"
|
|
|
|
|
quick_settings="$repo_root/components/mobileshell/qml/actiondrawer/private/QuickSettings.qml"
|
|
|
|
|
quick_settings_panel="$repo_root/components/mobileshell/qml/actiondrawer/private/QuickSettingsPanel.qml"
|
2026-05-24 13:49:13 +00:00
|
|
|
base_item="$repo_root/components/mobileshell/qml/components/BaseItem.qml"
|
|
|
|
|
notification_popup_manager="$repo_root/components/mobileshell/qml/popups/notifications/NotificationPopupManager.qml"
|
|
|
|
|
notification_popup="$repo_root/components/mobileshell/qml/popups/notifications/NotificationPopup.qml"
|
|
|
|
|
notification_popup_item="$repo_root/components/mobileshell/qml/widgets/notifications/NotificationPopupItem.qml"
|
|
|
|
|
notification_card="$repo_root/components/mobileshell/qml/widgets/notifications/NotificationCard.qml"
|
|
|
|
|
notification_drawer="$repo_root/components/mobileshell/qml/actiondrawer/private/NotificationDrawer.qml"
|
|
|
|
|
notifications_widget="$repo_root/components/mobileshell/qml/widgets/notifications/NotificationsWidget.qml"
|
2026-05-04 06:43:10 +00:00
|
|
|
|
|
|
|
|
require_line() {
|
|
|
|
|
local file="$1"
|
|
|
|
|
local needle="$2"
|
|
|
|
|
|
2026-05-19 07:13:34 +00:00
|
|
|
if ! grep -Fq -- "$needle" "$file"; then
|
2026-05-04 06:43:10 +00:00
|
|
|
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"
|
2026-05-19 07:13:34 +00:00
|
|
|
require_line "$constants" "readonly property real convergenceWorkspaceFrameThickness:"
|
|
|
|
|
require_line "$constants" "readonly property real convergenceWorkspaceFrameRadius:"
|
2026-05-04 06:43:10 +00:00
|
|
|
|
2026-05-19 07:13:34 +00:00
|
|
|
require_line "$panel" "readonly property real convergenceWorkspaceFrameThickness:"
|
2026-05-25 06:26:58 +00:00
|
|
|
require_line "$panel" "root.panel.location = PlasmaCore.Types.TopEdge"
|
|
|
|
|
require_line "$panel" "root.panel.offset = 0"
|
2026-05-26 15:27:44 +00:00
|
|
|
require_line "$panel" "root.panel.visibilityMode = (ShellSettings.Settings.convergenceModeEnabled || ShellSettings.Settings.autoHidePanelsEnabled) ? 3 : 0"
|
2026-05-25 06:26:58 +00:00
|
|
|
require_line "$panel" "readonly property real topBarHeight: gamingMode ? 0 : MobileShell.Constants.topPanelHeight"
|
2026-05-25 07:00:34 +00:00
|
|
|
require_line "$panel" "readonly property real topBarInputHeight: topBarHeight + convergenceWorkspaceFrameThickness"
|
|
|
|
|
require_line "$panel" "? 0"
|
|
|
|
|
require_line "$panel" ": (ShellSettings.Settings.convergenceModeEnabled ? topBarInputHeight : MobileShell.Constants.topPanelHeight)"
|
|
|
|
|
require_line "$panel" "MobileShell.ShellUtil.setInputRegion(root.panel, Qt.rect(0, 0, root.panel.width, root.panel.height));"
|
|
|
|
|
require_line "$panel" "height: Math.max(1, root.topBarInputHeight)"
|
|
|
|
|
require_line "$panel" "LayerShell.Window.exclusionZone: Math.max(1, root.topBarInputHeight)"
|
|
|
|
|
require_line "$panel" "visible: !ShellSettings.Settings.gamingModeEnabled"
|
|
|
|
|
|
|
|
|
|
require_line "$status_panel" "&& !ShellSettings.Settings.convergenceModeEnabled"
|
|
|
|
|
require_line "$status_panel" "visible: !ShellSettings.Settings.convergenceModeEnabled"
|
2026-05-25 19:59:19 +00:00
|
|
|
require_line "$status_panel" "TaskManager.VirtualDesktopInfo {"
|
2026-05-25 07:00:34 +00:00
|
|
|
require_line "$status_panel" "MobileShell.ActionDrawerOpenSurface {"
|
2026-05-25 19:59:19 +00:00
|
|
|
require_line "$status_panel" "virtualDesktopInfo: virtualDesktopInfo"
|
|
|
|
|
require_line "$action_open_surface" "property var virtualDesktopInfo: null"
|
|
|
|
|
require_line "$action_open_surface" "touchpadWorkspaceSwitchThreshold"
|
|
|
|
|
require_line "$action_open_surface" "function activateAdjacentWorkspace(direction)"
|
|
|
|
|
require_line "$action_open_surface" "virtualDesktopInfo.requestActivate(virtualDesktopInfo.desktopIds[targetIndex]);"
|
|
|
|
|
require_line "$action_open_surface" "absY >= touchpadDirectionLockThreshold && absY > absX * touchpadAxisDominance"
|
|
|
|
|
require_line "$action_open_surface" "workspaceScrollAvailable() && absX >= touchpadDirectionLockThreshold && absX > absY * touchpadAxisDominance"
|
2026-05-25 07:00:34 +00:00
|
|
|
require_line "$action_open_surface" "MouseArea {"
|
|
|
|
|
require_line "$action_open_surface" "acceptedButtons: Qt.NoButton"
|
|
|
|
|
require_line "$action_open_surface" "hoverEnabled: true"
|
2026-05-25 19:59:19 +00:00
|
|
|
require_line "$action_open_surface" "scrollGestureEnabled: false"
|
2026-05-25 07:00:34 +00:00
|
|
|
require_line "$action_open_surface" "cursorShape: ShellSettings.Settings.convergenceModeEnabled ? Qt.PointingHandCursor : Qt.ArrowCursor"
|
2026-05-25 19:59:19 +00:00
|
|
|
require_line "$swipearea_cpp" "const qreal WHEEL_STEP_PIXEL_DELTA = 48.0;"
|
|
|
|
|
require_line "$swipearea_cpp" "const int TOUCHPAD_SCROLL_END_TIMEOUT = 160;"
|
|
|
|
|
require_line "$swipearea_cpp" "const bool isTouchpad = event->deviceType() == QInputDevice::DeviceType::TouchPad;"
|
|
|
|
|
require_line "$swipearea_cpp" "startTouchpadScroll(event->points().first().position());"
|
|
|
|
|
require_line "$swipearea_cpp" "m_touchpadScrollEndTimer.start();"
|
|
|
|
|
require_line "$swipearea_cpp" "if (scrollDelta.isNull() && !event->angleDelta().isNull())"
|
|
|
|
|
require_line "$swipearea_cpp" "QWheelEvent::DefaultDeltasPerStep * WHEEL_STEP_PIXEL_DELTA"
|
|
|
|
|
require_line "$swipearea_header" "QTimer m_touchpadScrollEndTimer;"
|
|
|
|
|
require_line "$favourites_bar" "function handlePagerWheel(wheel)"
|
|
|
|
|
require_line "$favourites_bar" "onWheel: (wheel) => root.handlePagerWheel(wheel)"
|
|
|
|
|
require_line "$favourites_bar" "root.activateAdjacentDesktop(1)"
|
|
|
|
|
require_line "$folio_home" "onTouchpadScrollStarted: {"
|
|
|
|
|
require_line "$folio_home" "onTouchpadScrollMove: (totalDeltaX, totalDeltaY, deltaX, deltaY) => {"
|
|
|
|
|
require_line "$folio_home" "if (!ShellSettings.Settings.convergenceModeEnabled) {"
|
2026-05-25 06:26:58 +00:00
|
|
|
|
|
|
|
|
require_line "$status_bar_template" "panel.location = \"top\";"
|
2026-05-19 07:13:34 +00:00
|
|
|
|
|
|
|
|
require_line "$taskpanel" "readonly property real convergenceWorkspaceFrameThickness:"
|
|
|
|
|
require_line "$taskpanel" "height: MobileShell.Constants.convergenceDockHeight + root.convergenceWorkspaceFrameThickness"
|
|
|
|
|
require_line "$taskpanel" "LayerShell.Window.exclusionZone: MobileShell.Constants.convergenceDockHeight + root.convergenceWorkspaceFrameThickness"
|
2026-05-25 06:26:58 +00:00
|
|
|
require_line "$taskpanel" "visible: !root.fullscreen && !ShellSettings.Settings.convergenceModeEnabled"
|
2026-05-19 07:13:34 +00:00
|
|
|
require_line "$taskpanel" "LayerShell.Window.scope: \"workspace-frame-left\""
|
|
|
|
|
require_line "$taskpanel" "LayerShell.Window.scope: \"workspace-frame-right\""
|
2026-05-04 06:43:10 +00:00
|
|
|
|
2026-05-25 06:26:58 +00:00
|
|
|
require_line "$folio_main" "id: convergenceChrome"
|
|
|
|
|
require_line "$folio_main" "LayerShell.Window.scope: \"convergence-chrome\""
|
|
|
|
|
require_line "$folio_main" "height: Screen.height"
|
|
|
|
|
require_line "$folio_main" "MobileShell.StatusBar {"
|
2026-05-26 15:27:44 +00:00
|
|
|
require_line "$folio_main" "MobileShell.ShellUtil.setInputRegions(convergenceChrome, regions)"
|
2026-05-25 07:00:34 +00:00
|
|
|
require_line "$folio_main" "const topBarRegion = Qt.rect(0, 0, width, topBarHitHeight)"
|
2026-05-04 06:43:10 +00:00
|
|
|
require_line "$folio_main" "readonly property real dockHeight: MobileShell.Constants.convergenceDockHeight"
|
|
|
|
|
require_line "$folio_main" "readonly property real revealStripHeight: MobileShell.Constants.convergenceDockRevealHeight"
|
2026-05-19 07:13:34 +00:00
|
|
|
require_line "$folio_main" "import QtQuick.Shapes 1.8"
|
|
|
|
|
require_line "$folio_main" "id: workspaceFrame"
|
|
|
|
|
require_line "$folio_main" "readonly property real frameThickness: MobileShell.Constants.convergenceWorkspaceFrameThickness"
|
|
|
|
|
require_line "$folio_main" "readonly property real frameRadius:"
|
|
|
|
|
require_line "$folio_main" "readonly property real workAreaX: frameThickness"
|
2026-05-26 15:27:44 +00:00
|
|
|
require_line "$folio_main" "readonly property real topBarHitHeight: topBarHeight + frameThickness"
|
2026-05-25 07:00:34 +00:00
|
|
|
require_line "$folio_main" "readonly property real workAreaY: topBarHitHeight"
|
2026-05-19 07:13:34 +00:00
|
|
|
require_line "$folio_main" "readonly property real workAreaWidth: Math.max(0, width - frameThickness * 2)"
|
2026-05-25 06:26:58 +00:00
|
|
|
require_line "$folio_main" "readonly property real workAreaHeight: Math.max(0, height - topBarHeight - dockHeight - frameThickness * 2)"
|
2026-05-19 07:13:34 +00:00
|
|
|
require_line "$folio_main" "fillRule: ShapePath.OddEvenFill"
|
2026-05-26 15:27:44 +00:00
|
|
|
|
|
|
|
|
if grep -Fq "root.panel.visibilityMode = (!ShellSettings.Settings.convergenceModeEnabled && ShellSettings.Settings.autoHidePanelsEnabled) ? 3 : 0" "$panel"; then
|
|
|
|
|
echo "Convergence panel hit area must not reserve extra top space" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
2026-05-25 06:26:58 +00:00
|
|
|
require_line "$folio_main" "PathLine { x: convergenceChrome.width; y: convergenceChrome.height - convergenceChrome.dockHeight }"
|
|
|
|
|
require_line "$folio_main" "PathLine { x: 0; y: convergenceChrome.height - convergenceChrome.dockHeight }"
|
|
|
|
|
require_line "$folio_main" "PathArc { x: convergenceChrome.workAreaX + convergenceChrome.workAreaWidth - convergenceChrome.frameRadius; y: convergenceChrome.workAreaY + convergenceChrome.workAreaHeight; radiusX: convergenceChrome.frameRadius; radiusY: convergenceChrome.frameRadius }"
|
|
|
|
|
require_line "$folio_main" "PathArc { x: convergenceChrome.workAreaX; y: convergenceChrome.workAreaY + convergenceChrome.workAreaHeight - convergenceChrome.frameRadius; radiusX: convergenceChrome.frameRadius; radiusY: convergenceChrome.frameRadius }"
|
|
|
|
|
require_line "$shellutil_header" "Q_INVOKABLE void setInputRegions(QWindow *window, const QVariantList ®ions);"
|
|
|
|
|
require_line "$shellutil_cpp" "void ShellUtil::setInputRegions(QWindow *window, const QVariantList ®ions)"
|
|
|
|
|
require_line "$shellutil_cpp" "for (const QVariant &value : regions)"
|
2026-05-19 07:13:34 +00:00
|
|
|
require_line "$folio_main" "readonly property real popupTopY: MobileShell.Constants.topPanelHeight"
|
|
|
|
|
require_line "$folio_main" "+ MobileShell.Constants.convergenceWorkspaceFrameThickness"
|
|
|
|
|
require_line "$folio_main" "readonly property real popupBottomY: parent.height"
|
|
|
|
|
require_line "$folio_main" "- MobileShell.Constants.convergenceWorkspaceFrameThickness"
|
|
|
|
|
require_line "$folio_main" "readonly property real popupHeight: Math.max(0, popupBottomY - popupTopY)"
|
|
|
|
|
require_line "$folio_main" "? popupTopY + animationY"
|
2026-05-24 13:49:13 +00:00
|
|
|
require_line "$folio_main" "id: drawerSurface"
|
|
|
|
|
require_line "$folio_main" "readonly property real bodyWidth: Math.max(0, powerPanel.x + powerPanel.width - overlayDrawer.x)"
|
|
|
|
|
require_line "$folio_main" "readonly property real cornerRadius: Math.min(MobileShell.Constants.convergenceWorkspaceFrameRadius"
|
|
|
|
|
require_line "$folio_main" "PathArc { x: drawerSurface.bodyWidth; y: drawerSurfacePath.cornerRadius; radiusX: drawerSurfacePath.cornerRadius; radiusY: drawerSurfacePath.cornerRadius; direction: PathArc.Counterclockwise }"
|
|
|
|
|
require_line "$folio_main" "PathArc { x: drawerSurface.bodyWidth + drawerSurfacePath.cornerRadius; y: drawerSurface.height; radiusX: drawerSurfacePath.cornerRadius; radiusY: drawerSurfacePath.cornerRadius; direction: PathArc.Counterclockwise }"
|
2026-05-04 06:43:10 +00:00
|
|
|
require_line "$folio_home" "height: ShellSettings.Settings.convergenceModeEnabled ? MobileShell.Constants.convergenceDockHeight : Kirigami.Units.gridUnit * 6"
|
2026-05-23 13:33:23 +00:00
|
|
|
require_line "$folio_home" "&& !ShellSettings.Settings.convergenceModeEnabled"
|
|
|
|
|
require_line "$folio_backend" "Q_PROPERTY(bool overviewActive READ overviewActive NOTIFY overviewActiveChanged)"
|
|
|
|
|
|
|
|
|
|
overview_hide_guards="$(grep -F "&& !folio.overviewActive" "$folio_main" | wc -l)"
|
2026-05-25 06:26:58 +00:00
|
|
|
if [[ "$overview_hide_guards" -ne 1 ]]; then
|
|
|
|
|
echo "Expected Folio convergence chrome to hide during KWin Overview; found $overview_hide_guards overview guards" >&2
|
2026-05-23 13:33:23 +00:00
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if ! awk '
|
|
|
|
|
/void HomeScreen::triggerOverview\(\)/ { in_trigger = 1; next }
|
|
|
|
|
in_trigger && /setOverviewActive\(true\);/ { saw_pre_hide = 1; next }
|
|
|
|
|
in_trigger && /createMethodCall/ {
|
|
|
|
|
if (saw_pre_hide) {
|
|
|
|
|
found = 1
|
|
|
|
|
exit 0
|
|
|
|
|
}
|
|
|
|
|
exit 1
|
|
|
|
|
}
|
|
|
|
|
in_trigger && /^}/ { exit 1 }
|
|
|
|
|
END { if (!found) exit 1 }
|
|
|
|
|
' "$folio_backend_cpp"; then
|
|
|
|
|
echo "Expected Folio to hide convergence chrome before invoking KWin Overview" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
2026-05-04 06:43:10 +00:00
|
|
|
|
2026-05-24 13:49:13 +00:00
|
|
|
require_line "$action_content" "readonly property real convergenceSurfaceTopInset: MobileShell.Constants.topPanelHeight + convergenceFrameThickness"
|
2026-05-19 07:13:34 +00:00
|
|
|
require_line "$action_content" "readonly property real convergenceSurfaceBottomInset: MobileShell.Constants.convergenceDockHeight + convergenceFrameThickness"
|
|
|
|
|
require_line "$action_content" "readonly property real convergenceSurfaceSideInset: 0"
|
2026-05-24 14:31:28 +00:00
|
|
|
require_line "$action_content" "readonly property real convergenceFloatingMargin: Kirigami.Units.gridUnit"
|
|
|
|
|
require_line "$action_content" "readonly property real convergenceClickAwayGutter: Kirigami.Units.largeSpacing"
|
|
|
|
|
require_line "$action_content" "readonly property real convergenceLeftSurfaceBottomInset: convergenceSurfaceBottomInset + convergenceBottomClickAwayHeight"
|
|
|
|
|
require_line "$action_content" "readonly property real convergenceQuickSettingsLeft: contentContainerLoader.item ? contentContainerLoader.item.quickSettingsPanelLeft"
|
|
|
|
|
require_line "$action_content" "readonly property real convergenceLeftSurfaceTopInset: convergenceSurfaceTopInset + convergenceFloatingMargin"
|
|
|
|
|
require_line "$action_content" "readonly property real convergenceLeftSurfaceLeftInset: convergenceSurfaceSideInset + convergenceFloatingMargin"
|
|
|
|
|
require_line "$action_content" "readonly property real convergenceLeftSurfaceRightInset: convergenceNotificationRightMargin + convergenceFloatingMargin"
|
|
|
|
|
require_line "$action_content" "readonly property real convergenceLeftSurfaceBottomMargin: convergenceLeftSurfaceBottomInset + convergenceFloatingMargin"
|
|
|
|
|
require_line "$action_content" "id: convergenceLeftSurface"
|
|
|
|
|
require_line "$action_content" "id: convergenceMediaPanel"
|
|
|
|
|
require_line "$action_content" "PlasmaCalendar.MonthView {"
|
2026-05-24 13:49:13 +00:00
|
|
|
require_line "$action_content" "visible: actionDrawer.intendedToBeVisible"
|
2026-05-24 14:31:28 +00:00
|
|
|
require_line "$action_content" "topMargin: isConvergence ? root.convergenceLeftSurfaceTopInset : 0"
|
|
|
|
|
require_line "$action_content" "leftMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : (isConvergence ? root.convergenceLeftSurfaceLeftInset"
|
|
|
|
|
require_line "$action_content" "maximumHeight: isConvergence ? root.convergenceSurfaceHeight * 0.32 : -1"
|
2026-05-19 07:13:34 +00:00
|
|
|
|
2026-05-24 13:49:13 +00:00
|
|
|
if grep -Fq "visible: !isConvergence" "$action_content"; then
|
|
|
|
|
echo "NotificationDrawer must remain visible in convergence so the action drawer shows notification history" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
if grep -Fq "visible: actionDrawer.intendedToBeVisible && !root.isConvergence" "$action_content"; then
|
|
|
|
|
echo "Clear-all notification toolbar must remain visible in convergence" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
require_line "$action_landscape" "readonly property real convergenceSurfaceTopInset: MobileShell.Constants.topPanelHeight + convergenceFrameThickness"
|
2026-05-19 07:13:34 +00:00
|
|
|
require_line "$action_landscape" "readonly property real convergenceSurfaceBottomInset: MobileShell.Constants.convergenceDockHeight + convergenceFrameThickness"
|
|
|
|
|
require_line "$action_landscape" "readonly property real convergenceSurfaceSideInset: 0"
|
2026-05-24 14:31:28 +00:00
|
|
|
require_line "$action_landscape" "readonly property real quickSettingsPanelLeft: quickSettingsPanel.x"
|
2026-05-24 13:49:13 +00:00
|
|
|
require_line "$action_landscape" "import QtQuick.Shapes 1.8"
|
|
|
|
|
require_line "$action_landscape" "id: actionDrawerSurface"
|
|
|
|
|
require_line "$action_landscape" "x: quickSettingsPanel.x - cornerRadius"
|
|
|
|
|
require_line "$action_landscape" "readonly property real bodyWidth: quickSettingsPanel.width"
|
|
|
|
|
require_line "$action_landscape" "PathArc { x: actionDrawerSurfacePath.cornerRadius; y: actionDrawerSurfacePath.cornerRadius; radiusX: actionDrawerSurfacePath.cornerRadius; radiusY: actionDrawerSurfacePath.cornerRadius; direction: PathArc.Clockwise }"
|
|
|
|
|
require_line "$action_landscape" "PathArc { x: 0; y: actionDrawerSurface.height; radiusX: actionDrawerSurfacePath.cornerRadius; radiusY: actionDrawerSurfacePath.cornerRadius; direction: PathArc.Clockwise }"
|
2026-05-19 07:13:34 +00:00
|
|
|
require_line "$action_landscape" "anchors.topMargin: isConvergence ? restingTopMargin"
|
|
|
|
|
require_line "$action_landscape" "anchors.rightMargin: isConvergence ? root.convergenceSurfaceSideInset : 0"
|
|
|
|
|
require_line "$action_landscape" "fullScreenHeight: quickSettingsPanel.availableHeight"
|
|
|
|
|
|
|
|
|
|
require_line "$quick_settings_panel" "readonly property bool isConvergence: ShellSettings.Settings.convergenceModeEnabled"
|
|
|
|
|
require_line "$quick_settings_panel" "readonly property real panelPadding: isConvergence ? Kirigami.Units.smallSpacing : Kirigami.Units.smallSpacing * 4"
|
|
|
|
|
require_line "$quick_settings_panel" "anchors.margins: root.isConvergence ? 0 : Kirigami.Units.largeSpacing"
|
2026-05-24 13:49:13 +00:00
|
|
|
require_line "$quick_settings_panel" "visible: !root.isConvergence"
|
2026-05-19 07:13:34 +00:00
|
|
|
require_line "$quick_settings_panel" "panelType: root.isConvergence ? MobileShell.PanelBackground.PanelType.Flat : MobileShell.PanelBackground.PanelType.Base"
|
|
|
|
|
require_line "$quick_settings_panel" "radius: root.isConvergence ? 0 : Kirigami.Units.cornerRadius"
|
|
|
|
|
|
2026-05-24 13:49:13 +00:00
|
|
|
require_line "$base_item" "implicitHeight: topPadding + bottomPadding + (contentItem ? contentItem.implicitHeight : 0)"
|
|
|
|
|
require_line "$base_item" "implicitWidth: leftPadding + rightPadding + (contentItem ? contentItem.implicitWidth : 0)"
|
|
|
|
|
|
2026-05-19 07:13:34 +00:00
|
|
|
require_line "$quick_settings" "id: convergenceFlow"
|
|
|
|
|
require_line "$quick_settings" "visible: root.isConvergence"
|
|
|
|
|
require_line "$quick_settings" "visible: !root.isConvergence"
|
|
|
|
|
require_line "$quick_settings" "active: !root.isConvergence && swipeView.count > 1 ? true: false"
|
|
|
|
|
|
2026-05-24 13:49:13 +00:00
|
|
|
if grep -Fq "id: convergenceNotificationHistory" "$quick_settings"; then
|
|
|
|
|
echo "Convergence notification history must not consume quick-settings stack height" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if grep -Fq "NotificationHistoryPopup" "$quick_settings"; then
|
|
|
|
|
echo "Notification history must use the in-drawer NotificationDrawer, not a separate popup" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
require_line "$notification_popup_manager" "readonly property real convergencePopupMargin: MobileShell.Constants.convergenceWorkspaceFrameThickness + Kirigami.Units.largeSpacing"
|
|
|
|
|
require_line "$notification_popup_manager" "readonly property real convergencePopupBottomInset: MobileShell.Constants.convergenceDockHeight + MobileShell.Constants.convergenceWorkspaceFrameThickness + Kirigami.Units.largeSpacing"
|
|
|
|
|
require_line "$notification_popup_manager" "let regionY = (currentPopup ? currentPopup.effectiveOpenOffset : Screen.height - notificationPopupManager.convergencePopupBottomInset - popupHeight)"
|
|
|
|
|
require_line "$notification_popup_manager" "convergenceBottomInset: notificationPopupManager.convergencePopupBottomInset"
|
|
|
|
|
require_line "$notification_popup_manager" "? (notificationPopupManager.width - width - notificationPopupManager.convergencePopupMargin)"
|
|
|
|
|
require_line "$notification_popup" "property real convergenceBottomInset: openOffset"
|
|
|
|
|
require_line "$notification_popup" "? (Screen.height - convergenceBottomInset - popupHeight)"
|
|
|
|
|
require_line "$notification_popup_item" "icon.name: \"window-close\""
|
|
|
|
|
require_line "$notification_popup_item" "text: i18n(\"Dismiss\")"
|
|
|
|
|
require_line "$notification_card" "if (!contentItem) {"
|
2026-05-24 14:31:28 +00:00
|
|
|
require_line "$notification_drawer" "&& !ShellSettings.Settings.convergenceModeEnabled"
|
2026-05-24 13:49:13 +00:00
|
|
|
require_line "$notification_drawer" "emptyText: ShellSettings.Settings.convergenceModeEnabled ? i18n(\"No notifications\") : \"\""
|
|
|
|
|
require_line "$notifications_widget" "property string emptyText: \"\""
|
|
|
|
|
|
|
|
|
|
if grep -Fq "notificationItem.close();" "$notification_popup_item"; then
|
|
|
|
|
echo "Popup dismissals must expire the popup instead of closing notification history" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if grep -Fq "contentParent.children.push(contentItem);" "$notification_card"; then
|
|
|
|
|
echo "NotificationCard content is already parented by assignment; do not push it into children again" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
2026-05-25 06:26:58 +00:00
|
|
|
frame_arc_count="$(grep -F "PathArc { x: convergenceChrome." "$folio_main" | wc -l || true)"
|
2026-05-19 07:13:34 +00:00
|
|
|
if [[ "$frame_arc_count" -ne 4 ]]; then
|
|
|
|
|
echo "Expected the workspace frame cutout to have four rounded inner corners; found $frame_arc_count arcs" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if grep -Fq "convergenceWallpaperLayer" "$folio_main"; then
|
|
|
|
|
echo "Do not replace the real wallpaper with a custom convergence wallpaper layer" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
2026-05-25 06:26:58 +00:00
|
|
|
dock_offset_transforms="$(grep -F "transform: Translate { y: convergenceChrome.dockOffset }" "$folio_main" | wc -l || true)"
|
2026-05-04 06:43:10 +00:00
|
|
|
if [[ "$dock_offset_transforms" -ne 1 ]]; then
|
2026-05-25 06:26:58 +00:00
|
|
|
echo "Expected only dock contents to slide with convergenceChrome.dockOffset; found $dock_offset_transforms transforms" >&2
|
2026-05-04 06:43:10 +00:00
|
|
|
exit 1
|
|
|
|
|
fi
|