diff --git a/osdep/mac/events.m b/osdep/mac/events.m index f7e7bb6ba3..1c2928d89d 100644 --- a/osdep/mac/events.m +++ b/osdep/mac/events.m @@ -44,10 +44,8 @@ @interface EventsResponder () { - struct input_ctx *_inputContext; struct mpv_handle *_ctx; BOOL _is_application; - NSCondition *_input_lock; } - (NSEvent *)handleKey:(NSEvent *)event; @@ -183,20 +181,11 @@ void cocoa_init_cocoa_cb(void) static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ responder = [EventsResponder new]; - responder.inputHelper = [[InputHelper alloc] init: nil]; + responder.inputHelper = [[InputHelper alloc] init: nil :nil]; }); return responder; } -- (id)init -{ - self = [super init]; - if (self) { - _input_lock = [NSCondition new]; - } - return self; -} - - (void)waitForInputContext { [_inputHelper wait]; @@ -382,23 +371,7 @@ void cocoa_init_cocoa_cb(void) - (void)handleFilesArray:(NSArray *)files { - enum mp_dnd_action action = [NSEvent modifierFlags] & - NSEventModifierFlagShift ? DND_APPEND : DND_REPLACE; - - size_t num_files = [files count]; - char **files_utf8 = talloc_array(NULL, char*, num_files); - [files enumerateObjectsUsingBlock:^(NSString *p, NSUInteger i, BOOL *_){ - if ([p hasPrefix:@"file:///.file/id="]) - p = [[NSURL URLWithString:p] path]; - char *filename = (char *)[p UTF8String]; - size_t bytes = [p lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - files_utf8[i] = talloc_memdup(files_utf8, filename, bytes + 1); - }]; - [_input_lock lock]; - if (_inputContext) - mp_event_drop_files(_inputContext, num_files, files_utf8, action); - [_input_lock unlock]; - talloc_free(files_utf8); + [_inputHelper openWithFiles:files]; } @end diff --git a/osdep/mac/input_helper.swift b/osdep/mac/input_helper.swift index 396205fa77..f2e046042c 100644 --- a/osdep/mac/input_helper.swift +++ b/osdep/mac/input_helper.swift @@ -16,15 +16,52 @@ */ class InputHelper: NSObject { + var mpv: MPVHelper? var lock = NSCondition() private var input: OpaquePointer? - @objc init(_ input: OpaquePointer? = nil) { + @objc init(_ input: OpaquePointer? = nil, _ mpv: MPVHelper? = nil) { super.init() self.input = input + self.mpv = mpv } - @objc func command(_ cmd: String) -> Bool { + @objc func putKey(_ key: Int32) { + lock.withLock { + guard let input = input else { return } + mp_input_put_key(input, key) + } + } + + func draggable(at pos: NSPoint) -> Bool { + lock.withLock { + guard let input = input else { return false } + return !mp_input_test_dragging(input, Int32(pos.x), Int32(pos.y)) + } + } + + func mouseEnabled() -> Bool { + lock.withLock { + guard let input = input else { return true } + return mp_input_mouse_enabled(input) + } + } + + func setMouse(position pos: NSPoint) { + lock.withLock { + guard let input = input else { return } + mp_input_set_mouse_pos(input, Int32(pos.x), Int32(pos.y)) + } + } + + func putAxis(_ mpkey: Int32, modifiers: NSEvent.ModifierFlags, delta: Double) { + lock.withLock { + guard let input = input else { return } + mp_input_put_wheel(input, mpkey | mapModifier(modifiers), delta) + } + } + + @discardableResult @objc func command(_ cmd: String) -> Bool { lock.withLock { guard let input = input else { return false } let cCmd = UnsafePointer(strdup(cmd)) @@ -35,10 +72,42 @@ class InputHelper: NSObject { } } - @objc func putKey(_ key: Int32) { + private func mapModifier(_ modifiers: NSEvent.ModifierFlags) -> Int32 { + var mask: UInt32 = 0; + guard let input = input else { return Int32(mask) } + + if modifiers.contains(.shift) { + mask |= MP_KEY_MODIFIER_SHIFT + } + if modifiers.contains(.control) { + mask |= MP_KEY_MODIFIER_CTRL + } + if modifiers.contains(.command) { + mask |= MP_KEY_MODIFIER_META + } + if modifiers.rawValue & UInt(NX_DEVICELALTKEYMASK) != 0 || + modifiers.rawValue & UInt(NX_DEVICERALTKEYMASK) != 0 && !mp_input_use_alt_gr(input) + { + mask |= MP_KEY_MODIFIER_ALT + } + + return Int32(mask) + } + + @objc func open(files: [String]) { lock.withLock { guard let input = input else { return } - mp_input_put_key(input, key) + if (mpv?.opts.drag_and_drop ?? -1) == -2 { return } + + var action = NSEvent.modifierFlags.contains(.shift) ? DND_APPEND : DND_REPLACE + if (mpv?.opts.drag_and_drop ?? -1) >= 0 { + action = mp_dnd_action(UInt32(mpv?.opts.drag_and_drop ?? Int32(DND_REPLACE.rawValue))) + } + + let filesClean = files.map{ $0.hasPrefix("file:///.file/id=") ? (URL(string: $0)?.path ?? $0) : $0 } + var filesPtr = filesClean.map { UnsafeMutablePointer(strdup($0)) } + mp_event_drop_files(input, Int32(files.count), &filesPtr, action) + for charPtr in filesPtr { free(UnsafeMutablePointer(mutating: charPtr)) } } } diff --git a/osdep/mac/mpv_helper.swift b/osdep/mac/mpv_helper.swift index 53ef4cb521..084fed48da 100644 --- a/osdep/mac/mpv_helper.swift +++ b/osdep/mac/mpv_helper.swift @@ -19,7 +19,7 @@ import Cocoa typealias swift_wakeup_cb_fn = (@convention(c) (UnsafeMutableRawPointer?) -> Void)? -class MPVHelper { +class MPVHelper: NSObject { var log: LogHelper var vo: UnsafeMutablePointer var optsCachePtr: UnsafeMutablePointer @@ -36,8 +36,6 @@ class MPVHelper { var macOptsCache: m_config_cache { get { return macOptsCachePtr.pointee } } var macOpts: macos_opts { get { return macOptsPtr.pointee } } - var input: OpaquePointer { get { return vout.input_ctx } } - init(_ vo: UnsafeMutablePointer, _ log: LogHelper) { self.vo = vo self.log = log @@ -54,41 +52,10 @@ class MPVHelper { macOptsPtr = UnsafeMutablePointer(OpaquePointer(macCache.pointee.opts)) } - func canBeDraggedAt(_ pos: NSPoint) -> Bool { - let canDrag = !mp_input_test_dragging(input, Int32(pos.x), Int32(pos.y)) - return canDrag - } - - func mouseEnabled() -> Bool { - return mp_input_mouse_enabled(input) - } - - func setMousePosition(_ pos: NSPoint) { - mp_input_set_mouse_pos(input, Int32(pos.x), Int32(pos.y)) - } - - func putAxis(_ mpkey: Int32, modifiers: NSEvent.ModifierFlags, delta: Double) { - mp_input_put_wheel(input, mpkey | mapModifier(modifiers), delta) - } - func nextChangedOption(property: inout UnsafeMutableRawPointer?) -> Bool { return m_config_cache_get_next_changed(optsCachePtr, &property) } - func open(files: [String]) { - if opts.drag_and_drop == -2 { return } - - var action = NSEvent.modifierFlags.contains(.shift) ? DND_APPEND : DND_REPLACE - if opts.drag_and_drop >= 0 { - action = mp_dnd_action(UInt32(opts.drag_and_drop)) - } - - let filesClean = files.map{ $0.hasPrefix("file:///.file/id=") ? (URL(string: $0)?.path ?? $0) : $0 } - var filesPtr = filesClean.map { UnsafeMutablePointer(strdup($0)) } - mp_event_drop_files(input, Int32(files.count), &filesPtr, action) - for charPtr in filesPtr { free(UnsafeMutablePointer(mutating: charPtr)) } - } - func setOption(fullscreen: Bool) { optsPtr.pointee.fullscreen = fullscreen _ = withUnsafeMutableBytes(of: &optsPtr.pointee.fullscreen) { (ptr: UnsafeMutableRawBufferPointer) in @@ -118,34 +85,6 @@ class MPVHelper { return m_config_cache_get_next_changed(macOptsCachePtr, &property) } - func command(_ cmd: String) { - let cCmd = UnsafePointer(strdup(cmd)) - let mpvCmd = mp_input_parse_cmd(input, bstr0(cCmd), "") - mp_input_queue_cmd(input, mpvCmd) - free(UnsafeMutablePointer(mutating: cCmd)) - } - - func mapModifier(_ modifiers: NSEvent.ModifierFlags) -> Int32 { - var mask: UInt32 = 0; - - if modifiers.contains(.shift) { - mask |= MP_KEY_MODIFIER_SHIFT - } - if modifiers.contains(.control) { - mask |= MP_KEY_MODIFIER_CTRL - } - if modifiers.contains(.command) { - mask |= MP_KEY_MODIFIER_META - } - if modifiers.rawValue & UInt(NX_DEVICELALTKEYMASK) != 0 || - modifiers.rawValue & UInt(NX_DEVICERALTKEYMASK) != 0 && !mp_input_use_alt_gr(input) - { - mask |= MP_KEY_MODIFIER_ALT - } - - return Int32(mask) - } - // (__bridge void*) class func bridge(obj: T) -> UnsafeMutableRawPointer { return UnsafeMutableRawPointer(Unmanaged.passUnretained(obj).toOpaque()) diff --git a/video/out/cocoa_cb_common.swift b/video/out/cocoa_cb_common.swift index 2b260a2999..46e999fbb2 100644 --- a/video/out/cocoa_cb_common.swift +++ b/video/out/cocoa_cb_common.swift @@ -40,6 +40,7 @@ class CocoaCB: Common { func preinit(_ vo: UnsafeMutablePointer) { mpv = MPVHelper(vo, log) + input = InputHelper(vo.pointee.input_ctx, mpv) if backendState == .uninitialized { backendState = .needsInit diff --git a/video/out/mac/common.swift b/video/out/mac/common.swift index 5790d3b844..e0ea5f1164 100644 --- a/video/out/mac/common.swift +++ b/video/out/mac/common.swift @@ -20,6 +20,7 @@ import IOKit.pwr_mgt class Common: NSObject { var mpv: MPVHelper? + var input: InputHelper? var log: LogHelper let queue: DispatchQueue = DispatchQueue(label: "io.mpv.queue") diff --git a/video/out/mac/view.swift b/video/out/mac/view.swift index 89a2bc88ea..433284188c 100644 --- a/video/out/mac/view.swift +++ b/video/out/mac/view.swift @@ -20,6 +20,7 @@ import Cocoa class View: NSView, CALayerDelegate { unowned var common: Common var mpv: MPVHelper? { get { return common.mpv } } + var input: InputHelper? { get { return common.input } } var tracker: NSTrackingArea? var hasMouseDown: Bool = false @@ -81,7 +82,7 @@ class View: NSView, CALayerDelegate { if types.contains(.fileURL) || types.contains(.URL) { if let urls = pb.readObjects(forClasses: [NSURL.self]) as? [URL] { let files = urls.map { $0.absoluteString } - mpv?.open(files: files) + input?.open(files: files) return true } } else if types.contains(.string) { @@ -97,7 +98,7 @@ class View: NSView, CALayerDelegate { filesArray.append(path) } } - mpv?.open(files: filesArray) + input?.open(files: filesArray) return true } return false @@ -116,14 +117,14 @@ class View: NSView, CALayerDelegate { } override func mouseEntered(with event: NSEvent) { - if mpv?.mouseEnabled() ?? true { + if input?.mouseEnabled() ?? true { cocoa_put_key_with_modifiers(SWIFT_KEY_MOUSE_ENTER, 0) } common.updateCursorVisibility() } override func mouseExited(with event: NSEvent) { - if mpv?.mouseEnabled() ?? true { + if input?.mouseEnabled() ?? true { cocoa_put_key_with_modifiers(SWIFT_KEY_MOUSE_LEAVE, 0) } common.titleBar?.hide() @@ -131,51 +132,51 @@ class View: NSView, CALayerDelegate { } override func mouseMoved(with event: NSEvent) { - if mpv?.mouseEnabled() ?? true { + if input?.mouseEnabled() ?? true { signalMouseMovement(event) } common.titleBar?.show() } override func mouseDragged(with event: NSEvent) { - if mpv?.mouseEnabled() ?? true { + if input?.mouseEnabled() ?? true { signalMouseMovement(event) } } override func mouseDown(with event: NSEvent) { - if mpv?.mouseEnabled() ?? true { + if input?.mouseEnabled() ?? true { signalMouseDown(event) } } override func mouseUp(with event: NSEvent) { - if mpv?.mouseEnabled() ?? true { + if input?.mouseEnabled() ?? true { signalMouseUp(event) } common.window?.isMoving = false } override func rightMouseDown(with event: NSEvent) { - if mpv?.mouseEnabled() ?? true { + if input?.mouseEnabled() ?? true { signalMouseDown(event) } } override func rightMouseUp(with event: NSEvent) { - if mpv?.mouseEnabled() ?? true { + if input?.mouseEnabled() ?? true { signalMouseUp(event) } } override func otherMouseDown(with event: NSEvent) { - if mpv?.mouseEnabled() ?? true { + if input?.mouseEnabled() ?? true { signalMouseDown(event) } } override func otherMouseUp(with event: NSEvent) { - if mpv?.mouseEnabled() ?? true { + if input?.mouseEnabled() ?? true { signalMouseUp(event) } } @@ -211,7 +212,7 @@ class View: NSView, CALayerDelegate { common.window?.updateMovableBackground(point) if !(common.window?.isMoving ?? false) { - mpv?.setMousePosition(point) + input?.setMouse(position: point) } } @@ -227,11 +228,11 @@ class View: NSView, CALayerDelegate { cmd = delta > 0 ? SWIFT_WHEEL_LEFT : SWIFT_WHEEL_RIGHT } - mpv?.putAxis(cmd, modifiers: event.modifierFlags, delta: abs(delta)) + input?.putAxis(cmd, modifiers: event.modifierFlags, delta: abs(delta)) } override func scrollWheel(with event: NSEvent) { - if !(mpv?.mouseEnabled() ?? true) { + if !(input?.mouseEnabled() ?? true) { return } diff --git a/video/out/mac/window.swift b/video/out/mac/window.swift index 1fbb2374ec..26c0a44d83 100644 --- a/video/out/mac/window.swift +++ b/video/out/mac/window.swift @@ -20,6 +20,7 @@ import Cocoa class Window: NSWindow, NSWindowDelegate { weak var common: Common! = nil var mpv: MPVHelper? { get { return common.mpv } } + var input: InputHelper? { get { return common.input } } var targetScreen: NSScreen? var previousScreen: NSScreen? @@ -335,7 +336,7 @@ class Window: NSWindow, NSWindowDelegate { func updateMovableBackground(_ pos: NSPoint) { if !isInFullscreen { - isMovableByWindowBackground = mpv?.canBeDraggedAt(pos) ?? true + isMovableByWindowBackground = input?.draggable(at: pos) ?? true } else { isMovableByWindowBackground = false } @@ -503,12 +504,12 @@ class Window: NSWindow, NSWindowDelegate { @objc func setDoubleWindowSize() { setWindowScale(2.0) } func setWindowScale(_ scale: Double) { - mpv?.command("set window-scale \(scale)") + input?.command("set window-scale \(scale)") } func addWindowScale(_ scale: Double) { if !isInFullscreen { - mpv?.command("add window-scale \(scale)") + input?.command("add window-scale \(scale)") } } diff --git a/video/out/mac_common.swift b/video/out/mac_common.swift index f7b07596d3..00328ccad1 100644 --- a/video/out/mac_common.swift +++ b/video/out/mac_common.swift @@ -28,6 +28,7 @@ class MacCommon: Common { let newlog = mp_log_new(vo, vo.pointee.log, "mac") super.init(newlog) mpv = MPVHelper(vo, log) + input = InputHelper(vo.pointee.input_ctx, mpv) timer = PreciseTimer(common: self) DispatchQueue.main.sync {