Skip to content

Commit

Permalink
Fix incorrect directionality in RTL OSD. #4884
Browse files Browse the repository at this point in the history
This commit will:
- Add withPosition and withLeftToRightText message types to OSDMessage
- Change the seek message type in OSDMessage to use withPosition instead
  of withProgress
- Change the abLoop, abLoopUpdate, chapter, pause and  resume message
  types in OSDMessage to use withLeftToRightText instead of withText
- Add support for withPosition to MainWindowController.displayOSD that
  uses a left to right layout for the text and slider
- Add support for withLeftToRightText to MainWindowController.displayOSD
  that uses a left to right layout for the text

This adjusts IINA's behavior to match Apple's guidance that timeline
indicators should not flip in a right-to-left language. The updated OSD
messages all reference positions within the video.
  • Loading branch information
low-batt committed Apr 20, 2024
1 parent 73c9608 commit d8a8612
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 9 deletions.
25 changes: 24 additions & 1 deletion iina/MainWindowController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1917,7 +1917,17 @@ class MainWindowController: PlayerWindowController {

// MARK: - UI: OSD

// Do not call displayOSD directly, call PlayerCore.sendOSD instead.
/// Show a message in the on screen display.
/// - Parameters:
/// - message: The `OSDMessage` to display.
/// - autoHide: If `true` (the default) the message will be hidden after a timeout.
/// - forcedTimeout: Timeout after which the message will be hidden (overrides user configured timeout).
/// - accessoryView: Custom view to display (if not supplied normal OSD views are used).
/// - context: Additional information associated with the message.
/// - Attention: Do not call `displayOSD` directly, call `PlayerCore.sendOSD` instead.
/// - Important: As per Apple's [Internationalization and Localization Guide](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/SupportingRight-To-LeftLanguages/SupportingRight-To-LeftLanguages.html)
/// timeline indicators should not flip in a right-to-left language. Thus OSD messages referencing a position within the video
/// must always use a left to right layout.
func displayOSD(_ message: OSDMessage, autoHide: Bool = true, forcedTimeout: Float? = nil, accessoryView: NSView? = nil, context: Any? = nil) {
guard player.displayOSD && !isShowingPersistentOSD else { return }

Expand All @@ -1934,14 +1944,27 @@ class MainWindowController: PlayerWindowController {
osdAccessoryText.font = NSFont.monospacedDigitSystemFont(ofSize: CGFloat(osdTextSize * 0.5).clamped(to: 11...25), weight: .regular)
osdLabel.stringValue = osdString

// Most OSD messages are displayed based on the configured language direction.
osdAccessoryProgress.userInterfaceLayoutDirection = osdStackView.userInterfaceLayoutDirection
osdAccessoryText.baseWritingDirection = .natural
osdLabel.baseWritingDirection = .natural
switch osdType {
case .normal:
osdStackView.setVisibilityPriority(.notVisible, for: osdAccessoryText)
osdStackView.setVisibilityPriority(.notVisible, for: osdAccessoryProgress)
case .withPosition(let value):
// OSD messages displaying the playback position must always be displayed left to right.
osdAccessoryProgress.userInterfaceLayoutDirection = .leftToRight
osdLabel.baseWritingDirection = .leftToRight
fallthrough
case .withProgress(let value):
osdStackView.setVisibilityPriority(.notVisible, for: osdAccessoryText)
osdStackView.setVisibilityPriority(.mustHold, for: osdAccessoryProgress)
osdAccessoryProgress.doubleValue = value
case .withLeftToRightText(let text):
// OSD messages displaying the playback position must always be displayed left to right.
osdAccessoryText.baseWritingDirection = .leftToRight
fallthrough
case .withText(let text):
// data for mustache redering
let osdData: [String: String] = [
Expand Down
24 changes: 16 additions & 8 deletions iina/OSDMessage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ enum OSDType {
case normal
case withText(String)
case withProgress(Double)
case withPosition(Double)
case withLeftToRightText(String)
// case withButton(String)
}

Expand Down Expand Up @@ -89,13 +91,15 @@ enum OSDMessage {
return (filename, .normal)

case .pause:
return (NSLocalizedString("osd.pause", comment: "Pause"), .withText("{{position}} / {{duration}}"))
return (NSLocalizedString("osd.pause", comment: "Pause"),
.withLeftToRightText("{{position}} / {{duration}}"))

case .resume:
return (NSLocalizedString("osd.resume", comment: "Resume"), .withText("{{position}} / {{duration}}"))
return (NSLocalizedString("osd.resume", comment: "Resume"),
.withLeftToRightText("{{position}} / {{duration}}"))

case .seek(let text, let percent):
return (text, .withProgress(percent))
return (text, .withPosition(percent))

case .volume(let value):
return (
Expand Down Expand Up @@ -188,9 +192,11 @@ enum OSDMessage {
case .cleared:
return (NSLocalizedString("osd.abloop.clear", comment: "AB-Loop: Cleared"), .normal)
case .aSet:
return (NSLocalizedString("osd.abloop.a", comment: "AB-Loop: A"), .withText("{{position}} / {{duration}}"))
return (NSLocalizedString("osd.abloop.a", comment: "AB-Loop: A"),
.withLeftToRightText("{{position}} / {{duration}}"))
case .bSet:
return (NSLocalizedString("osd.abloop.b", comment: "AB-Loop: B"), .withText("{{position}} / {{duration}}"))
return (NSLocalizedString("osd.abloop.b", comment: "AB-Loop: B"),
.withLeftToRightText("{{position}} / {{duration}}"))
}

case .abLoopUpdate(let value, let position):
Expand All @@ -199,9 +205,11 @@ enum OSDMessage {
case .cleared:
Logger.fatal("Attempt to display invalid OSD message, type: .abLoopUpdate value: .cleared position \(position)")
case .aSet:
return (NSLocalizedString("osd.abloop.a", comment: "AB-Loop: A"), .withText("\(position) / {{duration}}"))
return (NSLocalizedString("osd.abloop.a", comment: "AB-Loop: A"),
.withLeftToRightText("\(position) / {{duration}}"))
case .bSet:
return (NSLocalizedString("osd.abloop.b", comment: "AB-Loop: B"), .withText("\(position) / {{duration}}"))
return (NSLocalizedString("osd.abloop.b", comment: "AB-Loop: B"),
.withLeftToRightText("\(position) / {{duration}}"))
}

case .stop:
Expand All @@ -210,7 +218,7 @@ enum OSDMessage {
case .chapter(let name):
return (
String(format: NSLocalizedString("osd.chapter", comment: "Chapter: %@"), name),
.withText("({{currChapter}}/{{chapterCount}}) {{position}} / {{duration}}")
.withLeftToRightText("({{currChapter}}/{{chapterCount}}) {{position}} / {{duration}}")
)

case .track(let track):
Expand Down

0 comments on commit d8a8612

Please sign in to comment.