shift-shell/tests/check-dynamic-tiles-motion.sh

196 lines
12 KiB
Bash
Raw Normal View History

2026-05-19 07:46:34 +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)"
effect_qml="$repo_root/kwin/effects/shift-tile-preview/contents/ui/main.qml"
effect_metadata="$repo_root/kwin/effects/shift-tile-preview/metadata.json"
animation_effect_js="$repo_root/kwin/effects/shift-tile-animations/contents/code/main.js"
animation_effect_metadata="$repo_root/kwin/effects/shift-tile-animations/metadata.json"
2026-05-19 07:46:34 +00:00
effects_cmake="$repo_root/kwin/effects/CMakeLists.txt"
tiling_script="$repo_root/kwin/scripts/shift-tiling/contents/ui/main.qml"
2026-05-22 07:39:45 +00:00
decoration_qml="$repo_root/kwin/decorations/org.shift.decoration/contents/ui/main.qml"
running_apps_panel="$repo_root/containments/homescreens/folio/qml/RunningAppsPanel.qml"
folio_main="$repo_root/containments/homescreens/folio/qml/main.qml"
2026-05-19 07:46:34 +00:00
env_config="$repo_root/envmanager/config.h"
require_line() {
local file="$1"
local needle="$2"
if ! grep -Fq -- "$needle" "$file"; then
echo "Missing dynamic tile motion invariant in ${file#$repo_root/}: $needle" >&2
exit 1
fi
}
reject_line() {
local file="$1"
local needle="$2"
if grep -Fq -- "$needle" "$file"; then
echo "Rejected dynamic tile motion pattern in ${file#$repo_root/}: $needle" >&2
exit 1
fi
}
require_line "$effects_cmake" "add_kwin_effect(shift-tile-preview shift-tile-preview)"
require_line "$effects_cmake" "add_kwin_effect(shift-tile-animations shift-tile-animations)"
2026-05-19 07:46:34 +00:00
require_line "$effect_metadata" '"Id": "shift-tile-preview"'
require_line "$effect_metadata" '"X-Plasma-API": "declarativescript"'
require_line "$animation_effect_metadata" '"Id": "shift-tile-animations"'
require_line "$animation_effect_metadata" '"X-Plasma-API": "javascript"'
2026-05-19 07:46:34 +00:00
require_line "$env_config" '{"shift-tilingEnabled", convergenceModeEnabled}'
require_line "$env_config" '{"shift-tile-previewEnabled", convergenceModeEnabled}'
require_line "$env_config" '{"shift-tile-animationsEnabled", convergenceModeEnabled}'
2026-05-19 07:46:34 +00:00
require_line "$env_config" '"shift-tile-preview"'
require_line "$env_config" '"shift-tile-animations"'
2026-05-19 07:46:34 +00:00
require_line "$env_config" '"shift-tiling"'
require_line "$effect_qml" "KWinComponents.SceneEffect"
require_line "$effect_qml" "visible: false"
2026-05-19 07:46:34 +00:00
require_line "$effect_qml" "ShellSettings.Settings.dynamicTilingEnabled"
require_line "$effect_qml" "interactiveMoveResizeStarted.connect"
require_line "$effect_qml" "interactiveMoveResizeStepped.connect"
require_line "$effect_qml" "interactiveMoveResizeFinished.connect"
require_line "$effect_qml" "showPreview(\"swap\""
2026-05-19 07:46:34 +00:00
require_line "$effect_qml" "showPreview(\"float\""
require_line "$effect_qml" "showPreview(\"restore\""
require_line "$effect_qml" "KWinComponents.Workspace.showOutline(previewGeometry)"
require_line "$effect_qml" "KWinComponents.Workspace.hideOutline()"
reject_line "$effect_qml" "MobileShell.MotionNumberAnimation"
reject_line "$effect_qml" "MobileShell.MotionColorAnimation"
reject_line "$effect_qml" "disableEffectTimer"
require_line "$animation_effect_js" "class ShiftTileAnimationsEffect"
require_line "$animation_effect_js" "window.windowFrameGeometryChanged.connect"
require_line "$animation_effect_js" "window.windowStartUserMovedResized.connect"
require_line "$animation_effect_js" "window.windowFinishUserMovedResized.connect"
require_line "$animation_effect_js" "animationTime("
require_line "$animation_effect_js" "type: Effect.Size"
require_line "$animation_effect_js" "type: Effect.Translation"
require_line "$animation_effect_js" "curve: QEasingCurve.OutCubic"
require_line "$animation_effect_js" "window.shiftTileUserMoveResize"
2026-05-19 07:46:34 +00:00
require_line "$tiling_script" "readonly property int maxWindowsPerPage: 4"
2026-05-19 07:55:25 +00:00
require_line "$tiling_script" "readonly property real stablePrimaryRatio: 0.58"
require_line "$tiling_script" "readonly property var layoutModes: [\"master\", \"columns\", \"rows\"]"
require_line "$tiling_script" "property int lastWindowRequestSerial: -1"
require_line "$tiling_script" "property int lastLayoutRequestSerial: -1"
require_line "$tiling_script" "lastWindowRequestSerial = ShellSettings.Settings.dynamicTilingWindowRequestSerial"
require_line "$tiling_script" "lastLayoutRequestSerial = ShellSettings.Settings.dynamicTilingLayoutRequestSerial"
require_line "$tiling_script" "function desktopKey(desktop)"
require_line "$tiling_script" "function desktopForWindow(win)"
2026-05-22 07:39:45 +00:00
require_line "$tiling_script" "function normalizeWindowDesktopScope(win)"
require_line "$tiling_script" "function layoutKeyFor(outputName, desktop)"
require_line "$tiling_script" "function desktopForLayoutKey(outputName)"
require_line "$tiling_script" "function layoutKeyForWindow(win)"
require_line "$tiling_script" "function assignWindowToDesktop(win, desktop)"
require_line "$tiling_script" "function targetLayoutForNewWindow(win)"
require_line "$tiling_script" "function leafIndexForWindow(outputName, win)"
require_line "$tiling_script" "function leafForSlot(outputName, preferredIndex)"
require_line "$tiling_script" "property var lastFocusedWindowKeys: ({})"
require_line "$tiling_script" "function rememberFocusedWindow(win)"
require_line "$tiling_script" "function replacementLeafForLayout(outputName, fallbackIndex)"
require_line "$tiling_script" "function swapWindowBetweenLayouts(win, sourceName, targetName)"
require_line "$tiling_script" "windowCountForLayout(currentKey) < maxWindowsPerPage"
require_line "$tiling_script" "windowCountForLayout(targetName) >= maxWindowsPerPage && swapWindowBetweenLayouts(win, currentName, targetName)"
require_line "$tiling_script" "KWinComponents.Workspace.currentDesktop = target.desktop"
require_line "$tiling_script" "assignWindowToDesktop(displacedWindow, sourceDesktop)"
require_line "$tiling_script" "const targetLeaf = replacementLeafForLayout(targetName, sourceIndex)"
require_line "$tiling_script" "function onActiveWindowChanged()"
require_line "$tiling_script" "root.rememberFocusedWindow(KWinComponents.Workspace.activeWindow)"
require_line "$tiling_script" "win.desktops = [desktop]"
require_line "$tiling_script" "win.desktopsChanged.connect"
2026-05-22 07:39:45 +00:00
require_line "$tiling_script" "function dynamicTilingOwnsWindow(win)"
require_line "$tiling_script" "function normalizeNativeWindowOperationState(win)"
require_line "$tiling_script" "function handleNativeWindowOperationStateChange(win)"
require_line "$tiling_script" "function adoptWindow(win)"
require_line "$tiling_script" "win.maximizeModeChanged.connect"
require_line "$tiling_script" "win.fullScreenChanged.connect"
require_line "$tiling_script" "win.noBorderChanged.connect"
require_line "$tiling_script" "win.keepAboveChanged.connect"
require_line "$tiling_script" "win.keepBelowChanged.connect"
require_line "$tiling_script" "property bool dragNativeResize: false"
require_line "$tiling_script" "if (dragNativeResize && dragSourceScreen && dragSourceIndex >= 0)"
2026-05-19 07:55:25 +00:00
require_line "$tiling_script" "function orderedWindowsForScreen(outputName)"
require_line "$tiling_script" "function buildStableStack(windows, startIndex)"
require_line "$tiling_script" "function buildLinearLayout(windows, startIndex, orientation)"
require_line "$tiling_script" "function layoutModeForScreen(outputName)"
require_line "$tiling_script" "function buildStableLayout(windows, mode)"
2026-05-19 07:55:25 +00:00
require_line "$tiling_script" "function setStableLayout(outputName, windows)"
require_line "$tiling_script" "function cycleLayoutMode(outputName)"
require_line "$tiling_script" "function swapDraggedWindow(target)"
require_line "$tiling_script" "showDragOutline(\"swap\", target.rect)"
require_line "$tiling_script" "swapDraggedWindow(dragSwapTarget)"
2026-05-19 07:55:25 +00:00
require_line "$tiling_script" "setStableLayout(outputName, windows)"
require_line "$tiling_script" "setStableLayout(outputName, remaining)"
2026-05-19 08:00:43 +00:00
require_line "$tiling_script" "retileScreen(name)"
2026-05-22 07:39:45 +00:00
require_line "$tiling_script" "markLayoutChanged(transaction, targetName)"
2026-05-19 08:01:45 +00:00
require_line "$tiling_script" "function promoteWindow(win)"
require_line "$tiling_script" "setStableLayout(outputName, reordered)"
require_line "$tiling_script" "name: \"SHIFT Tiling Promote Primary\""
require_line "$tiling_script" "sequence: \"Meta+Shift+Return\""
require_line "$tiling_script" "name: \"SHIFT Tiling Cycle Layout\""
require_line "$tiling_script" "sequence: \"Meta+Shift+T\""
2026-05-19 07:55:25 +00:00
2026-05-22 07:39:45 +00:00
require_line "$decoration_qml" "readonly property bool windowMenuAllowed: !ShellSettings.Settings.convergenceModeEnabled"
require_line "$decoration_qml" "return root.windowMenuAllowed;"
require_line "$decoration_qml" "enabled: !root.windowMenuAllowed"
require_line "$decoration_qml" "acceptedButtons: Qt.RightButton"
require_line "$decoration_qml" "readonly property int frameThickness: decoration.client.maximized ? 0 : normalCornerRadius"
require_line "$decoration_qml" "borders.left = normalCornerRadius;"
require_line "$decoration_qml" "borders.right = normalCornerRadius;"
require_line "$decoration_qml" "borders.bottom = normalCornerRadius;"
require_line "$decoration_qml" "PathArc { x: root.width - root.cornerRadius; y: root.height; radiusX: root.cornerRadius; radiusY: root.cornerRadius }"
require_line "$decoration_qml" "PathArc { x: 0; y: root.height - root.cornerRadius; radiusX: root.cornerRadius; radiusY: root.cornerRadius }"
2026-05-22 07:39:45 +00:00
require_line "$folio_main" "readonly property int layoutMenuWindowCount: Math.max(0, ShellSettings.Settings.dynamicTilingLayoutWindowCount)"
require_line "$folio_main" "&& layoutMenuWindowCount >= 2"
require_line "$folio_main" "if (layoutMenuEnabled) {"
require_line "$folio_main" "regions.push(rightEdgeRegion)"
require_line "$folio_main" "if (layoutMenuEnabled && layoutMenuOpen)"
require_line "$folio_main" "rightEdgeHovered = false"
require_line "$folio_main" "layoutMenuHovered = false"
require_line "$folio_main" "id: rightEdgeHoverArea"
require_line "$folio_main" "convergenceChrome.rightEdgeHovered = containsMouse"
require_line "$folio_main" "width: convergenceChrome.layoutMenuEnabled ? convergenceChrome.rightEdgeHotzoneWidth : 0"
running_panel_group_disabled_count="$(grep -F "groupMode: TaskManager.TasksModel.GroupDisabled" "$running_apps_panel" | wc -l)"
if [[ "$running_panel_group_disabled_count" -ne 2 ]]; then
echo "Expected the Folio Running panel to disable grouping for both task models; found $running_panel_group_disabled_count" >&2
exit 1
fi
reject_line "$running_apps_panel" "groupMode: TaskManager.TasksModel.GroupApplications"
if awk '
/ShellSettings\.Settings\.requestDynamicTilingWindowAction\(taskCard\.windowId, action\)/ { seen = 1; next }
seen && /return/ { exit 0 }
seen && /tasksModel\.requestVirtualDesktops\(taskCard\.modelIndex, \[desktopId\]\)/ { exit 1 }
END { exit 1 }
' "$running_apps_panel"; then
echo "Expected the Folio Running panel desktop drop to fall through to TaskManager after notifying dynamic tiling" >&2
exit 1
fi
2026-05-19 07:55:25 +00:00
reject_line "$tiling_script" "targetKey = lastLeafKey(rootNode)"
reject_line "$tiling_script" "function lastLeafKey(node)"
reject_line "$tiling_script" "win.output.name !== outputName"
reject_line "$tiling_script" "const targetName = output.name"
reject_line "$tiling_script" "const desktop = win.desktops[0]"
2026-05-19 07:55:25 +00:00
reject_line "$tiling_script" "setScreenLayout(outputName, splitLeaf(rootNode, targetKey"
reject_line "$tiling_script" "function moveWindowToSplit(target)"
reject_line "$tiling_script" "function splitLeaf(node, targetKey"
reject_line "$tiling_script" "function tileInsertDirection(cursor, rect)"
reject_line "$tiling_script" "showDragOutline(\"insert\""
2026-05-19 07:46:34 +00:00
reject_line "$tiling_script" "KWinComponents.Workspace.showOutline(dragOutlineRect)"
reject_line "$tiling_script" "KWinComponents.Workspace.hideOutline()"
reject_line "$tiling_script" "property int lastWindowRequestSerial: ShellSettings.Settings.dynamicTilingWindowRequestSerial"
reject_line "$tiling_script" "property int lastLayoutRequestSerial: ShellSettings.Settings.dynamicTilingLayoutRequestSerial"
reject_line "$effect_qml" "effect.visible = true"
2026-05-19 07:46:34 +00:00
printf '%s\n' 'dynamic-tiles-motion-ok'