93fe95827fccf5449644777def95bcf5eefa5657
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
93fe95827f |
Panel wächst in die Breite, Menüleiste wird schmaler
Das Raster ist weg. Widgets stehen nebeneinander, alle gleich groß, in der Reihenfolge aus den Einstellungen. Das Panel sitzt am oberen Rand — nach unten zu wachsen bedeckt den Bildschirm, nach rechts und links legt es sich in den ohnehin leeren Streifen neben der Notch. Eine zweite Reihe entsteht erst, wenn der Bildschirm keine weitere Kachel mehr hergibt. Die Größenauswahl fällt damit weg, und das ist kein Verlust: ein 2×1 neben einem 2×2 lässt oben rechts eine Lücke, die niemand füllen kann und die aussieht wie ein Fehler. Genau daher kam auch die Überlappung. Ein Test prüft jetzt für ein bis zwölf Kacheln, dass sich keine zwei schneiden und alle vollständig im Panel liegen — außerhalb heißt oben: hinter der Notch. Kacheln werden zusätzlich beschnitten, damit überquellender Inhalt nicht über den Nachbarn zeichnet. Der Kalender wählt jetzt zwischen Monatsraster und Terminliste. Das war vorher an die Kachelgröße gekoppelt und ist in Wahrheit eine Frage dessen, was man sehen will. In der Menüleiste wird die Breite gemessen statt geschätzt. Vorher stand je Darstellungsart eine feste Zahl im Code, großzügig gewählt — mit dem Ergebnis, dass neben jedem Wert Platz für ein weiteres Symbol blieb, in dem nichts stand. Gemessen wird die breiteste vorkommende Zeichenfolge, nicht die gerade angezeigte, sonst springt die Leiste bei jedem Messwert. Die Balkendarstellung bekommt ihre Breite aus der Kernzahl, die erst nach der ersten Messung feststeht. Popover schließen jetzt beim Klick daneben. `behavior = .transient` genügt nicht: es greift, solange die eigene App aktiv ist, aber Onyx läuft als .accessory und wird durch einen Klick auf ein Statuselement nicht aktiviert. Ein Klick in ein fremdes Fenster erreichte das Popover gar nicht. Ein globaler Beobachter sieht solche Klicks, ein lokaler die in der eigenen App, Escape schließt ebenfalls — und es ist immer nur eines offen. Mixer und Lüfter haben eigene Menüleistenelemente. Beides regelt man mitten in etwas anderem; der Weg über ein Einstellungsfenster war zu weit. Die Lüfter sind damit auch als Panel-Kachel echt statt Platzhalter. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
8308536227 |
Phase 8: Ablage, AirDrop und Calendarr
Calendarr liefert Termine über den Gruppencontainer. Streng lesend: keine eigene Anmeldung, kein Netz, kein Schreiben zurück. Die Abdeckung ist der Kern und kein Detail. Der Schnappschuss reicht 49 Tage nach vorne, und das steht nirgends in der Datei — es ist zugesagtes Verhalten des Schreibers. Außerhalb liegt keine Information vor, nicht keine Termine; das Monatsraster graut solche Tage aus, statt „frei" zu behaupten. Verlockend wäre, die Abdeckung aus dem frühesten Termin abzuleiten. Das ist falsch, und ein Test hält es fest: mehrtägige Termine ragen ins Fenster hinein und werden mitgeschrieben, obwohl ihr Anfang nicht abgedeckt ist. Bei „beide Quellen" ist die Abdeckung der Schnitt, nicht die Vereinigung. Ein Tag gilt nur als bekannt, wenn ihn jede Quelle abdeckt. Umgekehrt darf ein Ausfall einer Quelle die andere nicht mitreißen: Calendarr nie geöffnet zu haben knipst den Apple-Kalender nicht aus. Die Ablage kopiert, statt zu verweisen. Anhänge aus Mail oder WhatsApp liegen in temporären Verzeichnissen — ein Verweis wäre in Stunden tot, und die Ablage wäre leer, wenn man sie braucht. Aus demselben Grund nimmt die Fläche UTType.item statt public.file-url an: solche Anhänge kommen als Dateiversprechen, und loadFileRepresentation löst beides ein. Die übergebene Datei existiert nur innerhalb des Rückrufs, also wird sie dort sofort gesichert statt später auf dem MainActor. Gelöscht wird in den Papierkorb. Automatisches Aufräumen ist standardmäßig aus — eine Ablage, die ungefragt löscht, ist ein Papierkorb mit Zeitschaltuhr. Nebenbei: „mixer.on" und „network.vpn.active" standen als rohe Schlüssel in der Oberfläche. Label(_:systemImage:) kennt kein Bundle und sucht immer im Hauptbundle. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
aa8e903037 |
Frequenzanzeige: Datenzugang gelöst, Umrechnung nicht — bewusst abgebrochen
IOReport liefert je Kern die Verweilzeit in jeder Leistungsstufe, genau wie gebraucht: MCPU00 bis MCPU14, 17 Zustände, saubere Deltas zwischen zwei Messungen. Die Frequenz zu einer Stufe steht dort aber nicht. Sie muss aus den voltage-states-Tabellen im IODeviceTree kommen, und die passen nicht: der Kanal hat 16 Leistungsstufen, keine Tabelle hat 16 Einträge. Dazu sind die Einheiten uneinheitlich — voltage-states8 enthält echte Hertz (732–2472 MHz), voltage-states5 dagegen Paare wie (50103, 635), die in keiner Einheit sinnvolle Taktraten ergeben. Ab hier wäre es Reverse Engineering undokumentierter Firmware-Tabellen, deren Format sich zwischen Chip-Generationen ändert — genau die Sorte Code, die beim nächsten Mac still falsche Zahlen anzeigt statt zu scheitern. Dafür ist eine Zusatzangabe im Popover zu wenig, solange Phase 6 bis 9 offen sind. Die halbfertige Implementierung ist entfernt statt auskommentiert: nicht verdrahteter Code, der nil liefert, verrottet und täuscht später Vollständigkeit vor. Der Stand samt Fortsetzungsweg steht in docs/spikes/F-frequenz.md. |
||
|
|
7fcca61d70 |
Durchsatz je Programm und öffentliche IP
Beides läuft nur, solange jemand hinsieht. Die Prozessliste startet je Messung einen Fremdprozess — das im Sekundentakt zu tun kostete mehr als der gesamte übrige Monitor. Sie wird deshalb an das offene Popover gekoppelt, nicht an die Messschleife. Für den Durchsatz je Programm gibt es keine Bibliotheksschnittstelle: die zugrundeliegende NetworkStatistics-API ist privat und verlangt eine Entitlement, die Apple nicht vergibt. nettop ist Apples eigenes Werkzeug dafür, liegt im System und läuft — nachgemessen — ohne root für die Prozesse des eigenen Nutzers. Die Rate entsteht wie bei den Interface-Zählern aus der Differenz zweier Messungen. Die öffentliche IP bleibt standardmäßig aus, und der Schalter dafür steht im Popover statt versteckt in den Einstellungen: wer einen Systemmonitor benutzt, rechnet nicht damit, dass der nach draußen telefoniert. Ist sie an, steht der befragte Dienst sichtbar darunter — man soll nachlesen können, wem die Adresse bekannt wird. Höchstens alle 15 Minuten, weil sie sich selten ändert. Frequenzen sind der dritte Wunsch und der aufwendigste. Der Weg ist verifiziert: IOReport ist vollständig verfügbar, die Gruppe "CPU Stats" liefert unter "CPU Core Performance States" die Kanäle MCPU00 bis MCPU14 mit den P-Zustands-Residenzen, und die Frequenztabellen stehen als voltage-states* im IODeviceTree. Das kommt als Nächstes. 145 Tests grün. |
||
|
|
d85425671d |
Aussagekräftige Popovers für CPU, Speicher, Akku und Netzwerk
Ein Popover, das nur den Wert größer wiederholt, den man gerade angeklickt hat, ist verschenkter Platz. Hier ist Raum — anders als in der Menüleiste, wo jede Zahl um Breite kämpft. Prozessor: Ringe für Auslastung, Temperatur und Lüfter, alle Kerne als Raster statt als Balkenreihe (bei fünfzehn Kernen wird eine Reihe unleserlich schmal), Leistungsaufschlüsselung und beide Lüfter mit Namen. Die Leistungsschlüssel sind gegen iStat Menus abgeglichen: PHPC liefert 14,02 W und deckt sich mit deren CPU-Wert, PSTR mit der Gesamtleistung. Frequenzen fehlen bewusst — die stehen nicht im SMC, dafür bräuchte es IOReport. Speicher: Ring mit Aufschlüsselung nach Programmen, Reserviertem, Komprimiertem und Freiem, Auslagerung mit Gesamtgröße und die fünf größten Verbraucher über phys_footprint — derselbe Wert, den der Aktivitätsmonitor zeigt, nicht der virtuelle Adressraum. Akku: Restzeit, Kapazität, Zyklen, Temperatur, Lade- oder Entladeleistung, Netzteilleistung und Spannung. Netzwerk: Verlauf in beide Richtungen auf gemeinsamem Maßstab — getrennte Maßstäbe ließen einen Upload von 20 KB/s so hoch aussehen wie einen Download von 20 MB/s. Dazu Spitzenwerte, VPN-Hinweis, alle Adressen und die Summen seit dem Start. Was fehlt, wird benannt statt weggelassen: Durchsatz je Programm gibt es ohne root nicht, das Ladelimit braucht den privilegierten Helfer und einen Key, der auf diesem Modell noch nicht identifiziert ist. Sensorliste erweitert und benannt: CPU-Kerne und Grafik stehen vorn, dazu Luftstrom, Thunderbolt links und rechts. Lüfter heißen links und rechts statt 0 und 1. Nebenbei ein Übersetzungsfehler behoben: die Modus-Auswahl in den Einstellungen zeigte die Rohschlüssel, weil die Texte im MetricsProvider-Bündel liegen und die Einstellungen im App-Bündel suchen. 145 Tests grün. |
||
|
|
594d7c422a |
Phase 5: Hardware- und Netzwerkmonitor, Panel und Menüleiste
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. |