Make seek durations configurable in Playback menu and add secondary seek

Playback menu seek items now follow the durations from the active player
controls preset instead of hardcoded 10s/30s labels. AppEnvironment caches
the active preset's center settings (refreshed on preset change
notifications) so menu commands can read them synchronously.

Add secondary seek durations (default 30s) to CenterSectionSettings,
configurable on macOS in Seek Durations settings, used by Shift+arrows in
the player and Cmd+Shift+arrows in the Playback menu.

Also let Cmd-based key equivalents pass through the player keyboard
monitor so menu shortcuts (e.g. Cmd+Option+arrow previous/next video)
work while the player window has focus, and unify macOS built-in preset
primary seek at 10s to match iOS/tvOS (built-in presets version 8).
This commit is contained in:
Arkadiusz Fal
2026-06-19 08:50:39 +02:00
parent 5bc774dd83
commit ca67d480ca
7 changed files with 197 additions and 50 deletions

View File

@@ -50,10 +50,10 @@ struct PlaybackCommands: Commands {
Divider()
// Seeking
seekBackward10Button
seekForward10Button
seekBackward30Button
seekForward30Button
seekBackwardButton
seekForwardButton
secondarySeekBackwardButton
secondarySeekForwardButton
Divider()
@@ -121,41 +121,59 @@ struct PlaybackCommands: Commands {
// MARK: - Seeking
private var seekBackward10Button: some View {
/// Seek durations follow the active player controls preset, matching the
/// in-player arrow key shortcuts.
private var seekBackwardSeconds: Int {
appEnvironment.activeControlsCenterSettings.seekBackwardSeconds
}
private var seekForwardSeconds: Int {
appEnvironment.activeControlsCenterSettings.seekForwardSeconds
}
private var seekBackwardButton: some View {
Button {
playerService.seekBackward(by: 10)
playerService.seekBackward(by: TimeInterval(seekBackwardSeconds))
} label: {
Text(String(localized: "menu.playback.seekBackward10"))
Text(String(localized: "menu.playback.seekBackward \(seekBackwardSeconds)"))
}
.keyboardShortcut(.leftArrow, modifiers: [.command])
.disabled(!hasActiveVideo)
}
private var seekForward10Button: some View {
private var seekForwardButton: some View {
Button {
playerService.seekForward(by: 10)
playerService.seekForward(by: TimeInterval(seekForwardSeconds))
} label: {
Text(String(localized: "menu.playback.seekForward10"))
Text(String(localized: "menu.playback.seekForward \(seekForwardSeconds)"))
}
.keyboardShortcut(.rightArrow, modifiers: [.command])
.disabled(!hasActiveVideo)
}
private var seekBackward30Button: some View {
private var secondarySeekBackwardSeconds: Int {
appEnvironment.activeControlsCenterSettings.secondarySeekBackwardSeconds
}
private var secondarySeekForwardSeconds: Int {
appEnvironment.activeControlsCenterSettings.secondarySeekForwardSeconds
}
private var secondarySeekBackwardButton: some View {
Button {
playerService.seekBackward(by: 30)
playerService.seekBackward(by: TimeInterval(secondarySeekBackwardSeconds))
} label: {
Text(String(localized: "menu.playback.seekBackward30"))
Text(String(localized: "menu.playback.seekBackward \(secondarySeekBackwardSeconds)"))
}
.keyboardShortcut(.leftArrow, modifiers: [.command, .shift])
.disabled(!hasActiveVideo)
}
private var seekForward30Button: some View {
private var secondarySeekForwardButton: some View {
Button {
playerService.seekForward(by: 30)
playerService.seekForward(by: TimeInterval(secondarySeekForwardSeconds))
} label: {
Text(String(localized: "menu.playback.seekForward30"))
Text(String(localized: "menu.playback.seekForward \(secondarySeekForwardSeconds)"))
}
.keyboardShortcut(.rightArrow, modifiers: [.command, .shift])
.disabled(!hasActiveVideo)