Der Schluss im letzten Commit war falsch. Aus „der Dienst liegt in der
Benutzer-Domäne" hatte ich geschlossen, dass `launchctl bootout` ihn dort
aushängt. Nachgemessen, diesmal ausführend:
Boot-out failed: 150: Operation not permitted while
System Integrity Protection is engaged
SIP schützt den Dienst, nicht nur den Dateipfad; die Domäne spielt keine Rolle.
Ein rein lesender Spike konnte das nicht zeigen — nur der Versuch. `SystemOSD`
fliegt deshalb wieder raus: Code, der behauptet zu wirken und es nicht tut, ist
schlimmer als keiner.
Stattdessen ein `CGEventTap` auf die Lautstärketasten. Onyx regelt selbst und
verbraucht das Ereignis — was das System nie erreicht, blendet es auch nicht
ein. Preis ist die Berechtigung „Bedienungshilfen"; ohne sie bleibt alles wie
vorher, und der Dialog wird angefragt statt stumm zu scheitern.
Vorteil gegenüber dem Aushängen: es verschwindet nur die Einblendung für die
Tasten, die Onyx auch bedient. Die Feststelltaste behält ihre — beim Aushängen
wäre sie mit verschwunden, und dafür hat Onyx keinen Ersatz.
Der Rückruf steht als eigene Funktion und nicht als Verschluss in `start()`: als
Verschluss brachte er Swift 6.3.3 im Durchgang `SendNonSendable` zum Absturz.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2.3 KiB
Spike J — Apples eigene Einblendung unterdrücken
Im Plan heißt dieser Spike „G". Die Buchstaben in
docs/spikes/sind fortlaufend vergeben; hier läuft die vorhandene Reihe weiter.
Frage. Lässt sich com.apple.OSDUIHelper zuverlässig aushängen? Kommt er von
selbst zurück? Was passiert beim Ab- und Anmelden? Steht SIP im Weg?
Gemessen am 05.09.2026, rein lesend.
Ergebnis
| Prüfung | Befund |
|---|---|
| Prozess läuft dauerhaft? | nein — bedarfsgesteuert, state = not running |
| LaunchAgent | /System/Library/LaunchAgents/com.apple.OSDUIHelper.plist |
| Domäne | gui/<uid> — die des angemeldeten Benutzers, nicht system |
| SIP | aktiviert, OSDUIHelper.app/Contents ist restricted |
Der Schluss daraus war falsch
Aus „der Dienst liegt in der Benutzer-Domäne" habe ich geschlossen, dass
launchctl bootout gui/<uid>/… ihn dort aushängt, ohne Root und ohne SIP zu
berühren. Das stimmt nicht. Nachgemessen, diesmal ausführend:
$ launchctl bootout gui/501/com.apple.OSDUIHelper
Boot-out failed: 150: Operation not permitted while System Integrity Protection is engaged
SIP schützt den Dienst, nicht nur den Dateipfad. Die Domäne spielt keine Rolle. Ein rein lesender Spike konnte das nicht zeigen — nur der Versuch.
Die Lehre: Ein Spike, der die entscheidende Handlung nicht ausführt, hat die Frage nicht beantwortet. Er hat nur die Umstände beschrieben, unter denen sie gestellt wird. Wo die Handlung sich zurücknehmen lässt, gehört sie in den Spike — sonst steht am Ende eine Vermutung im Dokument, die wie ein Befund aussieht.
Was stattdessen geht
Nicht die Einblendung abschalten, sondern ihr zuvorkommen: die
Lautstärketasten mit einem CGEventTap abfangen, die Lautstärke selbst setzen
und das Ereignis verbrauchen. Was das System nie erreicht, blendet es auch nicht
ein.
Preis: das braucht die Berechtigung „Bedienungshilfen". Ohne sie tut der Tap nichts — dann erscheint Apples Einblendung wie gehabt, und das muss die Oberfläche sagen, statt es stumm hinzunehmen.
Der Vorteil des Abfangens
Es verschwindet nur die Einblendung für die Tasten, die Onyx selbst bedient. Feststelltaste und alles andere behalten ihre — beim Aushängen des Dienstes wären sie mit verschwunden, und für die Feststelltaste hat Onyx keinen Ersatz.