2024-03-29 14:48:36 +00:00
|
|
|
/*
|
|
|
|
* This file is part of mpv.
|
|
|
|
*
|
|
|
|
* mpv is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* mpv is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
import Cocoa
|
|
|
|
|
|
|
|
class Application: NSApplication, NSApplicationDelegate {
|
2024-04-27 20:11:33 +00:00
|
|
|
var appHub: AppHub { return AppHub.shared }
|
|
|
|
var eventManager: NSAppleEventManager { return NSAppleEventManager.shared() }
|
|
|
|
var isBundle: Bool { return ProcessInfo.processInfo.environment["MPVBUNDLE"] == "true" }
|
2024-03-30 18:26:45 +00:00
|
|
|
var playbackThreadId: mp_thread!
|
|
|
|
var argc: Int32?
|
|
|
|
var argv: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>?
|
|
|
|
|
2024-03-29 14:48:36 +00:00
|
|
|
override init() {
|
|
|
|
super.init()
|
|
|
|
}
|
|
|
|
|
|
|
|
required init?(coder: NSCoder) {
|
|
|
|
fatalError("init(coder:) has not been implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
override func sendEvent(_ event: NSEvent) {
|
|
|
|
if modalWindow != nil || !appHub.input.processKey(event: event) {
|
|
|
|
super.sendEvent(event)
|
|
|
|
}
|
|
|
|
appHub.input.wakeup()
|
|
|
|
}
|
|
|
|
|
|
|
|
#if HAVE_MACOS_TOUCHBAR
|
|
|
|
override func makeTouchBar() -> NSTouchBar? {
|
|
|
|
return appHub.touchBar
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2024-03-30 23:25:42 +00:00
|
|
|
func application(_ application: NSApplication, open urls: [URL]) {
|
2024-03-31 01:29:31 +00:00
|
|
|
appHub.open(urls: urls)
|
2024-03-30 23:25:42 +00:00
|
|
|
}
|
|
|
|
|
2024-03-29 14:48:36 +00:00
|
|
|
func applicationWillFinishLaunching(_ notification: Notification) {
|
2024-03-31 23:00:19 +00:00
|
|
|
// register quit and exit events
|
2024-03-29 14:48:36 +00:00
|
|
|
eventManager.setEventHandler(
|
|
|
|
self,
|
|
|
|
andSelector: #selector(handleQuit(event:replyEvent:)),
|
|
|
|
forEventClass: AEEventClass(kCoreEventClass),
|
|
|
|
andEventID: kAEQuitApplication
|
|
|
|
)
|
2024-03-31 23:00:19 +00:00
|
|
|
atexit_b({
|
|
|
|
// clean up after exit() was called
|
|
|
|
DispatchQueue.main.async {
|
|
|
|
NSApp.hide(NSApp)
|
|
|
|
NSApp.setActivationPolicy(.prohibited)
|
|
|
|
self.eventManager.removeEventHandler(forEventClass: AEEventClass(kCoreEventClass), andEventID: kAEQuitApplication)
|
|
|
|
}
|
|
|
|
})
|
2024-03-29 14:48:36 +00:00
|
|
|
}
|
|
|
|
|
2024-03-31 23:00:19 +00:00
|
|
|
// quit from App icon, external quit from NSWorkspace
|
2024-03-29 14:48:36 +00:00
|
|
|
@objc func handleQuit(event: NSAppleEventDescriptor?, replyEvent: NSAppleEventDescriptor?) {
|
2024-03-31 23:00:19 +00:00
|
|
|
// send quit to core, terminates mpv_main called in playbackThread,
|
2024-03-29 14:48:36 +00:00
|
|
|
if !appHub.input.command("quit") {
|
2024-03-31 23:00:19 +00:00
|
|
|
appHub.log.warning("Could not properly shut down mpv")
|
|
|
|
exit(1)
|
2024-03-29 14:48:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-30 18:26:45 +00:00
|
|
|
func setupBundle() {
|
2024-03-31 23:00:19 +00:00
|
|
|
if !isBundle { return }
|
|
|
|
|
2024-03-30 18:26:45 +00:00
|
|
|
// started from finder the first argument after the binary may start with -psn_
|
|
|
|
if CommandLine.argc > 1 && CommandLine.arguments[1].hasPrefix("-psn_") {
|
|
|
|
argc? = 1
|
|
|
|
argv?[1] = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
let path = (ProcessInfo.processInfo.environment["PATH"] ?? "") +
|
|
|
|
":/usr/local/bin:/usr/local/sbin:/opt/local/bin:/opt/local/sbin"
|
2024-03-31 23:30:48 +00:00
|
|
|
appHub.log.verbose("Setting Bundle $PATH to: \(path)")
|
2024-03-30 18:26:45 +00:00
|
|
|
_ = path.withCString { setenv("PATH", $0, 1) }
|
|
|
|
}
|
|
|
|
|
|
|
|
let playbackThread: @convention(c) (UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? = { (ptr: UnsafeMutableRawPointer) in
|
|
|
|
let application: Application = TypeHelper.bridge(ptr: ptr)
|
|
|
|
mp_thread_set_name("core/playback")
|
2024-03-31 23:00:19 +00:00
|
|
|
let exitCode: Int32 = mpv_main(application.argc ?? 1, application.argv)
|
|
|
|
// exit of any proper shut down
|
|
|
|
exit(exitCode)
|
2024-03-30 18:26:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@objc func main(_ argc: Int32, _ argv: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>) -> Int {
|
|
|
|
self.argc = argc
|
|
|
|
self.argv = argv
|
|
|
|
|
2024-03-31 23:00:19 +00:00
|
|
|
NSApp = self
|
|
|
|
NSApp.delegate = self
|
|
|
|
NSApp.setActivationPolicy(isBundle ? .regular : .accessory)
|
|
|
|
setupBundle()
|
2024-03-30 18:26:45 +00:00
|
|
|
pthread_create(&playbackThreadId, nil, playbackThread, TypeHelper.bridge(obj: self))
|
|
|
|
appHub.input.wait()
|
|
|
|
NSApp.run()
|
|
|
|
|
2024-03-31 23:00:19 +00:00
|
|
|
// should never be reached
|
2024-03-30 18:26:45 +00:00
|
|
|
print("""
|
|
|
|
There was either a problem initializing Cocoa or the Runloop was stopped unexpectedly. \
|
|
|
|
Please report this issues to a developer.\n
|
|
|
|
""")
|
|
|
|
pthread_join(playbackThreadId, nil)
|
|
|
|
return 1
|
|
|
|
}
|
2024-03-29 14:48:36 +00:00
|
|
|
}
|