Menüleiste zeigt das Glyph, nicht das ganze App-Icon

Das vollständige App-Icon bringt die abgerundete Kachel samt Farbverlauf mit.
Die gehört in Dock und Finder; in der Menüleiste steht sie als farbiger Klotz
zwischen lauter Strichsymbolen.

Geladen wird jetzt dieselbe SVG-Datei, aus der auch das App-Icon gebaut wird.
NSImage liest sie als Vektor (_NSSVGImageRep), sie skaliert also verlustfrei
auf die 18 pt der Menüleiste.

Der Weg dorthin ist ein Kopierschritt und keine zweite Datei: actool kompiliert
das .icon-Bündel zu .icns und Assets.car und legt nichts Lesbares ins Bundle,
und eine einzelne Datei aus dem Bündel lässt sich nicht als Ressource
referenzieren — XcodeGen bricht dabei ab. Ein Build-Schritt kopiert sie
stattdessen, damit es bei einer Quelldatei bleibt.

Weiterhin kein Template-Bild: als Schablone bliebe vom Kristall nur eine
schwarze Silhouette.
This commit is contained in:
Guido Schmit
2026-08-10 20:55:40 +02:00
parent 4b559ba840
commit 03dd7b945e
4 changed files with 385 additions and 332 deletions

View File

@@ -159,30 +159,38 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
onyxItem = item
}
/// Das App-Icon, auf Menüleistengröße gebracht.
/// Das Glyph aus dem App-Icon, auf Menüleistengröße gebracht.
///
/// Bewusst **kein** Template-Bild: als Schablone bliebe von dem Kristall nur
/// eine schwarze Silhouette übrig, und der Verlauf das Erkennungsmerkmal
/// des Icons wäre weg. Der Preis dafür ist, dass es sich nicht automatisch
/// an helle und dunkle Menüleisten anpasst.
/// Nicht das vollständige App-Icon: das bringt die abgerundete Kachel samt
/// Farbverlauf mit, und die gehört in Dock und Finder, nicht in die
/// Menüleiste. Dort steht sie als farbiger Klotz zwischen lauter
/// Strichsymbolen.
///
/// 18 pt ist die übliche Höhe für Menüleistensymbole; die Leiste ist 22 pt
/// hoch und braucht oben und unten Luft.
/// Geladen wird dieselbe SVG-Datei, aus der auch das App-Icon gebaut wird
/// NSImage liest sie als Vektor (`_NSSVGImageRep`), sie skaliert also
/// verlustfrei. Bewusst **kein** Template-Bild: als Schablone bliebe vom
/// Kristall eine schwarze Silhouette. Der Preis ist, dass er sich nicht
/// automatisch an helle und dunkle Menüleisten anpasst.
///
/// 18 pt ist die übliche Höhe; die Leiste ist 22 pt hoch und braucht oben
/// und unten Luft.
private static func menuBarIcon() -> NSImage {
guard let source = NSApp.applicationIconImage else {
// Sollte nicht vorkommen, aber ein Menüleisteneintrag ohne Symbol
// wäre unsichtbar und die App damit unerreichbar.
return NSImage(systemSymbolName: "circle.hexagongrid.fill",
accessibilityDescription: "Onyx") ?? NSImage()
let size = NSSize(width: 18, height: 18)
if let url = Bundle.main.url(forResource: "quartz", withExtension: "svg"),
let glyph = NSImage(contentsOf: url) {
let image = NSImage(size: size, flipped: false) { rect in
glyph.draw(in: rect, from: .zero, operation: .sourceOver, fraction: 1)
return true
}
image.accessibilityDescription = "Onyx"
return image
}
let size = NSSize(width: 18, height: 18)
let image = NSImage(size: size, flipped: false) { rect in
source.draw(in: rect, from: .zero, operation: .sourceOver, fraction: 1)
return true
}
image.accessibilityDescription = "Onyx"
return image
// Ein Menüleisteneintrag ohne Bild wäre unsichtbar und die App darüber
// unerreichbar deshalb ein Rückfall statt eines leeren Knopfs.
return NSImage(systemSymbolName: "circle.hexagongrid.fill",
accessibilityDescription: "Onyx") ?? NSImage()
}
private func observeMenuBarPreference() {