← Alle Beiträge

Der Mac App Store lässt Fenstermanager nicht zu. Ich habe trotzdem einen veröffentlicht.

Ein Ingenieur des Apple Developer Technical Support sagte mir, meine App sei unmöglich: „Es ist nicht möglich, die Accessibility-APIs aus einer sandboxed App heraus zu verwenden … Ihr einziger Weg nach vorn ist, Ihre App direkt zu vertreiben.“1 Die App war ein Fenster-Tiler, die Accessibility-API ist genau das Fundament, auf dem jeder Fenstermanager steht, und jede App im Mac App Store läuft in der Sandbox, die sie verbietet. Vergangene Woche ging 941 Tiles trotzdem im Mac App Store an den Start: ein Klick in der Menüleiste, und sämtliche verstreuten Fenster einer App rasten in ein gleichmäßiges Raster ein. Die Sandbox-Regel wurde kein einziges Mal gebogen. Der Kniff bestand darin zu bemerken, dass macOS bereits einen privilegierten Fensterbeweger mit Apples vollem Segen enthält — und dass dieser JSON entgegennimmt.

TL;DR

  • App Sandbox blockiert app-übergreifende Accessibility-Aufrufe grundsätzlich, kein Entitlement schaltet sie frei, und jede App im Mac App Store muss sandboxed sein. Die Kategorie der Fenstermanager ist seit Juni 2012 für Neuzugänge faktisch geschlossen; die Tiler, die noch im Store stehen, sind älter als diese Pflicht und laufen für immer ohne Sandbox.134
  • Die genehmigte Tür: Eine sandboxed App darf Apples Shortcuts-Engine über Apple events ansteuern, und Shortcuts liefert die Aktionen Find Windows / Move Window / Resize Window mit, die Fenster fremder Apps mit Apples eigenen Rechten bewegen.25 Meine App berechnet, wohin jedes Fenster gehört; das Bewegen übernimmt ein begleitender Shortcut. Delegation statt Erlaubnis.
  • Die Technik, die daraus Wirklichkeit machte: das begleitende .shortcut programmatisch als Binär-plist von WFWorkflowActions erzeugen, ein JSON-Rahmenprotokoll, dessen Nutzdaten an der Z-Reihenfolge der Fenster hängen, Schutzgeländer gegen Phantomfenster und Indexüberläufe sowie eine Codebasis mit zwei Engines, die in Developer-ID-Builds direkt Accessibility nutzt und in Store-Builds an Shortcuts delegiert.
  • Der erste erfolgreiche Lauf auf genau der Maschine, an der fünf Store-Builds gescheitert waren: vier verstreute Terminalfenster in 0.6 Sekunden auf exakte Quadrantenrahmen.
  • Ehre, wem Ehre gebührt: Der Mechanismus ist in freier Wildbahn durch snApp (Open Source, 2023) und Align (2024) belegt. Erst die Lektüre des Quellcodes von snApp machte aus „unmöglich“ einen Bauplan.2

Die Wand

Die erste Fassung von 941 Tiles war ein klassischer Tiler in der Menüleiste. macOS besitzt ein Accessibility-System, das es einer App mit Zustimmung der Benutzerin erlaubt, die Fenster einer anderen App aufzuzählen und zu bewegen (AXUIElementSetAttributeValue auf den Attributen für Fensterposition und -größe). Darauf aufgebaut lief die App wochenlang in der Entwicklung fehlerfrei. Den kompletten Eintrag in App Store Connect hatte ich vorbereitet: Metadaten in 17 Sprachen, Screenshots, Preis, 21 hochgeladene Builds.

Dann kam ein TestFlight-Build auf einen zweiten Mac. Accessibility-Berechtigung erteilt, die App meldete Zugriff aktiv — und sie konnte null Fenster lesen.

Kein Fehler. Jede App im Mac App Store läuft in Apples App Sandbox, einer Eingrenzungsregel, nach der eine App nur ihre eigenen Dinge anfassen darf, genau damit sie den Rest Ihres Mac weder ausspähen noch stören kann.4 In die Fenster einer fremden App zu greifen, ist exakt das, wozu die Sandbox existiert: um es zu verhindern. Entwicklungs-Builds laufen ohne Sandbox, deshalb funktionierte wochenlang alles; der Store-Build erzwang die Regel, die ich ignoriert hatte. Kein Berechtigungsdialog, kein Entitlement, keine Einstellung schaltet das frei. Als ich Apple direkt fragte, lautete die Antwort des DTS so wie am Anfang dieses Beitrags: außerhalb des Stores vertreiben.1

Eine seit 2012 geschlossene Kategorie

Interessant an dieser Wand ist, wer auf der anderen Seite steht. Magnet, Moom, BetterSnapTool: Fensterwerkzeuge, die Sie heute im Mac App Store kaufen können. Ihre Einträge sind älter als die Sandbox-Pflicht vom Juni 2012, also laufen sie unter einer Bestandsschutzklausel ohne Sandbox, die auf niemanden sonst übergeht. Jeder nach 2012 entstandene Fenstermanager (Rectangle, Swish, Loop, BetterTouchTool, Amethyst) wird außerhalb des Stores vertrieben. Apple hat die Linie auch in die andere Richtung durchgesetzt: PopClip, fast 13 Jahre lang im Store, ging im März 2024 fort, nachdem die Prüfung dem Entwickler mitgeteilt hatte, neue Accessibility-basierte Funktionen könnten in einem sandboxed Update nicht erscheinen.3

Ich will meine Lesart klar benennen: Die Sandbox-Regel ist vernünftig. Eine App, die jedes Fenster auf Ihrem Bildschirm still lesen und bewegen kann, ist eine App, die Sie überwachen kann, und „vertrauen Sie mir“ ist kein Sicherheitsmodell. Das Versprechen des Stores lautet, dass nichts, was Sie dort installieren, so etwas tun kann. Die Ungerechtigkeit ist eng und konkret: Etablierte behalten eine Fähigkeit, die Neuzugänge durch keinerlei Zustimmung der Benutzer erwerben können. Die Kategorie wurde nicht verboten, sie wurde versteinert.

Die Wendung

Das Urteil des DTS hatte einen Makel: Der Store enthielt bereits Gegenbeispiele. Align (2024) und snApp (2023) ordnen beide Fenster an, beide leben im Mac App Store, beide entstanden lange nach 2012. snApp ist Open Source, der Mechanismus ist also kein Geheimnis; er ist ein Repository.2

Die sandboxed App fasst nie die Fenster einer anderen App an. Sie steuert Shortcuts, Apples eigene Automations-App, über zwei deklarierte Entitlements:

<key>com.apple.security.automation.apple-events</key>
<true/>
<key>com.apple.security.temporary-exception.apple-events</key>
<array>
  <string>com.apple.shortcuts.events</string>
</array>

Seit macOS 12 liefert Shortcuts Aktionen namens Find Windows, Move Window und Resize Window mit.5 Shortcuts darf Fenster bewegen, weil es Apple gehört. Also berechnet die App, wohin jedes Fenster gehört, übergibt diesen Plan an einen vom Benutzer installierten begleitenden Shortcut, und Apples eigene Engine erledigt das Bewegen. Die Sandbox wird nie verletzt, denn der sandboxed Prozess führt die privilegierte Handlung nie selbst aus. Delegation statt Erlaubnis.

An dieser Form ist etwas beinahe Architektonisches: Die Sicherheitsgrenze bleibt genau dort, wo Apple sie gezogen hat, und die Fähigkeit überquert sie, indem sie durch den einen Prozess reist, der sie auf dem System legitim besitzt.

Der Ausbau

Den Mechanismus zu kennen und ihn auszuliefern sind verschiedene Wochen. Diese Bausteine machten ihn produktionsreif:

Den Shortcut programmatisch erzeugen. Niemand sollte einen Ablauf aus 12 Aktionen von Hand zusammensetzen müssen. Die begleitende .shortcut-Datei ist ein Binär-plist von WFWorkflowActions, das die App zur Build-Zeit erzeugt und mit shortcuts sign -m anyone signiert, sodass die Installation ein einziger Klick in der Shortcuts-App ist. Der Vertrag zur Laufzeit ist eine JSON-Nutzlast, die über ScriptingBridge per shortcut.run(withInput:) durchgereicht wird:

{"app": "Ghostty", "frames": [{"x": 0, "y": 38, "w": 1280, "h": 771}, ...]}

Fensteridentität ist Z-Reihenfolge. Die Aktion Find Windows des Shortcuts indiziert Fenster von vorn nach hinten, und CGWindowList zählt sie in derselben Reihenfolge auf. Platz i der Nutzlast trägt also schlicht den Rahmen für Fenster i, und weil die Zellen nach Positionsrang vergeben werden, reproduziert das Raster den Grundsatz „Fenster bleiben in der Nähe ihres bisherigen Orts“. Keine Fenster-IDs überqueren die Grenze, weil auf der anderen Seite keine existieren.

Schutzgeländer. Eine durch Count begrenzte Items in Range-Klammer verhindert, dass eine veraltete Nutzlast über die aktuelle Fensterliste hinaus indiziert. Ein Mindestgrößenfilter (120×80) schließt die Phantom-Panels aus, die CGWindowList meldet und die die alte Accessibility-Rollenprüfung verborgen hatte. Und eine Tatsache, die mich überraschte: Das Auflisten von Fenstern erfordert überhaupt keine Berechtigung; CGWindowList ist in der Sandbox erlaubt. Verboten war immer nur das Bewegen.

Eine Codebasis, zwei Engines. Beim Start erkennt die App die Sandbox über die Umgebungsvariable APP_SANDBOX_CONTAINER_ID. Store-Builds ordnen über Shortcuts an; Developer-ID- und Entwicklungs-Builds nehmen den direkten Accessibility-Weg. Gleiche Oberfläche, gleiche Rechnung, anderer Beweger.

Überwachungsmodus ohne Benachrichtigungen. Die optionale automatische Neuanordnung würde normalerweise Accessibility-Fensterbenachrichtigungen abonnieren, die die Sandbox ebenfalls entfernt. Sie überlebt als Polling des Fensterservers: günstige CGWindowList-Vergleiche, Neuanordnung bei Veränderung.

Der Preis, ehrlich benannt

Die Benutzerin zahlt eine einmalige Einrichtungssteuer: den begleitenden Shortcut installieren (ein Klick) und einen Automatisierungsdialog bestätigen (die übliche Meldung „941 Tiles möchte Shortcuts steuern“, über InfoPlist.xcstrings in alle 17 Sprachen lokalisiert). Danach ist die Erfahrung identisch mit der eines Tilers, der die API direkt nutzt: auf das Rastersymbol klicken, auf eine App klicken, die Fenster sitzen. Der Shortcuts-Lauf ist unsichtbar und dauert deutlich weniger als eine Sekunde.

Ich behaupte nicht, diese Steuer sei nichts; es ist ein Bildschirm mehr, als Magnet zeigt. Sie ist zugleich der gesamte Preis dafür, innerhalb der Sandbox zu existieren, statt Benutzer zu bitten, Gatekeeper für einen notarisierten Download zu umgehen, dem sie noch keinen Grund haben zu vertrauen.

Der Lohn

Derselbe Intel-Mac, an dem fünf Store-Builds gescheitert waren: Installation, Shortcut-Einrichtung, Zustimmung — und vier verstreute Ghostty-Fenster rasteten beim ersten Lauf in 0.6 Sekunden auf exakte Quadrantenrahmen ein. Danach folgten die Internationalisierung (String Catalogs, CLDR-Pluralregeln einschließlich aller sechs arabischen Kategorien), der lokalisierte Eintrag und die Einreichung. Nach einer Ablehnung in der Prüfung und einer erneuten Prüfung von rund 30 Minuten ist 941 Tiles live: 4.99 US-Dollar einmalig, macOS 15+, 17 Sprachen, keinerlei Datenerfassung, kein Netzwerkzugriff.

Was sich verallgemeinern lässt

Das Muster reicht weiter als Fensteranordnung. Schließt eine Plattform eine Fähigkeit hinter einer Grenze ein, besteht die Antwort selten darin, die Grenze zu bekämpfen; sie besteht darin zu erfassen, welche Erstanbieter-Prozesse die Fähigkeit bereits besitzen und eine genehmigte Schnittstelle dorthin anbieten. Auf macOS zeigt diese Bestandsaufnahme zunehmend auf eine Stelle: Shortcuts, das still zum privilegierten Automatisierungsvermittler des Systems geworden ist und aus der Sandbox heraus erreichbar sein soll. Mein Shortcuts-Leitfaden behandelt diese Oberfläche ausführlich, und die Fallstudie zu 941 Tiles erzählt dieselbe Geschichte mit den Architekturdiagrammen.

Die Sandbox hat ihre Aufgabe erfüllt. Die App erschien trotzdem. Beide Sätze stimmen, und die Tür dazwischen war Apples eigene.

Häufige Fragen

Darf eine sandboxed Mac-App die Accessibility-APIs nutzen?

Nein. App Sandbox blockiert app-übergreifende Accessibility-Aufrufe grundsätzlich, und weder ein Entitlement noch ein Berechtigungsdialog noch eine Einstellung schaltet sie frei. Apples eigene DTS-Antwort an mich lautete: „Es ist nicht möglich, die Accessibility-APIs aus einer sandboxed App heraus zu verwenden … Ihr einziger Weg nach vorn ist, Ihre App direkt zu vertreiben.“ Entwicklungs-Builds laufen ohne Sandbox, weshalb ein Tiler wochenlang funktionieren und dann in einem Store-Build null Fenster lesen kann.14

Wie kann ein Fenstermanager im Mac App Store erscheinen?

Indem er die privilegierte Handlung delegiert. Eine sandboxed App darf Apples Shortcuts-Engine über Apple events ansteuern, und Shortcuts liefert seit macOS 12 die Aktionen Find Windows, Move Window und Resize Window mit. Meine App berechnet, wohin jedes Fenster gehört, und übergibt diesen Plan an einen vom Benutzer installierten begleitenden Shortcut, der das Bewegen mit Apples eigenen Rechten erledigt. Die Sandbox wird nie verletzt, denn der sandboxed Prozess führt die privilegierte Handlung nie aus.25

Warum sind Magnet und Moom im Store, wenn Fenstermanager es nicht sein können?

Ihre Einträge sind älter als die Sandbox-Pflicht vom Juni 2012, also laufen sie unter einer Bestandsschutzklausel ohne Sandbox, die auf niemanden sonst übergeht. Jeder nach 2012 entstandene Fenstermanager, darunter Rectangle, Swish, Loop, BetterTouchTool und Amethyst, wird außerhalb des Stores vertrieben. PopClip ging im März 2024 fort, nachdem die Prüfung dem Entwickler mitgeteilt hatte, neue Accessibility-Funktionen könnten in einem sandboxed Update nicht erscheinen. Die Kategorie wurde nicht verboten, sie wurde versteinert.34

Was kostet die Shortcuts-Delegation die Benutzer?

Eine einmalige Einrichtungssteuer: den begleitenden Shortcut mit einem Klick installieren, danach einen Automatisierungsdialog bestätigen. Anschließend ist die Erfahrung identisch mit der eines Tilers, der die API direkt nutzt: auf das Rastersymbol klicken, auf eine App klicken, die Fenster sitzen, und der Shortcuts-Lauf bleibt unsichtbar und dauert deutlich weniger als eine Sekunde. Es ist ein Bildschirm mehr, als Magnet zeigt, und es ist der gesamte Preis dafür, innerhalb der Sandbox zu existieren.

Wie trägt eine Codebasis sowohl sandboxed als auch direkte Builds?

Beim Start erkennt die App die Sandbox über die Umgebungsvariable APP_SANDBOX_CONTAINER_ID. Store-Builds ordnen über Shortcuts an; Developer-ID- und Entwicklungs-Builds nehmen den direkten Accessibility-Weg. Gleiche Oberfläche, gleiche Rechnung, anderer Beweger. Auch der Überwachungsmodus passt sich an: Weil die Sandbox Accessibility-Fensterbenachrichtigungen entfernt, überlebt die optionale automatische Neuanordnung als günstiges CGWindowList-Polling, das vergleicht und bei Veränderung neu anordnet.

Quellen


  1. Apple Developer Forums, Thread 805556 (Oktober 2025), Antwort des Apple DTS: „Es ist nicht möglich, die Accessibility-APIs aus einer sandboxed App heraus zu verwenden … Ihr einziger Weg nach vorn ist, Ihre App mit Developer-ID-Signierung direkt zu vertreiben.“ ↩↩↩↩

  2. Om Chachad, snApp auf GitHub (2023), der quelloffene Fenster-Tiler im Mac App Store, dessen Quellcode den Mechanismus der Shortcuts-Delegation dokumentiert: com.apple.security.automation.apple-events-Entitlements für Skriptziele plus ein begleitender Shortcut, gebaut aus Apples Fensteraktionen. ↩↩↩↩

  3. Michael Tsai, „PopClip Leaving the Mac App Store“ (21. März 2024), darüber, dass Apples Prüfung nach fast 13 Jahren im Store die Entfernung neuer Accessibility-basierter Funktionen aus einem sandboxed Update verlangte. ↩↩↩

  4. Apple, Dokumentation zur App Sandbox, das Eingrenzungsmodell, das alle Apps im Mac App Store seit Juni 2012 übernehmen müssen. ↩↩↩↩

  5. Apple, Shortcuts Benutzerhandbuch für Mac, das die seit macOS 12 verfügbaren Aktionen Find Windows, Move Window und Resize Window dokumentiert. ↩↩↩

Verwandte Beiträge

The Shader Gallery That Lied: Debugging 216 WebGL Presets

A user said the shader playground looked broken. Pixel-readback testing found 30 dead presets, 11 that never compiled, a…

13 Min. Lesezeit

MacPaint im Browser nachbauen: Der Quellcode von 1984 ist die Spezifikation

Ich habe MacPaint 1.3 im Browser nachgebaut und jedes Werkzeug gegen Bill Atkinsons Pascal-Quellcode geprüft. Was ein or…

14 Min. Lesezeit

Engineering-Philosophie: Joanna Rutkowska

Joanna Rutkowska baute Qubes OS auf vernünftiger Paranoia: Software wird nie fehlerfrei – also Kompromittierung annehmen…

24 Min. Lesezeit