mirror of
https://github.com/mpv-player/mpv
synced 2025-03-19 18:05:21 +00:00
mac/helper: move input ctx related functionality into new input helper
also make functions thread safe.
This commit is contained in:
parent
f3e5fea4f5
commit
055e9cd93e
@ -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
|
||||
|
@ -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<Int8>(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<CChar>(strdup($0)) }
|
||||
mp_event_drop_files(input, Int32(files.count), &filesPtr, action)
|
||||
for charPtr in filesPtr { free(UnsafeMutablePointer(mutating: charPtr)) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<vo>
|
||||
var optsCachePtr: UnsafeMutablePointer<m_config_cache>
|
||||
@ -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<vo>, _ log: LogHelper) {
|
||||
self.vo = vo
|
||||
self.log = log
|
||||
@ -54,41 +52,10 @@ class MPVHelper {
|
||||
macOptsPtr = UnsafeMutablePointer<macos_opts>(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<CChar>(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<Int8>(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<T: AnyObject>(obj: T) -> UnsafeMutableRawPointer {
|
||||
return UnsafeMutableRawPointer(Unmanaged.passUnretained(obj).toOpaque())
|
||||
|
@ -40,6 +40,7 @@ class CocoaCB: Common {
|
||||
|
||||
func preinit(_ vo: UnsafeMutablePointer<vo>) {
|
||||
mpv = MPVHelper(vo, log)
|
||||
input = InputHelper(vo.pointee.input_ctx, mpv)
|
||||
|
||||
if backendState == .uninitialized {
|
||||
backendState = .needsInit
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user