From 7a9ce01b46363b43e5547ba5bfdec1f07b8a3404 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 00:47:17 +0200 Subject: [PATCH 01/31] build: prepare beta.16.1 release identities --- VERSION | 2 +- contracts/lifecycle-predecessors-v1.json | 63 +++++++++++++++++++ contracts/plugin-suite-v1.json | 2 +- hancore.shibumi.ai/Service.qml | 2 +- hancore.shibumi.ai/manifest.json | 2 +- hancore.shibumi.audio/Service.qml | 2 +- hancore.shibumi.audio/manifest.json | 2 +- hancore.shibumi.bar/Bar.qml | 2 +- hancore.shibumi.bar/manifest.json | 2 +- hancore.shibumi.battery/manifest.json | 2 +- hancore.shibumi.bluetooth/Service.qml | 2 +- hancore.shibumi.bluetooth/manifest.json | 2 +- hancore.shibumi.brightness/Service.qml | 2 +- hancore.shibumi.brightness/manifest.json | 2 +- hancore.shibumi.center/Service.qml | 2 +- hancore.shibumi.center/manifest.json | 2 +- .../PluginUpdateService.qml | 2 +- hancore.shibumi.control-center/manifest.json | 2 +- hancore.shibumi.cpu/Service.qml | 2 +- hancore.shibumi.cpu/manifest.json | 2 +- hancore.shibumi.gpu/manifest.json | 2 +- hancore.shibumi.media/Service.qml | 2 +- hancore.shibumi.media/manifest.json | 2 +- hancore.shibumi.memory/manifest.json | 2 +- hancore.shibumi.network/Service.qml | 2 +- hancore.shibumi.network/manifest.json | 2 +- hancore.shibumi.power-profile/manifest.json | 2 +- hancore.shibumi.power-state/Service.qml | 2 +- hancore.shibumi.power-state/manifest.json | 2 +- hancore.shibumi.quick-access/Service.qml | 2 +- hancore.shibumi.quick-access/manifest.json | 2 +- hancore.shibumi.reactor/Service.qml | 2 +- hancore.shibumi.reactor/manifest.json | 2 +- hancore.shibumi.state/Service.qml | 2 +- hancore.shibumi.state/manifest.json | 2 +- hancore.shibumi.state/runtime/Runtime.qml | 2 +- hancore.shibumi.status/Service.qml | 2 +- hancore.shibumi.status/manifest.json | 2 +- hancore.shibumi.storage/Service.qml | 2 +- hancore.shibumi.storage/manifest.json | 2 +- hancore.shibumi.telemetry/Service.qml | 2 +- hancore.shibumi.telemetry/manifest.json | 2 +- hancore.shibumi.temperature/manifest.json | 2 +- hancore.shibumi.update-center/Service.qml | 2 +- hancore.shibumi.update-center/manifest.json | 2 +- .../WorkspaceService.qml | 2 +- hancore.shibumi.workspaces/manifest.json | 2 +- packaging/package-metadata.json | 2 +- scripts/check-aur-package | 3 +- .../audio-native-backend-seam-regression.qml | 2 +- tests/audio-runtime-smoke.qml | 6 +- tests/bar-catalog-consumer-smoke.qml | 18 +++--- tests/bar-visibility-ipc-smoke.qml | 2 +- tests/catalog-service-smoke.qml | 2 +- tests/core-services-smoke.qml | 6 +- tests/fixtures/native-runtime/probe.py | 2 +- tests/fixtures/release-predecessor.json | 14 ++--- tests/gpu-selection-state-smoke.qml | 4 +- tests/host-registry-prime-smoke.qml | 8 +-- tests/media-spectrum-service-smoke.qml | 2 +- tests/native-runtime-regression.py | 4 +- tests/plugin-update-service-smoke.qml | 2 +- tests/power-deferred-smoke.qml | 2 +- tests/power-runtime-smoke.qml | 6 +- tests/power-service-runtime-smoke.qml | 2 +- tests/reactor-plugin-smoke.qml | 4 +- tests/reactor-runtime-smoke.qml | 10 +-- tests/scoped-state-regression.qml | 2 +- tests/shared-runtime-regression.qml | 16 ++--- tests/state-service-smoke.qml | 2 +- tests/status-plugin-smoke.qml | 6 +- tests/telemetry-plugins-smoke.qml | 4 +- tests/telemetry-runtime-smoke.qml | 4 +- tests/test_lifecycle_admission.py | 6 ++ tests/test_package_release.py | 12 +++- tests/test_shibumi_suite.py | 9 +++ tests/theme-palette-runtime-smoke.qml | 2 +- tests/third-party-integration-smoke.qml | 4 +- tests/widget-pipeline-diagnostics-smoke.qml | 6 +- tests/workspaces-plugin-smoke.qml | 2 +- tests/workspaces-runtime-smoke.qml | 6 +- 81 files changed, 213 insertions(+), 124 deletions(-) diff --git a/VERSION b/VERSION index 9ae57e5..a607da6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.1-beta.16 +0.1.1-beta.16.1 diff --git a/contracts/lifecycle-predecessors-v1.json b/contracts/lifecycle-predecessors-v1.json index f1c0637..b188b15 100644 --- a/contracts/lifecycle-predecessors-v1.json +++ b/contracts/lifecycle-predecessors-v1.json @@ -751,9 +751,72 @@ ], "settingsStorageVersion": 1, "sourceRevisions": [ + "4840482ec0e06a2ebd478120833d4fae1f30889e", + "05548c8d9ffdf0d37962d6e423e2a0dc21b8cd91", "package:0.1.1-beta.16" ], "suiteVersion": "0.1.1-beta.16" + }, + { + "id": "public-beta.16.1", + "payloadDigest": "aad95737d0650873140a8de723f76a75294eecc82528902a70366019bc68fd79", + "pluginDigests": { + "hancore.shibumi.bar": "f1eda2d05892d3756319e3cb4474565505f9e6ca2bbb30c4a8983d7103525b9a", + "hancore.shibumi.state": "3aed3c7a3cb92afb66d5f12d7d5c773f1988d5f11c933da187f8b31c68179da8", + "hancore.shibumi.control-center": "beb6fd4aa5f1d5a8399ed2907e22817d7dfae5422c333f7b3898ad4d25529546", + "hancore.shibumi.reactor": "347d5997e664581da56104a636af44d4675f37d311bb058b9624d8c9f6121322", + "hancore.shibumi.telemetry": "f52aff2aa784a11eab6edb12b5c3610986a01284f98844293e5cc8e1bb2963b0", + "hancore.shibumi.power-state": "f2f664b00436695dbd47edf9b8d7da46d0f4f7fbe740045023479ed707872a50", + "hancore.shibumi.workspaces": "de2a198c2a1fcbada535f046b91f37e5f5ca517ef4a0e3c6f570baf7930699c5", + "hancore.shibumi.update-center": "9f2cab591bed25ce79f886f240583cf33204d5037aa76307803454cea8eacfd3", + "hancore.shibumi.status": "8ac6a5da220dc2ce6e6cff7f69955ed0fca94a3e7a32de5e84bac880f425b165", + "hancore.shibumi.memory": "f6fbd0838180fac0740fd27d22f9fe1812528f45210e51fa9984f479f42da8f9", + "hancore.shibumi.cpu": "bb0d1df3404525a45c55fffaa2091a8340ae3d9536f7edab6e6bd56759f7999e", + "hancore.shibumi.audio": "20a3f204e0c55b6c9aff18d12e9627b91f3710596e3d1c2e00b08aaa0f3e3e4c", + "hancore.shibumi.ai": "a0f6238a89dc198ffab4528dcfda2bdddbcdf759e9daf093f9c8fc59ef1353d8", + "hancore.shibumi.center": "381a88047ed21afcf1e47a399acd5287f68664758283bb7180ae94dbcb393226", + "hancore.shibumi.media": "e67e51d2629520b6e7a4578940885b8ff2245798254af4f8ea39ce7b8d2d8c82", + "hancore.shibumi.quick-access": "4ce7d5575e758ddb3cec856672e0717f95dd494c5a4488f61e0269e534697502", + "hancore.shibumi.network": "9ee7d1725749da03e9480529bbfb22c557f6f7da534900c280f0cb031492a41d", + "hancore.shibumi.battery": "59f67a3358c5e419bb98e474a867b53630cf1ee0bcd61c44d59c5775d8c6933f", + "hancore.shibumi.brightness": "80ba42a406f9a24b675ed2daf83555e7f1da6e0442246ae093bb7800be1a8b91", + "hancore.shibumi.power-profile": "6d71528dc88132dfc2c33b22437427c9210df74cdc123dfcdd574b4a3a07113e", + "hancore.shibumi.bluetooth": "51b3271d445bfba82694d22be8d62650bcf572af63888c5ca9240adf7c8eb42b", + "hancore.shibumi.temperature": "72ac530bd97cf092349351a6c63e2ef78a9446053e7add71cfe72282704a76b4", + "hancore.shibumi.gpu": "a460b94a8f0142ce6da9318493a6343f7bdefcbd1999db3fe73c46d5ff59fa9e", + "hancore.shibumi.storage": "eb97c939b77fc88a17066bfa72ea4a1f9a0c7279d164afbc15b176f767837299" + }, + "pluginIds": [ + "hancore.shibumi.bar", + "hancore.shibumi.state", + "hancore.shibumi.control-center", + "hancore.shibumi.reactor", + "hancore.shibumi.telemetry", + "hancore.shibumi.power-state", + "hancore.shibumi.workspaces", + "hancore.shibumi.update-center", + "hancore.shibumi.status", + "hancore.shibumi.memory", + "hancore.shibumi.cpu", + "hancore.shibumi.audio", + "hancore.shibumi.ai", + "hancore.shibumi.center", + "hancore.shibumi.media", + "hancore.shibumi.quick-access", + "hancore.shibumi.network", + "hancore.shibumi.battery", + "hancore.shibumi.brightness", + "hancore.shibumi.power-profile", + "hancore.shibumi.bluetooth", + "hancore.shibumi.temperature", + "hancore.shibumi.gpu", + "hancore.shibumi.storage" + ], + "settingsStorageVersion": 1, + "sourceRevisions": [ + "package:0.1.1-beta.16.1" + ], + "suiteVersion": "0.1.1-beta.16.1" } ] } diff --git a/contracts/plugin-suite-v1.json b/contracts/plugin-suite-v1.json index 1cca875..5c6d7b6 100644 --- a/contracts/plugin-suite-v1.json +++ b/contracts/plugin-suite-v1.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "suiteId": "hancore.shibumi", - "suiteVersion": "0.1.1-beta.16", + "suiteVersion": "0.1.1-beta.16.1", "settingsStorageVersion": 1, "hostContract": "contracts/host-facade-v1.json", "retiredPlugins": [ diff --git a/hancore.shibumi.ai/Service.qml b/hancore.shibumi.ai/Service.qml index 5c9969b..fcf145b 100644 --- a/hancore.shibumi.ai/Service.qml +++ b/hancore.shibumi.ai/Service.qml @@ -19,7 +19,7 @@ Item { SuiteRuntime.HostShell { id: suiteShell; host: root.shell } SuiteRuntime.Provider { pluginId: "hancore.shibumi.ai" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.ai/manifest.json b/hancore.shibumi.ai/manifest.json index c57dd0d..1ae0281 100644 --- a/hancore.shibumi.ai/manifest.json +++ b/hancore.shibumi.ai/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.ai", "name": "Shibumi AI Usage", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Shibumi Claude, Codex, and OpenCode usage presentation.", diff --git a/hancore.shibumi.audio/Service.qml b/hancore.shibumi.audio/Service.qml index 4fa3f3f..a9f559a 100644 --- a/hancore.shibumi.audio/Service.qml +++ b/hancore.shibumi.audio/Service.qml @@ -14,7 +14,7 @@ Item { SuiteRuntime.Provider { id: runtimeProvider pluginId: "hancore.shibumi.audio" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.audio/manifest.json b/hancore.shibumi.audio/manifest.json index 36f494e..9f1ae9d 100644 --- a/hancore.shibumi.audio/manifest.json +++ b/hancore.shibumi.audio/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.audio", "name": "Shibumi Audio", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Shibumi audio presentation over Omarchy's PipeWire owner.", diff --git a/hancore.shibumi.bar/Bar.qml b/hancore.shibumi.bar/Bar.qml index d864f38..971639e 100644 --- a/hancore.shibumi.bar/Bar.qml +++ b/hancore.shibumi.bar/Bar.qml @@ -27,7 +27,7 @@ Item { SuiteRuntime.Provider { id: barRuntimeProvider pluginId: "hancore.shibumi.bar" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: suiteHostShell.host manifest: root.manifest diff --git a/hancore.shibumi.bar/manifest.json b/hancore.shibumi.bar/manifest.json index 4602856..88247d4 100644 --- a/hancore.shibumi.bar/manifest.json +++ b/hancore.shibumi.bar/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.bar", "name": "Shibumi Bar", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "The Shibumi full-bar host for Omarchy Shell.", diff --git a/hancore.shibumi.battery/manifest.json b/hancore.shibumi.battery/manifest.json index 3944a0b..553c9c6 100644 --- a/hancore.shibumi.battery/manifest.json +++ b/hancore.shibumi.battery/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.battery", "name": "Shibumi Battery", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Shibumi battery status and detailed battery panel.", diff --git a/hancore.shibumi.bluetooth/Service.qml b/hancore.shibumi.bluetooth/Service.qml index 2915c3b..2efb242 100644 --- a/hancore.shibumi.bluetooth/Service.qml +++ b/hancore.shibumi.bluetooth/Service.qml @@ -15,7 +15,7 @@ Item { SuiteRuntime.HostShell { id: suiteShell; host: root.shell } SuiteRuntime.Provider { pluginId: "hancore.shibumi.bluetooth" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.bluetooth/manifest.json b/hancore.shibumi.bluetooth/manifest.json index 6f8a7ed..e6f52f0 100644 --- a/hancore.shibumi.bluetooth/manifest.json +++ b/hancore.shibumi.bluetooth/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.bluetooth", "name": "Shibumi Bluetooth", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Shibumi Bluetooth presentation with a native BlueZ and audio backend.", diff --git a/hancore.shibumi.brightness/Service.qml b/hancore.shibumi.brightness/Service.qml index 044e4e7..667b781 100644 --- a/hancore.shibumi.brightness/Service.qml +++ b/hancore.shibumi.brightness/Service.qml @@ -13,7 +13,7 @@ Item { property var manifest: null SuiteRuntime.Provider { pluginId: "hancore.shibumi.brightness" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.brightness/manifest.json b/hancore.shibumi.brightness/manifest.json index 9047b3c..52f801c 100644 --- a/hancore.shibumi.brightness/manifest.json +++ b/hancore.shibumi.brightness/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.brightness", "name": "Shibumi Brightness", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Shibumi brightness and display presentation over Omarchy's monitor owner.", diff --git a/hancore.shibumi.center/Service.qml b/hancore.shibumi.center/Service.qml index acd130e..b010832 100644 --- a/hancore.shibumi.center/Service.qml +++ b/hancore.shibumi.center/Service.qml @@ -10,7 +10,7 @@ Item { property var manifest: null SuiteRuntime.Provider { pluginId: "hancore.shibumi.center" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.center/manifest.json b/hancore.shibumi.center/manifest.json index 0214485..eb287cc 100644 --- a/hancore.shibumi.center/manifest.json +++ b/hancore.shibumi.center/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.center", "name": "Shibumi Center", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Shibumi clock, calendar, weather, status, and update center.", diff --git a/hancore.shibumi.control-center/PluginUpdateService.qml b/hancore.shibumi.control-center/PluginUpdateService.qml index abc0aff..abf88d2 100644 --- a/hancore.shibumi.control-center/PluginUpdateService.qml +++ b/hancore.shibumi.control-center/PluginUpdateService.qml @@ -20,7 +20,7 @@ Item { SuiteRuntime.Provider { id: runtimeProvider pluginId: "hancore.shibumi.control-center" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.control-center/manifest.json b/hancore.shibumi.control-center/manifest.json index a41355b..d3f97a3 100644 --- a/hancore.shibumi.control-center/manifest.json +++ b/hancore.shibumi.control-center/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.control-center", "name": "Shibumi Control Center", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Shibumi G1 presentation and bar configuration panel.", diff --git a/hancore.shibumi.cpu/Service.qml b/hancore.shibumi.cpu/Service.qml index fca2904..9afd6df 100644 --- a/hancore.shibumi.cpu/Service.qml +++ b/hancore.shibumi.cpu/Service.qml @@ -13,7 +13,7 @@ Item { SuiteRuntime.Provider { id: runtimeProvider pluginId: "hancore.shibumi.cpu" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.cpu/manifest.json b/hancore.shibumi.cpu/manifest.json index 62888c0..ed5d387 100644 --- a/hancore.shibumi.cpu/manifest.json +++ b/hancore.shibumi.cpu/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.cpu", "name": "Shibumi CPU", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Shibumi CPU widget, GPU sampler, and detailed usage panel.", diff --git a/hancore.shibumi.gpu/manifest.json b/hancore.shibumi.gpu/manifest.json index 5548422..6ae26bb 100644 --- a/hancore.shibumi.gpu/manifest.json +++ b/hancore.shibumi.gpu/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.gpu", "name": "Shibumi GPU", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Lazy GPU load, hardware, driver, temperature, and VRAM widget.", diff --git a/hancore.shibumi.media/Service.qml b/hancore.shibumi.media/Service.qml index cf501cd..525c8b5 100644 --- a/hancore.shibumi.media/Service.qml +++ b/hancore.shibumi.media/Service.qml @@ -18,7 +18,7 @@ Item { SuiteRuntime.Provider { id: runtimeProvider pluginId: "hancore.shibumi.media" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.media/manifest.json b/hancore.shibumi.media/manifest.json index 4e2248f..dc45ff1 100644 --- a/hancore.shibumi.media/manifest.json +++ b/hancore.shibumi.media/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.media", "name": "Shibumi Media", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Shibumi media controls over Omarchy's MPRIS service.", diff --git a/hancore.shibumi.memory/manifest.json b/hancore.shibumi.memory/manifest.json index 234860a..bb02043 100644 --- a/hancore.shibumi.memory/manifest.json +++ b/hancore.shibumi.memory/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.memory", "name": "Shibumi Memory", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Shibumi memory widget and detailed memory panel.", diff --git a/hancore.shibumi.network/Service.qml b/hancore.shibumi.network/Service.qml index 833e81a..5d7af9b 100644 --- a/hancore.shibumi.network/Service.qml +++ b/hancore.shibumi.network/Service.qml @@ -15,7 +15,7 @@ Item { property var manifest: null SuiteRuntime.Provider { pluginId: "hancore.shibumi.network" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.network/manifest.json b/hancore.shibumi.network/manifest.json index 0a3f0b9..5635a96 100644 --- a/hancore.shibumi.network/manifest.json +++ b/hancore.shibumi.network/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.network", "name": "Shibumi Network", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Native Shibumi NetworkManager ownership, telemetry, actions, QR, and speed testing.", diff --git a/hancore.shibumi.power-profile/manifest.json b/hancore.shibumi.power-profile/manifest.json index 7571ccb..d53796e 100644 --- a/hancore.shibumi.power-profile/manifest.json +++ b/hancore.shibumi.power-profile/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.power-profile", "name": "Shibumi Power Profile", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Shibumi power-profile status and profile selector.", diff --git a/hancore.shibumi.power-state/Service.qml b/hancore.shibumi.power-state/Service.qml index 07fa555..a787714 100644 --- a/hancore.shibumi.power-state/Service.qml +++ b/hancore.shibumi.power-state/Service.qml @@ -23,7 +23,7 @@ Item { SuiteRuntime.Provider { id: runtimeProvider pluginId: "hancore.shibumi.power-state" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.power-state/manifest.json b/hancore.shibumi.power-state/manifest.json index 852d243..8ab5b05 100644 --- a/hancore.shibumi.power-state/manifest.json +++ b/hancore.shibumi.power-state/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.power-state", "name": "Shibumi Power State", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Shared battery and power-profile state for Shibumi widgets.", diff --git a/hancore.shibumi.quick-access/Service.qml b/hancore.shibumi.quick-access/Service.qml index a2b3980..9c7e3f5 100644 --- a/hancore.shibumi.quick-access/Service.qml +++ b/hancore.shibumi.quick-access/Service.qml @@ -18,7 +18,7 @@ Item { SuiteRuntime.HostShell { id: suiteShell; host: root.shell } SuiteRuntime.Provider { pluginId: "hancore.shibumi.quick-access" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.quick-access/manifest.json b/hancore.shibumi.quick-access/manifest.json index 879c88b..4f554c4 100644 --- a/hancore.shibumi.quick-access/manifest.json +++ b/hancore.shibumi.quick-access/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.quick-access", "name": "Shibumi Quick Access", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Shibumi idle inhibitor and theme, wallpaper, screenshot, and video pickers.", diff --git a/hancore.shibumi.reactor/Service.qml b/hancore.shibumi.reactor/Service.qml index 3f7aea8..26cfd6a 100644 --- a/hancore.shibumi.reactor/Service.qml +++ b/hancore.shibumi.reactor/Service.qml @@ -18,7 +18,7 @@ Item { SuiteRuntime.Provider { id: runtimeProvider pluginId: "hancore.shibumi.reactor" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.reactor/manifest.json b/hancore.shibumi.reactor/manifest.json index 9f041af..6d5fa81 100644 --- a/hancore.shibumi.reactor/manifest.json +++ b/hancore.shibumi.reactor/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.reactor", "name": "Shibumi Reactor", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Shibumi event and quote Reactor service for compatible bar styles.", diff --git a/hancore.shibumi.state/Service.qml b/hancore.shibumi.state/Service.qml index 6e5a765..bb16892 100644 --- a/hancore.shibumi.state/Service.qml +++ b/hancore.shibumi.state/Service.qml @@ -16,7 +16,7 @@ Item { SuiteRuntime.Provider { id: runtimeProvider pluginId: "hancore.shibumi.state" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.state/manifest.json b/hancore.shibumi.state/manifest.json index 7d0cc81..4429365 100644 --- a/hancore.shibumi.state/manifest.json +++ b/hancore.shibumi.state/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.state", "name": "Shibumi State", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Normalized Shibumi configuration and theme palette state.", diff --git a/hancore.shibumi.state/runtime/Runtime.qml b/hancore.shibumi.state/runtime/Runtime.qml index a874346..02af8e6 100644 --- a/hancore.shibumi.state/runtime/Runtime.qml +++ b/hancore.shibumi.state/runtime/Runtime.qml @@ -10,7 +10,7 @@ QtObject { id: runtime readonly property int contractVersion: 1 - readonly property string suiteVersion: "0.1.1-beta.16" + readonly property string suiteVersion: "0.1.1-beta.16.1" readonly property var providerIds: [ "hancore.shibumi.state", "hancore.shibumi.control-center", "hancore.shibumi.reactor", "hancore.shibumi.telemetry", diff --git a/hancore.shibumi.status/Service.qml b/hancore.shibumi.status/Service.qml index b93a81f..1188a1f 100644 --- a/hancore.shibumi.status/Service.qml +++ b/hancore.shibumi.status/Service.qml @@ -16,7 +16,7 @@ Item { SuiteRuntime.HostShell { id: suiteShell; host: root.shell } SuiteRuntime.Provider { pluginId: "hancore.shibumi.status" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.status/manifest.json b/hancore.shibumi.status/manifest.json index f12bc7f..56ec825 100644 --- a/hancore.shibumi.status/manifest.json +++ b/hancore.shibumi.status/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.status", "name": "Shibumi Status", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Shibumi tray and notification composition with shared desktop status state.", diff --git a/hancore.shibumi.storage/Service.qml b/hancore.shibumi.storage/Service.qml index beeb4f0..bcc8e49 100644 --- a/hancore.shibumi.storage/Service.qml +++ b/hancore.shibumi.storage/Service.qml @@ -13,7 +13,7 @@ Item { SuiteRuntime.Provider { id: runtimeProvider pluginId: "hancore.shibumi.storage" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.storage/manifest.json b/hancore.shibumi.storage/manifest.json index 57a72e0..a8da307 100644 --- a/hancore.shibumi.storage/manifest.json +++ b/hancore.shibumi.storage/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.storage", "name": "Shibumi Storage", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Read-only root usage and physical drive inventory.", diff --git a/hancore.shibumi.telemetry/Service.qml b/hancore.shibumi.telemetry/Service.qml index 04877df..807a6e7 100644 --- a/hancore.shibumi.telemetry/Service.qml +++ b/hancore.shibumi.telemetry/Service.qml @@ -15,7 +15,7 @@ Item { SuiteRuntime.Provider { id: runtimeProvider pluginId: "hancore.shibumi.telemetry" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.telemetry/manifest.json b/hancore.shibumi.telemetry/manifest.json index 64c8b58..4ab3418 100644 --- a/hancore.shibumi.telemetry/manifest.json +++ b/hancore.shibumi.telemetry/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.telemetry", "name": "Shibumi Telemetry", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Demand-driven CPU and memory telemetry shared by Shibumi widgets.", diff --git a/hancore.shibumi.temperature/manifest.json b/hancore.shibumi.temperature/manifest.json index 9b88dd5..e4ead09 100644 --- a/hancore.shibumi.temperature/manifest.json +++ b/hancore.shibumi.temperature/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.temperature", "name": "Shibumi Temperature", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Demand-driven hardware temperature widget and sensor panel.", diff --git a/hancore.shibumi.update-center/Service.qml b/hancore.shibumi.update-center/Service.qml index adbfd37..2a106d9 100644 --- a/hancore.shibumi.update-center/Service.qml +++ b/hancore.shibumi.update-center/Service.qml @@ -12,7 +12,7 @@ Item { property var manifest: null SuiteRuntime.Provider { pluginId: "hancore.shibumi.update-center" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.update-center/manifest.json b/hancore.shibumi.update-center/manifest.json index 4c112da..320f8d5 100644 --- a/hancore.shibumi.update-center/manifest.json +++ b/hancore.shibumi.update-center/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.update-center", "name": "Shibumi Update Center", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Safe repository package and user theme update status for Shibumi.", diff --git a/hancore.shibumi.workspaces/WorkspaceService.qml b/hancore.shibumi.workspaces/WorkspaceService.qml index 1f31231..4ec8f38 100644 --- a/hancore.shibumi.workspaces/WorkspaceService.qml +++ b/hancore.shibumi.workspaces/WorkspaceService.qml @@ -14,7 +14,7 @@ Item { SuiteRuntime.Provider { id: runtimeProvider pluginId: "hancore.shibumi.workspaces" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: root host: root.shell manifest: root.manifest diff --git a/hancore.shibumi.workspaces/manifest.json b/hancore.shibumi.workspaces/manifest.json index 602cab8..7f40b6f 100644 --- a/hancore.shibumi.workspaces/manifest.json +++ b/hancore.shibumi.workspaces/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "hancore.shibumi.workspaces", "name": "Shibumi Workspaces", - "version": "0.1.1-beta.16", + "version": "0.1.1-beta.16.1", "author": "HANCORE", "license": "MIT", "description": "Shared Hyprland workspace state with the Shibumi workspace presentation.", diff --git a/packaging/package-metadata.json b/packaging/package-metadata.json index 0bb141b..c369f9e 100644 --- a/packaging/package-metadata.json +++ b/packaging/package-metadata.json @@ -1,5 +1,5 @@ { "schemaVersion": 1, "packageName": "shibumi-shell", - "version": "0.1.1-beta.16" + "version": "0.1.1-beta.16.1" } diff --git a/scripts/check-aur-package b/scripts/check-aur-package index c79fd33..0107b58 100755 --- a/scripts/check-aur-package +++ b/scripts/check-aur-package @@ -44,7 +44,8 @@ jq -e '.schemaVersion == 1 and (.states | map(.id)) == [ "public-beta.11", "step-5-tip", "public-beta.12", "public-beta.13", "source-beta.14", "public-beta.14.1", "public-beta.15", "public-beta.15.1", - "public-beta.15.2", "public-beta.15.3", "public-beta.15.4", "public-beta.16" + "public-beta.15.2", "public-beta.15.3", "public-beta.15.4", "public-beta.16", + "public-beta.16.1" ]' \ contracts/lifecycle-predecessors-v1.json >/dev/null grep -Fq 'contracts/lifecycle-predecessors-v1.json' "$pkgbuild" || { diff --git a/tests/audio-native-backend-seam-regression.qml b/tests/audio-native-backend-seam-regression.qml index 8c8645b..178c4fb 100644 --- a/tests/audio-native-backend-seam-regression.qml +++ b/tests/audio-native-backend-seam-regression.qml @@ -174,7 +174,7 @@ ShellRoot { Audio.Service { id: service shell: serviceHost - manifest: ({id: "hancore.shibumi.audio", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.audio", version: "0.1.1-beta.16.1", kinds: ["service"]}) nativeBackendEnabled: true nativeBackendOverride: fakeBackend } diff --git a/tests/audio-runtime-smoke.qml b/tests/audio-runtime-smoke.qml index cdc3824..8b7880a 100644 --- a/tests/audio-runtime-smoke.qml +++ b/tests/audio-runtime-smoke.qml @@ -11,7 +11,7 @@ ShellRoot { property var savedPanel: null property real originalRadius: 0 property var audioManifest: ({id: "hancore.shibumi.audio", - version: "0.1.1-beta.16", kinds: ["service", "bar-widget"]}) + version: "0.1.1-beta.16.1", kinds: ["service", "bar-widget"]}) function check(value, message) { if (value) return console.error("audio-runtime-smoke:", message) @@ -48,9 +48,9 @@ ShellRoot { SuiteRuntime.Provider { id: stateProvider pluginId: "hancore.shibumi.state" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: tokenState - manifest: ({id: "hancore.shibumi.state", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.state", version: "0.1.1-beta.16.1", kinds: ["service"]}) } Fixtures.AudioRuntimeBackend { id: backend } Audio.Service { id: service; nativeBackendOverride: backend } diff --git a/tests/bar-catalog-consumer-smoke.qml b/tests/bar-catalog-consumer-smoke.qml index 2685111..aa8cfc8 100644 --- a/tests/bar-catalog-consumer-smoke.qml +++ b/tests/bar-catalog-consumer-smoke.qml @@ -67,10 +67,10 @@ ShellRoot { SuiteRuntime.Provider { id: stateProvider pluginId: "hancore.shibumi.state" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: stateService host: stateHost - manifest: ({ id: "hancore.shibumi.state", version: "0.1.1-beta.16", + manifest: ({ id: "hancore.shibumi.state", version: "0.1.1-beta.16.1", kinds: ["service"] }) } @@ -92,7 +92,7 @@ ShellRoot { id: fakePluginRegistry property string pluginId: "hancore.shibumi.bar" property var manifest: ({ id: "hancore.shibumi.bar", - version: "0.1.1-beta.16", kinds: ["bar"] }) + version: "0.1.1-beta.16.1", kinds: ["bar"] }) property bool enabled: true property var _entryPointUrl: null readonly property var installedPlugins: { @@ -138,11 +138,11 @@ ShellRoot { property int catalogReadSerial: currentObservation ? currentObservation.serial : 0 property int catalogGeneration: currentObservation ? currentObservation.generation : 0 property var providerManifest: ({ id: "hancore.shibumi.control-center", - version: "0.1.1-beta.16", kinds: ["service"] }) + version: "0.1.1-beta.16.1", kinds: ["service"] }) QtObject { id: serviceHost; property string pluginId: "hancore.shibumi.control-center" } SuiteRuntime.Provider { pluginId: "hancore.shibumi.control-center" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: service host: serviceHost manifest: service.providerManifest @@ -192,7 +192,7 @@ ShellRoot { root.bar = barFactory.createObject(root, { omarchyPath: "/fixture/omarchy", shell: scopedBarHost, - manifest: ({ id: "hancore.shibumi.bar", version: "0.1.1-beta.16", + manifest: ({ id: "hancore.shibumi.bar", version: "0.1.1-beta.16.1", kinds: ["bar"] }), pluginRegistry: fakePluginRegistry, barWidgetRegistry: fakeWidgetRegistry, @@ -243,7 +243,7 @@ ShellRoot { // pluginsChanged signal for Bar's legacy listener to receive. fakePluginRegistry.enabled = false fakePluginRegistry.manifest = ({ id: "hancore.shibumi.bar", - version: "0.1.1-beta.16-metadata", kinds: ["bar"] }) + version: "0.1.1-beta.16.1-metadata", kinds: ["bar"] }) root.stage = 20; root.waits = 0 } else if (root.stage === 20) { if (root.waits < 3) return @@ -339,7 +339,7 @@ ShellRoot { } else if (root.stage === 4) { if (root.firstService.acquireCalls !== 2) return root.firstService.providerManifest = ({ id: "invalid", - version: "0.1.1-beta.16", kinds: ["service"] }) + version: "0.1.1-beta.16.1", kinds: ["service"] }) root.stage = 5; root.waits = 0 } else if (root.stage === 5) { if (root.firstService.releaseCalls !== 2) return @@ -365,7 +365,7 @@ ShellRoot { || root.replacementService.acquireCalls !== 1) root.fail("shutdown retained or reacquired the catalog consumer") fakePluginRegistry.manifest = ({ id: "hancore.shibumi.bar", - version: "0.1.1-beta.16-shutdown", kinds: ["bar"] }) + version: "0.1.1-beta.16.1-shutdown", kinds: ["bar"] }) if (root.bar.providerRegistryRevision !== providerRevision) root.fail("shutdown accepted a late scoped registry publication") root.stage = 8; root.waits = 0 diff --git a/tests/bar-visibility-ipc-smoke.qml b/tests/bar-visibility-ipc-smoke.qml index 4d4bc91..49ec570 100644 --- a/tests/bar-visibility-ipc-smoke.qml +++ b/tests/bar-visibility-ipc-smoke.qml @@ -60,7 +60,7 @@ ShellRoot { shell: fakeShell manifest: ({ id: "hancore.shibumi.bar", - version: "0.1.1-beta.16", + version: "0.1.1-beta.16.1", kinds: ["bar"] }) pluginRegistry: fakePluginRegistry diff --git a/tests/catalog-service-smoke.qml b/tests/catalog-service-smoke.qml index 86fdb88..3e5dce0 100644 --- a/tests/catalog-service-smoke.qml +++ b/tests/catalog-service-smoke.qml @@ -62,7 +62,7 @@ Scope { } } function manifest(valid) { - return {id: "hancore.shibumi.control-center", version: valid ? "0.1.1-beta.16" : "invalid", + return {id: "hancore.shibumi.control-center", version: valid ? "0.1.1-beta.16.1" : "invalid", kinds: ["service", "bar-widget"]} } function changedCatalogOutput() { diff --git a/tests/core-services-smoke.qml b/tests/core-services-smoke.qml index c87af67..790fd85 100644 --- a/tests/core-services-smoke.qml +++ b/tests/core-services-smoke.qml @@ -20,14 +20,14 @@ ShellRoot { id: telemetry shell: fakeShell thermalProbeEnabled: false - manifest: ({id: "hancore.shibumi.telemetry", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.telemetry", version: "0.1.1-beta.16.1", kinds: ["service"]}) } Cpu.Service { id: cpu shell: fakeShell gpuProbeEnabled: false - manifest: ({id: "hancore.shibumi.cpu", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.cpu", version: "0.1.1-beta.16.1", kinds: ["service"]}) } QtObject { @@ -40,7 +40,7 @@ ShellRoot { PowerState.Service { id: power shell: fakeShell - manifest: ({id: "hancore.shibumi.power-state", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.power-state", version: "0.1.1-beta.16.1", kinds: ["service"]}) batterySnapshotOverride: ({ready: false}) commandOverrides: ({}) // This pure projection smoke may never launch helpers. } diff --git a/tests/fixtures/native-runtime/probe.py b/tests/fixtures/native-runtime/probe.py index c005166..c4b0ccc 100644 --- a/tests/fixtures/native-runtime/probe.py +++ b/tests/fixtures/native-runtime/probe.py @@ -132,7 +132,7 @@ def catalog_probe(): "actual native catalog identity DTO mismatch") control = ready["snapshot"]["byId"]["hancore.shibumi.control-center"] check(control["description"] and control["author"] == "HANCORE" - and control["version"] == "0.1.1-beta.16" + and control["version"] == "0.1.1-beta.16.1" and control["barWidget"]["defaultSection"] == "left", "package-bound catalog presentation metadata was lost") check(host_config() == original, "read-only catalog changed native config") diff --git a/tests/fixtures/release-predecessor.json b/tests/fixtures/release-predecessor.json index a581275..7366614 100644 --- a/tests/fixtures/release-predecessor.json +++ b/tests/fixtures/release-predecessor.json @@ -1,11 +1,11 @@ { "schemaVersion": 1, - "version": "0.1.1-beta.15.4", - "tag": "v0.1.1-beta.15.4", - "revision": "6594b989c9f5edfe557669b0413a9bd3e50f8e81", - "payloadDigest": "5686a127809125ea0b715f41fd4cf9d9bc6817b372ce8b0370dcb42337a616fa", - "releaseId": 398113071, - "releaseUrl": "https://github.com/HANCORE-linux/Shibumi-Shell/releases/tag/v0.1.1-beta.15.4", - "publishedAt": "2026-09-28T09:37:58Z", + "version": "0.1.1-beta.16", + "tag": "v0.1.1-beta.16", + "revision": "4840482ec0e06a2ebd478120833d4fae1f30889e", + "payloadDigest": "f08b4ec613f248fda62d7dec9865ea46a846fa2e91b2723a186adc0ab0bffc41", + "releaseId": 402148882, + "releaseUrl": "https://github.com/HANCORE-linux/Shibumi-Shell/releases/tag/v0.1.1-beta.16", + "publishedAt": "2026-10-02T20:54:44Z", "prerelease": true } diff --git a/tests/gpu-selection-state-smoke.qml b/tests/gpu-selection-state-smoke.qml index bd5a5b1..cc06530 100644 --- a/tests/gpu-selection-state-smoke.qml +++ b/tests/gpu-selection-state-smoke.qml @@ -25,13 +25,13 @@ ShellRoot { id: stateService shell: fakeShell omarchyPath: Quickshell.env("OMARCHY_PATH") - manifest: ({id: "hancore.shibumi.state", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.state", version: "0.1.1-beta.16.1", kinds: ["service"]}) } Cpu.Service { id: cpuService shell: fakeShell - manifest: ({id: "hancore.shibumi.cpu", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.cpu", version: "0.1.1-beta.16.1", kinds: ["service"]}) gpuProbeEnabled: false } diff --git a/tests/host-registry-prime-smoke.qml b/tests/host-registry-prime-smoke.qml index 0eee019..a8710d7 100644 --- a/tests/host-registry-prime-smoke.qml +++ b/tests/host-registry-prime-smoke.qml @@ -50,11 +50,11 @@ ShellRoot { Shared.Provider { id: stateProvider pluginId: "hancore.shibumi.state" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: stateOwner host: stateHost manifest: ({ id: "hancore.shibumi.state", - version: "0.1.1-beta.16", kinds: ["service"] }) + version: "0.1.1-beta.16.1", kinds: ["service"] }) } QtObject { @@ -77,11 +77,11 @@ ShellRoot { } Shared.Provider { pluginId: "hancore.shibumi.bar" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: owner host: owner.providerHost manifest: ({ id: "hancore.shibumi.bar", - version: "0.1.1-beta.16", kinds: ["bar"] }) + version: "0.1.1-beta.16.1", kinds: ["bar"] }) } } } diff --git a/tests/media-spectrum-service-smoke.qml b/tests/media-spectrum-service-smoke.qml index 0a4caae..27b3ab6 100644 --- a/tests/media-spectrum-service-smoke.qml +++ b/tests/media-spectrum-service-smoke.qml @@ -42,7 +42,7 @@ ShellRoot { Media.Service { id: spectrum shell: fakeShell - manifest: ({id: "hancore.shibumi.media", version: "0.1.1-beta.16", kinds: ["service", "bar-widget"]}) + manifest: ({id: "hancore.shibumi.media", version: "0.1.1-beta.16.1", kinds: ["service", "bar-widget"]}) } Timer { diff --git a/tests/native-runtime-regression.py b/tests/native-runtime-regression.py index d41bede..5538460 100644 --- a/tests/native-runtime-regression.py +++ b/tests/native-runtime-regression.py @@ -94,7 +94,7 @@ def stage(base, native): "suiteId": "hancore.shibumi", "suitePayloadDigest": "a" * 64})) (shibumi_audio / "manifest.json").write_text(json.dumps({ "schemaVersion": 1, "id": "hancore.shibumi.audio", "name": "Shibumi Audio", - "version": "0.1.1-beta.16", "kinds": ["bar-widget"], + "version": "0.1.1-beta.16.1", "kinds": ["bar-widget"], "entryPoints": {"barWidget": "Widget.qml"}, "x-shibumi": {"suiteId": "hancore.shibumi"}, "barWidget": {"displayName": "Shibumi Audio", "category": "Audio", @@ -109,7 +109,7 @@ def stage(base, native): "suiteId": "hancore.shibumi", "suitePayloadDigest": "a" * 64})) (shibumi_cpu / "manifest.json").write_text(json.dumps({ "schemaVersion": 1, "id": "hancore.shibumi.cpu", "name": "Shibumi CPU", - "version": "0.1.1-beta.16", "kinds": ["bar-widget"], + "version": "0.1.1-beta.16.1", "kinds": ["bar-widget"], "entryPoints": {"barWidget": "Widget.qml"}, "x-shibumi": {"suiteId": "hancore.shibumi"}, "barWidget": {"displayName": "Shibumi CPU", "category": "System", diff --git a/tests/plugin-update-service-smoke.qml b/tests/plugin-update-service-smoke.qml index e163d66..6a5fbf9 100644 --- a/tests/plugin-update-service-smoke.qml +++ b/tests/plugin-update-service-smoke.qml @@ -209,7 +209,7 @@ ShellRoot { if (service.available || service.check(true)) return root.fail("scoped update worker started before manifest admission") service.manifest = {id: "hancore.shibumi.control-center", - version: "0.1.1-beta.16", kinds: ["service", "bar-widget"]} + version: "0.1.1-beta.16.1", kinds: ["service", "bar-widget"]} root.phase++ root.ticks = 0 return diff --git a/tests/power-deferred-smoke.qml b/tests/power-deferred-smoke.qml index 0bd4035..15c4adf 100644 --- a/tests/power-deferred-smoke.qml +++ b/tests/power-deferred-smoke.qml @@ -57,7 +57,7 @@ ShellRoot { PowerState.Service { id: power shell: host - manifest: root.allowed ? ({id: "hancore.shibumi.power-state", version: "0.1.1-beta.16", kinds: ["service"]}) : null + manifest: root.allowed ? ({id: "hancore.shibumi.power-state", version: "0.1.1-beta.16.1", kinds: ["service"]}) : null batterySnapshotOverride: battery commandOverrides: ({ profiles: ["/usr/bin/python3", "-I", root.helper, root.directory, "profiles"], diff --git a/tests/power-runtime-smoke.qml b/tests/power-runtime-smoke.qml index 7f283ae..9fbee18 100644 --- a/tests/power-runtime-smoke.qml +++ b/tests/power-runtime-smoke.qml @@ -24,7 +24,7 @@ ShellRoot { readonly property var power: serviceLoader.item readonly property string fixturePath: Quickshell.env("SHIBUMI_POWER_SCOPE_DIR") readonly property string helper: decodeURIComponent(String(Qt.resolvedUrl("fixtures/power-runtime-helper.py")).substring(7)) - readonly property var validManifest: ({ id: "hancore.shibumi.power-state", version: "0.1.1-beta.16", kinds: ["service"], entryPoints: { service: "Service.qml" } }) + readonly property var validManifest: ({ id: "hancore.shibumi.power-state", version: "0.1.1-beta.16.1", kinds: ["service"], entryPoints: { service: "Service.qml" } }) readonly property var fakeCommands: ({ profiles: ["/usr/bin/python3", "-I", helper, fixturePath, "profiles"], activeProfile: ["/usr/bin/python3", "-I", helper, fixturePath, "activeProfile"], @@ -55,10 +55,10 @@ ShellRoot { } SuiteRuntime.Provider { pluginId: "hancore.shibumi.state" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: state host: root.stateEnabled ? stateHost : null - manifest: ({ id: "hancore.shibumi.state", version: "0.1.1-beta.16", kinds: ["service"] }) + manifest: ({ id: "hancore.shibumi.state", version: "0.1.1-beta.16.1", kinds: ["service"] }) } QtObject { id: battery diff --git a/tests/power-service-runtime-smoke.qml b/tests/power-service-runtime-smoke.qml index 11ef04c..c8d6f26 100644 --- a/tests/power-service-runtime-smoke.qml +++ b/tests/power-service-runtime-smoke.qml @@ -14,7 +14,7 @@ ShellRoot { PowerState.Service { id: power shell: scopedHost - manifest: ({ id: "hancore.shibumi.power-state", version: "0.1.1-beta.16", + manifest: ({ id: "hancore.shibumi.power-state", version: "0.1.1-beta.16.1", kinds: ["service"], entryPoints: { service: "Service.qml" } }) batterySnapshotOverride: ({ ready: false }) commandOverrides: ({ diff --git a/tests/reactor-plugin-smoke.qml b/tests/reactor-plugin-smoke.qml index 3dce879..6e2ef21 100644 --- a/tests/reactor-plugin-smoke.qml +++ b/tests/reactor-plugin-smoke.qml @@ -76,7 +76,7 @@ ShellRoot { Audio.Service { id: fakeAudio shell: fakeShell - manifest: ({id: "hancore.shibumi.audio", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.audio", version: "0.1.1-beta.16.1", kinds: ["service"]}) nativeBackendEnabled: false } @@ -115,7 +115,7 @@ ShellRoot { Reactor.Service { id: reactorService - manifest: ({id: "hancore.shibumi.reactor", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.reactor", version: "0.1.1-beta.16.1", kinds: ["service"]}) shell: fakeShell runtimeProbesEnabled: false } diff --git a/tests/reactor-runtime-smoke.qml b/tests/reactor-runtime-smoke.qml index 5428057..e98a02a 100644 --- a/tests/reactor-runtime-smoke.qml +++ b/tests/reactor-runtime-smoke.qml @@ -16,7 +16,7 @@ ShellRoot { property int beforeLoss: 0 property var cachedMode: null property var cachedTest: null - readonly property var manifest: ({id: "hancore.shibumi.reactor", version: "0.1.1-beta.16", kinds: ["service"]}) + readonly property var manifest: ({id: "hancore.shibumi.reactor", version: "0.1.1-beta.16.1", kinds: ["service"]}) function check(value, message) { if (value) return console.error("reactor-runtime:", message) @@ -44,14 +44,14 @@ ShellRoot { property bool outputMuted: true } SuiteRuntime.Provider { - pluginId: "hancore.shibumi.state"; implementationVersion: "0.1.1-beta.16" + pluginId: "hancore.shibumi.state"; implementationVersion: "0.1.1-beta.16.1" owner: state; host: root.stateEnabled ? stateHost : null - manifest: ({id: "hancore.shibumi.state", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.state", version: "0.1.1-beta.16.1", kinds: ["service"]}) } SuiteRuntime.Provider { - pluginId: "hancore.shibumi.audio"; implementationVersion: "0.1.1-beta.16" + pluginId: "hancore.shibumi.audio"; implementationVersion: "0.1.1-beta.16.1" owner: audio; host: root.audioEnabled ? audioHost : null - manifest: ({id: "hancore.shibumi.audio", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.audio", version: "0.1.1-beta.16.1", kinds: ["service"]}) } Reactor.Service { id: service; runtimeProbesEnabled: false } Reactor.Service { id: duplicate; runtimeProbesEnabled: false } diff --git a/tests/scoped-state-regression.qml b/tests/scoped-state-regression.qml index 0d0d599..1d7302c 100644 --- a/tests/scoped-state-regression.qml +++ b/tests/scoped-state-regression.qml @@ -36,7 +36,7 @@ ShellRoot { id: state shell: host omarchyPath: Quickshell.env("OMARCHY_PATH") - manifest: ({ id: "hancore.shibumi.state", version: "0.1.1-beta.16", + manifest: ({ id: "hancore.shibumi.state", version: "0.1.1-beta.16.1", kinds: ["service"], __sourceDir: Quickshell.env("DECOY_MARKER_DIR") }) } BarProbe.Marker { diff --git a/tests/shared-runtime-regression.qml b/tests/shared-runtime-regression.qml index 06c8893..ef4bbb5 100644 --- a/tests/shared-runtime-regression.qml +++ b/tests/shared-runtime-regression.qml @@ -54,7 +54,7 @@ ShellRoot { id: state shell: stateApi omarchyPath: Quickshell.env("OMARCHY_PATH") - manifest: ({id: "hancore.shibumi.state", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.state", version: "0.1.1-beta.16.1", kinds: ["service"]}) } BarProbe.Marker { id: markerBar } Item { @@ -66,10 +66,10 @@ ShellRoot { Shared.Provider { id: barProvider pluginId: "hancore.shibumi.bar" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: barOwner host: barOwner.injectedHost - manifest: ({id: "hancore.shibumi.bar", version: "0.1.1-beta.16", kinds: ["bar"]}) + manifest: ({id: "hancore.shibumi.bar", version: "0.1.1-beta.16.1", kinds: ["bar"]}) } } Shared.HostShell { id: client; host: stateApi } @@ -82,7 +82,7 @@ ShellRoot { property int value: 0 Shared.Provider { pluginId: "hancore.shibumi.audio" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: peer host: peer.injectedHost manifest: peer.injectedManifest @@ -152,7 +152,7 @@ ShellRoot { check(left.state === null && right.state === null && !state.ready && !state.writePending, "version drift retained State authority or queued intent") check(!state.setGroupSetting("G4", "compact", true), "revoked State accepted intent") - state.manifest = {id: "hancore.shibumi.state", version: "0.1.1-beta.16", kinds: ["service"]} + state.manifest = {id: "hancore.shibumi.state", version: "0.1.1-beta.16.1", kinds: ["service"]} check(left.state === state && Shared.Runtime._selected("hancore.shibumi.state") !== oldLease, "State did not register a new lifetime") Shared.Runtime.unregisterProvider(oldLease) @@ -161,10 +161,10 @@ ShellRoot { check(first !== null && client.serviceFor("hancore.shibumi.audio") === null, "parentless service published before injection") first.injectedHost = audioApi - first.injectedManifest = {id: "hancore.shibumi.audio", version: "0.1.1-beta.16", kinds: ["service"]} + first.injectedManifest = {id: "hancore.shibumi.audio", version: "0.1.1-beta.16.1", kinds: ["service"]} check(client.serviceFor("hancore.shibumi.audio") === first, "provider registration failed") second = serviceFactory.createObject(null, {injectedHost: audioApi, - injectedManifest: {id: "hancore.shibumi.audio", version: "0.1.1-beta.16", kinds: ["service"]}}) + injectedManifest: {id: "hancore.shibumi.audio", version: "0.1.1-beta.16.1", kinds: ["service"]}}) check(client.serviceFor("hancore.shibumi.audio") === null, "duplicate provider was last-writer-wins: second=" + JSON.stringify({ manifest: second.injectedManifest, kindsArray: Array.isArray(second.injectedManifest.kinds), @@ -192,7 +192,7 @@ ShellRoot { first.injectedHost = audioApi check(client.serviceFor("hancore.shibumi.audio") === first, "scope recovery stayed unavailable") let getterReached = false - const malformed = {version: "0.1.1-beta.16", kinds: ["service"]} + const malformed = {version: "0.1.1-beta.16.1", kinds: ["service"]} Object.defineProperty(malformed, "id", {get: function() { getterReached = true throw new Error("controlled malformed metadata getter") diff --git a/tests/state-service-smoke.qml b/tests/state-service-smoke.qml index cad279c..ca06499 100644 --- a/tests/state-service-smoke.qml +++ b/tests/state-service-smoke.qml @@ -55,7 +55,7 @@ ShellRoot { id: state omarchyPath: Quickshell.env("OMARCHY_PATH") shell: fakeShell - manifest: ({id: "hancore.shibumi.state", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.state", version: "0.1.1-beta.16.1", kinds: ["service"]}) } Component.onCompleted: steps = [ function() { diff --git a/tests/status-plugin-smoke.qml b/tests/status-plugin-smoke.qml index 46030ac..1d14fb9 100644 --- a/tests/status-plugin-smoke.qml +++ b/tests/status-plugin-smoke.qml @@ -204,11 +204,11 @@ ShellRoot { SuiteRuntime.Provider { id: leasedBarProvider pluginId: "hancore.shibumi.bar" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: leasedBarOwner host: leasedBarOwner.providerHost manifest: ({ id: "hancore.shibumi.bar", - version: "0.1.1-beta.16", kinds: ["bar"] }) + version: "0.1.1-beta.16.1", kinds: ["bar"] }) } } @@ -226,7 +226,7 @@ ShellRoot { Status.Service { shell: rawScopedStatusShell manifest: ({ id: "hancore.shibumi.status", - version: "0.1.1-beta.16", kinds: ["service"] }) + version: "0.1.1-beta.16.1", kinds: ["service"] }) actionRunner: actionRecorder runtimeProbesEnabled: false } diff --git a/tests/telemetry-plugins-smoke.qml b/tests/telemetry-plugins-smoke.qml index 298c4c0..fe23fd0 100644 --- a/tests/telemetry-plugins-smoke.qml +++ b/tests/telemetry-plugins-smoke.qml @@ -27,7 +27,7 @@ ShellRoot { Telemetry.Service { id: telemetryService shell: fakeShell - manifest: ({id: "hancore.shibumi.telemetry", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.telemetry", version: "0.1.1-beta.16.1", kinds: ["service"]}) // Keep this fixture isolated from machine-specific hwmon inventory. thermalProbeEnabled: false } @@ -35,7 +35,7 @@ ShellRoot { Cpu.Service { id: cpuService shell: fakeShell - manifest: ({id: "hancore.shibumi.cpu", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.cpu", version: "0.1.1-beta.16.1", kinds: ["service"]}) gpuProbeEnabled: false } diff --git a/tests/telemetry-runtime-smoke.qml b/tests/telemetry-runtime-smoke.qml index 6b23b3c..1010b60 100644 --- a/tests/telemetry-runtime-smoke.qml +++ b/tests/telemetry-runtime-smoke.qml @@ -22,7 +22,7 @@ ShellRoot { Qt.exit(1) throw new Error(message) } - function manifest(id) { return {id: id, version: "0.1.1-beta.16", kinds: ["service"]} } + function manifest(id) { return {id: id, version: "0.1.1-beta.16.1", kinds: ["service"]} } component ScopedHost: QtObject { property string pluginId: "" function serviceFor(id) { root.check(false, "raw scoped lookup: " + id); return null } @@ -43,7 +43,7 @@ ShellRoot { } SuiteRuntime.Provider { pluginId: "hancore.shibumi.state" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" host: stateHost owner: state manifest: root.manifest("hancore.shibumi.state") diff --git a/tests/test_lifecycle_admission.py b/tests/test_lifecycle_admission.py index 3f031e4..a87a8ae 100644 --- a/tests/test_lifecycle_admission.py +++ b/tests/test_lifecycle_admission.py @@ -267,6 +267,7 @@ def test_exact_public_release_and_step5_states_are_admitted(self) -> None: "public-beta.15.2", "public-beta.15.3", "public-beta.15.4", + "public-beta.16", ): identity = next( item for item in self.identities if item["id"] == identity_id @@ -322,6 +323,11 @@ def test_published_beta15_checkout_revisions_keep_exact_identity(self) -> None: "81f6bcd28cf0e0b5c435761150b2b73083f1e4fa", "package:0.1.1-beta.15.4", ), + "public-beta.16": ( + "4840482ec0e06a2ebd478120833d4fae1f30889e", + "05548c8d9ffdf0d37962d6e423e2a0dc21b8cd91", + "package:0.1.1-beta.16", + ), } for identity_id, revisions in published.items(): identity = next( diff --git a/tests/test_package_release.py b/tests/test_package_release.py index 270ab2a..f9bafda 100644 --- a/tests/test_package_release.py +++ b/tests/test_package_release.py @@ -213,10 +213,20 @@ def test_lifecycle_contract_pins_exact_release_identities(self) -> None: }, "public-beta.16": { "suiteVersion": "0.1.1-beta.16", - "sourceRevisions": ["package:0.1.1-beta.16"], + "sourceRevisions": [ + "4840482ec0e06a2ebd478120833d4fae1f30889e", + "05548c8d9ffdf0d37962d6e423e2a0dc21b8cd91", + "package:0.1.1-beta.16", + ], "settingsStorageVersion": 1, "payloadDigest": "f08b4ec613f248fda62d7dec9865ea46a846fa2e91b2723a186adc0ab0bffc41", }, + "public-beta.16.1": { + "suiteVersion": "0.1.1-beta.16.1", + "sourceRevisions": ["package:0.1.1-beta.16.1"], + "settingsStorageVersion": 1, + "payloadDigest": "aad95737d0650873140a8de723f76a75294eecc82528902a70366019bc68fd79", + }, } self.assertEqual(set(states), set(expected)) for identity_id, pinned in expected.items(): diff --git a/tests/test_shibumi_suite.py b/tests/test_shibumi_suite.py index 56168b3..444bd88 100755 --- a/tests/test_shibumi_suite.py +++ b/tests/test_shibumi_suite.py @@ -31,6 +31,7 @@ PUBLISHED_BETA152_REVISION = "c45af77c8333b691ac36522247b6e5b5481a3666" PUBLISHED_BETA153_REVISION = "5b1d21f0cea73bb9e7997278a828b3ef295e6c94" PUBLISHED_BETA154_REVISION = "6594b989c9f5edfe557669b0413a9bd3e50f8e81" +PUBLISHED_BETA16_REVISION = "4840482ec0e06a2ebd478120833d4fae1f30889e" sys.path.insert(0, str(REPO_ROOT / "scripts")) from shibumi_suite.admission import ( # noqa: E402 @@ -1306,6 +1307,11 @@ def test_published_beta154_checkout_can_update_from_its_tag(self) -> None: "v0.1.1-beta.15.4", PUBLISHED_BETA154_REVISION, "public-beta.15.4" ) + def test_published_beta16_checkout_can_update_from_its_tag(self) -> None: + self.assert_published_checkout_can_update_from_tag( + "v0.1.1-beta.16", PUBLISHED_BETA16_REVISION, "public-beta.16" + ) + def test_admitted_beta15_merge_payloads_match_their_exact_tags(self) -> None: releases = ( (PUBLISHED_BETA15_REVISION, ( @@ -1325,6 +1331,9 @@ def test_admitted_beta15_merge_payloads_match_their_exact_tags(self) -> None: "67d87c5d7f61fca4b05e79a089238805e0e0737f", "81f6bcd28cf0e0b5c435761150b2b73083f1e4fa", )), + (PUBLISHED_BETA16_REVISION, ( + "05548c8d9ffdf0d37962d6e423e2a0dc21b8cd91", + )), ) payload_paths = ["contracts/plugin-suite-v1.json", *self.suite.plugins] for tag_revision, merges in releases: diff --git a/tests/theme-palette-runtime-smoke.qml b/tests/theme-palette-runtime-smoke.qml index 74d3a1d..07c2a21 100644 --- a/tests/theme-palette-runtime-smoke.qml +++ b/tests/theme-palette-runtime-smoke.qml @@ -26,7 +26,7 @@ ShellRoot { id: state shell: fakeShell omarchyPath: Quickshell.env("OMARCHY_PATH") - manifest: ({id: "hancore.shibumi.state", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.state", version: "0.1.1-beta.16.1", kinds: ["service"]}) } function colorText(value) { diff --git a/tests/third-party-integration-smoke.qml b/tests/third-party-integration-smoke.qml index 1499a83..917e372 100644 --- a/tests/third-party-integration-smoke.qml +++ b/tests/third-party-integration-smoke.qml @@ -38,14 +38,14 @@ ShellRoot { AudioOwner.Service { shell: fakeShell nativeBackendEnabled: false // Controlled peak stub; this fixture tests IPC. - manifest: ({ id: "hancore.shibumi.audio", version: "0.1.1-beta.16", kinds: ["service"] }) + manifest: ({ id: "hancore.shibumi.audio", version: "0.1.1-beta.16.1", kinds: ["service"] }) } StateOwner.Service { shell: fakeShell omarchyPath: "" manifest: ({ - id: "hancore.shibumi.state", version: "0.1.1-beta.16", kinds: ["service"] + id: "hancore.shibumi.state", version: "0.1.1-beta.16.1", kinds: ["service"] }) } diff --git a/tests/widget-pipeline-diagnostics-smoke.qml b/tests/widget-pipeline-diagnostics-smoke.qml index 9a63149..4c55eab 100644 --- a/tests/widget-pipeline-diagnostics-smoke.qml +++ b/tests/widget-pipeline-diagnostics-smoke.qml @@ -237,11 +237,11 @@ ShellRoot { Shared.Provider { id: stateProvider pluginId: "hancore.shibumi.state" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: stateOwner host: stateHost manifest: ({ id: "hancore.shibumi.state", - version: "0.1.1-beta.16", kinds: ["service"] }) + version: "0.1.1-beta.16.1", kinds: ["service"] }) } QtObject { @@ -290,7 +290,7 @@ ShellRoot { barWidgetRegistry: scopedWidgetRegistry manifest: ({ id: "hancore.shibumi.bar", - version: "0.1.1-beta.16", + version: "0.1.1-beta.16.1", kinds: ["bar"] }) barConfig: ({ diff --git a/tests/workspaces-plugin-smoke.qml b/tests/workspaces-plugin-smoke.qml index 43826c7..5db9ee3 100644 --- a/tests/workspaces-plugin-smoke.qml +++ b/tests/workspaces-plugin-smoke.qml @@ -125,7 +125,7 @@ ShellRoot { Workspaces.WorkspaceService { id: workspaceState shell: fakeShell - manifest: ({id: "hancore.shibumi.workspaces", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.workspaces", version: "0.1.1-beta.16.1", kinds: ["service"]}) stateService: preferenceState backendOverride: QtObject { property var focusedWorkspace: ({ id: 8 }) diff --git a/tests/workspaces-runtime-smoke.qml b/tests/workspaces-runtime-smoke.qml index 9dc3a0b..8e0f67d 100644 --- a/tests/workspaces-runtime-smoke.qml +++ b/tests/workspaces-runtime-smoke.qml @@ -15,7 +15,7 @@ ShellRoot { property var cachedPreference: null property int callsBeforeLoss: 0 property int writesBeforeLoss: 0 - readonly property var validManifest: ({id: "hancore.shibumi.workspaces", version: "0.1.1-beta.16", kinds: ["service"]}) + readonly property var validManifest: ({id: "hancore.shibumi.workspaces", version: "0.1.1-beta.16.1", kinds: ["service"]}) function check(value, message) { if (value) return console.error("workspaces-runtime:", message) @@ -44,10 +44,10 @@ ShellRoot { } SuiteRuntime.Provider { pluginId: "hancore.shibumi.state" - implementationVersion: "0.1.1-beta.16" + implementationVersion: "0.1.1-beta.16.1" owner: state host: root.stateEnabled ? stateHost : null - manifest: ({id: "hancore.shibumi.state", version: "0.1.1-beta.16", kinds: ["service"]}) + manifest: ({id: "hancore.shibumi.state", version: "0.1.1-beta.16.1", kinds: ["service"]}) } QtObject { id: backend From e6a2bc02335619e35b812e4e48a16e2a3181ab84 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 00:47:17 +0200 Subject: [PATCH 02/31] fix: unblock Bluetooth power through the Omarchy helper --- contracts/backend-boundary-v1.json | 1 + contracts/package-runtime-v1.json | 1 + .../BluetoothBackendAdapter.qml | 40 ++++++++++++++++++- scripts/shibumi_suite/runtime.py | 1 + tests/bluetooth-backend-regression.qml | 13 ++++++ tests/bluetooth-plugin-regression.sh | 4 +- tests/test_package_release.py | 2 +- tests/test_shibumi_suite.py | 2 + 8 files changed, 59 insertions(+), 5 deletions(-) diff --git a/contracts/backend-boundary-v1.json b/contracts/backend-boundary-v1.json index 7e5a4f1..9de84f3 100644 --- a/contracts/backend-boundary-v1.json +++ b/contracts/backend-boundary-v1.json @@ -395,6 +395,7 @@ {"value":"omarchy-audio-output-sink","count":1,"category":"omarchyBackend","owner":"hancore.shibumi.audio","capability":"audio","backend":"omarchy.audio","removalStep":"Step 4A","reason":"Resolve the effective physical output before native volume and mute mutations."}, {"value":"omarchy-battery-status","count":1,"category":"omarchyBackend","owner":"hancore.shibumi.power-state","capability":"battery-ac","backend":"omarchy.power","removalStep":"Step 6","reason":"Remove the Omarchy battery helper after UPower is authoritative."}, {"value":"omarchy-bluetooth-device","count":1,"category":"omarchyBackend","owner":"hancore.shibumi.bluetooth","capability":"bluetooth","backend":"omarchy.bluetooth","removalStep":"Step 4B","reason":"Beta.13 resolves the current device and adapter incarnation immediately before this single helper dispatch and rejects a multi-adapter production inventory because the Omarchy 4.0.2 helper carries only action/address, not controller path; closing the residual post-dispatch helper race remains a separately scoped native-action cutover."}, + {"value":"omarchy-bluetooth-power","count":1,"category":"omarchyAction","owner":"hancore.shibumi.bluetooth","capability":"bluetooth","reason":"Explicit global radio power requests use the host rfkill persistence policy through one argv-only detached action; BlueZ remains the native state source."}, {"value":"omarchy-capture-screenrecording","count":1,"category":"omarchyBackend","owner":"hancore.shibumi.status","capability":"recording-voxtype","backend":"omarchy.recording","removalStep":"Step 8","reason":"Move recording actions behind the typed Shibumi status service."}, {"value":"omarchy-cmd-missing","count":1,"category":"hostIntegration","owner":"quattro.host","capability":"bar-host-routing"}, {"value":"omarchy-cmd-present","count":4,"category":"hostIntegration","owner":"quattro.host","capability":"bar-host-routing"}, diff --git a/contracts/package-runtime-v1.json b/contracts/package-runtime-v1.json index 7870d58..c5bf2a8 100644 --- a/contracts/package-runtime-v1.json +++ b/contracts/package-runtime-v1.json @@ -37,6 +37,7 @@ "wl-copy": "wl-clipboard" }, "requiredHostCommands": { + "omarchy-bluetooth-power": "Bluetooth radio power and persistent rfkill policy", "omarchy-bluetooth-device": "Retained Beta.13 Bluetooth device mutation path", "omarchy-audio-output-set-default": "Retained Bluetooth audio-route compatibility path" }, diff --git a/hancore.shibumi.bluetooth/BluetoothBackendAdapter.qml b/hancore.shibumi.bluetooth/BluetoothBackendAdapter.qml index e02ebd4..f674909 100644 --- a/hancore.shibumi.bluetooth/BluetoothBackendAdapter.qml +++ b/hancore.shibumi.bluetooth/BluetoothBackendAdapter.qml @@ -33,6 +33,8 @@ Item { property var retiredDiscoveryAdapter: null property bool discoveryDesired: false property var nativePendingActions: ({}) + property var pendingPowerTarget: null + property var pendingPowerAdapter: null // Raw native entities remain private here. The registry assigns a monotonic // incarnation whenever a device or adapter QObject is replaced. property var nativeAdapterEntity: null @@ -313,11 +315,29 @@ Item { backendOverride.toggleBluetooth() return true } + if (pendingPowerTarget !== null) return false + pendingPowerAdapter = adapter + pendingPowerTarget = !radioEnabled + powerRequestTimeout.restart() if (radioEnabled) stopDiscovery() - adapter.enabled = !adapter.enabled + try { + executeDeviceCommand([ + "omarchy-bluetooth-power", pendingPowerTarget ? "on" : "off" + ]) + } catch (error) { + clearPendingPower() + return false + } + // Detached dispatch is not success: only observed BlueZ state settles it. return true } + function clearPendingPower() { + pendingPowerTarget = null + pendingPowerAdapter = null + powerRequestTimeout.stop() + } + function setNativePendingAction(address, action) { if (!address) return nativePendingActions = Model.withPendingAction( @@ -711,8 +731,13 @@ Item { syncNativeAudioHandoffIntents() } onDiscoveryDesiredChanged: if (!discoveryDesired) stopDiscovery() - onRadioEnabledChanged: if (!radioEnabled) cancelAllAudioHandoffs() + onRadioEnabledChanged: { + if (pendingPowerAdapter === adapter && pendingPowerTarget === radioEnabled) + clearPendingPower() + if (!radioEnabled) cancelAllAudioHandoffs() + } onAdapterChanged: { + clearPendingPower() observeNativeAdapter() reconcileNativeEntities() // Ownership is tied to the adapter instance on which Shibumi started the @@ -729,6 +754,17 @@ Item { Component.onCompleted: reconcileNativeEntities() Component.onDestruction: destroyDiscovery() + // A deadline for the desired state, not a timeout/cancellation of the helper. + Timer { + id: powerRequestTimeout + interval: 20000 + repeat: false + onTriggered: { + console.warn("Bluetooth power request did not reach its target") + root.clearPendingPower() + } + } + Timer { id: pendingTimeout interval: 20000 diff --git a/scripts/shibumi_suite/runtime.py b/scripts/shibumi_suite/runtime.py index f3f8315..c297853 100644 --- a/scripts/shibumi_suite/runtime.py +++ b/scripts/shibumi_suite/runtime.py @@ -63,6 +63,7 @@ def validate(self) -> None: "omarchy", "omarchy-shell", "omarchy-bluetooth-device", + "omarchy-bluetooth-power", "omarchy-audio-output-set-default", ): if not (self.omarchy_root / "bin" / command).is_file(): diff --git a/tests/bluetooth-backend-regression.qml b/tests/bluetooth-backend-regression.qml index 1b047a0..f79530e 100644 --- a/tests/bluetooth-backend-regression.qml +++ b/tests/bluetooth-backend-regression.qml @@ -42,6 +42,8 @@ ShellRoot { property string adapterId: "hci-test" property string dbusPath: "/org/bluez/hci_test" property bool enabled: true + property bool softBlocked: false + onEnabledChanged: if (enabled && softBlocked) enabled = false property bool discovering: false } @@ -217,6 +219,17 @@ ShellRoot { if (root.phase === 0) { if (root.ticks < 3) return + nativeAdapter.enabled = false + nativeAdapter.softBlocked = true + audioBackend.toggleBluetooth() + audioBackend.toggleBluetooth() + if (commandRunner.count !== 1 + || JSON.stringify(commandRunner.lastCommand) !== '["omarchy-bluetooth-power","on"]' + || nativeAdapter.enabled) + return root.fail("rfkill power-on dispatch and pending coalescing") + nativeAdapter.softBlocked = false + nativeAdapter.enabled = true + commandRunner.count = 0 discoveryFixture.rejectedDiscoveryStarts = 1 discoveryService.beginSession(root) diff --git a/tests/bluetooth-plugin-regression.sh b/tests/bluetooth-plugin-regression.sh index d034b6e..b1d981f 100755 --- a/tests/bluetooth-plugin-regression.sh +++ b/tests/bluetooth-plugin-regression.sh @@ -207,8 +207,8 @@ fi if rg -q 'Process \{|FileView \{' "$service" "$adapter"; then fail "Bluetooth owner uses an unbounded worker instead of native APIs" fi -[[ $(rg -c '^ Timer \{' "$adapter") -eq 4 ]] \ - || fail "Bluetooth adapter must keep exactly the four bounded lifecycle timers" +[[ $(rg -c '^ Timer \{' "$adapter") -eq 5 ]] \ + || fail "Bluetooth adapter must keep exactly the five bounded lifecycle timers" rg -q 'id: heroPowerToggle' "$panel" \ || fail "Bluetooth radio toggle is not grouped with adapter status" if sed -n '/id: headerActions/,/^ }/p' "$panel" \ diff --git a/tests/test_package_release.py b/tests/test_package_release.py index f9bafda..af40460 100644 --- a/tests/test_package_release.py +++ b/tests/test_package_release.py @@ -1796,7 +1796,7 @@ def test_dependency_contract_matches_pkgbuild(self) -> None: self.assertIn(f"\toptdepends = {package}: {purpose}", srcinfo) self.assertEqual( set(contract["requiredHostCommands"]), - {"omarchy-bluetooth-device", "omarchy-audio-output-set-default"}, + {"omarchy-bluetooth-device", "omarchy-bluetooth-power", "omarchy-audio-output-set-default"}, ) runtime = (ROOT / "scripts/shibumi_suite/runtime.py").read_text( encoding="utf-8" diff --git a/tests/test_shibumi_suite.py b/tests/test_shibumi_suite.py index 444bd88..f36e2af 100755 --- a/tests/test_shibumi_suite.py +++ b/tests/test_shibumi_suite.py @@ -845,6 +845,7 @@ def test_runtime_paths_reject_symlinked_writable_root_before_mutation( "omarchy", "omarchy-shell", "omarchy-bluetooth-device", + "omarchy-bluetooth-power", "omarchy-audio-output-set-default", "omarchy-plugin-validate", ): @@ -1818,6 +1819,7 @@ def create_quattro_host_contract(self) -> None: "omarchy-shell", "omarchy-plugin-validate", "omarchy-bluetooth-device", + "omarchy-bluetooth-power", "omarchy-audio-output-set-default", ): (bin_dir / command).write_text("#!/bin/sh\n", encoding="utf-8") From e9280ba55ffefff998e72a0b6c3479e342563921 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 00:47:18 +0200 Subject: [PATCH 03/31] fix: restore the raised date beside the clock --- hancore.shibumi.center/BarWidget.qml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/hancore.shibumi.center/BarWidget.qml b/hancore.shibumi.center/BarWidget.qml index 746417b..2e53d59 100644 --- a/hancore.shibumi.center/BarWidget.qml +++ b/hancore.shibumi.center/BarWidget.qml @@ -295,11 +295,15 @@ Ui.Panel { else root.toggle() } - // Keep the native button's reservation and input; only its bar label - // opts into the shared ink alignment. Vertical rendering stays native. - Presentation.IconText { - barText: true - baselineFont: clockWidget.textFont + // Keep the native line-box centring: the smaller date sits raised + // beside the clock. Only paint is snapped; reservation/input stay native. + Presentation.BarInk { id: datePlacement; target: dateLabel } + Text { + id: dateLabel + transform: Translate { + x: datePlacement.snapX(0) + y: datePlacement.snapY(0) + } visible: !dateButton.labelVisible anchors.centerIn: parent textFormat: Text.PlainText From 5c49fa26024d2bfdb396c317b918892dd836b69c Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 00:47:18 +0200 Subject: [PATCH 04/31] fix: center badge digits in odd-pixel circles --- hancore.shibumi.status/TrayStatusView.qml | 23 +++++++++++++-------- hancore.shibumi.update-center/BarWidget.qml | 23 +++++++++++++-------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/hancore.shibumi.status/TrayStatusView.qml b/hancore.shibumi.status/TrayStatusView.qml index d949207..998138e 100644 --- a/hancore.shibumi.status/TrayStatusView.qml +++ b/hancore.shibumi.status/TrayStatusView.qml @@ -207,9 +207,10 @@ Item { Rectangle { id: badgePaint readonly property real pixel: 1 / badgePlacement.dpr - readonly property real diameter: Math.max(1, - Math.round(Commons.Style.space(10) * badgePlacement.dpr)) * pixel - width: Math.floor(Math.max(diameter, badgeValue.implicitWidth + Commons.Style.space(6)) / pixel) * pixel + readonly property real diameter: (2 * Math.floor( + Math.round(Commons.Style.space(10) * badgePlacement.dpr) / 2) + 1) * pixel + width: badgeValue.text.length === 1 ? diameter + : Math.floor(Math.max(diameter, badgeValue.implicitWidth + Commons.Style.space(3)) / pixel) * pixel height: diameter radius: height / 2 color: root.customToneActive @@ -237,20 +238,24 @@ Item { id: valueInk text: badgeValue.text font: Qt.font({family: badgeValue.font.family, - pixelSize: badgeValue.font.pixelSize * valuePlacement.metricScale, - weight: badgeValue.font.weight, hintingPreference: Font.PreferNoHinting}) + pixelSize: Math.round(badgeValue.font.pixelSize * valuePlacement.dpr), + weight: badgeValue.font.weight, hintingPreference: Font.PreferDefaultHinting}) + renderType: Text.NativeRendering } Text { id: badgeValue text: root.drawerCount > 99 ? "99+" : String(root.drawerCount) x: valuePlacement.snapX(parent.width / 2 - - (valueInk.tightBoundingRect.x + valueInk.tightBoundingRect.width / 2) / valuePlacement.metricScale) - y: valuePlacement.snapY(parent.height / 2 - - (valueInk.tightBoundingRect.y + valueInk.tightBoundingRect.height / 2) / valuePlacement.metricScale) - baselineOffset + - (valueInk.tightBoundingRect.x + valueInk.tightBoundingRect.width / 2) / valuePlacement.dpr) + // Match the native raster font; on an odd/even tie use the upper pixel. + y: Math.floor((valuePlacement.origin.y + parent.height / 2) * valuePlacement.dpr + - valueInk.tightBoundingRect.y - valueInk.tightBoundingRect.height / 2) / valuePlacement.dpr + - valuePlacement.origin.y - Math.round(baselineOffset * valuePlacement.dpr) / valuePlacement.dpr color: badgeText.color font.family: badgeText.font.family - font.pixelSize: Commons.Style.space(7) + font.pixelSize: Commons.Style.space(8) font.bold: true + renderType: Text.NativeRendering } } } diff --git a/hancore.shibumi.update-center/BarWidget.qml b/hancore.shibumi.update-center/BarWidget.qml index 5fc8a84..8b48fbf 100644 --- a/hancore.shibumi.update-center/BarWidget.qml +++ b/hancore.shibumi.update-center/BarWidget.qml @@ -210,9 +210,10 @@ Ui.Panel { Rectangle { id: badgePaint readonly property real pixel: 1 / badgePlacement.dpr - readonly property real diameter: Math.max(1, - Math.round(Commons.Style.space(10) * badgePlacement.dpr)) * pixel - width: Math.floor(Math.max(diameter, badgeValue.implicitWidth + Commons.Style.space(6)) / pixel) * pixel + readonly property real diameter: (2 * Math.floor( + Math.round(Commons.Style.space(10) * badgePlacement.dpr) / 2) + 1) * pixel + width: badgeValue.text.length === 1 ? diameter + : Math.floor(Math.max(diameter, badgeValue.implicitWidth + Commons.Style.space(3)) / pixel) * pixel height: diameter radius: height / 2 color: root.contentColor @@ -238,20 +239,24 @@ Ui.Panel { id: valueInk text: badgeValue.text font: Qt.font({family: badgeValue.font.family, - pixelSize: badgeValue.font.pixelSize * valuePlacement.metricScale, - weight: badgeValue.font.weight, hintingPreference: Font.PreferNoHinting}) + pixelSize: Math.round(badgeValue.font.pixelSize * valuePlacement.dpr), + weight: badgeValue.font.weight, hintingPreference: Font.PreferDefaultHinting}) + renderType: Text.NativeRendering } Text { id: badgeValue text: root.updateCount > 99 ? "99+" : String(root.updateCount) x: valuePlacement.snapX(parent.width / 2 - - (valueInk.tightBoundingRect.x + valueInk.tightBoundingRect.width / 2) / valuePlacement.metricScale) - y: valuePlacement.snapY(parent.height / 2 - - (valueInk.tightBoundingRect.y + valueInk.tightBoundingRect.height / 2) / valuePlacement.metricScale) - baselineOffset + - (valueInk.tightBoundingRect.x + valueInk.tightBoundingRect.width / 2) / valuePlacement.dpr) + // Match the native raster font; on an odd/even tie use the upper pixel. + y: Math.floor((valuePlacement.origin.y + parent.height / 2) * valuePlacement.dpr + - valueInk.tightBoundingRect.y - valueInk.tightBoundingRect.height / 2) / valuePlacement.dpr + - valuePlacement.origin.y - Math.round(baselineOffset * valuePlacement.dpr) / valuePlacement.dpr color: badgeText.color font.family: badgeText.font.family - font.pixelSize: Commons.Style.space(7) + font.pixelSize: Commons.Style.space(8) font.bold: true + renderType: Text.NativeRendering } } } From 047bcba64f99cfa4962fa4c12d8ddd7791c8f436 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 00:48:29 +0200 Subject: [PATCH 05/31] release: repin the beta.16.1 candidate payload --- contracts/lifecycle-predecessors-v1.json | 10 +++++----- tests/test_package_release.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/lifecycle-predecessors-v1.json b/contracts/lifecycle-predecessors-v1.json index b188b15..a608f32 100644 --- a/contracts/lifecycle-predecessors-v1.json +++ b/contracts/lifecycle-predecessors-v1.json @@ -759,7 +759,7 @@ }, { "id": "public-beta.16.1", - "payloadDigest": "aad95737d0650873140a8de723f76a75294eecc82528902a70366019bc68fd79", + "payloadDigest": "25fe4252e981e57f1a550862d448e4f9d858e66efb34f915af32743480fa05d7", "pluginDigests": { "hancore.shibumi.bar": "f1eda2d05892d3756319e3cb4474565505f9e6ca2bbb30c4a8983d7103525b9a", "hancore.shibumi.state": "3aed3c7a3cb92afb66d5f12d7d5c773f1988d5f11c933da187f8b31c68179da8", @@ -768,20 +768,20 @@ "hancore.shibumi.telemetry": "f52aff2aa784a11eab6edb12b5c3610986a01284f98844293e5cc8e1bb2963b0", "hancore.shibumi.power-state": "f2f664b00436695dbd47edf9b8d7da46d0f4f7fbe740045023479ed707872a50", "hancore.shibumi.workspaces": "de2a198c2a1fcbada535f046b91f37e5f5ca517ef4a0e3c6f570baf7930699c5", - "hancore.shibumi.update-center": "9f2cab591bed25ce79f886f240583cf33204d5037aa76307803454cea8eacfd3", - "hancore.shibumi.status": "8ac6a5da220dc2ce6e6cff7f69955ed0fca94a3e7a32de5e84bac880f425b165", + "hancore.shibumi.update-center": "505433f5a19ef761b10f4a04628cbc04aca42c4f340bfe1cfabdcb4b986cc70c", + "hancore.shibumi.status": "bdd586e5e3ab866f048c367e0f0695a30ab0714f0d98b2ad41bc3db7adb6b974", "hancore.shibumi.memory": "f6fbd0838180fac0740fd27d22f9fe1812528f45210e51fa9984f479f42da8f9", "hancore.shibumi.cpu": "bb0d1df3404525a45c55fffaa2091a8340ae3d9536f7edab6e6bd56759f7999e", "hancore.shibumi.audio": "20a3f204e0c55b6c9aff18d12e9627b91f3710596e3d1c2e00b08aaa0f3e3e4c", "hancore.shibumi.ai": "a0f6238a89dc198ffab4528dcfda2bdddbcdf759e9daf093f9c8fc59ef1353d8", - "hancore.shibumi.center": "381a88047ed21afcf1e47a399acd5287f68664758283bb7180ae94dbcb393226", + "hancore.shibumi.center": "fe792ff696628b9b6ce324e0767d6ccabc6bca98a0529f9c2d7d2a58f36761a6", "hancore.shibumi.media": "e67e51d2629520b6e7a4578940885b8ff2245798254af4f8ea39ce7b8d2d8c82", "hancore.shibumi.quick-access": "4ce7d5575e758ddb3cec856672e0717f95dd494c5a4488f61e0269e534697502", "hancore.shibumi.network": "9ee7d1725749da03e9480529bbfb22c557f6f7da534900c280f0cb031492a41d", "hancore.shibumi.battery": "59f67a3358c5e419bb98e474a867b53630cf1ee0bcd61c44d59c5775d8c6933f", "hancore.shibumi.brightness": "80ba42a406f9a24b675ed2daf83555e7f1da6e0442246ae093bb7800be1a8b91", "hancore.shibumi.power-profile": "6d71528dc88132dfc2c33b22437427c9210df74cdc123dfcdd574b4a3a07113e", - "hancore.shibumi.bluetooth": "51b3271d445bfba82694d22be8d62650bcf572af63888c5ca9240adf7c8eb42b", + "hancore.shibumi.bluetooth": "4d77a458e857a53d68f079abab395f3807b614096b8a90741603fb9c091c6b9d", "hancore.shibumi.temperature": "72ac530bd97cf092349351a6c63e2ef78a9446053e7add71cfe72282704a76b4", "hancore.shibumi.gpu": "a460b94a8f0142ce6da9318493a6343f7bdefcbd1999db3fe73c46d5ff59fa9e", "hancore.shibumi.storage": "eb97c939b77fc88a17066bfa72ea4a1f9a0c7279d164afbc15b176f767837299" diff --git a/tests/test_package_release.py b/tests/test_package_release.py index af40460..c72038c 100644 --- a/tests/test_package_release.py +++ b/tests/test_package_release.py @@ -225,7 +225,7 @@ def test_lifecycle_contract_pins_exact_release_identities(self) -> None: "suiteVersion": "0.1.1-beta.16.1", "sourceRevisions": ["package:0.1.1-beta.16.1"], "settingsStorageVersion": 1, - "payloadDigest": "aad95737d0650873140a8de723f76a75294eecc82528902a70366019bc68fd79", + "payloadDigest": "25fe4252e981e57f1a550862d448e4f9d858e66efb34f915af32743480fa05d7", }, } self.assertEqual(set(states), set(expected)) From 7d896b384507af19d337eb78fb1430f960fd2639 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 01:29:36 +0200 Subject: [PATCH 06/31] docs: document the beta.16.1 release --- .github/release-notes/v0.1.1-beta.16.1.md | 66 ++++++++++++++++++ ARCHITECTURE.md | 35 ++++++---- CHANGELOG.md | 17 +++++ README.md | 12 ++-- docs/architecture/quattro-compatibility.md | 2 +- docs/development/packaging.md | 13 ++-- docs/install.md | 20 +++--- docs/plugins/README.md | 18 +++-- docs/release-readiness.md | 81 +++++++++++++--------- 9 files changed, 194 insertions(+), 70 deletions(-) create mode 100644 .github/release-notes/v0.1.1-beta.16.1.md diff --git a/.github/release-notes/v0.1.1-beta.16.1.md b/.github/release-notes/v0.1.1-beta.16.1.md new file mode 100644 index 0000000..cd84507 --- /dev/null +++ b/.github/release-notes/v0.1.1-beta.16.1.md @@ -0,0 +1,66 @@ +# 0.1.1-beta.16.1 + +Beta.16.1 is a patch release for Bluetooth power, the raised date, and badge +alignment. + +## Fixes + +- Bluetooth power uses Omarchy's power helper to turn a soft-blocked radio on + and to turn it off again (#68). Repeat clicks while a power request is pending + do not dispatch a reverse action; the display follows observed BlueZ state. +- The smaller date is raised beside the clock again, as before Beta.16. The + clock keeps its shared baseline. +- Single-digit update and tray badges are exactly centered at DPR 1 in circles + with odd physical-pixel diameters. Fractional scales retain whole-pixel + placement with parity-limited rounding. + +## Compatibility + +The 24-plugin suite and transactional installation model are unchanged. +Beta.16.1 retains Beta.16's pinned Omarchy and Omarchy Settings `4.0.4-1` +package and Omarchy `v4.0.4` source baselines with Quickshell `0.3.1-1`. +It does not update Omarchy. + +## Install and update + +For a new source installation, use the release tag: + +```bash +sudo pacman -S --needed python jq curl networkmanager power-profiles-daemon upower xdg-utils libnotify wl-clipboard ttf-material-symbols-variable ttf-jetbrains-mono-nerd-basic noto-fonts-cjk adwaita-fonts +git clone https://github.com/HANCORE-linux/Shibumi-Shell.git +cd Shibumi-Shell +git checkout v0.1.1-beta.16.1 +./scripts/shibumi-suite install --yes +``` + +Update an admitted Beta.16 installation from its existing checkout: + +```bash +git fetch --tags +git checkout v0.1.1-beta.16.1 +./scripts/shibumi-suite update --dry-run +./scripts/shibumi-suite update --yes +./scripts/shibumi-suite status +``` + +The exact Beta.16 tag and release-merge checkouts are admitted predecessors. +Older supported identities retain their exact revision and payload checks; +an arbitrary checkout with the same version is not admitted. Do not install +or update from `main`, or delete lifecycle state to bypass admission. See the +[installation and recovery guide](https://github.com/HANCORE-linux/Shibumi-Shell/blob/v0.1.1-beta.16.1/docs/install.md). +AUR publication remains deferred; use the source workflow above. + +## Downgrade warning + +**Downgrade:** Beta.15.4 and older cannot read V1 layouts with parked widgets +(`order.parked`). They reset the V1 order, roles and splits to defaults; other +settings and V2 stay. `uninstall --keep-settings` does not prevent this. Before +downgrading, back up `~/.config/omarchy/shell.json` and `~/.local/state/shibumi/`. +Details: [Backup before downgrade](https://github.com/HANCORE-linux/Shibumi-Shell/blob/v0.1.1-beta.16.1/docs/install.md#backup-before-downgrade). + +## Known limits + +- The power helper affects all Bluetooth radios, not only the displayed + adapter, and cannot clear a hardware rfkill block. +- Badge digits are exactly centered at DPR 1; fractional scales can leave a + half-pixel offset. diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index d2a7a1f..accdfe9 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -947,22 +947,33 @@ Current Phase 2 foundation: `BluetoothBackendAdapter`. The adapter keeps native BlueZ device QObjects private and publishes detached primitive records carrying the device path, address, adapter identity, and monotonic device/adapter incarnations. Every - mutation resolves exactly one current entity immediately before dispatch; - stale, malformed, ambiguous, unavailable, or state-conflicting requests - return typed failures and dispatch nothing. Beta.13 deliberately retains one - `omarchy-bluetooth-device` helper path per device action and never invokes a - native device method in parallel. Because the 4.0.2 helper accepts only an - action/address pair, production fails closed with more than one adapter; the - residual replacement race after dispatch remains explicit Step-4B helper - debt. Callers inspect `.ok` explicitly. The - adapter also owns pending state and Bluetooth-audio handoff; no complete - Omarchy Bluetooth UI component is instantiated as a backend; + device mutation resolves exactly one current entity immediately before dispatch; + stale, malformed, ambiguous, unavailable, or state-conflicting device requests + return typed failures and dispatch nothing. Device actions retain one + `omarchy-bluetooth-device` helper path and never invoke a native device method + in parallel. Because the helper accepts only an action/address pair, device + actions fail closed with more than one production adapter; the residual + replacement race after dispatch remains explicit Step-4B helper debt. + Device callers inspect `.ok` explicitly. The adapter also owns pending state + and Bluetooth-audio handoff; no complete Omarchy Bluetooth UI component is + instantiated as a backend. Global radio power is a separate host action: + one argv-only detached `omarchy-bluetooth-power on|off` request applies + Omarchy's rfkill persistence policy to all Bluetooth radios. It can clear a + soft block, not a hardware block. Bar, panel, and IPC share this power path; + no direct `adapter.enabled` write or helper `toggle` is used. BlueZ's observed + `adapter.enabled` remains authoritative for the displayed state, not dispatch + success. Repeat clicks are ignored while the adapter-bound target is pending; + observing that target, adapter loss/replacement, a dispatch exception, or the + deadline clears it. Power-off stops owned discovery; - each output owns only its V1 Bluetooth presentation and lazy Shibumi device panel. The process-wide service leases discovery across open panels and owns one symmetric six-method `omarchy.bluetooth` IPC target. Presentation has no Bluetooth/PipeWire import, process, timer, or file watcher; the service facade - owns one bounded discovery-reconciliation timer and the adapter owns four - bounded lifecycle timers. While a requested Discovery start is still pending + owns one bounded discovery-reconciliation timer and the adapter owns five + bounded lifecycle timers, including a separate one-shot 20-second power-state + deadline. This clears pending state, not the detached helper process; late + helper effects remain possible. It is not a process timeout or cancellation. + While a requested Discovery start is still pending during teardown, at most one temporary 30-second retry/expiry timer per native adapter survives the facade. Top mapping, adapter/radio reactivity, discovery ownership/teardown, both backend load orders, and IPC diff --git a/CHANGELOG.md b/CHANGELOG.md index e772e80..60d45e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## [0.1.1-beta.16.1] - Unreleased + +### Fixed + +- Turn Bluetooth on after an rfkill soft block, and off again, through + Omarchy's power helper (#68). Ignore repeat clicks while a power request + is pending instead of dispatching a reverse action. +- Raise the smaller date beside the clock again, as before Beta.16. +- Center single-digit update and tray badges exactly at DPR 1 using circles + with odd physical-pixel diameters; retain whole-pixel placement at fractional + scales. + +### Changed + +- Admit the exact Beta.16 tag and merge checkouts as update predecessors, + retaining strict payload and lifecycle checks. + ## [0.1.1-beta.16] - 2026-10-02 ### Added diff --git a/README.md b/README.md index fce15be..4cc50ac 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,9 @@ process.

[Documentation](docs/README.md) · [Release status](docs/release-readiness.md) -`0.1.1-beta.16` is published as a GitHub prerelease. AUR publication is +`0.1.1-beta.16.1` is published as a GitHub prerelease. AUR publication is deferred; use the source installation below. See the -[release notes](.github/release-notes/v0.1.1-beta.16.md) for changes and the +[release notes](.github/release-notes/v0.1.1-beta.16.1.md) for changes and the downgrade warning. The current pinned host contracts use Omarchy and Omarchy Settings `4.0.4-1` (source tag `v4.0.4`, revision `c668141e`) with Quickshell `0.3.1-1`; the @@ -82,19 +82,21 @@ Install from source using the release tag: sudo pacman -S --needed python jq curl networkmanager power-profiles-daemon upower xdg-utils libnotify wl-clipboard ttf-material-symbols-variable ttf-jetbrains-mono-nerd-basic noto-fonts-cjk adwaita-fonts git clone https://github.com/HANCORE-linux/Shibumi-Shell.git cd Shibumi-Shell -git checkout v0.1.1-beta.16 +git checkout v0.1.1-beta.16.1 ./scripts/shibumi-suite install --yes ``` -Update an admitted source installation, including Beta.15.4, to Beta.16. +Update an admitted Beta.16 source installation to Beta.16.1. Exact predecessor identities, not a version range, govern admission; see the [update guide](docs/install.md#update). ```sh cd Shibumi-Shell git fetch --tags -git checkout v0.1.1-beta.16 +git checkout v0.1.1-beta.16.1 +./scripts/shibumi-suite update --dry-run ./scripts/shibumi-suite update --yes +./scripts/shibumi-suite status ``` Do not install or update from `main`. If you previously installed from `main`, run `./scripts/shibumi-suite uninstall --keep-settings --yes` from that exact checkout before switching to a tag. diff --git a/docs/architecture/quattro-compatibility.md b/docs/architecture/quattro-compatibility.md index 73f202e..257f559 100644 --- a/docs/architecture/quattro-compatibility.md +++ b/docs/architecture/quattro-compatibility.md @@ -8,7 +8,7 @@ by this evidence. ## Current pinned host -Beta.16 targets the exact official Omarchy 4.0.4 baseline. These pins are not +Beta.16.1 retains Beta.16's exact official Omarchy 4.0.4 baseline. These pins are not physical release acceptance. The historical Beta.13 physical host acceptance below applies to its recorded single-output Omarchy 4.0.3 setup: diff --git a/docs/development/packaging.md b/docs/development/packaging.md index 01b5181..2fcd71b 100644 --- a/docs/development/packaging.md +++ b/docs/development/packaging.md @@ -1,6 +1,6 @@ # Arch packaging and AUR publication -Status: `0.1.1-beta.16` is published as a GitHub prerelease; AUR publication +Status: `0.1.1-beta.16.1` is published as a GitHub prerelease; AUR publication is deferred. Shibumi ships one versioned suite containing 24 separately validated Omarchy @@ -74,7 +74,7 @@ and lifecycle code before the user-level update runs, so Beta.12's storage guard cannot reject that package afterward. There is no reverse migration to legacy storage. -The additional [Beta.16 downgrade warning and backup requirements](../install.md#backup-before-downgrade) +The additional [Beta.16.1 downgrade warning and backup requirements](../install.md#backup-before-downgrade) apply even to readers using canonical State storage: Beta.15.4 and older cannot preserve a V1 layout containing `order.parked`. `--keep-settings` does not prevent this. Restore the settings with a matching payload. @@ -136,10 +136,11 @@ result. It requires: `--nodeps` is used only by this controlled rehearsal because dependency resolution is verified separately against the validation system. The package -continues to depend on Omarchy's `omarchy-bluetooth-device` and -`omarchy-audio-output-set-default` helpers for the Beta.12 hotfix; those are -explicit compatibility debt, not undeclared native replacements. A clean-chroot -build must perform normal dependency resolution before publication. +requires Omarchy's `omarchy-bluetooth-device`, `omarchy-bluetooth-power`, and +`omarchy-audio-output-set-default` helpers. Device/audio mutation paths retain +their declared compatibility boundaries; global Bluetooth power delegates +rfkill persistence to the host while BlueZ remains authoritative for state. +A clean-chroot build must perform normal dependency resolution before publication. ## Publication gates diff --git a/docs/install.md b/docs/install.md index c27cef7..64f4fc0 100644 --- a/docs/install.md +++ b/docs/install.md @@ -6,7 +6,7 @@ Shibumi installs 24 independent plugin roots into Omarchy's normal plugin directory. The repository root is a suite source, not a single installable Omarchy plugin. -`0.1.1-beta.16` is published as a GitHub prerelease. AUR publication is +`0.1.1-beta.16.1` is published as a GitHub prerelease. AUR publication is deferred; install from the release tag using the source workflow below. Do not install or update from `main`. @@ -51,7 +51,7 @@ For an intentional non-interactive installation: sudo pacman -S --needed python jq curl networkmanager power-profiles-daemon upower xdg-utils libnotify wl-clipboard ttf-material-symbols-variable ttf-jetbrains-mono-nerd-basic noto-fonts-cjk adwaita-fonts git clone https://github.com/HANCORE-linux/Shibumi-Shell.git cd Shibumi-Shell -git checkout v0.1.1-beta.16 +git checkout v0.1.1-beta.16.1 ./scripts/shibumi-suite install --yes ``` @@ -66,7 +66,7 @@ To inspect the transaction before installing: ```bash git clone https://github.com/HANCORE-linux/Shibumi-Shell.git cd Shibumi-Shell -git checkout v0.1.1-beta.16 +git checkout v0.1.1-beta.16.1 ./scripts/shibumi-suite install --dry-run ./scripts/shibumi-suite install ``` @@ -146,15 +146,17 @@ Pacman updating `/usr/share/shibumi-shell` does not silently change a running desktop. The explicit update validates, stages, reloads, and verifies all 24 plugins as one transaction. -For an admitted trusted source checkout, including the published Beta.15.4 -tag, its release merge, and its documentation merge: +To update an admitted Beta.16 source installation to Beta.16.1, use its +trusted checkout. The exact published Beta.16 tag and release merge are +admitted predecessors: ```bash cd Shibumi-Shell git fetch --tags -git checkout v0.1.1-beta.16 +git checkout v0.1.1-beta.16.1 ./scripts/shibumi-suite update --dry-run -./scripts/shibumi-suite update +./scripts/shibumi-suite update --yes +./scripts/shibumi-suite status ``` An update requires a suite-managed Shibumi installation. It stages all 24 @@ -204,7 +206,7 @@ authoritative origin. The old checkout is not deleted or modified. ### Roll back a package version > [!WARNING] -> **Beta.16 downgrade warning.** +> **Beta.16.1 downgrade warning.** > Beta.15.4 and older cannot read V1 layouts containing > `order.parked`. They reset V1 order, roles, and splits to defaults; other > settings and V2 remain. `uninstall --keep-settings` does not prevent this. @@ -404,7 +406,7 @@ then install the published tag. For example, only if the recorded revision is ```bash git checkout e92d8ee1ce9821d0b203a9d4d5dd9932d2e460fb ./scripts/shibumi-suite uninstall --keep-settings --yes -git checkout v0.1.1-beta.16 +git checkout v0.1.1-beta.16.1 ./scripts/shibumi-suite install --yes ``` diff --git a/docs/plugins/README.md b/docs/plugins/README.md index 5e5b302..173fd50 100644 --- a/docs/plugins/README.md +++ b/docs/plugins/README.md @@ -2,7 +2,7 @@ Status: reference -Shibumi `0.1.1-beta.16` contains 24 independently registered Omarchy plugins. The +Shibumi `0.1.1-beta.16.1` contains 24 independently registered Omarchy plugins. The default suite profile installs all of them as one verified transaction. The authoritative inventory is @@ -52,9 +52,19 @@ required device or service is unavailable. Shibumi uses native Quattro owners where they provide sufficient state and actions, including media, notifications, tray, background, monitor, weather, idle, and system-update services. Shibumi owns native Audio and Network state. -Its Bluetooth adapter keeps BlueZ QObjects private, publishes detached -identity-bound records, and retains one declared Omarchy helper mutation path -per device action for Beta.14. +Its Bluetooth adapter keeps BlueZ QObjects private and publishes detached +identity-bound records. Device actions retain one `omarchy-bluetooth-device` +helper path with exact device-identity checks. Global radio power instead uses +one explicit `omarchy-bluetooth-power on|off` request for all Bluetooth radios; +it follows the host's rfkill persistence policy and cannot clear a hardware +block. BlueZ remains authoritative for the displayed radio state. Bar, panel, +and IPC share the same adapter-bound pending target and ignore repeat clicks. + +The Bluetooth adapter owns five bounded lifecycle timers. Its separate +one-shot 20-second power-state deadline clears pending state; it neither stops +the detached helper nor prevents later effects. The service facade retains +one discovery-reconciliation timer and the bounded native-adapter discovery +teardown guard. See the [architecture contract](../../ARCHITECTURE.md). Shibumi owns its presentation and adds a narrow adapter only where the host contract cannot produce the approved behavior. It must not create a duplicate diff --git a/docs/release-readiness.md b/docs/release-readiness.md index de41823..6a5a7f2 100644 --- a/docs/release-readiness.md +++ b/docs/release-readiness.md @@ -1,45 +1,50 @@ -# Shibumi 0.1.1-beta.16 release readiness +# Shibumi 0.1.1-beta.16.1 release readiness > **Document status: Revision-bound validation record.** This page separates > recorded product evidence from release, package, and physical acceptance. > It cannot override [`../ARCHITECTURE.md`](../ARCHITECTURE.md). -## Release and published predecessor +## Candidate and published predecessor -`0.1.1-beta.16` is published as a GitHub prerelease. The validated product -revision recorded here is `30746f56f61f08e7cf665e7d1fc894711b563fa2`, with -24 plugins and suite payload digest -`f08b4ec613f248fda62d7dec9865ea46a846fa2e91b2723a186adc0ab0bffc41`. -This product record does not substitute for the exact release commit's archive, -checksum, package, or complete release-evidence records. +The Beta.16.1 product commit is +`047bcba64f99cfa4962fa4c12d8ddd7791c8f436`, with 24 plugins and suite payload +digest `25fe4252e981e57f1a550862d448e4f9d858e66efb34f915af32743480fa05d7`. +The validation target is this product plus the documentation commit containing +the Beta.16.1 release texts. Documentation outside plugin roots leaves the +suite digest unchanged but changes release-archive bytes. Gates must bind the +accepted combined revision, not a future commit or inherited predecessor pass. -Beta.15.4 was published on 2026-09-28 as a GitHub prerelease from -`6594b989c9f5edfe557669b0413a9bd3e50f8e81`. It is the frozen rolling +Beta.16 was published on 2026-10-02 as a GitHub prerelease from +`4840482ec0e06a2ebd478120833d4fae1f30889e`. It is the frozen rolling predecessor in [`release-predecessor.json`](../tests/fixtures/release-predecessor.json). -Exact tag, merge, and documentation-merge checkout identities are admitted by -[`lifecycle-predecessors-v1.json`](../contracts/lifecycle-predecessors-v1.json). -A version string alone never authorizes recovery or replacement. AUR publication -remains deferred. +That exact tag checkout and release merge +`05548c8d9ffdf0d37962d6e423e2a0dc21b8cd91` are admitted by +[`lifecycle-predecessors-v1.json`](../contracts/lifecycle-predecessors-v1.json), +with the unchanged Beta.16 payload digest +`f08b4ec613f248fda62d7dec9865ea46a846fa2e91b2723a186adc0ab0bffc41`. +Older exact identities remain admitted; a version string alone never authorizes +recovery or replacement. AUR publication remains deferred. -## Evidence at the recorded product revision +## Recorded evidence and outstanding gates | Gate | Evidence and boundary | | --- | --- | -| Complete source contract | Passed on `30746f5`, exit 0; 638.65 seconds | -| Isolated Quattro lifecycle | Passed on `30746f5`, exit 0; 32/32 shell generations; 109.68 seconds | -| Retained runtime paths | Historical Beta.13 → Beta.14.1 package arm; fresh checkout; Beta.15, Beta.15.2, and rolling Beta.15.4 checkout updates | -| Settings round trips | Isolated keep-settings/reinstall retained the complete State entry and host layout, including delayed follow-up | -| Live installations | Reviewer reports `30746f5` installed on two maintainer machines by keep-settings round trip, identical settings and no Shibumi warnings in the new shell logs | -| Scoped visual previews | Reviewed V1/V2 badge, text, bell, battery, and palette comparisons; software-rendered previews do not establish physical acceptance | -| Scoped maintainer live check | Maintainer confirms the battery, charging bolt, and palette; this is not blanket acceptance of all visuals or hardware workflows | - -The contract/runtime passes above are not a full 14-gate collector result. -The historical package arm is not a Beta.16 package-upgrade proof. Private +| Complete source contract | Failed on `047bcba`, exit 1 after 151.43 seconds: `test_release_workflow_uses_curated_notes` required the missing Beta.16.1 notes. A full rerun including the documentation commit is pending. | +| Isolated Quattro lifecycle | Pending on the combined revision; not started after the contract failure. No Beta.16.1 32/32 result is recorded. | +| Retained runtime paths | Required: historical Beta.13 → Beta.14.1 package arm (5), fresh checkout (6), Beta.15 (7), Beta.15.2 (7), and rolling Beta.16 → current checkout (7): exactly 32 shell generations. | +| Bluetooth preparation | Native-QML softblock-mock red/green regression and scoped Bluetooth, IPC, hotplug, and audio checks passed during fix preparation; these are not final-HEAD full gates or real rfkill acceptance. | +| Scoped visual previews | Maintainer-approved raised-date and badge comparisons in V1/V2 fit at DPR 1/1.6; private software-rendered previews, not physical acceptance. | +| Live installation and Bluetooth | Pending: reviewer installation and real softblock → on through Bar, panel, and IPC; rapid repeat clicks; on → off. No hardware or persistence result is recorded. | +| Release/package verification | Release date, exact-commit archive/checksum, updated PKGBUILD/`.SRCINFO`, source/package rehearsal, 14-gate collector, and publication verification remain pending. | + +The failed contract run passed the baseline and documentation checks and +26 of 27 PackageReleaseTests; the missing release notes were the sole package +test failure. No test was relaxed and no placeholder notes were added to bypass +it. Focused documentation checks do not replace the full contract rerun. +The historical package arm is not a Beta.16.1 package-upgrade proof. Private Wayland/software-rendered previews are not live GPU, layer-shell, hotplug, or -physical multi-output acceptance. The recorded contract run retained six known -PillSurface teardown TypeErrors. Its 590 warning/error lines in 154 normalized -classes matched the preceding product run, as did the runtime warning/error -multiset; these are not warning-free fixture logs. +physical multi-output acceptance. Earlier release passes do not transfer to +this candidate. ## Pinned host contracts @@ -100,9 +105,16 @@ was performed. Each operation needs its own maintainer Go. - Local whole-ink, workspace/Pacman, meter, Calendar overhang, and charge-bolt raster limits are not declared solved by the ordinary-text baseline work. - The pinned host exposes Recent notification history, not Live popup access. +- Bluetooth power affects all radios through the host helper and cannot clear + a hardware block. The 20-second pending deadline does not stop the detached + process or prevent later effects. Real rfkill and persistence acceptance is + separate from controlled native-QML feedback. +- Single-digit badges are exactly centered at DPR 1 in the approved previews; + fractional-scale digit parity and antialiased circle edges can retain a + half-pixel bounding-box offset. - **Downgrade:** Beta.15.4 and older cannot read V1 `order.parked`; they reset V1 order, roles, and splits while retaining other settings and V2. - `--keep-settings` does not prevent this. The [release notes](../.github/release-notes/v0.1.1-beta.16.md) + `--keep-settings` does not prevent this. The [release notes](../.github/release-notes/v0.1.1-beta.16.1.md) and [backup guide](install.md#backup-before-downgrade) identify the complete settings and recovery evidence to preserve. Restore the settings with a matching payload. @@ -124,6 +136,9 @@ block updates and deletion. See [packaging](development/packaging.md). Beta.13's single-output Omarchy 4.0.3 acceptance remains historical in [Get started](getting-started.md#know-the-beta-boundary). The paused [Beta.14 validation record](development/beta14-validation.md) is not a current -release checklist. Beta.15.4's published changes and limits are recorded in its -[release notes](../.github/release-notes/v0.1.1-beta.15.4.md). Earlier readiness -snapshots remain in Git history; none confers acceptance on Beta.16. +release checklist. Beta.16's published changes and limits remain in its +[release notes](../.github/release-notes/v0.1.1-beta.16.md). Its earlier product +revision `30746f5` passed the complete contract and 32-generation runtime; +those fixtures retained known teardown warnings and did not establish blanket +hardware acceptance. Earlier readiness snapshots remain in Git history; none +confers acceptance on Beta.16.1. From 935641cb46074b52d1701db146e5a588f675f843 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 09:15:55 +0200 Subject: [PATCH 07/31] test: expect the Bluetooth power deadline timer in the contract guard --- tests/contract-regression.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/contract-regression.sh b/tests/contract-regression.sh index 4dc9699..22e98bf 100755 --- a/tests/contract-regression.sh +++ b/tests/contract-regression.sh @@ -947,8 +947,8 @@ for bluetooth_adapter in "$bluetooth_adapter"; do rg -U -q 'function validatePendingAudioOutput\(\)[^}]*resolveNativeDevice\([^}]*!device\.connected[^}]*!deviceUsesCurrentAdapter' \ "$bluetooth_adapter" \ || fail "$bluetooth_adapter does not revalidate audio handoff identity/state" - [[ $(rg -c '^ Timer \{' "$bluetooth_adapter") -eq 4 ]] \ - || fail "$bluetooth_adapter must have exactly four bounded lifecycle timers" + [[ $(rg -c '^ Timer \{' "$bluetooth_adapter") -eq 5 ]] \ + || fail "$bluetooth_adapter must have exactly five bounded lifecycle timers" if rg -q 'IpcHandler \{|Loader \{|panelSource|panelComponent|registeredWidget' \ "$bluetooth_adapter"; then fail "$bluetooth_adapter still owns IPC or loads a foreign UI component" From 53bd4f30baf463eed849cd4dfa71ddb02d2fd55c Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 09:15:56 +0200 Subject: [PATCH 08/31] fix: restore application icons for pinned tray apps --- hancore.shibumi.status/TrayStatusView.qml | 29 +++++++++++++++++++---- tests/status-plugin-regression.sh | 2 ++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/hancore.shibumi.status/TrayStatusView.qml b/hancore.shibumi.status/TrayStatusView.qml index 998138e..c84e4a2 100644 --- a/hancore.shibumi.status/TrayStatusView.qml +++ b/hancore.shibumi.status/TrayStatusView.qml @@ -91,14 +91,35 @@ Item { if (root.bar) root.bar.unregisterClickTarget(trayDelegate) } - Presentation.BarGlyph { + Item { + id: trayIconSlot anchors.centerIn: parent anchors.horizontalCenterOffset: root.pinnedIconHorizontalOffset - text: "󰀻" - font.family: Commons.Style.font.family - color: root.contentColor width: Commons.Style.space(14) height: Commons.Style.space(14) + + Presentation.BarInk { id: iconPlacement; target: trayIconSlot } + Image { + id: trayIcon + source: String(trayDelegate.modelData.icon || "") + sourceSize: Qt.size(Math.round(parent.width * iconPlacement.dpr), + Math.round(parent.height * iconPlacement.dpr)) + width: sourceSize.width / iconPlacement.dpr + height: sourceSize.height / iconPlacement.dpr + x: iconPlacement.snapX((parent.width - width) / 2) + y: iconPlacement.rectangleY(height) + fillMode: Image.PreserveAspectFit + smooth: true + mipmap: true + } + + Presentation.BarGlyph { + visible: trayIcon.status !== Image.Ready + anchors.fill: parent + text: "󰀻" + font.family: Commons.Style.font.family + color: root.contentColor + } } MouseArea { diff --git a/tests/status-plugin-regression.sh b/tests/status-plugin-regression.sh index ad46c41..e739910 100755 --- a/tests/status-plugin-regression.sh +++ b/tests/status-plugin-regression.sh @@ -137,6 +137,8 @@ fi rg -q 'notificationPanelSource: Qt\.resolvedUrl\("NotificationPanel\.qml"\)' \ "$status_widget" || fail "status view does not own the V1 notification panel" tray_view="$repo_root/hancore.shibumi.status/TrayStatusView.qml" +rg -Fq 'source: String(trayDelegate.modelData.icon || "")' "$tray_view" \ + || fail "pinned tray items must render their application icon" tray_panel="$repo_root/hancore.shibumi.status/TrayDrawerPanel.qml" tray_menu="$repo_root/hancore.shibumi.status/TrayAppMenuPanel.qml" rg -q 'pinnedCount \* Commons\.Style\.space\(18\)' "$tray_view" \ From 665cff33385b158080d314b1a313bba74619bc38 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 09:15:57 +0200 Subject: [PATCH 09/31] fix: restore launcher logos without symbol remapping --- hancore.shibumi.control-center/BarWidget.qml | 44 ++++++++++++++++---- tests/control-center-regression.sh | 10 +++-- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/hancore.shibumi.control-center/BarWidget.qml b/hancore.shibumi.control-center/BarWidget.qml index 4877fc7..2765629 100644 --- a/hancore.shibumi.control-center/BarWidget.qml +++ b/hancore.shibumi.control-center/BarWidget.qml @@ -3,7 +3,6 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Effects import qs.Ui as Ui -import qs.Commons as Commons import "HostIdentity.js" as HostIdentity import "../hancore.shibumi.state/runtime" as SuiteRuntime import "../hancore.shibumi.state/lib/presentation" as Presentation @@ -355,7 +354,7 @@ Ui.Panel { visible: root.archWordmark anchors.fill: parent - Presentation.BarGlyph { + Text { id: archLogo anchors.left: parent.left anchors.leftMargin: root.archWordLeftPad @@ -418,12 +417,43 @@ Ui.Panel { width: root.stockOmarchyHost ? 18 : 16 height: root.tokens ? root.tokens.pillHeight : 24 - Presentation.BarGlyph { - anchors.fill: parent - text: !root.stockOmarchyHost && root.launcherConfig.icon !== "shibumi" - ? root.iconGlyph(root.launcherConfig.icon) : "" + Text { + visible: !root.stockOmarchyHost + && root.launcherConfig.icon !== "shibumi" + anchors.centerIn: parent + anchors.horizontalCenterOffset: root.iconXOffset(root.launcherConfig.icon) + anchors.verticalCenterOffset: root.iconYOffset(root.launcherConfig.icon) + text: root.iconGlyph(root.launcherConfig.icon) color: root.widgetInk - font.family: Commons.Style.font.family + renderType: Text.QtRendering + font.family: root.iconFont(root.launcherConfig.icon) + font.pixelSize: root.iconSize(root.launcherConfig.icon) + } + + Image { + visible: root.stockOmarchyHost + || (root.launcherConfig.icon === "shibumi" && !root.v1CustomFill) + anchors.centerIn: parent + width: 18 + height: 18 + source: Qt.resolvedUrl("assets/shibumi-icon-hikiryo.svg") + fillMode: Image.PreserveAspectFit + sourceSize.width: 24 + sourceSize.height: 24 + smooth: true + mipmap: true + } + + FlatTintedImage { + id: v1TintedLauncherIcon + visible: !root.stockOmarchyHost + && root.launcherConfig.icon === "shibumi" + && root.v1CustomFill + anchors.centerIn: parent + width: 18 + height: 18 + source: Qt.resolvedUrl("assets/shibumi-icon-hikiryo.svg") + tint: root.widgetInk } } diff --git a/tests/control-center-regression.sh b/tests/control-center-regression.sh index 8adfa07..da235ec 100755 --- a/tests/control-center-regression.sh +++ b/tests/control-center-regression.sh @@ -152,16 +152,18 @@ rg -Fq 'onClicked: function(mouse) { root.triggerPress(mouse.button) }' \ || fail "G1 bypasses its shared host click path" [[ -f $control_dir/assets/shibumi-icon-hikiryo.svg ]] \ || fail "stock Omarchy host icon is missing" -rg -Fq 'text: !root.stockOmarchyHost && root.launcherConfig.icon !== "shibumi"' \ +rg -Fq 'source: Qt.resolvedUrl("assets/shibumi-icon-hikiryo.svg")' \ "$control_dir/BarWidget.qml" \ - || fail "stock Omarchy host icon bypasses the native bar glyph" + || fail "Shibumi and stock-host launchers must retain the Hikiryō SVG" +! rg -Fq 'Presentation.BarGlyph {' "$control_dir/BarWidget.qml" \ + || fail "launcher logos must bypass the shared symbol mapper" rg -Fq 'width: root.stockOmarchyHost ? 18 : 16' \ "$control_dir/BarWidget.qml" \ || fail "stock Omarchy host icon is not pixel-centered in its even slot" for hikiryo_tone_contract in \ '&& !stockOmarchyHost && launcherConfig.icon === "shibumi" && v1CustomFill' \ - 'font.family: Commons.Style.font.family' \ - 'Presentation.BarGlyph {' \ + 'font.family: root.iconFont(root.launcherConfig.icon)' \ + 'text: root.iconGlyph(root.launcherConfig.icon)' \ 'color: root.widgetInk'; do rg -Fq "$hikiryo_tone_contract" "$control_dir/BarWidget.qml" \ || fail "Hikiryō V1 tone contract drifted: $hikiryo_tone_contract" From 65c09b2c708d87a6939e49436d9ecd1502b8e327 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 09:15:58 +0200 Subject: [PATCH 10/31] fix: render the OpenCode usage mark crisply at the shared icon size --- hancore.shibumi.ai/BarWidget.qml | 16 +++++-- hancore.shibumi.ai/OpenCodeUsageIcon.qml | 57 ++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 hancore.shibumi.ai/OpenCodeUsageIcon.qml diff --git a/hancore.shibumi.ai/BarWidget.qml b/hancore.shibumi.ai/BarWidget.qml index cce70c1..abd39a8 100644 --- a/hancore.shibumi.ai/BarWidget.qml +++ b/hancore.shibumi.ai/BarWidget.qml @@ -56,9 +56,9 @@ Ui.Panel { readonly property int providerIconSlotWidth: 20 readonly property int providerIconSlotHeight: 16 readonly property int claudeGlyphPixelSize: 15 - readonly property int providerGlyphWidth: providerId === "opencode" ? 20 + readonly property int providerGlyphWidth: providerId === "opencode" ? 15 : providerId === "codex" ? 14 : 15 - readonly property int providerGlyphHeight: providerId === "opencode" ? 12 + readonly property int providerGlyphHeight: providerId === "opencode" ? 10 : providerId === "codex" ? 14 : 15 readonly property int providerGlyphHorizontalOffset: 0 readonly property int providerContentHorizontalOffset: @@ -209,10 +209,20 @@ Ui.Panel { } } + OpenCodeUsageIcon { + anchors.fill: parent + visible: root.providerId === "opencode" + baseColor: root.baseIconColor + fillColor: root.usageIconColor + baseOpacity: root.baseIconOpacity + usageFraction: root.steppedPercent > 0 + ? Math.min(1, Math.max(root.steppedPercent / 100, 0.22)) : 0 + } + Item { id: providerImage anchors.fill: parent - visible: root.providerId === "codex" || root.providerId === "opencode" + visible: root.providerId === "codex" Presentation.BarInk { id: imageInk; target: providerImage } transform: Translate { x: imageInk.enabled ? imageInk.snapX(0) : 0 diff --git a/hancore.shibumi.ai/OpenCodeUsageIcon.qml b/hancore.shibumi.ai/OpenCodeUsageIcon.qml new file mode 100644 index 0000000..bdd14ce --- /dev/null +++ b/hancore.shibumi.ai/OpenCodeUsageIcon.qml @@ -0,0 +1,57 @@ +import QtQuick +import QtQuick.Effects +import "../hancore.shibumi.state/lib/presentation" as Presentation + +// The original pixel mark, rasterized at its native grid before nearest sampling. +Item { + id: root + required property color baseColor + required property color fillColor + required property real baseOpacity + required property real usageFraction + + Presentation.BarInk { id: placement; target: root } + Item { + id: paint + width: Math.round(root.width * placement.dpr) / placement.dpr + height: Math.round(width * placement.dpr * 14 / 22) / placement.dpr + x: placement.snapX((root.width - width) / 2) + y: placement.rectangleY(height) + + Image { + id: mark + anchors.fill: parent + visible: false + source: Qt.resolvedUrl("assets/opencode-mark.svg") + // Qt scales SVG requests by DPR before rasterizing them. + sourceSize: Qt.size(Math.max(1, Math.round(22 / placement.dpr)), + Math.max(1, Math.round(14 / placement.dpr))) + fillMode: Image.Stretch + smooth: false + mipmap: false + } + MultiEffect { + anchors.fill: parent + source: mark + colorization: 1 + colorizationColor: Qt.rgba(root.baseColor.r, root.baseColor.g, root.baseColor.b, 1) + opacity: root.baseColor.a * root.baseOpacity + } + Item { + anchors.bottom: parent.bottom + width: parent.width + height: Math.round(parent.height * root.usageFraction * placement.dpr) / placement.dpr + clip: true + Behavior on height { NumberAnimation { duration: 600; easing.type: Easing.OutCubic } } + MultiEffect { + anchors.bottom: parent.bottom + width: paint.width + height: paint.height + source: mark + colorization: 1 + colorizationColor: Qt.rgba(root.fillColor.r, root.fillColor.g, root.fillColor.b, 1) + opacity: root.fillColor.a + } + } + } +} From 59fda3cf059f91c19d089c382ab8664fd0cd5b07 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 09:15:59 +0200 Subject: [PATCH 11/31] docs: note the tray, launcher and OpenCode fixes --- .github/release-notes/v0.1.1-beta.16.1.md | 3 +++ CHANGELOG.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.github/release-notes/v0.1.1-beta.16.1.md b/.github/release-notes/v0.1.1-beta.16.1.md index cd84507..844d76c 100644 --- a/.github/release-notes/v0.1.1-beta.16.1.md +++ b/.github/release-notes/v0.1.1-beta.16.1.md @@ -13,6 +13,9 @@ alignment. - Single-digit update and tray badges are exactly centered at DPR 1 in circles with odd physical-pixel diameters. Fractional scales retain whole-pixel placement with parity-limited rounding. +- Restore application icons for pinned tray apps, with a fallback when no icon is available. +- Restore the selected launcher logo, including Omarchy, Shibumi, and Dragon, without symbol remapping. +- Render the OpenCode usage mark crisply at the size of the other provider icons, so its usage fill reads clearly. ## Compatibility diff --git a/CHANGELOG.md b/CHANGELOG.md index 60d45e7..47f9fb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ - Center single-digit update and tray badges exactly at DPR 1 using circles with odd physical-pixel diameters; retain whole-pixel placement at fractional scales. +- Restore application icons for pinned tray apps, with a fallback when no icon is available. +- Restore the selected launcher logo, including Omarchy, Shibumi, and Dragon, without symbol remapping. +- Render the OpenCode usage mark crisply at the size of the other provider icons, so its usage fill reads clearly. ### Changed From ee24e2f005965470c245c7737e0f6e7d1281bdc7 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 09:17:16 +0200 Subject: [PATCH 12/31] release: repin the beta.16.1 candidate payload --- contracts/lifecycle-predecessors-v1.json | 8 ++++---- tests/test_package_release.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/lifecycle-predecessors-v1.json b/contracts/lifecycle-predecessors-v1.json index a608f32..c6b6c10 100644 --- a/contracts/lifecycle-predecessors-v1.json +++ b/contracts/lifecycle-predecessors-v1.json @@ -759,21 +759,21 @@ }, { "id": "public-beta.16.1", - "payloadDigest": "25fe4252e981e57f1a550862d448e4f9d858e66efb34f915af32743480fa05d7", + "payloadDigest": "f0f951c91f14611bc1efbc932d2f48ead1fd43a0133c1f739fa503c3ee9ebd5e", "pluginDigests": { "hancore.shibumi.bar": "f1eda2d05892d3756319e3cb4474565505f9e6ca2bbb30c4a8983d7103525b9a", "hancore.shibumi.state": "3aed3c7a3cb92afb66d5f12d7d5c773f1988d5f11c933da187f8b31c68179da8", - "hancore.shibumi.control-center": "beb6fd4aa5f1d5a8399ed2907e22817d7dfae5422c333f7b3898ad4d25529546", + "hancore.shibumi.control-center": "730ab1517cf0fe52ec5409203bdeb03661f8440c50a6b8ba8baf6563a4f23ec8", "hancore.shibumi.reactor": "347d5997e664581da56104a636af44d4675f37d311bb058b9624d8c9f6121322", "hancore.shibumi.telemetry": "f52aff2aa784a11eab6edb12b5c3610986a01284f98844293e5cc8e1bb2963b0", "hancore.shibumi.power-state": "f2f664b00436695dbd47edf9b8d7da46d0f4f7fbe740045023479ed707872a50", "hancore.shibumi.workspaces": "de2a198c2a1fcbada535f046b91f37e5f5ca517ef4a0e3c6f570baf7930699c5", "hancore.shibumi.update-center": "505433f5a19ef761b10f4a04628cbc04aca42c4f340bfe1cfabdcb4b986cc70c", - "hancore.shibumi.status": "bdd586e5e3ab866f048c367e0f0695a30ab0714f0d98b2ad41bc3db7adb6b974", + "hancore.shibumi.status": "97138019874d45d3e1f7e50b4693751b8ac13492c99e9809f5fa8d20e13f7c2b", "hancore.shibumi.memory": "f6fbd0838180fac0740fd27d22f9fe1812528f45210e51fa9984f479f42da8f9", "hancore.shibumi.cpu": "bb0d1df3404525a45c55fffaa2091a8340ae3d9536f7edab6e6bd56759f7999e", "hancore.shibumi.audio": "20a3f204e0c55b6c9aff18d12e9627b91f3710596e3d1c2e00b08aaa0f3e3e4c", - "hancore.shibumi.ai": "a0f6238a89dc198ffab4528dcfda2bdddbcdf759e9daf093f9c8fc59ef1353d8", + "hancore.shibumi.ai": "4915e89db32c358ff9f8dca120f56ba05425281ac62836752c3de91171097c5c", "hancore.shibumi.center": "fe792ff696628b9b6ce324e0767d6ccabc6bca98a0529f9c2d7d2a58f36761a6", "hancore.shibumi.media": "e67e51d2629520b6e7a4578940885b8ff2245798254af4f8ea39ce7b8d2d8c82", "hancore.shibumi.quick-access": "4ce7d5575e758ddb3cec856672e0717f95dd494c5a4488f61e0269e534697502", diff --git a/tests/test_package_release.py b/tests/test_package_release.py index c72038c..5066755 100644 --- a/tests/test_package_release.py +++ b/tests/test_package_release.py @@ -225,7 +225,7 @@ def test_lifecycle_contract_pins_exact_release_identities(self) -> None: "suiteVersion": "0.1.1-beta.16.1", "sourceRevisions": ["package:0.1.1-beta.16.1"], "settingsStorageVersion": 1, - "payloadDigest": "25fe4252e981e57f1a550862d448e4f9d858e66efb34f915af32743480fa05d7", + "payloadDigest": "f0f951c91f14611bc1efbc932d2f48ead1fd43a0133c1f739fa503c3ee9ebd5e", }, } self.assertEqual(set(states), set(expected)) From 4774f70b343588954ec59052c6e7cfb5d743db1e Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 10:02:08 +0200 Subject: [PATCH 13/31] fix: keep the OpenCode usage icon within the AI widget's approved imports --- hancore.shibumi.ai/BarWidget.qml | 55 +++++++++++++++++++++++ hancore.shibumi.ai/OpenCodeUsageIcon.qml | 57 ------------------------ 2 files changed, 55 insertions(+), 57 deletions(-) delete mode 100644 hancore.shibumi.ai/OpenCodeUsageIcon.qml diff --git a/hancore.shibumi.ai/BarWidget.qml b/hancore.shibumi.ai/BarWidget.qml index abd39a8..75155e7 100644 --- a/hancore.shibumi.ai/BarWidget.qml +++ b/hancore.shibumi.ai/BarWidget.qml @@ -1,6 +1,7 @@ pragma ComponentBehavior: Bound import QtQuick +import QtQuick.Effects import qs.Commons as Commons import qs.Ui as Ui import "../hancore.shibumi.state/lib/presentation" as Presentation @@ -284,6 +285,60 @@ Ui.Panel { } } + // The original pixel mark, rasterized at its native grid before nearest sampling. + component OpenCodeUsageIcon: Item { + id: iconRoot + required property color baseColor + required property color fillColor + required property real baseOpacity + required property real usageFraction + + Presentation.BarInk { id: placement; target: iconRoot } + Item { + id: paint + width: Math.round(iconRoot.width * placement.dpr) / placement.dpr + height: Math.round(width * placement.dpr * 14 / 22) / placement.dpr + x: placement.snapX((iconRoot.width - width) / 2) + y: placement.rectangleY(height) + + Image { + id: mark + anchors.fill: parent + visible: false + source: Qt.resolvedUrl("assets/opencode-mark.svg") + // Qt scales SVG requests by DPR before rasterizing them. + sourceSize: Qt.size(Math.max(1, Math.round(22 / placement.dpr)), + Math.max(1, Math.round(14 / placement.dpr))) + fillMode: Image.Stretch + smooth: false + mipmap: false + } + MultiEffect { + anchors.fill: parent + source: mark + colorization: 1 + colorizationColor: Qt.rgba(iconRoot.baseColor.r, iconRoot.baseColor.g, iconRoot.baseColor.b, 1) + opacity: iconRoot.baseColor.a * iconRoot.baseOpacity + } + Item { + anchors.bottom: parent.bottom + width: parent.width + height: Math.round(parent.height * iconRoot.usageFraction * placement.dpr) / placement.dpr + clip: true + Behavior on height { NumberAnimation { duration: 600; easing.type: Easing.OutCubic } } + MultiEffect { + anchors.bottom: parent.bottom + width: paint.width + height: paint.height + source: mark + colorization: 1 + colorizationColor: Qt.rgba(iconRoot.fillColor.r, iconRoot.fillColor.g, iconRoot.fillColor.b, 1) + opacity: iconRoot.fillColor.a + } + } + } + } + Loader { id: panelLoader } diff --git a/hancore.shibumi.ai/OpenCodeUsageIcon.qml b/hancore.shibumi.ai/OpenCodeUsageIcon.qml deleted file mode 100644 index bdd14ce..0000000 --- a/hancore.shibumi.ai/OpenCodeUsageIcon.qml +++ /dev/null @@ -1,57 +0,0 @@ -import QtQuick -import QtQuick.Effects -import "../hancore.shibumi.state/lib/presentation" as Presentation - -// The original pixel mark, rasterized at its native grid before nearest sampling. -Item { - id: root - required property color baseColor - required property color fillColor - required property real baseOpacity - required property real usageFraction - - Presentation.BarInk { id: placement; target: root } - Item { - id: paint - width: Math.round(root.width * placement.dpr) / placement.dpr - height: Math.round(width * placement.dpr * 14 / 22) / placement.dpr - x: placement.snapX((root.width - width) / 2) - y: placement.rectangleY(height) - - Image { - id: mark - anchors.fill: parent - visible: false - source: Qt.resolvedUrl("assets/opencode-mark.svg") - // Qt scales SVG requests by DPR before rasterizing them. - sourceSize: Qt.size(Math.max(1, Math.round(22 / placement.dpr)), - Math.max(1, Math.round(14 / placement.dpr))) - fillMode: Image.Stretch - smooth: false - mipmap: false - } - MultiEffect { - anchors.fill: parent - source: mark - colorization: 1 - colorizationColor: Qt.rgba(root.baseColor.r, root.baseColor.g, root.baseColor.b, 1) - opacity: root.baseColor.a * root.baseOpacity - } - Item { - anchors.bottom: parent.bottom - width: parent.width - height: Math.round(parent.height * root.usageFraction * placement.dpr) / placement.dpr - clip: true - Behavior on height { NumberAnimation { duration: 600; easing.type: Easing.OutCubic } } - MultiEffect { - anchors.bottom: parent.bottom - width: paint.width - height: paint.height - source: mark - colorization: 1 - colorizationColor: Qt.rgba(root.fillColor.r, root.fillColor.g, root.fillColor.b, 1) - opacity: root.fillColor.a - } - } - } -} From 14fe4a4317f66a91f26c2261e835aeb9293a0a3b Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 10:02:21 +0200 Subject: [PATCH 14/31] release: repin the beta.16.1 candidate payload --- contracts/lifecycle-predecessors-v1.json | 4 ++-- tests/test_package_release.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/lifecycle-predecessors-v1.json b/contracts/lifecycle-predecessors-v1.json index c6b6c10..2436c79 100644 --- a/contracts/lifecycle-predecessors-v1.json +++ b/contracts/lifecycle-predecessors-v1.json @@ -759,7 +759,7 @@ }, { "id": "public-beta.16.1", - "payloadDigest": "f0f951c91f14611bc1efbc932d2f48ead1fd43a0133c1f739fa503c3ee9ebd5e", + "payloadDigest": "952093e41d9a30d79ab87fd97bafc2034dd0eb8be78eae03a5af2d91357fc5b5", "pluginDigests": { "hancore.shibumi.bar": "f1eda2d05892d3756319e3cb4474565505f9e6ca2bbb30c4a8983d7103525b9a", "hancore.shibumi.state": "3aed3c7a3cb92afb66d5f12d7d5c773f1988d5f11c933da187f8b31c68179da8", @@ -773,7 +773,7 @@ "hancore.shibumi.memory": "f6fbd0838180fac0740fd27d22f9fe1812528f45210e51fa9984f479f42da8f9", "hancore.shibumi.cpu": "bb0d1df3404525a45c55fffaa2091a8340ae3d9536f7edab6e6bd56759f7999e", "hancore.shibumi.audio": "20a3f204e0c55b6c9aff18d12e9627b91f3710596e3d1c2e00b08aaa0f3e3e4c", - "hancore.shibumi.ai": "4915e89db32c358ff9f8dca120f56ba05425281ac62836752c3de91171097c5c", + "hancore.shibumi.ai": "38e41e443b34c888107bc64e654adef9982130067c52702660f3960450a50959", "hancore.shibumi.center": "fe792ff696628b9b6ce324e0767d6ccabc6bca98a0529f9c2d7d2a58f36761a6", "hancore.shibumi.media": "e67e51d2629520b6e7a4578940885b8ff2245798254af4f8ea39ce7b8d2d8c82", "hancore.shibumi.quick-access": "4ce7d5575e758ddb3cec856672e0717f95dd494c5a4488f61e0269e534697502", diff --git a/tests/test_package_release.py b/tests/test_package_release.py index 5066755..b4edde1 100644 --- a/tests/test_package_release.py +++ b/tests/test_package_release.py @@ -225,7 +225,7 @@ def test_lifecycle_contract_pins_exact_release_identities(self) -> None: "suiteVersion": "0.1.1-beta.16.1", "sourceRevisions": ["package:0.1.1-beta.16.1"], "settingsStorageVersion": 1, - "payloadDigest": "f0f951c91f14611bc1efbc932d2f48ead1fd43a0133c1f739fa503c3ee9ebd5e", + "payloadDigest": "952093e41d9a30d79ab87fd97bafc2034dd0eb8be78eae03a5af2d91357fc5b5", }, } self.assertEqual(set(states), set(expected)) From 7f31759bb2466fbf6199809efcfcb66ada33b35f Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 10:54:00 +0200 Subject: [PATCH 15/31] test: align expectations with the approved beta.16.1 visuals --- tests/ai-plugin-smoke.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ai-plugin-smoke.qml b/tests/ai-plugin-smoke.qml index de39c3c..0d5ea3f 100644 --- a/tests/ai-plugin-smoke.qml +++ b/tests/ai-plugin-smoke.qml @@ -532,9 +532,9 @@ ShellRoot { const customBaseContrast = root.contrastRatio( root.composite(expectedBase, fakeBar.customFill, expected.baseOpacity), fakeBar.customFill) - const glyphWidth = expected.providerId === "opencode" ? 20 + const glyphWidth = expected.providerId === "opencode" ? 15 : expected.providerId === "codex" ? 14 : 15 - const glyphHeight = expected.providerId === "opencode" ? 12 + const glyphHeight = expected.providerId === "opencode" ? 10 : expected.providerId === "codex" ? 14 : 15 const glyphOffset = 0 const contentOffset = expected.providerId === "codex" ? -1 : 0 From 9d065bcbfcacd562722d968ce57c744ce5ceb337 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 14:17:29 +0200 Subject: [PATCH 16/31] fix: show the update count beside its icon and drop the tray count badge --- contracts/v2-feature-evidence.json | 2 +- contracts/v2-feature-port.json | 2 +- hancore.shibumi.status/BarWidget.qml | 20 +-- hancore.shibumi.status/TrayStatusView.qml | 95 ----------- hancore.shibumi.update-center/BarWidget.qml | 153 +++++++----------- .../UpdateCenterPanel.qml | 8 +- 6 files changed, 66 insertions(+), 214 deletions(-) diff --git a/contracts/v2-feature-evidence.json b/contracts/v2-feature-evidence.json index ac78e92..d056917 100644 --- a/contracts/v2-feature-evidence.json +++ b/contracts/v2-feature-evidence.json @@ -34,7 +34,7 @@ {"id":"tray.drawer","implementation":["hancore.shibumi.status/TrayDrawerPanel.qml"],"tests":["tests/status-plugin-smoke.qml","tests/status-plugin-regression.sh"]}, {"id":"tray.item-menu","implementation":["hancore.shibumi.status/TrayAppMenuPanel.qml"],"tests":["tests/tray-app-menu-smoke.qml","tests/status-plugin-regression.sh"]}, {"id":"launcher.logo-variants","implementation":["hancore.shibumi.state/ShibumiConfig.js","hancore.shibumi.control-center/BarWidget.qml"],"tests":["tests/shibumi-config-regression.qml","tests/control-center-smoke.qml"]}, - {"id":"updates.badge-controls","implementation":["hancore.shibumi.update-center/UpdateCenterPanel.qml"],"tests":["tests/update-center-ui-smoke.qml","tests/update-center-regression.sh"]}, + {"id":"updates.badge-controls","implementation":["hancore.shibumi.update-center/UpdateCenterPanel.qml","hancore.shibumi.update-center/BarWidget.qml"],"tests":["tests/update-center-ui-smoke.qml","tests/update-center-regression.sh"]}, {"id":"updates.shell-lifecycle","implementation":["scripts/shibumi_suite/runtime.py"],"tests":["tests/shibumi-suite-quattro-runtime.sh","tests/test_shibumi_suite.py"]}, {"id":"control-center.v2-capabilities","implementation":["hancore.shibumi.control-center/ControlSettings.qml","hancore.shibumi.control-center/BarFunctionsPage.qml"],"tests":["tests/control-center-smoke.qml","tests/control-center-regression.sh"]}, {"id":"output.lifecycle-recovery","implementation":["hancore.shibumi.bar/core/WindowRecovery.qml","hancore.shibumi.bar/core/BarPanel.qml"],"tests":["tests/bar-host-registry-smoke.qml","tests/contract-regression.sh"]}, diff --git a/contracts/v2-feature-port.json b/contracts/v2-feature-port.json index 254b9a7..1ee864b 100644 --- a/contracts/v2-feature-port.json +++ b/contracts/v2-feature-port.json @@ -40,7 +40,7 @@ {"id":"tray.drawer","decision":"port","owner":"hancore.shibumi.status","strategy":"official-tray-owner-presentation","phase":4}, {"id":"tray.item-menu","decision":"port","owner":"hancore.shibumi.status","strategy":"official-tray-owner-presentation","phase":4}, {"id":"launcher.logo-variants","decision":"port","owner":"hancore.shibumi.control-center","strategy":"presentation","phase":5}, - {"id":"updates.badge-controls","decision":"port","owner":"hancore.shibumi.update-center","strategy":"official-update-actions","phase":4}, + {"id":"updates.badge-controls","decision":"port","owner":"hancore.shibumi.update-center","strategy":"bar-count-controls","phase":4}, {"id":"updates.shell-lifecycle","decision":"port","owner":"shibumi-suite","strategy":"transactional-source-update","phase":4}, {"id":"control-center.v2-capabilities","decision":"port","owner":"hancore.shibumi.control-center","strategy":"user-directed-redesign","phase":5}, {"id":"output.lifecycle-recovery","decision":"port","owner":"hancore.shibumi.bar","strategy":"native-quattro-lifecycle","phase":6}, diff --git a/hancore.shibumi.status/BarWidget.qml b/hancore.shibumi.status/BarWidget.qml index 8eacbcc..34f0c58 100644 --- a/hancore.shibumi.status/BarWidget.qml +++ b/hancore.shibumi.status/BarWidget.qml @@ -107,9 +107,6 @@ Item { readonly property real trayPinnedIconOffset: trayView.pinnedIconHorizontalOffset readonly property color trayDrawerIconColor: trayView.drawerIconColor - readonly property color trayDrawerBadgeColor: trayView.drawerBadgeColor - readonly property color trayDrawerBadgeTextColor: - trayView.drawerBadgeTextColor readonly property color notificationBadgeColor: notificationView.badgeFillColor readonly property color notificationBadgeTextColor: @@ -119,9 +116,6 @@ Item { readonly property real updateSlotLayer: updateSlot.z readonly property real traySlotLayer: trayView.z readonly property real notificationSlotLayer: notificationView.z - readonly property real updateBadgeLayer: updateWidget - && "badgeLayer" in updateWidget ? Number(updateWidget.badgeLayer) : 0 - readonly property real trayBadgeLayer: trayView.badgeLayer readonly property real notificationBadgeLayer: notificationView.badgeLayer visible: ready && hasVisibleChild @@ -190,20 +184,12 @@ Item { if ("settings" in item) item.settings = childSettings("hancore.shibumi.update-center") if ("contentColor" in item) item.contentColor = root.widgetInk - if ("customToneActive" in item) - item.customToneActive = root.v1CustomToneActive - if ("badgeContrastColor" in item) - item.badgeContrastColor = root.badgeContrastColor } function syncUpdateInk() { if (!updateWidget) return if ("contentColor" in updateWidget) updateWidget.contentColor = root.widgetInk - if ("customToneActive" in updateWidget) - updateWidget.customToneActive = root.v1CustomToneActive - if ("badgeContrastColor" in updateWidget) - updateWidget.badgeContrastColor = root.badgeContrastColor } function injectChildren() { @@ -591,7 +577,9 @@ Item { id: updateSlot anchors.verticalCenter: parent.verticalCenter visible: root.fullMode && updateLoader.item !== null - implicitWidth: visible ? root.statusActionSlot : 0 + implicitWidth: visible ? root.statusActionSlot + + (root.updateWidget && "leadingWidth" in root.updateWidget + ? Number(root.updateWidget.leadingWidth) : 0) : 0 implicitHeight: updateLoader.implicitHeight width: implicitWidth height: implicitHeight @@ -609,10 +597,8 @@ Item { visible: root.fullMode && presented bar: root.bar trayBackend: root.trayWidget - customToneActive: root.v1CustomToneActive contentColor: root.v1CustomToneActive ? root.widgetInk : root.bar ? root.bar.foreground : root.widgetInk - badgeContrastColor: root.badgeContrastColor z: 2 onDrawerRequested: root.toggleTrayDrawer() } diff --git a/hancore.shibumi.status/TrayStatusView.qml b/hancore.shibumi.status/TrayStatusView.qml index c84e4a2..51eda43 100644 --- a/hancore.shibumi.status/TrayStatusView.qml +++ b/hancore.shibumi.status/TrayStatusView.qml @@ -9,15 +9,9 @@ Item { required property var bar property var trayBackend: null - property bool customToneActive: false property color contentColor: bar ? bar.foreground : Commons.Color.foreground - property color badgeContrastColor: bar - ? bar.background : Commons.Color.background readonly property color drawerIconColor: moreIcon.color - readonly property color drawerBadgeColor: badgePaint.color - readonly property color drawerBadgeTextColor: badgeValue.color - readonly property real badgeLayer: drawerBadge.z readonly property var pinnedItems: trayBackend && Array.isArray(trayBackend.pinnedItems) ? trayBackend.pinnedItems : [] readonly property int drawerCount: trayBackend @@ -192,95 +186,6 @@ Item { Behavior on color { ColorAnimation { duration: 150 } } } - Presentation.BarInk { id: badgePlacement; target: drawerBadge } - - Rectangle { - id: drawerBadge - visible: root.drawerCount > 0 - width: Math.floor(Math.max(Commons.Style.space(12), badgeText.implicitWidth + 6)) - height: Commons.Style.space(12) - radius: height / 2 - color: "transparent" - border.width: 0 - border.color: "transparent" - z: 10 - x: moreIcon.x + moreIcon.badgeLeft - y: moreIcon.badgeY(root, drawerBadge) - anchors.verticalCenter: !moreIcon.optical ? moreIcon.verticalCenter : undefined - anchors.verticalCenterOffset: -6 - anchors.horizontalCenter: !moreIcon.optical ? moreIcon.horizontalCenter : undefined - anchors.horizontalCenterOffset: 7 - - Text { - id: badgeText - visible: false - anchors.centerIn: parent - text: root.drawerCount > 99 ? "99" : String(root.drawerCount) - color: root.customToneActive - ? root.badgeContrastColor - : root.bar ? root.bar.background : Commons.Color.background - font.family: root.bar ? root.bar.fontFamily : Commons.Style.font.family - font.pixelSize: 7 - font.weight: Font.Bold - } - - // Paint only; the original badge still reserves its layout and anchor. - Rectangle { - id: badgePaint - readonly property real pixel: 1 / badgePlacement.dpr - readonly property real diameter: (2 * Math.floor( - Math.round(Commons.Style.space(10) * badgePlacement.dpr) / 2) + 1) * pixel - width: badgeValue.text.length === 1 ? diameter - : Math.floor(Math.max(diameter, badgeValue.implicitWidth + Commons.Style.space(3)) / pixel) * pixel - height: diameter - radius: height / 2 - color: root.customToneActive - ? root.contentColor - : root.bar ? root.bar.urgent : Commons.Color.accent - x: { - const origin = badgePlacement.origin - const slot = drawerToggle.mapToItem(drawerBadge, 0, 0) - const first = Math.ceil((origin.x + slot.x) / pixel) * pixel - origin.x - // Keep the single-digit circle anchored; extra width grows right. - const last = Math.floor((origin.x + slot.x + drawerToggle.width) / pixel) * pixel - origin.x - diameter - return Math.max(first, Math.min(last, badgePlacement.snapX(0))) - } - y: { - const origin = badgePlacement.origin - const slot = drawerToggle.mapToItem(drawerBadge, 0, 0) - const first = Math.ceil((origin.y + slot.y) / pixel) * pixel - origin.y - const last = Math.floor((origin.y + slot.y + drawerToggle.height) / pixel) * pixel - origin.y - height - return Math.max(first, Math.min(last, - badgePlacement.snapY((drawerBadge.height - height) / 2))) - } - - Presentation.BarInk { id: valuePlacement; target: badgePaint } - TextMetrics { - id: valueInk - text: badgeValue.text - font: Qt.font({family: badgeValue.font.family, - pixelSize: Math.round(badgeValue.font.pixelSize * valuePlacement.dpr), - weight: badgeValue.font.weight, hintingPreference: Font.PreferDefaultHinting}) - renderType: Text.NativeRendering - } - Text { - id: badgeValue - text: root.drawerCount > 99 ? "99+" : String(root.drawerCount) - x: valuePlacement.snapX(parent.width / 2 - - (valueInk.tightBoundingRect.x + valueInk.tightBoundingRect.width / 2) / valuePlacement.dpr) - // Match the native raster font; on an odd/even tie use the upper pixel. - y: Math.floor((valuePlacement.origin.y + parent.height / 2) * valuePlacement.dpr - - valueInk.tightBoundingRect.y - valueInk.tightBoundingRect.height / 2) / valuePlacement.dpr - - valuePlacement.origin.y - Math.round(baselineOffset * valuePlacement.dpr) / valuePlacement.dpr - color: badgeText.color - font.family: badgeText.font.family - font.pixelSize: Commons.Style.space(8) - font.bold: true - renderType: Text.NativeRendering - } - } - } - MouseArea { id: drawerMouse anchors.fill: parent diff --git a/hancore.shibumi.update-center/BarWidget.qml b/hancore.shibumi.update-center/BarWidget.qml index 8b48fbf..b6b56aa 100644 --- a/hancore.shibumi.update-center/BarWidget.qml +++ b/hancore.shibumi.update-center/BarWidget.qml @@ -44,12 +44,6 @@ Ui.Panel { readonly property color activeColor: bar ? bar.urgent : Commons.Color.bar.active property color contentColor: activeColor - property bool customToneActive: false - property color badgeContrastColor: bar - ? bar.background : Commons.Color.background - readonly property color badgeFillColor: badgePaint.color - readonly property color badgeTextColor: badgeValue.color - readonly property real badgeLayer: updateBadge.z readonly property string fontFamily: bar ? String(bar.fontFamily || Commons.Style.font.family) : Commons.Style.font.family @@ -57,7 +51,37 @@ Ui.Panel { Qt.fontFamilies().indexOf("Material Symbols Rounded") !== -1 readonly property bool panelLoaded: panelLoader.item !== null - implicitWidth: button.implicitWidth + Presentation.HostTokens { id: hostTokens; bar: root.bar } + readonly property var tokens: bar && "visualTokens" in bar + && bar.visualTokens ? bar.visualTokens : hostTokens + readonly property bool countVisible: !vertical && updateCount > 0 + Presentation.BarInk { id: countPlacement; target: root } + // Fit rounds its origin in logical pixels. Keep both the full expansion and + // its centered half integral in logical AND physical pixels (Wayland /120). + readonly property real countQuantum: { + let numerator = Math.max(1, Math.round(countPlacement.dpr * 120)) + let denominator = 120 + while (denominator !== 0) { + const remainder = numerator % denominator + numerator = denominator + denominator = remainder + } + return 240 / numerator + } + readonly property real countGap: Commons.Style.space(6) + readonly property real leadingWidth: countVisible + ? Math.ceil((Math.ceil(updateValue.implicitWidth) + countGap + - ((button.implicitWidth - updateIcon.width) / 2 + updateIcon.inkLeft)) + / countQuantum) * countQuantum : 0 + TextMetrics { + id: countInk + text: updateValue.text + font: Qt.font({ family: updateValue.font.family, + pixelSize: updateValue.font.pixelSize * countPlacement.metricScale, + weight: updateValue.font.weight, hintingPreference: Font.PreferNoHinting }) + } + + implicitWidth: button.implicitWidth + leadingWidth implicitHeight: button.implicitHeight function tooltipText() { @@ -137,9 +161,34 @@ Ui.Panel { registeredBar.unregisterClickTarget(root) } + Presentation.IconText { + id: updateValue + visible: root.countVisible + barText: true + x: { + const iconLeft = updateIcon.mapToItem(root, updateIcon.symbolInk.x, 0).x + const first = Math.floor((countPlacement.origin.x + iconLeft) + * countPlacement.dpr + 1e-7) + const end = Math.ceil((countInk.tightBoundingRect.x + + countInk.tightBoundingRect.width) * countPlacement.dpr + / countPlacement.metricScale) + return (first - Math.round(root.countGap * countPlacement.dpr) - end) + / countPlacement.dpr - countPlacement.origin.x + } + anchors.verticalCenter: parent.verticalCenter + text: root.updateCount > 99 ? "99+" : String(root.updateCount) + color: root.contentColor + font.family: root.fontFamily + font.pixelSize: root.tokens.labelSize + renderType: Text.NativeRendering + } + Ui.WidgetButton { id: button - anchors.fill: parent + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + width: implicitWidth + height: parent.height bar: root.bar text: "" labelVisible: false @@ -172,94 +221,6 @@ Ui.Panel { renderType: root.hasMaterialSymbols ? Text.QtRendering : Text.NativeRendering } - - Presentation.BarInk { id: badgePlacement; target: updateBadge } - - Rectangle { - id: updateBadge - visible: root.updateCount > 0 - x: updateIcon.x + updateIcon.badgeLeft - y: updateIcon.badgeY(root, updateBadge) - anchors.verticalCenter: !updateIcon.optical ? updateIcon.verticalCenter : undefined - anchors.verticalCenterOffset: -Commons.Style.space(6) - anchors.horizontalCenter: !updateIcon.optical ? updateIcon.horizontalCenter : undefined - anchors.horizontalCenterOffset: Commons.Style.space(7) - width: Math.floor(Math.max(Commons.Style.space(12), - badgeText.implicitWidth + Commons.Style.space(6))) - height: Commons.Style.space(12) - radius: height / 2 - color: "transparent" - border.width: 0 - border.color: "transparent" - z: 10 - - Text { - id: badgeText - visible: false - anchors.centerIn: parent - text: root.updateCount > 99 ? "99+" : String(root.updateCount) - color: root.customToneActive - ? root.badgeContrastColor : Commons.Color.background - font.family: root.fontFamily - font.pixelSize: Math.max(Commons.Style.space(7), - Commons.Style.font.caption - 3) - font.bold: true - } - - // Paint only; the original badge still reserves its layout and anchor. - Rectangle { - id: badgePaint - readonly property real pixel: 1 / badgePlacement.dpr - readonly property real diameter: (2 * Math.floor( - Math.round(Commons.Style.space(10) * badgePlacement.dpr) / 2) + 1) * pixel - width: badgeValue.text.length === 1 ? diameter - : Math.floor(Math.max(diameter, badgeValue.implicitWidth + Commons.Style.space(3)) / pixel) * pixel - height: diameter - radius: height / 2 - color: root.contentColor - x: { - const origin = badgePlacement.origin - const slot = root.mapToItem(updateBadge, 0, 0) - const first = Math.ceil((origin.x + slot.x) / pixel) * pixel - origin.x - // Keep the single-digit circle anchored; extra width grows right. - const last = Math.floor((origin.x + slot.x + root.width) / pixel) * pixel - origin.x - diameter - return Math.max(first, Math.min(last, badgePlacement.snapX(0))) - } - y: { - const origin = badgePlacement.origin - const slot = root.mapToItem(updateBadge, 0, 0) - const first = Math.ceil((origin.y + slot.y) / pixel) * pixel - origin.y - const last = Math.floor((origin.y + slot.y + root.height) / pixel) * pixel - origin.y - height - return Math.max(first, Math.min(last, - badgePlacement.snapY((updateBadge.height - height) / 2))) - } - - Presentation.BarInk { id: valuePlacement; target: badgePaint } - TextMetrics { - id: valueInk - text: badgeValue.text - font: Qt.font({family: badgeValue.font.family, - pixelSize: Math.round(badgeValue.font.pixelSize * valuePlacement.dpr), - weight: badgeValue.font.weight, hintingPreference: Font.PreferDefaultHinting}) - renderType: Text.NativeRendering - } - Text { - id: badgeValue - text: root.updateCount > 99 ? "99+" : String(root.updateCount) - x: valuePlacement.snapX(parent.width / 2 - - (valueInk.tightBoundingRect.x + valueInk.tightBoundingRect.width / 2) / valuePlacement.dpr) - // Match the native raster font; on an odd/even tie use the upper pixel. - y: Math.floor((valuePlacement.origin.y + parent.height / 2) * valuePlacement.dpr - - valueInk.tightBoundingRect.y - valueInk.tightBoundingRect.height / 2) / valuePlacement.dpr - - valuePlacement.origin.y - Math.round(baselineOffset * valuePlacement.dpr) / valuePlacement.dpr - color: badgeText.color - font.family: badgeText.font.family - font.pixelSize: Commons.Style.space(8) - font.bold: true - renderType: Text.NativeRendering - } - } - } } } diff --git a/hancore.shibumi.update-center/UpdateCenterPanel.qml b/hancore.shibumi.update-center/UpdateCenterPanel.qml index 36b0f8e..5b51a48 100644 --- a/hancore.shibumi.update-center/UpdateCenterPanel.qml +++ b/hancore.shibumi.update-center/UpdateCenterPanel.qml @@ -102,8 +102,8 @@ ShibumiPanel { hoverTextColor: panel.controlMutedHigh hoverBorderColor: panel.controlHoverBorderColor tooltipText: selected - ? "Package count is shown in the badge" - : "Package count is hidden from the badge" + ? "Package count is shown in the bar" + : "Package count is hidden from the bar" onClicked: panel.setBadgePreference( "packageBadge", !panel.packageBadgeEnabled) } @@ -121,8 +121,8 @@ ShibumiPanel { hoverTextColor: panel.controlMutedHigh hoverBorderColor: panel.controlHoverBorderColor tooltipText: selected - ? "Theme count is shown in the badge" - : "Theme count is hidden from the badge" + ? "Theme count is shown in the bar" + : "Theme count is hidden from the bar" onClicked: panel.setBadgePreference( "themeBadge", !panel.themeBadgeEnabled) } From ad08300ade10343ccd89e9488ff32724f6f72431 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 14:17:30 +0200 Subject: [PATCH 17/31] test: align status expectations with the beta.16.1 count presentation --- tests/status-plugin-smoke.qml | 14 ++------------ tests/update-center-owner-smoke.qml | 6 ------ 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/tests/status-plugin-smoke.qml b/tests/status-plugin-smoke.qml index 1d14fb9..84f3272 100644 --- a/tests/status-plugin-smoke.qml +++ b/tests/status-plugin-smoke.qml @@ -618,8 +618,6 @@ ShellRoot { || status.updateSlotLayer !== 3 || status.traySlotLayer !== 2 || status.notificationSlotLayer !== 1 - || status.updateBadgeLayer !== 10 - || status.trayBadgeLayer !== 10 || status.notificationBadgeLayer !== 10 || status.implicitWidth !== 112) return root.fail("V2 status geometry is not symmetric: inset=" @@ -816,7 +814,7 @@ ShellRoot { } else if (root.phase === 8) { if (root.phaseTicks < 3) return if (status.v2Mode || !status.v1CustomToneActive - || !status.updateWidget.customToneActive + || !Qt.colorEqual(status.updateWidget.contentColor, fakeBar.background) || Math.abs(status.trayDrawerIconColor.r - fakeBar.background.r) > 0.001 || Math.abs(status.trayDrawerIconColor.g @@ -824,23 +822,15 @@ ShellRoot { || Math.abs(status.trayDrawerIconColor.b - fakeBar.background.b) > 0.001 || Math.abs(status.trayDrawerIconColor.a - 0.7) > 0.003 - || !Qt.colorEqual( - status.trayDrawerBadgeColor, fakeBar.background) - || !Qt.colorEqual( - status.trayDrawerBadgeTextColor, "#cc8844") || !Qt.colorEqual( status.notificationBadgeColor, "#e85d74") || !Qt.colorEqual( status.notificationBadgeTextColor, "#cc8844") - || !Qt.colorEqual(status.badgeContrastColor, "#cc8844") - || !Qt.colorEqual( - status.updateWidget.badgeContrastColor, "#cc8844")) + || !Qt.colorEqual(status.badgeContrastColor, "#cc8844")) return root.fail("V1 tray drawer content tone" + " v2=" + status.v2Mode + " custom=" + status.v1CustomToneActive + " icon=" + status.trayDrawerIconColor - + " badge=" + status.trayDrawerBadgeColor - + " text=" + status.trayDrawerBadgeTextColor + " background=" + fakeBar.background) statusLoader.active = false root.phase++ diff --git a/tests/update-center-owner-smoke.qml b/tests/update-center-owner-smoke.qml index f2cd8d9..8417811 100644 --- a/tests/update-center-owner-smoke.qml +++ b/tests/update-center-owner-smoke.qml @@ -90,8 +90,6 @@ ShellRoot { height: implicitHeight bar: fakeBar contentColor: fakeBar.background - customToneActive: true - badgeContrastColor: "#cc8844" } Timer { @@ -100,10 +98,6 @@ ShellRoot { running: true onTriggered: { if (root.phase === 0) { - if (!Qt.colorEqual(widget.badgeFillColor, fakeBar.background) - || !Qt.colorEqual(widget.badgeTextColor, "#cc8844") - || widget.badgeLayer !== 10) - return root.fail("custom content tone badge") widget.open() } else if (root.phase === 1 && (!widget.opened || !widget.panelLoaded)) { From 1aa7bf425035f9b51f335f7bce9d07c0ee9a0b93 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 14:17:31 +0200 Subject: [PATCH 18/31] docs: describe the beta.16.1 count presentation --- .github/release-notes/v0.1.1-beta.16.1.md | 12 +++++------- CHANGELOG.md | 6 +++--- docs/release-readiness.md | 10 ++++++---- docs/v1-parity-matrix.md | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/release-notes/v0.1.1-beta.16.1.md b/.github/release-notes/v0.1.1-beta.16.1.md index 844d76c..0d42aec 100644 --- a/.github/release-notes/v0.1.1-beta.16.1.md +++ b/.github/release-notes/v0.1.1-beta.16.1.md @@ -1,7 +1,7 @@ # 0.1.1-beta.16.1 -Beta.16.1 is a patch release for Bluetooth power, the raised date, and badge -alignment. +Beta.16.1 fixes Bluetooth power and the raised date, restores tray and launcher +icons, and simplifies the update and tray count presentation. ## Fixes @@ -10,9 +10,9 @@ alignment. do not dispatch a reverse action; the display follows observed BlueZ state. - The smaller date is raised beside the clock again, as before Beta.16. The clock keeps its shared baseline. -- Single-digit update and tray badges are exactly centered at DPR 1 in circles - with odd physical-pixel diameters. Fractional scales retain whole-pixel - placement with parity-limited rounding. +- Show the update count beside the update icon instead of in a badge, and remove + the tray count badge. Both counts remain in the tooltips; vertical bars show + the update count only there. - Restore application icons for pinned tray apps, with a fallback when no icon is available. - Restore the selected launcher logo, including Omarchy, Shibumi, and Dragon, without symbol remapping. - Render the OpenCode usage mark crisply at the size of the other provider icons, so its usage fill reads clearly. @@ -65,5 +65,3 @@ Details: [Backup before downgrade](https://github.com/HANCORE-linux/Shibumi-Shel - The power helper affects all Bluetooth radios, not only the displayed adapter, and cannot clear a hardware rfkill block. -- Badge digits are exactly centered at DPR 1; fractional scales can leave a - half-pixel offset. diff --git a/CHANGELOG.md b/CHANGELOG.md index 47f9fb1..e5f2e90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,9 @@ Omarchy's power helper (#68). Ignore repeat clicks while a power request is pending instead of dispatching a reverse action. - Raise the smaller date beside the clock again, as before Beta.16. -- Center single-digit update and tray badges exactly at DPR 1 using circles - with odd physical-pixel diameters; retain whole-pixel placement at fractional - scales. +- Show the update count beside the update icon instead of in a badge, and remove + the tray count badge. Both counts remain in the tooltips; vertical bars show + the update count only there. - Restore application icons for pinned tray apps, with a fallback when no icon is available. - Restore the selected launcher logo, including Omarchy, Shibumi, and Dragon, without symbol remapping. - Render the OpenCode usage mark crisply at the size of the other provider icons, so its usage fill reads clearly. diff --git a/docs/release-readiness.md b/docs/release-readiness.md index 6a5a7f2..554799e 100644 --- a/docs/release-readiness.md +++ b/docs/release-readiness.md @@ -33,7 +33,7 @@ recovery or replacement. AUR publication remains deferred. | Isolated Quattro lifecycle | Pending on the combined revision; not started after the contract failure. No Beta.16.1 32/32 result is recorded. | | Retained runtime paths | Required: historical Beta.13 → Beta.14.1 package arm (5), fresh checkout (6), Beta.15 (7), Beta.15.2 (7), and rolling Beta.16 → current checkout (7): exactly 32 shell generations. | | Bluetooth preparation | Native-QML softblock-mock red/green regression and scoped Bluetooth, IPC, hotplug, and audio checks passed during fix preparation; these are not final-HEAD full gates or real rfkill acceptance. | -| Scoped visual previews | Maintainer-approved raised-date and badge comparisons in V1/V2 fit at DPR 1/1.6; private software-rendered previews, not physical acceptance. | +| Scoped visual previews | Private V1/V2 fit comparisons at DPR 1/1.6 cover the update count, badge-free tray, custom tone and count transitions; these revision-bound previews are not physical acceptance. | | Live installation and Bluetooth | Pending: reviewer installation and real softblock → on through Bar, panel, and IPC; rapid repeat clicks; on → off. No hardware or persistence result is recorded. | | Release/package verification | Release date, exact-commit archive/checksum, updated PKGBUILD/`.SRCINFO`, source/package rehearsal, 14-gate collector, and publication verification remain pending. | @@ -109,9 +109,11 @@ was performed. Each operation needs its own maintainer Go. a hardware block. The 20-second pending deadline does not stop the detached process or prevent later effects. Real rfkill and persistence acceptance is separate from controlled native-QML feedback. -- Single-digit badges are exactly centered at DPR 1 in the approved previews; - fractional-scale digit parity and antialiased circle edges can retain a - half-pixel bounding-box offset. +- The horizontal update count shares the bar-value baseline and CPU ink spacing. + Its leading reservation grows on an output-scale grid so the unchanged bell + retains its raster phase, including centered Fit. The private captures still + contain isolated one-level RGB differences in other widgets after translation; + exact whole-bar pixel identity and physical acceptance are not claimed. - **Downgrade:** Beta.15.4 and older cannot read V1 `order.parked`; they reset V1 order, roles, and splits while retaining other settings and V2. `--keep-settings` does not prevent this. The [release notes](../.github/release-notes/v0.1.1-beta.16.1.md) diff --git a/docs/v1-parity-matrix.md b/docs/v1-parity-matrix.md index 4421532..d8e61f9 100644 --- a/docs/v1-parity-matrix.md +++ b/docs/v1-parity-matrix.md @@ -52,7 +52,7 @@ Status values: | Themes/wallpapers | Discover, preview and apply supported sources | Omarchy theme APIs plus current and user background roots through one shared scanner | Partial; discovery and previews pass on the validation system, while apply and failure-path acceptance remain | | AI usage | Claude, Codex and OpenCode quota state and warnings | One process-wide V1 single-provider facade; lazy official Claude/Codex scanners and one cache-free OpenCode SQLite adapter | Partial; OpenCode runtime, legacy IPC, and Top/Bottom product-panel routing are accepted on the validation system; Claude/Codex account-data and physical multi-output gates remain | | Reactor | Approved modes, gating and event behavior | Backend-free Modes 1-6; one lazy root event/quote source for Modes 7-8; style owns only per-output rendering | Partial; all modes are implemented, Mode 0 is zero-work, and Modes 1-8 now have single-output the validation system visual evidence. Mode 7/8 lifecycle and bounded CPU are characterized; physical multi-output acceptance remains. | -| Package/theme updates | User-visible checks, package apply, theme review and apply | Independent G3 Update Center plugin with read-only package/theme scans and actions delegated to visible Omarchy-owned commands | Partial; the compact V1-style package and theme tabs load with real the validation system state, badge preferences, pinned theme review/update/reinstall/remove controls, and no copied shell updater. Real theme apply/failure, package apply, bottom placement, and multi-output remain release gates. | +| Package/theme updates | User-visible checks, package apply, theme review and apply | Independent G3 Update Center plugin with read-only package/theme scans and actions delegated to visible Omarchy-owned commands | Partial; the compact V1-style package and theme tabs load with real the validation system state, bar-count preferences, pinned theme review/update/reinstall/remove controls, and no copied shell updater. Real theme apply/failure, package apply, bottom placement, and multi-output remain release gates. | | Shell self-update | V1 pinned standalone updater and progress UI | Omarchy plugin install/update/rollback lifecycle | Adapt | | Install/uninstall | Standalone scripts and post-boot hooks | Transactional Shibumi suite installer stages independently validated Omarchy plugins; Omarchy owns runtime activation | Adapt | | User configuration | V1 cache/config behavior | Host-owned `shell.json` plus versioned Shibumi feature state | Adapt | From 69ea4da7e599d2f6cd7fe246fe3fd803a3123504 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 14:17:57 +0200 Subject: [PATCH 19/31] release: repin the beta.16.1 candidate payload --- contracts/lifecycle-predecessors-v1.json | 6 +++--- tests/test_package_release.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/lifecycle-predecessors-v1.json b/contracts/lifecycle-predecessors-v1.json index 2436c79..adc5e9f 100644 --- a/contracts/lifecycle-predecessors-v1.json +++ b/contracts/lifecycle-predecessors-v1.json @@ -759,7 +759,7 @@ }, { "id": "public-beta.16.1", - "payloadDigest": "952093e41d9a30d79ab87fd97bafc2034dd0eb8be78eae03a5af2d91357fc5b5", + "payloadDigest": "836ff9b08fa2b8845aace116191f42b9d728e1a830471f305c39f4cd74d15679", "pluginDigests": { "hancore.shibumi.bar": "f1eda2d05892d3756319e3cb4474565505f9e6ca2bbb30c4a8983d7103525b9a", "hancore.shibumi.state": "3aed3c7a3cb92afb66d5f12d7d5c773f1988d5f11c933da187f8b31c68179da8", @@ -768,8 +768,8 @@ "hancore.shibumi.telemetry": "f52aff2aa784a11eab6edb12b5c3610986a01284f98844293e5cc8e1bb2963b0", "hancore.shibumi.power-state": "f2f664b00436695dbd47edf9b8d7da46d0f4f7fbe740045023479ed707872a50", "hancore.shibumi.workspaces": "de2a198c2a1fcbada535f046b91f37e5f5ca517ef4a0e3c6f570baf7930699c5", - "hancore.shibumi.update-center": "505433f5a19ef761b10f4a04628cbc04aca42c4f340bfe1cfabdcb4b986cc70c", - "hancore.shibumi.status": "97138019874d45d3e1f7e50b4693751b8ac13492c99e9809f5fa8d20e13f7c2b", + "hancore.shibumi.update-center": "3b448c4493526933b79282ae9d8dfce91dc2b2a48475ae052afc4dca3edfbe0a", + "hancore.shibumi.status": "d7d03e7a65307c63c402ad7637770824776e88b6e852d16341c9dd457a27b790", "hancore.shibumi.memory": "f6fbd0838180fac0740fd27d22f9fe1812528f45210e51fa9984f479f42da8f9", "hancore.shibumi.cpu": "bb0d1df3404525a45c55fffaa2091a8340ae3d9536f7edab6e6bd56759f7999e", "hancore.shibumi.audio": "20a3f204e0c55b6c9aff18d12e9627b91f3710596e3d1c2e00b08aaa0f3e3e4c", diff --git a/tests/test_package_release.py b/tests/test_package_release.py index b4edde1..8d1cabf 100644 --- a/tests/test_package_release.py +++ b/tests/test_package_release.py @@ -225,7 +225,7 @@ def test_lifecycle_contract_pins_exact_release_identities(self) -> None: "suiteVersion": "0.1.1-beta.16.1", "sourceRevisions": ["package:0.1.1-beta.16.1"], "settingsStorageVersion": 1, - "payloadDigest": "952093e41d9a30d79ab87fd97bafc2034dd0eb8be78eae03a5af2d91357fc5b5", + "payloadDigest": "836ff9b08fa2b8845aace116191f42b9d728e1a830471f305c39f4cd74d15679", }, } self.assertEqual(set(states), set(expected)) From 299a4a55a914b306177a52e90142e1d1f6c4d372 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 16:25:15 +0200 Subject: [PATCH 20/31] fix: match the status icon spacing to the quick-access group --- hancore.shibumi.status/BarWidget.qml | 33 +++++++++++++++++++ .../NotificationStatusView.qml | 1 + hancore.shibumi.status/TrayStatusView.qml | 1 + hancore.shibumi.update-center/BarWidget.qml | 6 ++++ 4 files changed, 41 insertions(+) diff --git a/hancore.shibumi.status/BarWidget.qml b/hancore.shibumi.status/BarWidget.qml index 34f0c58..34a4cb1 100644 --- a/hancore.shibumi.status/BarWidget.qml +++ b/hancore.shibumi.status/BarWidget.qml @@ -89,6 +89,35 @@ Item { || iconMode && notificationPresented || textMode && notificationService !== null readonly property real childGap: Commons.Style.space(4) + Presentation.BarInk { id: statusPlacement; target: root } + // Quick Access: 22px slots + 4px spacing - 12px glyphs = 14px ink gap. Keep + // the outer reservation and translate whole slots by physical pixels only. + readonly property real iconGapPixels: Math.round(Commons.Style.space(14) * statusPlacement.dpr) + readonly property rect updateInk: updateWidget && updateWidget.iconInk !== undefined + ? updateWidget.mapToItem(updateSlot, updateWidget.iconInk) : Qt.rect(0, 0, 0, 0) + function inkEdge(slot, ink, end) { + const edge = (statusPlacement.origin.x + statusRow.x + slot.x + + ink.x + (end ? ink.width : 0)) * statusPlacement.dpr + return end ? Math.ceil(edge - 1e-7) : Math.floor(edge + 1e-7) + } + readonly property real directContraction: fullMode && updatePresented + && notificationPresented && !trayPresented && updateInk.width > 0 + ? Math.max(0, inkEdge(notificationView, notificationView.iconInk, false) + - inkEdge(updateSlot, updateInk, true) - iconGapPixels) : 0 + readonly property real updateShift: !fullMode || !updatePresented || updateInk.width <= 0 ? 0 + : (trayPresented ? trayView.pinnedCount > 0 + ? Math.round(Commons.Style.space(3) * statusPlacement.dpr) + : Math.min(Math.floor(childGap * statusPlacement.dpr), + Math.max(0, inkEdge(trayView, trayView.drawerInk, false) + - inkEdge(updateSlot, updateInk, true) - iconGapPixels)) + : Math.ceil(directContraction / 2)) / statusPlacement.dpr + readonly property real bellShift: !fullMode || !notificationPresented ? 0 + : -(trayPresented ? trayView.drawerCount > 0 + ? Math.min(Math.floor(childGap * statusPlacement.dpr), + Math.max(0, inkEdge(notificationView, notificationView.iconInk, false) + - inkEdge(trayView, trayView.drawerInk, true) - iconGapPixels)) + : Math.round(Commons.Style.space(3) * statusPlacement.dpr) + : Math.floor(directContraction / 2)) / statusPlacement.dpr readonly property int presentedCount: fullMode ? (updatePresented ? 1 : 0) + (trayPresented ? 1 : 0) + (notificationPresented ? 1 : 0) @@ -560,6 +589,8 @@ Item { settings: root.settings v1AppearanceEnabled: true anchors.fill: parent + anchors.leftMargin: root.updateShift + anchors.rightMargin: -root.bellShift anchors.topMargin: root.tokens ? Math.round((parent.height - root.tokens.pillHeight) / 2) : 0 anchors.bottomMargin: root.tokens @@ -575,6 +606,7 @@ Item { Item { id: updateSlot + transform: Translate { x: root.updateShift } anchors.verticalCenter: parent.verticalCenter visible: root.fullMode && updateLoader.item !== null implicitWidth: visible ? root.statusActionSlot @@ -605,6 +637,7 @@ Item { NotificationStatusView { id: notificationView + transform: Translate { x: root.bellShift } visible: (root.fullMode || root.iconMode) && presented bar: root.bar contentColor: root.widgetInk diff --git a/hancore.shibumi.status/NotificationStatusView.qml b/hancore.shibumi.status/NotificationStatusView.qml index 62e8f4b..9cc1922 100644 --- a/hancore.shibumi.status/NotificationStatusView.qml +++ b/hancore.shibumi.status/NotificationStatusView.qml @@ -15,6 +15,7 @@ Item { ? bar.background : Commons.Color.background property real slotWidth: Commons.Style.space(26) readonly property real iconHorizontalOffset: Commons.Style.space(1) + readonly property rect iconInk: bellIcon.mapToItem(root, bellIcon.symbolInk) property var notificationService: null readonly property int pendingCount: notificationService && notificationService.liveAvailable === true && notificationService.pendingModel diff --git a/hancore.shibumi.status/TrayStatusView.qml b/hancore.shibumi.status/TrayStatusView.qml index 51eda43..301d355 100644 --- a/hancore.shibumi.status/TrayStatusView.qml +++ b/hancore.shibumi.status/TrayStatusView.qml @@ -12,6 +12,7 @@ Item { property color contentColor: bar ? bar.foreground : Commons.Color.foreground readonly property color drawerIconColor: moreIcon.color + readonly property rect drawerInk: moreIcon.mapToItem(root, moreIcon.symbolInk) readonly property var pinnedItems: trayBackend && Array.isArray(trayBackend.pinnedItems) ? trayBackend.pinnedItems : [] readonly property int drawerCount: trayBackend diff --git a/hancore.shibumi.update-center/BarWidget.qml b/hancore.shibumi.update-center/BarWidget.qml index b6b56aa..5ee4eff 100644 --- a/hancore.shibumi.update-center/BarWidget.qml +++ b/hancore.shibumi.update-center/BarWidget.qml @@ -50,6 +50,12 @@ Ui.Panel { readonly property bool hasMaterialSymbols: Qt.fontFamilies().indexOf("Material Symbols Rounded") !== -1 readonly property bool panelLoaded: panelLoader.item !== null + readonly property rect iconInk: { + for (let item = updateIcon; item && item !== root; item = item.parent) { + void(item.x); void(item.width) + } + return updateIcon.mapToItem(root, updateIcon.symbolInk) + } Presentation.HostTokens { id: hostTokens; bar: root.bar } readonly property var tokens: bar && "visualTokens" in bar From 2c150907ece0d963107d3e37c24b53d5741ccb56 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 16:25:16 +0200 Subject: [PATCH 21/31] fix: follow Omarchy's any-controller Bluetooth power state --- .../BluetoothBackendAdapter.qml | 23 +++++++++++++------ hancore.shibumi.bluetooth/Service.qml | 11 +++++---- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/hancore.shibumi.bluetooth/BluetoothBackendAdapter.qml b/hancore.shibumi.bluetooth/BluetoothBackendAdapter.qml index f674909..b737f02 100644 --- a/hancore.shibumi.bluetooth/BluetoothBackendAdapter.qml +++ b/hancore.shibumi.bluetooth/BluetoothBackendAdapter.qml @@ -18,6 +18,7 @@ Item { // Lets the component smoke test drive native device property transitions // without touching the host's real Bluetooth devices. property var nativeDevicesOverride: null + property var nativeAdaptersOverride: null property var pipewireNodesOverride: null property var commandRunnerOverride: null property var audioOutputOverride: null @@ -51,9 +52,17 @@ Item { readonly property var adapter: backendOverride !== null ? ("adapter" in backendOverride ? backendOverride.adapter : null) : (adapterOverride !== null ? adapterOverride : Bluetooth.defaultAdapter) - readonly property var nativeAdapters: backendOverride === null - && adapterOverride === null && Bluetooth.adapters - ? Model.toArray(Bluetooth.adapters.values) : (adapter ? [adapter] : []) + readonly property var nativeAdapters: nativeAdaptersOverride !== null + ? nativeAdaptersOverride : backendOverride === null + && adapterOverride === null && Bluetooth.adapters + ? Model.toArray(Bluetooth.adapters.values) : (adapter ? [adapter] : []) + // The host power helper acts globally; discovery/device actions remain local. + readonly property bool powerEnabled: { + for (let i = 0; i < nativeAdapters.length; i++) { + if (nativeAdapters[i] && nativeAdapters[i].enabled === true) return true + } + return false + } readonly property bool adapterAvailable: adapter !== null readonly property bool radioEnabled: adapterAvailable && adapter.enabled !== undefined && adapter.enabled === true @@ -317,7 +326,7 @@ Item { } if (pendingPowerTarget !== null) return false pendingPowerAdapter = adapter - pendingPowerTarget = !radioEnabled + pendingPowerTarget = !powerEnabled powerRequestTimeout.restart() if (radioEnabled) stopDiscovery() try { @@ -731,11 +740,11 @@ Item { syncNativeAudioHandoffIntents() } onDiscoveryDesiredChanged: if (!discoveryDesired) stopDiscovery() - onRadioEnabledChanged: { - if (pendingPowerAdapter === adapter && pendingPowerTarget === radioEnabled) + onPowerEnabledChanged: { + if (pendingPowerAdapter === adapter && pendingPowerTarget === powerEnabled) clearPendingPower() - if (!radioEnabled) cancelAllAudioHandoffs() } + onRadioEnabledChanged: if (!radioEnabled) cancelAllAudioHandoffs() onAdapterChanged: { clearPendingPower() observeNativeAdapter() diff --git a/hancore.shibumi.bluetooth/Service.qml b/hancore.shibumi.bluetooth/Service.qml index 2efb242..bd206c3 100644 --- a/hancore.shibumi.bluetooth/Service.qml +++ b/hancore.shibumi.bluetooth/Service.qml @@ -36,7 +36,8 @@ Item { readonly property bool ready: adapter.ready readonly property bool adapterAvailable: adapter.adapterAvailable - readonly property bool radioEnabled: adapter.radioEnabled + readonly property bool radioEnabled: adapter.powerEnabled + readonly property bool adapterEnabled: adapter.radioEnabled readonly property bool discovering: adapter.discovering readonly property var connectedDevices: adapter.connectedDevices readonly property var knownDevices: adapter.knownDevices @@ -53,7 +54,7 @@ Item { if (!owner) return false if (sessionOwners.indexOf(owner) < 0) sessionOwners = sessionOwners.concat([owner]) - if (sessionOwners.length === 1 && radioEnabled) adapter.startDiscovery() + if (sessionOwners.length === 1 && adapterEnabled) adapter.startDiscovery() return true } @@ -94,8 +95,8 @@ Item { function pendingAction(address) { return adapter.pendingAction(address) } function deviceLabel(device) { return adapter.deviceLabel(device) } - onRadioEnabledChanged: { - if (!radioEnabled) adapter.stopDiscovery() + onAdapterEnabledChanged: { + if (!adapterEnabled) adapter.stopDiscovery() } Component.onDestruction: adapter.stopDiscovery() @@ -135,7 +136,7 @@ Item { repeat: true triggeredOnStart: true running: root.sessionCount > 0 && root.adapterAvailable - && root.radioEnabled && !root.discovering + && root.adapterEnabled && !root.discovering onTriggered: adapter.startDiscovery() } } From 52749f59441a34f58849e80e6f612d002b127064 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 16:25:17 +0200 Subject: [PATCH 22/31] fix: make the update count part of the update button --- hancore.shibumi.update-center/BarWidget.qml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/hancore.shibumi.update-center/BarWidget.qml b/hancore.shibumi.update-center/BarWidget.qml index 5ee4eff..e0e0860 100644 --- a/hancore.shibumi.update-center/BarWidget.qml +++ b/hancore.shibumi.update-center/BarWidget.qml @@ -136,7 +136,7 @@ Ui.Panel { panelLoader.source = "" if (!opened || !updateService) return panelLoader.setSource(panelSource, { - anchorItem: button, + anchorItem: panelAnchor, bar: root.bar, open: true, ownerWidget: root, @@ -172,7 +172,7 @@ Ui.Panel { visible: root.countVisible barText: true x: { - const iconLeft = updateIcon.mapToItem(root, updateIcon.symbolInk.x, 0).x + const iconLeft = root.iconInk.x const first = Math.floor((countPlacement.origin.x + iconLeft) * countPlacement.dpr + 1e-7) const end = Math.ceil((countInk.tightBoundingRect.x @@ -189,12 +189,18 @@ Ui.Panel { renderType: Text.NativeRendering } - Ui.WidgetButton { - id: button + // Keep the panel/caret on the original icon slot while input spans the count. + Item { + id: panelAnchor anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - width: implicitWidth + width: button.implicitWidth height: parent.height + } + + Ui.WidgetButton { + id: button + anchors.fill: parent bar: root.bar text: "" labelVisible: false @@ -209,7 +215,10 @@ Ui.Panel { onPressed: function(mouseButton) { root.triggerPress(mouseButton) } Item { - anchors.centerIn: parent + anchors.right: parent.right + anchors.rightMargin: button.implicitWidth - width + - Math.round((button.implicitWidth - width) / 2) + anchors.verticalCenter: parent.verticalCenter width: Commons.Style.space(20) height: Commons.Style.space(20) From 22ab9dbdf097c2485281ee9acccd3c4488e5d6e5 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 16:25:18 +0200 Subject: [PATCH 23/31] test: align expectations with the beta.16.1 status fixes --- tests/bluetooth-plugin-regression.sh | 2 +- tests/contract-regression.sh | 2 +- tests/update-center-regression.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/bluetooth-plugin-regression.sh b/tests/bluetooth-plugin-regression.sh index b1d981f..d9457c3 100755 --- a/tests/bluetooth-plugin-regression.sh +++ b/tests/bluetooth-plugin-regression.sh @@ -189,7 +189,7 @@ rg -q 'property var sessionOwners: \[\]' "$service" \ || fail "Bluetooth panel sessions are not centrally tracked" rg -q 'adapter\.stopDiscovery\(\)' "$service" \ || fail "Bluetooth discovery lacks final-close cleanup" -rg -U -q 'id: discoveryRetry[^}]*repeat: true[^}]*running: root\.sessionCount > 0 && root\.adapterAvailable[^}]*root\.radioEnabled && !root\.discovering' \ +rg -U -q 'id: discoveryRetry[^}]*repeat: true[^}]*running: root\.sessionCount > 0 && root\.adapterAvailable[^}]*root\.adapterEnabled && !root\.discovering' \ "$service" \ || fail "Bluetooth discovery retry is not bounded to an open, powered idle session" rg -U -q 'function confirmRequestedDiscovery\(\) \{(.|\n)*?requested\.discovering(.|\n)*?discoveryOwned = true(.|\n)*?\n \}' \ diff --git a/tests/contract-regression.sh b/tests/contract-regression.sh index 22e98bf..7b4af58 100755 --- a/tests/contract-regression.sh +++ b/tests/contract-regression.sh @@ -954,7 +954,7 @@ for bluetooth_adapter in "$bluetooth_adapter"; do fail "$bluetooth_adapter still owns IPC or loads a foreign UI component" fi done -rg -U -q 'id: discoveryRetry[^}]*repeat: true[^}]*running: root\.sessionCount > 0 && root\.adapterAvailable[^}]*root\.radioEnabled && !root\.discovering' \ +rg -U -q 'id: discoveryRetry[^}]*repeat: true[^}]*running: root\.sessionCount > 0 && root\.adapterAvailable[^}]*root\.adapterEnabled && !root\.discovering' \ "$bluetooth_service" \ || fail "Bluetooth service does not bound discovery retries to an open session" if rg -q 'registeredWidget|registeredSource|registeredComponent|panelSource|panelComponent|Loader \{' \ diff --git a/tests/update-center-regression.sh b/tests/update-center-regression.sh index 79f470a..a8b381e 100755 --- a/tests/update-center-regression.sh +++ b/tests/update-center-regression.sh @@ -47,7 +47,7 @@ for preference in packageBadge themeBadge; do done rg -q 'panelSource: Qt\.resolvedUrl\("UpdateCenterPanel\.qml"\)' "$widget" \ || fail 'update widget does not lazy-load its panel' -rg -q 'anchorItem: button' "$widget" \ +rg -q 'anchorItem: panelAnchor' "$widget" \ || fail 'update panel is not anchored to its own bar button' if rg -Fq 'open: ownerWidget.opened' "$panel"; then fail 'update panel binds its lifecycle back to the owner widget' From deeca9b96857037e4c85ac4828c203883919c8bf Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sat, 3 Oct 2026 16:25:58 +0200 Subject: [PATCH 24/31] release: repin the beta.16.1 candidate payload --- contracts/lifecycle-predecessors-v1.json | 8 ++++---- tests/test_package_release.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/lifecycle-predecessors-v1.json b/contracts/lifecycle-predecessors-v1.json index adc5e9f..bb7130d 100644 --- a/contracts/lifecycle-predecessors-v1.json +++ b/contracts/lifecycle-predecessors-v1.json @@ -759,7 +759,7 @@ }, { "id": "public-beta.16.1", - "payloadDigest": "836ff9b08fa2b8845aace116191f42b9d728e1a830471f305c39f4cd74d15679", + "payloadDigest": "76cd94d0b1991f1628c2f7ffdc9ebf64198a888f3677dd5bb7815b85875ade30", "pluginDigests": { "hancore.shibumi.bar": "f1eda2d05892d3756319e3cb4474565505f9e6ca2bbb30c4a8983d7103525b9a", "hancore.shibumi.state": "3aed3c7a3cb92afb66d5f12d7d5c773f1988d5f11c933da187f8b31c68179da8", @@ -768,8 +768,8 @@ "hancore.shibumi.telemetry": "f52aff2aa784a11eab6edb12b5c3610986a01284f98844293e5cc8e1bb2963b0", "hancore.shibumi.power-state": "f2f664b00436695dbd47edf9b8d7da46d0f4f7fbe740045023479ed707872a50", "hancore.shibumi.workspaces": "de2a198c2a1fcbada535f046b91f37e5f5ca517ef4a0e3c6f570baf7930699c5", - "hancore.shibumi.update-center": "3b448c4493526933b79282ae9d8dfce91dc2b2a48475ae052afc4dca3edfbe0a", - "hancore.shibumi.status": "d7d03e7a65307c63c402ad7637770824776e88b6e852d16341c9dd457a27b790", + "hancore.shibumi.update-center": "4f028d0c82cbe0d85c74799a77c12e7e26acc9bd4dcda6f7c14fc40a5f991a86", + "hancore.shibumi.status": "270037acf2fc5d0edad827c5300c308b9adc2abb80509e499dd7f6702871ef63", "hancore.shibumi.memory": "f6fbd0838180fac0740fd27d22f9fe1812528f45210e51fa9984f479f42da8f9", "hancore.shibumi.cpu": "bb0d1df3404525a45c55fffaa2091a8340ae3d9536f7edab6e6bd56759f7999e", "hancore.shibumi.audio": "20a3f204e0c55b6c9aff18d12e9627b91f3710596e3d1c2e00b08aaa0f3e3e4c", @@ -781,7 +781,7 @@ "hancore.shibumi.battery": "59f67a3358c5e419bb98e474a867b53630cf1ee0bcd61c44d59c5775d8c6933f", "hancore.shibumi.brightness": "80ba42a406f9a24b675ed2daf83555e7f1da6e0442246ae093bb7800be1a8b91", "hancore.shibumi.power-profile": "6d71528dc88132dfc2c33b22437427c9210df74cdc123dfcdd574b4a3a07113e", - "hancore.shibumi.bluetooth": "4d77a458e857a53d68f079abab395f3807b614096b8a90741603fb9c091c6b9d", + "hancore.shibumi.bluetooth": "f61a18cd1a47be8c820b731ddb9156c6311c02dcafe46533e798f5adba147fbb", "hancore.shibumi.temperature": "72ac530bd97cf092349351a6c63e2ef78a9446053e7add71cfe72282704a76b4", "hancore.shibumi.gpu": "a460b94a8f0142ce6da9318493a6343f7bdefcbd1999db3fe73c46d5ff59fa9e", "hancore.shibumi.storage": "eb97c939b77fc88a17066bfa72ea4a1f9a0c7279d164afbc15b176f767837299" diff --git a/tests/test_package_release.py b/tests/test_package_release.py index 8d1cabf..2ba4da6 100644 --- a/tests/test_package_release.py +++ b/tests/test_package_release.py @@ -225,7 +225,7 @@ def test_lifecycle_contract_pins_exact_release_identities(self) -> None: "suiteVersion": "0.1.1-beta.16.1", "sourceRevisions": ["package:0.1.1-beta.16.1"], "settingsStorageVersion": 1, - "payloadDigest": "836ff9b08fa2b8845aace116191f42b9d728e1a830471f305c39f4cd74d15679", + "payloadDigest": "76cd94d0b1991f1628c2f7ffdc9ebf64198a888f3677dd5bb7815b85875ade30", }, } self.assertEqual(set(states), set(expected)) From 27896a579da3755bf288fd3a9ea9f8a90797f0ea Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sun, 4 Oct 2026 00:02:20 +0200 Subject: [PATCH 25/31] fix: give the status spacing savings back to the group width --- hancore.shibumi.bar/core/GroupSlot.qml | 12 +++++++ .../styles/shibumi/BarSurface.qml | 32 +++++++++++++++++-- .../styles/shibumi/GroupSection.qml | 13 ++++++++ hancore.shibumi.status/BarWidget.qml | 28 ++++++++++++---- 4 files changed, 75 insertions(+), 10 deletions(-) diff --git a/hancore.shibumi.bar/core/GroupSlot.qml b/hancore.shibumi.bar/core/GroupSlot.qml index 019211a..c901133 100644 --- a/hancore.shibumi.bar/core/GroupSlot.qml +++ b/hancore.shibumi.bar/core/GroupSlot.qml @@ -108,6 +108,8 @@ Item { // that same selection and can oscillate for width-reactive providers. readonly property bool hasLoadedWidgets: contentItem ? contentItem.hasLoadedWidgets === true : false + readonly property real spacingRecovery: contentItem && "spacingRecovery" in contentItem + ? contentItem.spacingRecovery : 0 readonly property bool hasContent: implicitWidth > 0.5 && implicitHeight > 0.5 readonly property real minimumResponsiveWidth: contentItem && "minimumResponsiveWidth" in contentItem @@ -226,6 +228,16 @@ Item { readonly property bool hasLoadedWidgets: root ? root.anyLoadedWidget(moduleRepeater) : false + readonly property real spacingRecovery: { + void(moduleRow.implicitWidth) + let total = 0 + for (let i = 0; i < moduleRepeater.count; i++) { + const slot = moduleRepeater.itemAt(i) + const item = slot && slot.activeItemVisible ? slot.activeItem : null + if (item && "spacingSavings" in item) total += item.spacingSavings + } + return total + } readonly property real minimumResponsiveWidth: { void(moduleRow.implicitWidth) var total = 0 diff --git a/hancore.shibumi.bar/styles/shibumi/BarSurface.qml b/hancore.shibumi.bar/styles/shibumi/BarSurface.qml index 19bd4ef..7cbe411 100644 --- a/hancore.shibumi.bar/styles/shibumi/BarSurface.qml +++ b/hancore.shibumi.bar/styles/shibumi/BarSurface.qml @@ -1,6 +1,7 @@ pragma ComponentBehavior: Bound import QtQuick +import QtQuick.Window import qs.Commons as Commons import "../../core" as Core import "../../core/RunGeometry.js" as RunGeometry @@ -104,8 +105,19 @@ Item { // Stage against the output capacity; shellWidth remains presentation. readonly property real responsiveCapacity: compactShell ? Math.max(0, width - 2 * frameInset) : shellWidth - readonly property real shellX: shibumiShell ? frameInset - : Math.round((width - shellWidth) / 2) + readonly property real spacingRecovery: leftGroups.spacingRecovery + + centerGroups.spacingRecovery + rightGroups.spacingRecovery + readonly property real pixelRatio: root.Window.window + ? root.Window.window.devicePixelRatio : 1 + readonly property real expandedShellWidth: compactShell + ? Math.min(width - 2 * frameInset, shellWidth + spacingRecovery) : shellWidth + readonly property real expandedShellX: shibumiShell ? frameInset + : Math.round((width - expandedShellWidth) / 2) + // Preserve the old raster phase; recover real width, not outer padding. + readonly property real shellX: compactShell && spacingRecovery > 0 + ? expandedShellX + Math.round((expandedShellWidth - shellWidth) + * pixelRatio / 2) / pixelRatio + : shibumiShell ? frameInset : Math.round((width - shellWidth) / 2) readonly property real shellContentInset: contentInset + (shellStyle === "notch" ? root.bar.visualTokens.shellWingWidth : 0) @@ -144,13 +156,27 @@ Item { readonly property real idealCenterX: Math.round((width - centerRegion.width) / 2) readonly property real minCenterX: Math.round(leftRegion.x + leftRegion.width + centerGap) readonly property real maxCenterX: Math.round(rightRegion.x - centerGap - centerRegion.width) - readonly property real centerTargetX: maxCenterX < minCenterX + readonly property real logicalCenterTargetX: maxCenterX < minCenterX // At an exact fit, pixel rounding can make the two legal limits cross // by one pixel. Falling back to the screen center then overlaps the // asymmetric right run (notably G8 with G9/MPRIS). Split the tiny // deficit between both sides instead and preserve the visible gaps. ? Math.round((minCenterX + maxCenterX) / 2) : Math.max(minCenterX, Math.min(idealCenterX, maxCenterX)) + readonly property real expandedCenterTargetX: { + const centerWidth = centerRegion.width + centerGroups.spacingRecovery + const ideal = Math.round((width - centerWidth) / 2) + const minimum = Math.round(expandedShellX + shellContentInset + + leftRegion.width + leftGroups.spacingRecovery + centerGap) + const maximum = Math.round(width - expandedShellX - shellContentInset + - rightRegion.width - rightGroups.spacingRecovery - centerGap - centerWidth) + return maximum < minimum ? Math.round((minimum + maximum) / 2) + : Math.max(minimum, Math.min(ideal, maximum)) + } + readonly property real centerTargetX: compactShell && spacingRecovery > 0 + ? expandedCenterTargetX + Math.round((logicalCenterTargetX + - expandedCenterTargetX) * pixelRatio) / pixelRatio + : logicalCenterTargetX readonly property var runs: { void(leftGroups.groupGeometry) void(centerGroups.groupGeometry) diff --git a/hancore.shibumi.bar/styles/shibumi/GroupSection.qml b/hancore.shibumi.bar/styles/shibumi/GroupSection.qml index ba3e7d3..bd77f63 100644 --- a/hancore.shibumi.bar/styles/shibumi/GroupSection.qml +++ b/hancore.shibumi.bar/styles/shibumi/GroupSection.qml @@ -62,6 +62,8 @@ Item { readonly property var stateConfig: stateService && stateService.config ? stateService.config : ({}) readonly property var contentItem: content.item + readonly property real spacingRecovery: contentItem && "spacingRecovery" in contentItem + ? contentItem.spacingRecovery : 0 readonly property var groupGeometry: contentItem && contentItem.groupGeometry ? contentItem.groupGeometry : [] readonly property var separatorGeometry: contentItem @@ -393,6 +395,16 @@ Item { return Math.max(1, root.availableWidth - siblings) } + readonly property real spacingRecovery: { + if (!root) return 0 + void(root.groups) + let total = 0 + for (let i = 0; i < horizontalRepeater.count; i++) { + const cell = horizontalRepeater.itemAt(i) + if (cell && cell.contentShown) total += cell.spacingRecovery + } + return total + } readonly property var groupGeometry: { if (!root) return [] void(root.groups) @@ -534,6 +546,7 @@ Item { readonly property real minimumGroupWidth: placeholderSlot ? emptySlotTarget.width : groupHasContent ? groupSlot.minimumResponsiveWidth : measuredMinimumGroupWidth + readonly property real spacingRecovery: groupSlot.spacingRecovery readonly property real contentLeft: targetVisual.x readonly property real contentRight: targetVisual.x + targetVisual.width readonly property real visualRightEdge: groupSlot.x + groupSlot.width diff --git a/hancore.shibumi.status/BarWidget.qml b/hancore.shibumi.status/BarWidget.qml index 34a4cb1..88ad46e 100644 --- a/hancore.shibumi.status/BarWidget.qml +++ b/hancore.shibumi.status/BarWidget.qml @@ -90,13 +90,13 @@ Item { || textMode && notificationService !== null readonly property real childGap: Commons.Style.space(4) Presentation.BarInk { id: statusPlacement; target: root } - // Quick Access: 22px slots + 4px spacing - 12px glyphs = 14px ink gap. Keep - // the outer reservation and translate whole slots by physical pixels only. + // Quick Access: 22px slots + 4px spacing - 12px glyphs = 14px ink gap. + // Return the interior savings to the owner rather than to its outer gaps. readonly property real iconGapPixels: Math.round(Commons.Style.space(14) * statusPlacement.dpr) readonly property rect updateInk: updateWidget && updateWidget.iconInk !== undefined ? updateWidget.mapToItem(updateSlot, updateWidget.iconInk) : Qt.rect(0, 0, 0, 0) function inkEdge(slot, ink, end) { - const edge = (statusPlacement.origin.x + statusRow.x + slot.x + const edge = (statusPlacement.origin.x + horizontalInset + slot.x + ink.x + (end ? ink.width : 0)) * statusPlacement.dpr return end ? Math.ceil(edge - 1e-7) : Math.floor(edge + 1e-7) } @@ -118,6 +118,17 @@ Item { - inkEdge(trayView, trayView.drawerInk, true) - iconGapPixels)) : Math.round(Commons.Style.space(3) * statusPlacement.dpr) : Math.floor(directContraction / 2)) / statusPlacement.dpr + property real spacingSavings: 0 + property bool spacingActive: false + // Settle after layout: binding width directly to snapped ink feeds the + // parent's new position back into its own reservation. + function syncSpacingSavings() { + if (!root || !spacingActive) return + const saved = Math.max(0, updateShift - bellShift) + if (Math.abs(spacingSavings - saved) > 1e-7) spacingSavings = saved + } + onUpdateShiftChanged: Qt.callLater(syncSpacingSavings) + onBellShiftChanged: Qt.callLater(syncSpacingSavings) readonly property int presentedCount: fullMode ? (updatePresented ? 1 : 0) + (trayPresented ? 1 : 0) + (notificationPresented ? 1 : 0) @@ -125,7 +136,7 @@ Item { readonly property real contentWidth: fullMode ? updateSlotWidth + traySlotWidth + notificationSlotWidth - + Math.max(0, presentedCount - 1) * childGap + + Math.max(0, presentedCount - 1) * childGap - spacingSavings : textMode ? textStatus.implicitWidth : notificationView.implicitWidth readonly property real updateSlotWidth: updatePresented ? updateSlot.implicitWidth : 0 @@ -485,10 +496,13 @@ Item { onBadgeContrastColorChanged: syncUpdateInk() Component.onCompleted: { + spacingActive = true + Qt.callLater(syncSpacingSavings) lifecycleBar = bar scheduleChildSync() } Component.onDestruction: { + spacingActive = false close() const dyingBar = bar || lifecycleBar if (dyingBar && "tearingDown" in dyingBar @@ -589,8 +603,6 @@ Item { settings: root.settings v1AppearanceEnabled: true anchors.fill: parent - anchors.leftMargin: root.updateShift - anchors.rightMargin: -root.bellShift anchors.topMargin: root.tokens ? Math.round((parent.height - root.tokens.pillHeight) / 2) : 0 anchors.bottomMargin: root.tokens @@ -600,7 +612,9 @@ Item { Row { id: statusRow - anchors.centerIn: parent + anchors.verticalCenter: parent.verticalCenter + x: root.horizontalInset + transform: Translate { x: -root.updateShift } spacing: root.childGap z: 2 From 4625bfc21ddf67892a50ea386557d90b90b5d6b0 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sun, 4 Oct 2026 00:02:41 +0200 Subject: [PATCH 26/31] release: repin the beta.16.1 candidate payload --- contracts/lifecycle-predecessors-v1.json | 6 +++--- tests/test_package_release.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/lifecycle-predecessors-v1.json b/contracts/lifecycle-predecessors-v1.json index bb7130d..55677eb 100644 --- a/contracts/lifecycle-predecessors-v1.json +++ b/contracts/lifecycle-predecessors-v1.json @@ -759,9 +759,9 @@ }, { "id": "public-beta.16.1", - "payloadDigest": "76cd94d0b1991f1628c2f7ffdc9ebf64198a888f3677dd5bb7815b85875ade30", + "payloadDigest": "148dcbb1e36ac21df24f05089abdd45fe0c5eb140d057b1e1de60250da6c8962", "pluginDigests": { - "hancore.shibumi.bar": "f1eda2d05892d3756319e3cb4474565505f9e6ca2bbb30c4a8983d7103525b9a", + "hancore.shibumi.bar": "8a436d4878c2ee80f49ce52fb541a1d455ca3f745ef0a62429bac184c31754d1", "hancore.shibumi.state": "3aed3c7a3cb92afb66d5f12d7d5c773f1988d5f11c933da187f8b31c68179da8", "hancore.shibumi.control-center": "730ab1517cf0fe52ec5409203bdeb03661f8440c50a6b8ba8baf6563a4f23ec8", "hancore.shibumi.reactor": "347d5997e664581da56104a636af44d4675f37d311bb058b9624d8c9f6121322", @@ -769,7 +769,7 @@ "hancore.shibumi.power-state": "f2f664b00436695dbd47edf9b8d7da46d0f4f7fbe740045023479ed707872a50", "hancore.shibumi.workspaces": "de2a198c2a1fcbada535f046b91f37e5f5ca517ef4a0e3c6f570baf7930699c5", "hancore.shibumi.update-center": "4f028d0c82cbe0d85c74799a77c12e7e26acc9bd4dcda6f7c14fc40a5f991a86", - "hancore.shibumi.status": "270037acf2fc5d0edad827c5300c308b9adc2abb80509e499dd7f6702871ef63", + "hancore.shibumi.status": "1f16174c157c70e6b05a7ff7c00339090a1d4c2d051a4bd389cde1de6e296fe0", "hancore.shibumi.memory": "f6fbd0838180fac0740fd27d22f9fe1812528f45210e51fa9984f479f42da8f9", "hancore.shibumi.cpu": "bb0d1df3404525a45c55fffaa2091a8340ae3d9536f7edab6e6bd56759f7999e", "hancore.shibumi.audio": "20a3f204e0c55b6c9aff18d12e9627b91f3710596e3d1c2e00b08aaa0f3e3e4c", diff --git a/tests/test_package_release.py b/tests/test_package_release.py index 2ba4da6..7ddf45f 100644 --- a/tests/test_package_release.py +++ b/tests/test_package_release.py @@ -225,7 +225,7 @@ def test_lifecycle_contract_pins_exact_release_identities(self) -> None: "suiteVersion": "0.1.1-beta.16.1", "sourceRevisions": ["package:0.1.1-beta.16.1"], "settingsStorageVersion": 1, - "payloadDigest": "76cd94d0b1991f1628c2f7ffdc9ebf64198a888f3677dd5bb7815b85875ade30", + "payloadDigest": "148dcbb1e36ac21df24f05089abdd45fe0c5eb140d057b1e1de60250da6c8962", }, } self.assertEqual(set(states), set(expected)) From c7b9f077a897b466734d9f70233f0cfecd1355c6 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sun, 4 Oct 2026 01:00:23 +0200 Subject: [PATCH 27/31] fix: keep the bar raster phase for recovered V1 center placement --- hancore.shibumi.bar/styles/shibumi/BarSurface.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hancore.shibumi.bar/styles/shibumi/BarSurface.qml b/hancore.shibumi.bar/styles/shibumi/BarSurface.qml index 7cbe411..3c3c5fd 100644 --- a/hancore.shibumi.bar/styles/shibumi/BarSurface.qml +++ b/hancore.shibumi.bar/styles/shibumi/BarSurface.qml @@ -173,7 +173,7 @@ Item { return maximum < minimum ? Math.round((minimum + maximum) / 2) : Math.max(minimum, Math.min(ideal, maximum)) } - readonly property real centerTargetX: compactShell && spacingRecovery > 0 + readonly property real centerTargetX: (shibumiShell || compactShell) && spacingRecovery > 0 ? expandedCenterTargetX + Math.round((logicalCenterTargetX - expandedCenterTargetX) * pixelRatio) / pixelRatio : logicalCenterTargetX From 9f1fc90c4f9414286969cb039445bb91301701b6 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sun, 4 Oct 2026 01:00:45 +0200 Subject: [PATCH 28/31] release: repin the beta.16.1 candidate payload --- contracts/lifecycle-predecessors-v1.json | 4 ++-- tests/test_package_release.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/lifecycle-predecessors-v1.json b/contracts/lifecycle-predecessors-v1.json index 55677eb..d5942ff 100644 --- a/contracts/lifecycle-predecessors-v1.json +++ b/contracts/lifecycle-predecessors-v1.json @@ -759,9 +759,9 @@ }, { "id": "public-beta.16.1", - "payloadDigest": "148dcbb1e36ac21df24f05089abdd45fe0c5eb140d057b1e1de60250da6c8962", + "payloadDigest": "46f72fd02b00dbe34326dbbdf6e95556e7e35641a4d597c5281bc2beed94a974", "pluginDigests": { - "hancore.shibumi.bar": "8a436d4878c2ee80f49ce52fb541a1d455ca3f745ef0a62429bac184c31754d1", + "hancore.shibumi.bar": "8bd1ac4ce7ac2eea83f83c1e2a1e87257d1db41e06ce93f17c88849e04939cb4", "hancore.shibumi.state": "3aed3c7a3cb92afb66d5f12d7d5c773f1988d5f11c933da187f8b31c68179da8", "hancore.shibumi.control-center": "730ab1517cf0fe52ec5409203bdeb03661f8440c50a6b8ba8baf6563a4f23ec8", "hancore.shibumi.reactor": "347d5997e664581da56104a636af44d4675f37d311bb058b9624d8c9f6121322", diff --git a/tests/test_package_release.py b/tests/test_package_release.py index 7ddf45f..bf1b445 100644 --- a/tests/test_package_release.py +++ b/tests/test_package_release.py @@ -225,7 +225,7 @@ def test_lifecycle_contract_pins_exact_release_identities(self) -> None: "suiteVersion": "0.1.1-beta.16.1", "sourceRevisions": ["package:0.1.1-beta.16.1"], "settingsStorageVersion": 1, - "payloadDigest": "148dcbb1e36ac21df24f05089abdd45fe0c5eb140d057b1e1de60250da6c8962", + "payloadDigest": "46f72fd02b00dbe34326dbbdf6e95556e7e35641a4d597c5281bc2beed94a974", }, } self.assertEqual(set(states), set(expected)) From 981f5e31026a5027168375ca7bc02edc1b09610c Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sun, 4 Oct 2026 01:15:42 +0200 Subject: [PATCH 29/31] docs: bind the beta.16.1 readiness record to the candidate --- docs/release-readiness.md | 60 +++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/docs/release-readiness.md b/docs/release-readiness.md index 554799e..c8ece07 100644 --- a/docs/release-readiness.md +++ b/docs/release-readiness.md @@ -6,13 +6,16 @@ ## Candidate and published predecessor -The Beta.16.1 product commit is -`047bcba64f99cfa4962fa4c12d8ddd7791c8f436`, with 24 plugins and suite payload -digest `25fe4252e981e57f1a550862d448e4f9d858e66efb34f915af32743480fa05d7`. -The validation target is this product plus the documentation commit containing -the Beta.16.1 release texts. Documentation outside plugin roots leaves the -suite digest unchanged but changes release-archive bytes. Gates must bind the -accepted combined revision, not a future commit or inherited predecessor pass. +The Beta.16.1 product, expectation, and payload-pin revision is +`9f1fc90c4f9414286969cb039445bb91301701b6` (tree +`0660d7e2cb97c2f8286423d356550c880ef7c6f9`), with 24 plugins and suite payload +digest `46f72fd02b00dbe34326dbbdf6e95556e7e35641a4d597c5281bc2beed94a974`. +The complete source contract and isolated Quattro gate below bind exactly that +revision. This is a pre-checksum readiness snapshot, not final release evidence. +Subsequent readiness, changelog-date, and AUR checksum commits do not change the +plugin-only suite payload, but shipped documentation changes the release archive. +Source review, the complete 14-gate collector, and a byte-identical clean-commit +rebuild must bind the final combined release revision before publication. Beta.16 was published on 2026-10-02 as a GitHub prerelease from `4840482ec0e06a2ebd478120833d4fae1f30889e`. It is the frozen rolling @@ -29,22 +32,23 @@ recovery or replacement. AUR publication remains deferred. | Gate | Evidence and boundary | | --- | --- | -| Complete source contract | Failed on `047bcba`, exit 1 after 151.43 seconds: `test_release_workflow_uses_curated_notes` required the missing Beta.16.1 notes. A full rerun including the documentation commit is pending. | -| Isolated Quattro lifecycle | Pending on the combined revision; not started after the contract failure. No Beta.16.1 32/32 result is recorded. | -| Retained runtime paths | Required: historical Beta.13 → Beta.14.1 package arm (5), fresh checkout (6), Beta.15 (7), Beta.15.2 (7), and rolling Beta.16 → current checkout (7): exactly 32 shell generations. | -| Bluetooth preparation | Native-QML softblock-mock red/green regression and scoped Bluetooth, IPC, hotplug, and audio checks passed during fix preparation; these are not final-HEAD full gates or real rfkill acceptance. | -| Scoped visual previews | Private V1/V2 fit comparisons at DPR 1/1.6 cover the update count, badge-free tray, custom tone and count transitions; these revision-bound previews are not physical acceptance. | -| Live installation and Bluetooth | Pending: reviewer installation and real softblock → on through Bar, panel, and IPC; rapid repeat clicks; on → off. No hardware or persistence result is recorded. | -| Release/package verification | Release date, exact-commit archive/checksum, updated PKGBUILD/`.SRCINFO`, source/package rehearsal, 14-gate collector, and publication verification remain pending. | - -The failed contract run passed the baseline and documentation checks and -26 of 27 PackageReleaseTests; the missing release notes were the sole package -test failure. No test was relaxed and no placeholder notes were added to bypass -it. Focused documentation checks do not replace the full contract rerun. -The historical package arm is not a Beta.16.1 package-upgrade proof. Private -Wayland/software-rendered previews are not live GPU, layer-shell, hotplug, or -physical multi-output acceptance. Earlier release passes do not transfer to -this candidate. +| Complete source contract | Passed on `9f1fc90`, exit 0 in 637.634 seconds, complete marker, no retry or timeout. Fresh exact-HEAD source; private staged validation passed separately. | +| Isolated Quattro lifecycle | Passed on the same exact HEAD, exit 0, 32/32 generations in 108.747 seconds; no retry or timeout. | +| Retained runtime paths | Historical Beta.13 → Beta.14.1 package arm (5), fresh checkout (6), Beta.15 (7), Beta.15.2 (7), and rolling frozen Beta.16 → candidate (7). Payload, layout, keep-settings, reinstall, and delayed readbacks passed; owned fixtures were cleaned. | +| Status spacing | Private same-render V1/V2 fit × DPR 1/1.6 × update 13/0 × drawer absent/present: all 16 outer-gap cases match `69ea4da`; inner gaps and count spacing retain `deeca9b`. Neighbors move by whole physical pixels. Bell glyph and point RGBA are exactly translated in all 42 main and supplementary comparisons, including G3 in the V1 center at DPR 1.6. | +| Bluetooth and Update input | `deeca9b`'s any-controller power/display/completion fix and whole-widget Update button are byte-identical. Their controlled QML checks are not physical multi-controller, rfkill, or desktop input acceptance. | +| Diagnostics | Retained fixture diagnostics match the accepted reference, including the known VisualTokens color-assignment warning and six PillSurface teardown TypeErrors; not warning-free. No new diagnostic class or native type/reference/binding error was accepted. | +| Live installation and hardware | Separate reviewer live status-spacing measurement remains outside these private fixtures. Multi-controller/rfkill, persistence, real focus/menu/input, physical multi-output and 1366px acceptance are not supplied here. | +| Release/package verification | At this pre-checksum snapshot, dated changelog, two reproducible archive builds, AUR metadata/checksum commit, clean-HEAD source review and rehearsal, final 14-gate collector, matching rebuild, and publication verification remain pending. Final external evidence must identify their exact combined commit. | + +The historical package arm is not a Beta.16.1 installed-package upgrade proof. +Private Wayland/Mesa captures are not live GPU, layer-shell, hotplug, or physical +multi-output acceptance. The private V2/DPR1 separator reference is 24/19 free +columns, not the reviewer's 24/20 live reference; equality is claimed only within +the same controlled render, including the notification point and halo in the +last painted pixel. V1 island backgrounds change as their outer margins +are restored: exact bell paint does not mean exact complete slot backgrounds or +whole-bar RGBA. Earlier release passes do not transfer to this candidate. ## Pinned host contracts @@ -110,10 +114,12 @@ was performed. Each operation needs its own maintainer Go. process or prevent later effects. Real rfkill and persistence acceptance is separate from controlled native-QML feedback. - The horizontal update count shares the bar-value baseline and CPU ink spacing. - Its leading reservation grows on an output-scale grid so the unchanged bell - retains its raster phase, including centered Fit. The private captures still - contain isolated one-level RGB differences in other widgets after translation; - exact whole-bar pixel identity and physical acceptance are not claimed. + Its leading reservation grows on an output-scale grid. Status inner-spacing + savings are returned to the group width; centered Fit preserves whole-physical- + pixel movements relative to the previous raster phase. Complete other-widget + rectangles are not all RGBA-identical after translation, and the restored V1 + island edges change slot backgrounds. Exact whole-bar pixel identity and + physical acceptance are not claimed. - **Downgrade:** Beta.15.4 and older cannot read V1 `order.parked`; they reset V1 order, roles, and splits while retaining other settings and V2. `--keep-settings` does not prevent this. The [release notes](../.github/release-notes/v0.1.1-beta.16.1.md) From 84c50f44963ded281e4869afbee7485e0141c2c8 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sun, 4 Oct 2026 01:15:43 +0200 Subject: [PATCH 30/31] docs: date the beta.16.1 changelog entry --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5f2e90..5aca984 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [0.1.1-beta.16.1] - Unreleased +## [0.1.1-beta.16.1] - 2026-10-04 ### Fixed From 3b35049af69aba57784376e916f50146d61eb411 Mon Sep 17 00:00:00 2001 From: HANCORE-linux <230438592+HANCORE-linux@users.noreply.github.com> Date: Sun, 4 Oct 2026 01:16:29 +0200 Subject: [PATCH 31/31] build: update beta.16.1 release archive checksum --- packaging/aur/.SRCINFO | 6 +++--- packaging/aur/PKGBUILD | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packaging/aur/.SRCINFO b/packaging/aur/.SRCINFO index de877d4..5c97fc3 100644 --- a/packaging/aur/.SRCINFO +++ b/packaging/aur/.SRCINFO @@ -1,6 +1,6 @@ pkgbase = shibumi-shell pkgdesc = Transactional Shibumi desktop shell plugins for Omarchy Quattro - pkgver = 0.1.1beta.16 + pkgver = 0.1.1beta.16.1 pkgrel = 1 url = https://github.com/HANCORE-linux/Shibumi-Shell arch = any @@ -30,7 +30,7 @@ pkgbase = shibumi-shell optdepends = btop: battery panel system monitor action optdepends = nvidia-utils: NVIDIA GPU telemetry optdepends = git: source-checkout diagnostics and migration - source = shibumi-shell-0.1.1-beta.16.tar.gz::https://github.com/HANCORE-linux/Shibumi-Shell/releases/download/v0.1.1-beta.16/shibumi-shell-0.1.1-beta.16.tar.gz - sha256sums = 3e1a2de055a070916e16cb7de51fa3922db8ecf8363bc6976e1b297f1dffc367 + source = shibumi-shell-0.1.1-beta.16.1.tar.gz::https://github.com/HANCORE-linux/Shibumi-Shell/releases/download/v0.1.1-beta.16.1/shibumi-shell-0.1.1-beta.16.1.tar.gz + sha256sums = 8209b53464b5deeb4025c9ab45038946d2e5a794ae7f368da8bee679fed2f30d pkgname = shibumi-shell diff --git a/packaging/aur/PKGBUILD b/packaging/aur/PKGBUILD index d8d498d..e5640b7 100644 --- a/packaging/aur/PKGBUILD +++ b/packaging/aur/PKGBUILD @@ -1,7 +1,7 @@ # Maintainer: HANCORE Linux pkgname=shibumi-shell -_upstream_version=0.1.1-beta.16 -_source_sha256=3e1a2de055a070916e16cb7de51fa3922db8ecf8363bc6976e1b297f1dffc367 +_upstream_version=0.1.1-beta.16.1 +_source_sha256=8209b53464b5deeb4025c9ab45038946d2e5a794ae7f368da8bee679fed2f30d pkgver=${_upstream_version//-/} pkgrel=1 pkgdesc="Transactional Shibumi desktop shell plugins for Omarchy Quattro"