diff --git a/Onyx/AppIcon.icon/icon.json b/Onyx/AppIcon.icon/icon.json index 21df5ad..0ff68ad 100644 --- a/Onyx/AppIcon.icon/icon.json +++ b/Onyx/AppIcon.icon/icon.json @@ -1,7 +1,17 @@ { - "fill" : { - "automatic-gradient" : "display-p3:0.21900,0.30045,0.61471,1.00000" - }, + "fill-specializations" : [ + { + "value" : { + "automatic-gradient" : "display-p3:0.21900,0.30045,0.61471,1.00000" + } + }, + { + "appearance" : "dark", + "value" : { + "automatic-gradient" : "display-p3:0.12445,0.17422,0.36459,1.00000" + } + } + ], "groups" : [ { "layers" : [ diff --git a/Onyx/Localizable.xcstrings b/Onyx/Localizable.xcstrings index 9c1d777..aeed9f6 100644 --- a/Onyx/Localizable.xcstrings +++ b/Onyx/Localizable.xcstrings @@ -1,523 +1,526 @@ { - "sourceLanguage": "en", - "strings": { - "menu.openPanel": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Panel öffnen" + "sourceLanguage" : "en", + "strings" : { + "menu.openPanel" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Panel öffnen" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Open Panel" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Open Panel" } } } }, - "menu.quit": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Onyx beenden" + "menu.quit" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Onyx beenden" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Quit Onyx" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quit Onyx" } } } }, - "menu.settings": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Einstellungen …" + "menu.settings" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Einstellungen …" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Settings…" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Settings…" } } } }, - "settings.display.all": { - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Allen Displays" + "settings.display.all" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Allen Displays" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "All displays" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "All displays" } } } }, - "settings.display.builtInOnly": { - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Nur dem internen Display" + "settings.display.builtInOnly" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nur dem internen Display" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Built-in display only" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Built-in display only" } } } }, - "settings.display.hint": { - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Auf Displays ohne echte Notch erscheint oben mittig ein Balken, der sich genauso verhält. Ist der Deckel geschlossen und kein internes Display vorhanden, erscheint das Panel trotzdem auf einem externen — sonst wäre Onyx nicht erreichbar." + "settings.display.dockIcon" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Symbol im Dock anzeigen" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "On displays without a real notch, a bar appears at the top centre and behaves the same. With the lid closed and no built-in display present, the panel still appears on an external one — otherwise Onyx would be unreachable." + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Show icon in the Dock" } } } }, - "settings.display.menuBarIcon": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Symbol in der Menüleiste anzeigen" + "settings.display.dockIcon.hint" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Standardmäßig aus. Onyx lebt in der Notch und in der Menüleiste und hat kein Hauptfenster — im Dock wäre es ein Symbol, das beim Anklicken nichts öffnet, und es stünde im Programmumschalter zwischen den Programmen, mit denen du arbeitest." } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Show icon in the menu bar" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Off by default. Onyx lives in the notch and the menu bar and has no main window — in the Dock it would be an icon that opens nothing, and it would sit in the app switcher among the apps you actually work with." } } } }, - "settings.display.menuBarIcon.hint": { - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Über das Symbol erreichst du Panel, Einstellungen und Beenden. Ohne es kommst du nur über die Notch an Onyx heran." + "settings.display.hint" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Auf Displays ohne echte Notch erscheint oben mittig ein Balken, der sich genauso verhält. Ist der Deckel geschlossen und kein internes Display vorhanden, erscheint das Panel trotzdem auf einem externen — sonst wäre Onyx nicht erreichbar." } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "The icon gives you the panel, settings and quit. Without it, the notch is the only way to reach Onyx." + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "On displays without a real notch, a bar appears at the top centre and behaves the same. With the lid closed and no built-in display present, the panel still appears on an external one — otherwise Onyx would be unreachable." } } } }, - "settings.display.policy": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Panel anzeigen auf" + "settings.display.menuBarIcon" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Symbol in der Menüleiste anzeigen" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Show panel on" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Show icon in the menu bar" } } } }, - "settings.permissions.calendar": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Kalender" + "settings.display.menuBarIcon.hint" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Über das Symbol erreichst du Panel, Einstellungen und Beenden. Ohne es kommst du nur über die Notch an Onyx heran." } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Calendar" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "The icon gives you the panel, settings and quit. Without it, the notch is the only way to reach Onyx." } } } }, - "settings.permissions.calendar.why": { - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Onyx zeigt deine Termine im Kalender-Widget an. Es wird ausschließlich gelesen, nie geschrieben." + "settings.display.policy" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Panel anzeigen auf" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Onyx shows your events in the calendar widget. It only ever reads, never writes." + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Show panel on" } } } }, - "settings.permissions.granted": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Erteilt" + "settings.permissions.calendar" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kalender" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Granted" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Calendar" } } } }, - "settings.permissions.location": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Standort" + "settings.permissions.calendar.why" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Onyx zeigt deine Termine im Kalender-Widget an. Es wird ausschließlich gelesen, nie geschrieben." } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Location" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Onyx shows your events in the calendar widget. It only ever reads, never writes." } } } }, - "settings.permissions.location.why": { - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Onyx zeigt das Wetter an deinem aktuellen Standort. Ohne Zugriff kannst du stattdessen einen festen Ort wählen." + "settings.permissions.granted" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erteilt" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Onyx shows the weather for your current location. Without access you can pick a fixed place instead." + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Granted" } } } }, - "settings.permissions.openSystem": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Systemeinstellungen öffnen" + "settings.permissions.location" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Standort" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Open System Settings" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Location" } } } }, - "settings.permissions.request": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Anfragen" + "settings.permissions.location.why" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Onyx zeigt das Wetter an deinem aktuellen Standort. Ohne Zugriff kannst du stattdessen einen festen Ort wählen." } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Request" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Onyx shows the weather for your current location. Without access you can pick a fixed place instead." } } } }, - "settings.size.large": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Groß (2×2)" + "settings.permissions.openSystem" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Systemeinstellungen öffnen" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Large (2×2)" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Open System Settings" } } } }, - "settings.size.medium": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Mittel (2×1)" + "settings.permissions.request" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Anfragen" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Medium (2×1)" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Request" } } } }, - "settings.size.small": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Klein (1×1)" + "settings.size.large" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Groß (2×2)" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Small (1×1)" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Large (2×2)" } } } }, - "settings.size.wide": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Breit (4×1)" + "settings.size.medium" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mittel (2×1)" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Wide (4×1)" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Medium (2×1)" } } } }, - "settings.tab.display": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Anzeige" + "settings.size.small" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Klein (1×1)" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Display" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Small (1×1)" } } } }, - "settings.tab.permissions": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Berechtigungen" + "settings.size.wide" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Breit (4×1)" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Permissions" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wide (4×1)" } } } }, - "settings.tab.widgets": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Widgets" + "settings.tab.display" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Anzeige" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Widgets" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Display" } } } }, - "settings.widgets.add": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Hinzufügen" + "settings.tab.permissions" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Berechtigungen" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Add" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Permissions" } } } }, - "settings.widgets.available": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Verfügbar" + "settings.tab.widgets" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Widgets" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Available" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Widgets" } } } }, - "settings.widgets.empty": { - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Keine Widgets im Panel. Das Panel bleibt leer, bis du eins hinzufügst." + "settings.widgets.add" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hinzufügen" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "No widgets in the panel. It stays empty until you add one." + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Add" } } } }, - "settings.widgets.hint": { - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Die Reihenfolge bestimmt die Anordnung im Panel. Jedes Widget rückt an die erste Stelle, an die es passt." + "settings.widgets.available" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Verfügbar" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "The order determines the arrangement in the panel. Each widget takes the first spot it fits into." + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Available" } } } }, - "settings.widgets.inPanel": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Im Panel" + "settings.widgets.empty" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Keine Widgets im Panel. Das Panel bleibt leer, bis du eins hinzufügst." } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "In the panel" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No widgets in the panel. It stays empty until you add one." } } } }, - "settings.widgets.remove": { - "extractionState": "stale", - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Aus dem Panel entfernen" + "settings.widgets.hint" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Die Reihenfolge bestimmt die Anordnung im Panel. Jedes Widget rückt an die erste Stelle, an die es passt." } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Remove from panel" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "The order determines the arrangement in the panel. Each widget takes the first spot it fits into." } } } }, - "settings.display.dockIcon": { - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Symbol im Dock anzeigen" + "settings.widgets.inPanel" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Im Panel" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Show icon in the Dock" + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "In the panel" } } } }, - "settings.display.dockIcon.hint": { - "localizations": { - "de": { - "stringUnit": { - "state": "translated", - "value": "Standardmäßig aus. Onyx lebt in der Notch und in der Menüleiste und hat kein Hauptfenster — im Dock wäre es ein Symbol, das beim Anklicken nichts öffnet, und es stünde im Programmumschalter zwischen den Programmen, mit denen du arbeitest." + "settings.widgets.remove" : { + "extractionState" : "stale", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aus dem Panel entfernen" } }, - "en": { - "stringUnit": { - "state": "translated", - "value": "Off by default. Onyx lives in the notch and the menu bar and has no main window — in the Dock it would be an icon that opens nothing, and it would sit in the app switcher among the apps you actually work with." + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Remove from panel" } } } } }, - "version": "1.0" + "version" : "1.0" } \ No newline at end of file diff --git a/Onyx/SettingsWindowController.swift b/Onyx/SettingsWindowController.swift index 67cc3b8..6f8befd 100644 --- a/Onyx/SettingsWindowController.swift +++ b/Onyx/SettingsWindowController.swift @@ -20,9 +20,22 @@ final class SettingsWindowController: NSObject, NSWindowDelegate { /// Muss außerhalb der View liegen, damit ein erneutes Öffnen den Reiter setzen kann. private var selectedTab: SettingsTab = .widgets + /// Ob Onyx dauerhaft im Dock steht. Bestimmt, wohin nach dem Schließen + /// zurückgeschaltet wird. + var keepsDockIcon = false + func show(model: AppModel, calendarModel: CalendarModel, weatherModel: WeatherModel, tab: SettingsTab = .widgets) { selectedTab = tab + keepsDockIcon = model.showsDockIcon + + // Solange ein Fenster offen ist, gehört Onyx in den Dock. + // + // Als reine `.accessory`-App hat sie dort keinen Eintrag — das ist im + // Hintergrund richtig, aber mit sichtbarem Fenster verwirrend: das + // Fenster lässt sich dann weder über den Dock noch über ⌘-Tab + // zurückholen, wenn es hinter etwas anderes rutscht. + NSApp.setActivationPolicy(.regular) if window == nil { let hosting = NSHostingController( @@ -52,8 +65,11 @@ final class SettingsWindowController: NSObject, NSWindowDelegate { } func windowWillClose(_ notification: Notification) { - // Zurück in den Hintergrund: Onyx hat sonst weiter den Fokus, obwohl - // kein Fenster mehr offen ist. + // Zurück in den Hintergrund — es sei denn, der Dock-Eintrag ist + // ausdrücklich gewünscht. + if !keepsDockIcon { + NSApp.setActivationPolicy(.accessory) + } NSApp.hide(nil) } }