Mixer kann beim Start von Onyx mitlaufen
Ein Häkchen im Mixer selbst. Standardmäßig aus: der Mixer greift in den Tonweg der geregelten Programme ein, und das soll niemandem ungefragt passieren — beim ersten Start soll nichts umgeleitet werden, was der Nutzer nicht angeschaltet hat. Das Häkchen steht in beiden Zuständen: eingeschaltet, um es wieder abzuwählen, ausgeschaltet, um es gleich mit zu setzen. Sonst müsste man den Mixer erst einschalten, um sagen zu können, dass er von selbst einschalten soll. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -116,6 +116,10 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
self.menuBar = menuBar
|
self.menuBar = menuBar
|
||||||
model.menuBar = menuBar
|
model.menuBar = menuBar
|
||||||
|
|
||||||
|
// Der Mixer läuft nur an, wenn das Häkchen gesetzt ist — er greift in
|
||||||
|
// den Tonweg ein, und das soll niemandem ungefragt passieren.
|
||||||
|
audioMixer.enableIfWanted()
|
||||||
|
|
||||||
installOnyxStatusItem()
|
installOnyxStatusItem()
|
||||||
observeMenuBarPreference()
|
observeMenuBarPreference()
|
||||||
requestPermissions()
|
requestPermissions()
|
||||||
|
|||||||
@@ -38,10 +38,23 @@ public final class AudioMixer {
|
|||||||
/// verschwindet ein pausiertes Programm sofort aus der Liste.
|
/// verschwindet ein pausiertes Programm sofort aus der Liste.
|
||||||
private var lastHeard: [String: Date] = [:]
|
private var lastHeard: [String: Date] = [:]
|
||||||
|
|
||||||
|
/// Ob der Mixer beim Programmstart von selbst anläuft.
|
||||||
|
///
|
||||||
|
/// Standardmäßig aus: der Mixer greift in den Tonweg ein, und das soll
|
||||||
|
/// niemandem ungefragt passieren. Wer ihn täglich benutzt, spart sich mit
|
||||||
|
/// dem Häkchen den Klick.
|
||||||
|
public var startsAutomatically: Bool {
|
||||||
|
didSet {
|
||||||
|
guard startsAutomatically != oldValue else { return }
|
||||||
|
defaults.set(startsAutomatically, forKey: Keys.autostart)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private enum Keys {
|
private enum Keys {
|
||||||
static let volumes = "onyx.audio.volumes"
|
static let volumes = "onyx.audio.volumes"
|
||||||
static let muted = "onyx.audio.muted"
|
static let muted = "onyx.audio.muted"
|
||||||
static let managed = "onyx.audio.managed"
|
static let managed = "onyx.audio.managed"
|
||||||
|
static let autostart = "onyx.audio.autostart"
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(defaults: UserDefaults = .standard) {
|
public init(defaults: UserDefaults = .standard) {
|
||||||
@@ -50,6 +63,13 @@ public final class AudioMixer {
|
|||||||
let muted = defaults.stringArray(forKey: Keys.muted) ?? []
|
let muted = defaults.stringArray(forKey: Keys.muted) ?? []
|
||||||
store = VolumeStore(volumes: volumes, muted: muted)
|
store = VolumeStore(volumes: volumes, muted: muted)
|
||||||
managed = Set(defaults.stringArray(forKey: Keys.managed) ?? [])
|
managed = Set(defaults.stringArray(forKey: Keys.managed) ?? [])
|
||||||
|
startsAutomatically = defaults.bool(forKey: Keys.autostart)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Beim Programmstart aufrufen. Läuft nur an, wenn das Häkchen gesetzt ist.
|
||||||
|
public func enableIfWanted() {
|
||||||
|
guard startsAutomatically else { return }
|
||||||
|
enable()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Ein und aus
|
// MARK: - Ein und aus
|
||||||
|
|||||||
@@ -20,6 +20,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mixer.autostart": {
|
||||||
|
"localizations": {
|
||||||
|
"de": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Beim Start von Onyx einschalten"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "Turn on when Onyx starts"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"mixer.input": {
|
"mixer.input": {
|
||||||
"localizations": {
|
"localizations": {
|
||||||
"de": {
|
"de": {
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ public struct MixerView: View {
|
|||||||
.fixedSize(horizontal: false, vertical: true)
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
autostartToggle
|
||||||
|
|
||||||
// Der Notausschalter gehört sichtbar dazu, nicht in ein Menü:
|
// Der Notausschalter gehört sichtbar dazu, nicht in ein Menü:
|
||||||
// wenn der Ton weg ist, ist das der Knopf, den man sucht.
|
// wenn der Ton weg ist, ist das der Knopf, den man sucht.
|
||||||
Button { mixer.disable() } label: {
|
Button { mixer.disable() } label: {
|
||||||
@@ -79,6 +81,7 @@ public struct MixerView: View {
|
|||||||
.padding(.top, 2)
|
.padding(.top, 2)
|
||||||
} else {
|
} else {
|
||||||
OffState(mixer: mixer, compact: compact)
|
OffState(mixer: mixer, compact: compact)
|
||||||
|
autostartToggle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
@@ -86,6 +89,22 @@ public struct MixerView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension MixerView {
|
||||||
|
/// Das Häkchen steht in **beiden** Zuständen: eingeschaltet, um es wieder
|
||||||
|
/// abzuwählen, ausgeschaltet, um es gleich mit zu setzen.
|
||||||
|
@ViewBuilder
|
||||||
|
var autostartToggle: some View {
|
||||||
|
Toggle(isOn: Binding(get: { mixer.startsAutomatically },
|
||||||
|
set: { mixer.startsAutomatically = $0 })) {
|
||||||
|
Text("mixer.autostart", bundle: .module)
|
||||||
|
.font(Onyx.Font.caption)
|
||||||
|
.foregroundStyle(Onyx.Color.textSecondary)
|
||||||
|
}
|
||||||
|
.toggleStyle(.checkbox)
|
||||||
|
.controlSize(.small)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Der ausgeschaltete Zustand erklärt, worauf man sich einlässt — in zwei
|
/// Der ausgeschaltete Zustand erklärt, worauf man sich einlässt — in zwei
|
||||||
/// Sätzen, nicht in einem Absatz. Wer vier Zeilen lesen muss, bevor er einen
|
/// Sätzen, nicht in einem Absatz. Wer vier Zeilen lesen muss, bevor er einen
|
||||||
/// Regler sieht, liest sie nicht.
|
/// Regler sieht, liest sie nicht.
|
||||||
|
|||||||
Reference in New Issue
Block a user