Skip to content

Commit

Permalink
Rectify timeline in Touchbar freezes, iina#4058
Browse files Browse the repository at this point in the history
This commit will:
- Add a new method makeTouchBar to PlayerCore
- Change MainWindowController and MiniPlayerWindowController extensions
  in TouchBarSupport to call the new method
- Add a hasTouchBar property to TouchBarSupport
- Change MainWindowController.hideUI to not stop the timer that
  synchronizes the UI if the Mac has a touch bar

This corrects a regression added by a change to hideUI to stop the timer
when the OSC is hidden in order to save energy. That change failed to
take into account that the timer also synchronizes controls in the
touch bar on MacBooks that have one.
  • Loading branch information
low-batt authored and MikeWang000000 committed Mar 8, 2023
1 parent cdc1135 commit 5d0048f
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 19 deletions.
29 changes: 16 additions & 13 deletions iina/MainWindowController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1663,17 +1663,17 @@ class MainWindowController: PlayerWindowController {
}

// Follow energy efficiency best practices and stop the timer that updates the OSC while it is
// hidden. However the timer can't be stopped if the mini player is being used as it always
// displays the the OSC or the timer is also updating the information being displayed in the
// touch bar. Does this host have a touch bar? Is the touch bar configured to show app controls?
// Is the touch bar awake? Is the host being operated in closed clamshell mode? This is the kind
// of information needed to avoid running the timer and updating controls that are not visible.
// Unfortunately in the documentation for NSTouchBar Apple indicates "There’s no need, and no
// API, for your app to know whether or not there’s a Touch Bar available". So this code keys
// off whether AppKit has requested that a NSTouchBar object be created. This avoids running the
// timer on Macs that do not have a touch bar. It also may avoid running the timer when a
// MacBook with a touch bar is being operated in closed clameshell mode.
if !player.isInMiniPlayer && !player.hasTouchBar {
// hidden. However the timer can't be stopped if it is also updating the information being
// displayed in the touch bar. Does this host have a touch bar? Is the touch bar configured to
// show app controls? Is the touch bar awake? Is the host being operated in closed clamshell
// mode? This is the kind of information needed to avoid running the timer and updating controls
// that are not visible. Unfortunately in the documentation for NSTouchBar Apple indicates
// "There’s no need, and no API, for your app to know whether or not there’s a Touch Bar
// available". So this code keys off whether AppKit has requested that a NSTouchBar object be
// created. This avoids running the timer on Macs that do not have a touch bar. It also may
// avoid running the timer when a MacBook with a touch bar is being operated in closed
// clameshell mode.
if !player.hasTouchBar {
player.invalidateTimer()
}

Expand Down Expand Up @@ -1710,9 +1710,12 @@ class MainWindowController: PlayerWindowController {
fadeableViews.forEach { (v) in
v.isHidden = false
}
// The OSC was not updated while it was hidden to avoid wasting energy. Update it now.
// The OSC may not have been updated while it was hidden to avoid wasting energy. Make sure it
// is up to date.
player.syncUITime()
player.createSyncUITimer()
if !player.info.isPaused {
player.createSyncUITimer()
}
standardWindowButtons.forEach { $0.isEnabled = true }
NSAnimationContext.runAnimationGroup({ (context) in
context.duration = UIAnimationDuration
Expand Down
4 changes: 2 additions & 2 deletions iina/PlayerCore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class PlayerCore: NSObject {
///
/// - Note: This is set based on whether `AppKit` has called `MakeTouchBar`, therefore it can, for example, be `false` for
/// a MacBook that has a touch bar if the touch bar is asleep because the Mac is in closed clamshell mode.
var needsTouchBar = false
var hasTouchBar = false

/// A dispatch queue for auto load feature.
let backgroundQueue = DispatchQueue(label: "IINAPlayerCoreTask", qos: .background)
Expand Down Expand Up @@ -1800,7 +1800,7 @@ class PlayerCore: NSObject {
@available(macOS 10.12.2, *)
func makeTouchBar() -> NSTouchBar {
Logger.log("Activating Touch Bar", subsystem: subsystem)
needsTouchBar = true
hasTouchBar = true
// The timer that synchronizes the UI is shutdown to conserve energy when the OSC is hidden.
// However the timer can't be stopped if it is needed to update the information being displayed
// in the touch bar. If currently playing make sure the timer is running.
Expand Down
6 changes: 2 additions & 4 deletions iina/TouchBarSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -247,18 +247,16 @@ class TouchBarSupport: NSObject, NSTouchBarDelegate {
extension MainWindowController {

override func makeTouchBar() -> NSTouchBar? {
return player.touchBarSupport.touchBar
return player.makeTouchBar()
}

}

@available(macOS 10.12.2, *)
extension MiniPlayerWindowController {

override func makeTouchBar() -> NSTouchBar? {
return player.touchBarSupport.touchBar
return player.makeTouchBar()
}

}

// MARK: - Slider
Expand Down

0 comments on commit 5d0048f

Please sign in to comment.