Sechs neue Widgets (CPU, GPU, Speicher, Akku, Sensoren, Netzwerk) und dieselben sechs als einzeln aktivierbare Menüleisten-Module mit fünf Darstellungsarten. Panel-Widget und Menüleisten-Modul derselben Größe teilen sich die Messschleife über Referenzzählung. Ohne das liefe für jede Anzeige ein eigener Timer mit denselben IOKit- und SMC-Abfragen — bei sechs Modulen und ebenso vielen Widgets ein Vielfaches der nötigen Arbeit. Meldet sich der letzte Konsument ab, hört die Schleife auf; im Ruhezustand misst Onyx nichts. Die Differenzrechnung ist testgetrieben, und die Tests haben zwei echte Fehler gefunden. Erstens: mein Überlaufschutz beim Durchsatz hielt einen zurückgesetzten Zähler (Interface-Wechsel) für einen Überlauf und zeigte 4,3 GB/s. Da if_data64 64-Bit-Zähler liefert, die bei 10 Gbit/s erst nach 470 Jahren umlaufen, ist ein kleinerer Wert immer ein Zurücksetzen — die Unterscheidung produzierte nur den Ausreißer, den sie verhindern sollte. Zweitens: ByteCountFormatter schrieb bei null „Zero KB/s" statt „0 KB/s". Bei den CPU-Zählern bleibt der Überlaufschutz nötig: die sind 32 Bit breit und laufen nach gut 400 Tagen wirklich um, deshalb `&-` statt `-`. Sensoren kommen über den SMC-Leser aus Spike A statt über die private IOHID-Schnittstelle — auf dieser Maschine nachweislich verifiziert, und die dort gefundene Little-Endian-Eigenheit ist berücksichtigt. Nur eine kurze Liste benannter Fühler statt aller 3486 Keys: eine Wand aus Kürzeln ist keine Information. Gegengemessen statt vermutet: 15 Kerne, 39,8 W, GPU 50 %, 16,6/24 GB mit kritischem Druck, Akku 68 Zyklen bei 100 % Gesundheit, fünf Sensoren, zwei Lüfter, en0 mit 661 KB/s. Menüleisten-Module zeichnen in labelColor statt in den Onyx-Farben — nur die Systemfarbe passt sich heller wie dunkler Leiste an. Feste Breite je Darstellungsart, sonst schiebt jeder Messwert die halbe Leiste hin und her. Standardmäßig ist kein Modul aktiv: sechs neue Symbole beim ersten Start wären eine Zumutung. 145 Tests grün.
96 lines
3.7 KiB
YAML
96 lines
3.7 KiB
YAML
name: Onyx
|
|
options:
|
|
bundleIdPrefix: com.scarriffleservices
|
|
deploymentTarget:
|
|
macOS: "26.0"
|
|
createIntermediateGroups: true
|
|
groupSortPosition: top
|
|
|
|
settings:
|
|
base:
|
|
DEVELOPMENT_TEAM: PP34X97WS3
|
|
SWIFT_VERSION: "6.0"
|
|
MARKETING_VERSION: "0.1.0"
|
|
CURRENT_PROJECT_VERSION: "1"
|
|
ENABLE_HARDENED_RUNTIME: YES
|
|
# Der MediaRemote-Adapter bringt ein ad-hoc signiertes Framework mit, das
|
|
# der mit Team-Zertifikat signierte Host sonst nicht laden darf.
|
|
OTHER_CODE_SIGN_FLAGS: "--deep"
|
|
SWIFT_STRICT_CONCURRENCY: complete
|
|
# Xcode lagert im Debug-Build den Programmcode in eine eigene dylib aus
|
|
# (für SwiftUI-Vorschauen). Das Hauptprogramm ist dann nur noch ein Rumpf —
|
|
# und TCC ordnet Berechtigungsanfragen dem Rumpf zu, der weder Info.plist
|
|
# noch Entitlements trägt. Ergebnis: requestFullAccessToEvents() liefert
|
|
# kommentarlos false, ohne dass je ein Dialog erscheint.
|
|
ENABLE_DEBUG_DYLIB: NO
|
|
|
|
packages:
|
|
OnyxKit:
|
|
path: Packages/OnyxKit
|
|
|
|
targets:
|
|
Onyx:
|
|
type: application
|
|
platform: macOS
|
|
sources:
|
|
- path: Onyx
|
|
dependencies:
|
|
- package: OnyxKit
|
|
product: OnyxCore
|
|
- package: OnyxKit
|
|
product: OnyxDesign
|
|
- package: OnyxKit
|
|
product: OnyxNotch
|
|
- package: OnyxKit
|
|
product: OnyxWidgetKit
|
|
- package: OnyxKit
|
|
product: OnyxMenuBar
|
|
- package: OnyxKit
|
|
product: CalendarProvider
|
|
- package: OnyxKit
|
|
product: WeatherProvider
|
|
- package: OnyxKit
|
|
product: MediaProvider
|
|
- package: OnyxKit
|
|
product: MetricsProvider
|
|
- package: OnyxKit
|
|
product: NetworkProvider
|
|
postBuildScripts:
|
|
# Der MediaRemote-Adapter wird aus dem mitgelieferten Quellcode gebaut,
|
|
# nicht als fertige Binary eingecheckt: so ist nachvollziehbar, was da
|
|
# läuft, und die Ad-hoc-Signatur passt zum restlichen Bundle.
|
|
#
|
|
# Er darf NICHT gelinkt werden. Geladen wird er von /usr/bin/perl, einem
|
|
# berechtigten Systemprogramm — im eigenen Prozess greift Apples
|
|
# Entitlement-Prüfung und es käme gar nichts an.
|
|
- name: MediaRemote-Adapter bauen und beilegen
|
|
script: |
|
|
OUT="$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/Vendor" \
|
|
"$SRCROOT/Scripts/build-mediaremote-adapter.sh"
|
|
inputFiles:
|
|
- $(SRCROOT)/Scripts/build-mediaremote-adapter.sh
|
|
outputFiles:
|
|
- $(BUILT_PRODUCTS_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/Vendor/mediaremote-adapter.pl
|
|
# Das Menüleistensymbol soll das Glyph aus dem App-Icon zeigen, nicht die
|
|
# abgerundete Kachel mit Verlauf. actool kompiliert das .icon-Bündel zu
|
|
# .icns und Assets.car und legt nichts Lesbares ins Bundle — und eine
|
|
# einzelne Datei daraus lässt sich nicht als Ressource referenzieren.
|
|
# Deshalb kopieren statt duplizieren: es bleibt bei einer Quelldatei.
|
|
outputFiles:
|
|
- $(BUILT_PRODUCTS_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/quartz.svg
|
|
settings:
|
|
base:
|
|
PRODUCT_BUNDLE_IDENTIFIER: com.scarriffleservices.onyx
|
|
INFOPLIST_FILE: Onyx/Info.plist
|
|
CODE_SIGN_ENTITLEMENTS: Onyx/Onyx.entitlements
|
|
CODE_SIGN_STYLE: Automatic
|
|
# Kein App-Sandbox: der privilegierte Helper, IOKit und der
|
|
# MediaRemote-Adapter sind damit unvereinbar. Der App-Group-Container
|
|
# bleibt trotzdem erreichbar — siehe docs/spikes/D-appgroup.md.
|
|
ENABLE_APP_SANDBOX: NO
|
|
ENABLE_USER_SCRIPT_SANDBOXING: NO
|
|
COMBINE_HIDPI_IMAGES: YES
|
|
# Icon-Composer-Bündel (Onyx/AppIcon.icon). actool übernimmt daraus
|
|
# alle Größen und die Transluzenz-Darstellung von macOS 26.
|
|
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
|