Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,930 changes: 1,930 additions & 0 deletions bars/widgets/ruixen.notch/NotchWindow.qml

Large diffs are not rendered by default.

2,193 changes: 200 additions & 1,993 deletions bars/widgets/ruixen.notch/Overlay.qml

Large diffs are not rendered by default.

17 changes: 11 additions & 6 deletions tests/avatar-custom-gif.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ launcher_settings_qml="$repo_dir/ruixen.launcher/extensions/settings/SettingsCon
# against launcher_settings_qml) stayed put.
profile_page_qml="$repo_dir/ruixen.launcher/extensions/settings/pages/ProfilePage.qml"
notch_qml="$repo_dir/bars/widgets/ruixen.notch/Overlay.qml"
# The avatar RENDERING (AnimatedImage, frame extraction/timer,
# MultiEffect mask swap) lives in NotchWindow.qml now -- the state
# itself (avatarAnimated = !!p.animated, reading the JSON) stays on
# Overlay.qml's own root, genuinely singleton.
notch_window_qml="$repo_dir/bars/widgets/ruixen.notch/NotchWindow.qml"
metrics_qml="$repo_dir/bars/widgets/ruixen.notch/MetricsContent.qml"

pass=0
Expand Down Expand Up @@ -53,19 +58,19 @@ check "launcher settings preview renders animated avatars directly instead of th
check "launcher settings preview keeps the MultiEffect mask for static avatars only" \
"$(grep -cF 'visible: !settingsRoot.avatarAnimated' "$profile_page_qml")" "2"
check "notch avatar uses AnimatedImage so a valid GIF can animate" \
"$(grep -c 'AnimatedImage {' "$notch_qml")" "1"
"$(grep -c 'AnimatedImage {' "$notch_window_qml")" "1"
check "notch reads avatar state to decide whether the active avatar is animated" \
"$(grep -cF 'root.avatarAnimated = !!p.animated' "$notch_qml")" "1"
check "notch switches to extracted frame sources when avatar state is animated" \
"$(grep -cF 'root.avatarFrameDir' "$notch_qml")" "2"
"$(grep -cF 'notchRoot.avatarFrameDir' "$notch_window_qml")" "2"
check "notch advances extracted avatar frames with a timer" \
"$(grep -cF 'root.avatarFrameCount > 1' "$notch_qml")" "1"
"$(grep -cF 'notchRoot.avatarFrameCount > 1' "$notch_window_qml")" "1"
check "notch renders animated avatars directly instead of through MultiEffect" \
"$(grep -cF 'visible: root.avatarAnimated' "$notch_qml")" "1"
"$(grep -cF 'visible: panel.notchRoot.avatarAnimated' "$notch_window_qml")" "1"
check "notch keeps the MultiEffect mask for static avatars only" \
"$(grep -cF 'visible: !root.avatarAnimated' "$notch_qml")" "2"
"$(grep -cF 'visible: !panel.notchRoot.avatarAnimated' "$notch_window_qml")" "2"
check "expanded health page receives animated avatar state from the notch" \
"$(grep -cF 'avatarAnimated: root.avatarAnimated' "$notch_qml")" "1"
"$(grep -cF 'avatarAnimated: panel.notchRoot.avatarAnimated' "$notch_window_qml")" "1"
check "expanded health page switches to extracted frame sources when avatar state is animated" \
"$(grep -cF 'root.avatarFrameDir' "$metrics_qml")" "1"
check "expanded health page advances extracted avatar frames with a timer" \
Expand Down
6 changes: 5 additions & 1 deletion tests/bar-popup-clearance.sh
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
repo_dir="$(cd -- "$script_dir/.." && pwd)"
bar_qml="$repo_dir/bars/v2/ruixen.bar/Bar.qml"
barpanel_qml="$repo_dir/bars/v2/ruixen.bar/BarPanel.qml"
notch_overlay_qml="$repo_dir/bars/widgets/ruixen.notch/Overlay.qml"
# Everything this file reads off the notch (margins.top, notchOuter's
# own restY/cornerSize/seamOverlap, the collapsed/expanded body size)
# is the window's own visible content -- lives in its own per-screen
# file now, see NotchWindow.qml's own header for why.
notch_overlay_qml="$repo_dir/bars/widgets/ruixen.notch/NotchWindow.qml"

pass=0
fail_count=0
Expand Down
5 changes: 4 additions & 1 deletion tests/bar-style-mode.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,11 @@ check "legacy right docked background is disabled in fullbar or when frame owns
check "notch reads shell.json to learn bar.style" \
"$(grep -m1 'readonly property string shellConfigPath:' "$notch_qml")" ' readonly property string shellConfigPath: Quickshell.env("HOME") + "/.config/omarchy/shell.json"'

# The notch's own PanelWindow visibility now lives in NotchWindow.qml --
# see its own header for why the window itself is a separate, per-screen
# file. shellConfigPath (checked above) stays on Overlay.qml's own root.
check "notch hides itself in fullbar style" \
"$(grep -m1 'visible: !root.fullscreenActive && !root.barHidden && !root.fullbarStyle' "$notch_qml")" ' visible: !root.fullscreenActive && !root.barHidden && !root.fullbarStyle'
"$(grep -m1 'visible: !notchRoot.fullscreenActive && !notchRoot.barHidden && !notchRoot.fullbarStyle' "$repo_dir/bars/widgets/ruixen.notch/NotchWindow.qml")" ' visible: !notchRoot.fullscreenActive && !notchRoot.barHidden && !notchRoot.fullbarStyle'

check "bar style helper supports fullbar" \
"$(grep -m1 'Usage: ruixen-bar-style <notch|fullbar|status>' "$style_script")" 'Usage: ruixen-bar-style <notch|fullbar|status>'
Expand Down
6 changes: 4 additions & 2 deletions tests/idle-nightlight-relay.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ set -Eeuo pipefail
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
repo_dir="$(cd -- "$script_dir/.." && pwd)"
dashboard_qml="$repo_dir/bars/widgets/ruixen.notch/DashboardContent.qml"
overlay_qml="$repo_dir/bars/widgets/ruixen.notch/Overlay.qml"
# DashboardContent's own instantiation is window content now --
# see NotchWindow.qml's own header.
notch_window_qml="$repo_dir/bars/widgets/ruixen.notch/NotchWindow.qml"

pass=0
fail_count=0
Expand Down Expand Up @@ -78,7 +80,7 @@ check "an action refreshes status immediately afterward rather than waiting up t
check "DashboardContent.qml declares panelExpanded" \
"$(grep -c 'property bool panelExpanded: false' "$dashboard_qml")" "1"
check "Overlay.qml wires panelExpanded from the real panel.expanded" \
"$(grep -c 'panelExpanded: panel\.expanded' "$overlay_qml")" "1"
"$(grep -c 'panelExpanded: panel\.expanded' "$notch_window_qml")" "1"

# --- no leftover debug scaffolding ---------------------------------------

Expand Down
5 changes: 4 additions & 1 deletion tests/notch-bar-hidden-sync.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
repo_dir="$(cd -- "$script_dir/.." && pwd)"
bar_qml="$repo_dir/bars/v2/ruixen.bar/Bar.qml"
overlay_qml="$repo_dir/bars/widgets/ruixen.notch/Overlay.qml"
# The PanelWindow's own visible: line is window content now --
# see NotchWindow.qml's own header.
notch_window_qml="$repo_dir/bars/widgets/ruixen.notch/NotchWindow.qml"

pass=0
fail_count=0
Expand Down Expand Up @@ -55,7 +58,7 @@ check "ruixen.notch watches the parent toggles directory (FileView can't observe
"$(grep -c 'path: Quickshell.env("HOME") + "/.local/state/omarchy/toggles"' "$overlay_qml" || true)" "1"

check "the notch's own PanelWindow visibility now also depends on barHidden, not fullscreen alone" \
"$(grep -c 'visible: !root.fullscreenActive && !root.barHidden' "$overlay_qml" || true)" "1"
"$(grep -c 'visible: !notchRoot.fullscreenActive && !notchRoot.barHidden' "$notch_window_qml" || true)" "1"

printf '\n%d passed, %d failed\n' "$pass" "$fail_count"
[[ "$fail_count" -eq 0 ]]
11 changes: 7 additions & 4 deletions tests/notch-kanban-gui.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
repo_dir="$(cd -- "$script_dir/.." && pwd)"
content_qml="$repo_dir/bars/widgets/ruixen.notch/KanbanContent.qml"
overlay_qml="$repo_dir/bars/widgets/ruixen.notch/Overlay.qml"
# KanbanContent's own instantiation (the color props it's fed) is
# window content now -- see NotchWindow.qml's own header.
notch_window_qml="$repo_dir/bars/widgets/ruixen.notch/NotchWindow.qml"
service_qml="$repo_dir/bars/widgets/ruixen.notch/KanbanService.qml"
model_js="$repo_dir/bars/widgets/ruixen.notch/KanbanModel.js"
run_all="$repo_dir/tests/run-all.sh"
Expand Down Expand Up @@ -141,18 +144,18 @@ check "add editor cancel uses the reusable red action button" \
"$(grep -c 'id: addCancelButton' "$content_qml")" "1"

check "Kanban confirm token is supplied from the active theme blue swatch" \
"$(grep -c 'confirmColor: root.cavaCoolColor' "$overlay_qml")" "1"
"$(grep -c 'confirmColor: panel.notchRoot.cavaCoolColor' "$notch_window_qml")" "1"

check "Kanban semantic colors are supplied from the active theme palette" \
"$(grep -E -c 'successColor: root.kanbanSuccessColor|dangerColor: root.kanbanDangerColor|warningColor: root.kanbanWarningColor' "$overlay_qml")" "4"
"$(grep -E -c 'successColor: panel.notchRoot.kanbanSuccessColor|dangerColor: panel.notchRoot.kanbanDangerColor|warningColor: panel.notchRoot.kanbanWarningColor' "$notch_window_qml")" "4"
# 4, not 3 -- WallpapersContent's own search clear "x" started reading
# the same kanbanDangerColor token too (was a hardcoded #e05252),
# a second dangerColor: match alongside Kanban's three.

check "Kanban card surface tints toward white on a light theme (nested lighter than the column it sits on), textColor on a dark one" \
"$(( $(grep -c 'root.surfaceLuminance(root.textColor) < 0.5' "$overlay_qml") + $(grep -c '? Qt.rgba(1, 1, 1, 0.65)' "$overlay_qml") ))" "2"
"$(( $(grep -c 'panel.notchRoot.surfaceLuminance(panel.notchRoot.textColor) < 0.5' "$notch_window_qml") + $(grep -c '? Qt.rgba(1, 1, 1, 0.65)' "$notch_window_qml") ))" "2"
check "Kanban editor surface is text-contrast derived for dark and light themes" \
"$(grep -c 'editorSurface: Qt.rgba(root.textColor.r, root.textColor.g, root.textColor.b, 0.075)' "$overlay_qml")" "1"
"$(grep -c 'editorSurface: Qt.rgba(panel.notchRoot.textColor.r, panel.notchRoot.textColor.g, panel.notchRoot.textColor.b, 0.075)' "$notch_window_qml")" "1"

check "Kanban idle cards use no grey outline" \
"$(( $(grep -F -c ': "transparent"' "$content_qml") + $(grep -F -c 'border.width: cardRoot.deleteArmed || cardArea.containsMouse || editButton.hovered || deleteButton.hovered ? 1.5 : 0' "$content_qml") ))" "2"
Expand Down
52 changes: 29 additions & 23 deletions tests/notch-media-viz-mode.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ set -Eeuo pipefail
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
repo_dir="$(cd -- "$script_dir/.." && pwd)"
overlay_qml="$repo_dir/bars/widgets/ruixen.notch/Overlay.qml"
# The window's own visible content (collapsed pill, cava mini feed,
# bars/wave rendering) now lives in its own per-screen file -- see
# NotchWindow.qml's own header for why. mediaVizMode/cavaWarmColor/etc.
# themselves stay genuinely singleton on Overlay.qml's own root; only
# their RENDERING (the checks below that read this file) moved.
notch_window_qml="$repo_dir/bars/widgets/ruixen.notch/NotchWindow.qml"
notch_feed="$repo_dir/bars/widgets/ruixen.notch/CavaFeed.qml"
cava_feed="$repo_dir/ruixen.cava/CavaFeed.qml"

Expand Down Expand Up @@ -64,11 +70,11 @@ check "the mini feed uses a smaller band count than the full edge-docked overlay
# --- mirroring: real bass-on-both-edges/treble-in-the-center, not a sweep --

check "displayBars doubles the real band count for the mirror fold" \
"$(grep -c 'readonly property int displayBars: compactCavaFeed.bands \* 2' "$overlay_qml")" "1"
"$(grep -c 'readonly property int displayBars: panel.notchRoot.compactCavaFeed.bands \* 2' "$notch_window_qml")" "1"
check "mirrorBandAt folds the display index around the center (distance from nearest edge)" \
"$(grep -A2 'function mirrorBandAt' "$overlay_qml" | grep -c 'Math.min(i, cavaMiniSlot.displayBars - 1 - i)')" "1"
"$(grep -A2 'function mirrorBandAt' "$notch_window_qml" | grep -c 'Math.min(i, cavaMiniSlot.displayBars - 1 - i)')" "1"
check "each rendered bar reads its level through the mirror fold, not a direct 1:1 index" \
"$(grep -c 'compactCavaFeed.levels\[cavaMiniSlot.mirrorBandAt(index)\]' "$overlay_qml")" "1"
"$(grep -c 'panel.notchRoot.compactCavaFeed.levels\[cavaMiniSlot.mirrorBandAt(index)\]' "$notch_window_qml")" "1"

# --- warm/cool theme color, same mechanism ruixen.cava/Overlay.qml uses --

Expand All @@ -79,27 +85,27 @@ check "colors are parsed from the real active theme file" \
check "a load failure falls back to Color.accent AND schedules the one-shot retry" \
"$(grep -A10 'onLoadFailed: {' "$overlay_qml" | grep -c 'cavaThemeColorsRetryTimer.restart()')" "1"
check "each bar's color comes from the warm/cool gradient function, not a flat accent" \
"$(grep -c 'color: cavaMiniSlot.barColor(index, level)' "$overlay_qml")" "1"
"$(grep -c 'color: cavaMiniSlot.barColor(index, level)' "$notch_window_qml")" "1"

# --- nowPlayingSlot: exactly 3 mutually-exclusive children + the scroll toggle --

check "the seeker is scoped to media present AND seeker mode selected" \
"$(grep -c 'visible: root.hasMedia && root.mediaVizMode === "seeker"' "$overlay_qml")" "1"
"$(grep -c 'visible: panel.notchRoot.hasMedia && panel.notchRoot.mediaVizMode === "seeker"' "$notch_window_qml")" "1"
check "the cava mini slot is scoped to media present AND cava mode selected" \
"$(grep -c 'visible: root.hasMedia && root.mediaVizMode === "cava"' "$overlay_qml")" "1"
"$(grep -c 'visible: panel.notchRoot.hasMedia && panel.notchRoot.mediaVizMode === "cava"' "$notch_window_qml")" "1"
check "the window name stays unconditional on media absence, no mode gating" \
"$(grep -c 'visible: !root.hasMedia' "$overlay_qml")" "1"
"$(grep -c 'visible: !panel.notchRoot.hasMedia' "$notch_window_qml")" "1"
# Wheel no longer toggles mode -- the seeker's own MouseArea (visible
# only in seeker mode) repurposes wheel to seek instead, and right
# click is now the only way to switch modes (see the seek-support PR's
# own follow-up commit for why: wheel scrolling the seeker used to
# accidentally jump to the visualizer).
check "right click toggles the mode on the always-present now-playing slot" \
"$(grep -c 'if (mouse.button === Qt.RightButton) {' "$overlay_qml")" "1"
"$(grep -c 'if (mouse.button === Qt.RightButton) {' "$notch_window_qml")" "1"
check "right click toggles the mode on the seeker's own MouseArea too" \
"$(grep -c 'if (mouse.button === Qt.RightButton) root.toggleMediaVizMode()' "$overlay_qml")" "1"
"$(grep -c 'if (mouse.button === Qt.RightButton) panel.notchRoot.toggleMediaVizMode()' "$notch_window_qml")" "1"
check "wheel on the seeker seeks instead of switching modes" \
"$(grep -c 'wheel.angleDelta.y > 0 ? 5 : -5' "$overlay_qml")" "1"
"$(grep -c 'wheel.angleDelta.y > 0 ? 5 : -5' "$notch_window_qml")" "1"
check "no MouseArea wheel handler still toggles the mode" \
"$(grep -c 'onWheel:.*toggleMediaVizMode' "$overlay_qml")" "0"

Expand All @@ -117,39 +123,39 @@ check "toggleCavaMiniStyle flips bars/wave and persists" \
# 2, not 1 -- both left click AND wheel now reach the same toggle
# (identical guard text in each handler), not just click alone.
check "left click AND wheel on the slot toggle style, but only while already in cava mode" \
"$(grep -c 'if (root.mediaVizMode === "cava") root.toggleCavaMiniStyle()' "$overlay_qml")" "2"
"$(grep -c 'if (panel.notchRoot.mediaVizMode === "cava") panel.notchRoot.toggleCavaMiniStyle()' "$notch_window_qml")" "2"
check "the mode/style state file round-trips both fields together" \
"$(grep -c 'mode: root.mediaVizMode, style: root.cavaMiniStyle' "$overlay_qml")" "1"

# --- bars vs. wave rendering: mutually exclusive, same mirrored data ------

check "the bars Repeater only populates in bars style (0 delegates otherwise)" \
"$(grep -c 'model: root.cavaMiniStyle === "bars" ? cavaMiniSlot.displayBars : 0' "$overlay_qml")" "1"
"$(grep -c 'model: panel.notchRoot.cavaMiniStyle === "bars" ? cavaMiniSlot.displayBars : 0' "$notch_window_qml")" "1"
check "the wave Canvas is scoped to wave style" \
"$(grep -c 'visible: root.cavaMiniStyle === "wave"' "$overlay_qml")" "1"
"$(grep -c 'visible: panel.notchRoot.cavaMiniStyle === "wave"' "$notch_window_qml")" "1"
check "the wave reads through the exact same mirror fold the bars use, not a separate index scheme" \
"$(grep -c 'compactCavaFeed.levels\[cavaMiniSlot.mirrorBandAt(i)\]' "$overlay_qml")" "1"
"$(grep -c 'panel.notchRoot.compactCavaFeed.levels\[cavaMiniSlot.mirrorBandAt(i)\]' "$notch_window_qml")" "1"
check "the wave repaints when new cava data arrives" \
"$(grep -A1 'function onLevelsChanged() { if (cavaMiniWave.visible)' "$overlay_qml" | grep -c 'requestPaint()')" "1"
"$(grep -A1 'function onLevelsChanged() { if (cavaMiniWave.visible)' "$notch_window_qml" | grep -c 'requestPaint()')" "1"
check "the wave forces a fresh paint on becoming visible, not stale cached content" \
"$(grep -c 'onVisibleChanged: if (visible) requestPaint()' "$overlay_qml")" "1"
"$(grep -c 'onVisibleChanged: if (visible) requestPaint()' "$notch_window_qml")" "1"
check "the wave is a FILLED area, not just a stroked line -- direct correction" \
"$(grep -c 'ctx.fillStyle = grad' "$overlay_qml")" "1"
"$(grep -c 'ctx.fillStyle = grad' "$notch_window_qml")" "1"
check "the fill curve is smoothed via quadratic-through-midpoints, same technique the desktop wave uses, not raw straight segments" \
"$(grep -c 'ctx.quadraticCurveTo(pts\[j\].x, pts\[j\].y, mx, my)' "$overlay_qml")" "1"
"$(grep -c 'ctx.quadraticCurveTo(pts\[j\].x, pts\[j\].y, mx, my)' "$notch_window_qml")" "1"
check "the fill starts and closes down to the bottom edge (same baseline bars grow up from)" \
"$(grep -c 'ctx.moveTo(pts\[0\].x, height)' "$overlay_qml")$(grep -c 'ctx.lineTo(pts\[n - 1\].x, height)' "$overlay_qml")" "11"
"$(grep -c 'ctx.moveTo(pts\[0\].x, height)' "$notch_window_qml")$(grep -c 'ctx.lineTo(pts\[n - 1\].x, height)' "$notch_window_qml")" "11"
check "a brighter stroke is retraced on top of the fill for definition" \
"$(grep -c 'ctx.strokeStyle = grad' "$overlay_qml")" "1"
"$(grep -c 'ctx.strokeStyle = grad' "$notch_window_qml")" "1"

# --- edge fade: opacity tapers at the outermost couple of positions -------

check "edgeFade exists, scaled down from the desktop's own fixed 6 to fit displayBars=12" \
"$(grep -c 'readonly property int edgeFadeBands: 2' "$overlay_qml")" "1"
"$(grep -c 'readonly property int edgeFadeBands: 2' "$notch_window_qml")" "1"
check "each bar's own opacity is driven by edgeFade, not always full-strength" \
"$(grep -c 'opacity: cavaMiniSlot.edgeFade(index)' "$overlay_qml")" "1"
"$(grep -c 'opacity: cavaMiniSlot.edgeFade(index)' "$notch_window_qml")" "1"
check "the wave gradient is an 8-step ramp (not 3 flat stops), each step scaled by edgeFade too" \
"$(grep -c '0.85 \* fade' "$overlay_qml")" "1"
"$(grep -c '0.85 \* fade' "$notch_window_qml")" "1"

printf '\n%d passed, %d failed\n' "$pass" "$fail_count"
[[ "$fail_count" -eq 0 ]]
2 changes: 1 addition & 1 deletion tests/notch-theme-switcher.sh
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ check "Overlay exposes toggleWallpapers on the notch IPC target" \
"$(grep -c 'function toggleWallpapers(): void' "$overlay_qml")" "1"

check "toggleWallpapers lands on the wallpapers tab when closed" \
"$(grep -A2 'function toggleWallpapers' "$overlay_qml" | grep -c 'panel.dashboardTab = 1')" "1"
"$(grep -A2 'function toggleWallpapers' "$overlay_qml" | grep -c 'root.dashboardTab = 1')" "1"

# --- The installer -----------------------------------------------------
check "install.sh recommends the wallpapers keybind" \
Expand Down
6 changes: 4 additions & 2 deletions tests/notch-wallpaper-shuffle-jump.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ set -Eeuo pipefail
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
repo_dir="$(cd -- "$script_dir/.." && pwd)"
wallpapers_qml="$repo_dir/bars/widgets/ruixen.notch/WallpapersContent.qml"
overlay_qml="$repo_dir/bars/widgets/ruixen.notch/Overlay.qml"
# These close-requests are wired on the window content now --
# see NotchWindow.qml's own header.
notch_window_qml="$repo_dir/bars/widgets/ruixen.notch/NotchWindow.qml"

pass=0
fail_count=0
Expand Down Expand Up @@ -73,7 +75,7 @@ check "all three jumps go through omarchy-shell, not a raw IPC call (resolved OM
"$(( $(grep -A2 'id: openWallpaperShuffleProc' "$wallpapers_qml" | grep -Fc '"omarchy-shell"') + $(grep -A2 'id: openWallpaperEffectsProc' "$wallpapers_qml" | grep -Fc '"omarchy-shell"') + $(grep -A2 'id: openThemeBrowserProc' "$wallpapers_qml" | grep -Fc '"omarchy-shell"') ))" "3"

check "Overlay.qml collapses the notch when any of the three jumps fire, so the launcher doesn't open with the notch still expanded underneath it" \
"$(( $(grep -Fc 'onOpenWallpaperShuffleRequested: panel.pinnedOpen = false' "$overlay_qml") + $(grep -Fc 'onOpenWallpaperEffectsRequested: panel.pinnedOpen = false' "$overlay_qml") + $(grep -Fc 'onOpenThemeBrowserRequested: panel.pinnedOpen = false' "$overlay_qml") ))" "3"
"$(( $(grep -Fc 'onOpenWallpaperShuffleRequested: panel.notchRoot.pinnedOpen = false' "$notch_window_qml") + $(grep -Fc 'onOpenWallpaperEffectsRequested: panel.notchRoot.pinnedOpen = false' "$notch_window_qml") + $(grep -Fc 'onOpenThemeBrowserRequested: panel.notchRoot.pinnedOpen = false' "$notch_window_qml") ))" "3"

printf '\n%d passed, %d failed\n' "$pass" "$fail_count"
[[ "$fail_count" -eq 0 ]]
Loading
Loading