mirror of https://github.com/mpv-player/mpv
cocoa: decouple events from application somewhat
This commit is contained in:
parent
ff6c387a73
commit
78a266d599
|
@ -23,16 +23,20 @@
|
|||
#include "common/msg.h"
|
||||
#include "input/input.h"
|
||||
#include "input/event.h"
|
||||
#include "input/keycodes.h"
|
||||
|
||||
#include "osdep/macosx_application_objc.h"
|
||||
#import "osdep/macosx_application_objc.h"
|
||||
#include "osdep/macosx_compat.h"
|
||||
#import "osdep/macosx_events_objc.h"
|
||||
|
||||
#define MPV_PROTOCOL @"mpv://"
|
||||
|
||||
static pthread_t playback_thread_id;
|
||||
|
||||
@interface Application (PrivateMethods)
|
||||
@interface Application ()
|
||||
{
|
||||
EventsResponder *_eventsResponder;
|
||||
}
|
||||
|
||||
- (NSMenuItem *)menuItemWithParent:(NSMenu *)parent
|
||||
title:(NSString *)title
|
||||
action:(SEL)selector
|
||||
|
@ -61,17 +65,14 @@ Application *mpv_shared_app(void)
|
|||
@synthesize argumentsList = _arguments_list;
|
||||
@synthesize willStopOnOpenEvent = _will_stop_on_open_event;
|
||||
|
||||
@synthesize inputContext = _input_context;
|
||||
@synthesize eventsResponder = _events_responder;
|
||||
@synthesize menuItems = _menu_items;
|
||||
@synthesize input_ready = _input_ready;
|
||||
|
||||
- (void)sendEvent:(NSEvent *)event
|
||||
{
|
||||
[super sendEvent:event];
|
||||
|
||||
if (self.inputContext)
|
||||
mp_input_wakeup(self.inputContext);
|
||||
if (_eventsResponder.inputContext)
|
||||
mp_input_wakeup(_eventsResponder.inputContext);
|
||||
}
|
||||
|
||||
- (id)init
|
||||
|
@ -80,19 +81,8 @@ Application *mpv_shared_app(void)
|
|||
self.menuItems = [[[NSMutableDictionary alloc] init] autorelease];
|
||||
self.files = nil;
|
||||
self.argumentsList = [[[NSMutableArray alloc] init] autorelease];
|
||||
self.eventsResponder = [[[EventsResponder alloc] init] autorelease];
|
||||
_eventsResponder = [EventsResponder sharedInstance];
|
||||
self.willStopOnOpenEvent = NO;
|
||||
self.input_ready = [[[NSCondition alloc] init] autorelease];
|
||||
|
||||
[NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask|NSKeyUpMask
|
||||
handler:^(NSEvent *event) {
|
||||
BOOL equivalent = [[NSApp mainMenu] performKeyEquivalent:event];
|
||||
if (equivalent) {
|
||||
return (NSEvent *)nil;
|
||||
} else {
|
||||
return [self.eventsResponder handleKey:event];
|
||||
}
|
||||
}];
|
||||
|
||||
NSAppleEventManager *em = [NSAppleEventManager sharedAppleEventManager];
|
||||
[em setEventHandler:self
|
||||
|
@ -174,9 +164,10 @@ Application *mpv_shared_app(void)
|
|||
|
||||
- (void)stopMPV:(char *)cmd
|
||||
{
|
||||
if (self.inputContext) {
|
||||
mp_cmd_t *cmdt = mp_input_parse_cmd(self.inputContext, bstr0(cmd), "");
|
||||
mp_input_queue_cmd(self.inputContext, cmdt);
|
||||
struct input_ctx *inputContext = _eventsResponder.inputContext;
|
||||
if (inputContext) {
|
||||
mp_cmd_t *cmdt = mp_input_parse_cmd(inputContext, bstr0(cmd), "");
|
||||
mp_input_queue_cmd(inputContext, cmdt);
|
||||
} else {
|
||||
terminate_cocoa_application();
|
||||
}
|
||||
|
@ -289,7 +280,7 @@ Application *mpv_shared_app(void)
|
|||
size_t bytes = [obj lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
files_utf8[i] = talloc_memdup(files_utf8, filename, bytes + 1);
|
||||
}];
|
||||
mp_event_drop_files(self.inputContext, num_files, files_utf8);
|
||||
mp_event_drop_files(_eventsResponder.inputContext, num_files, files_utf8);
|
||||
talloc_free(files_utf8);
|
||||
}
|
||||
|
||||
|
@ -327,10 +318,10 @@ int cocoa_main(mpv_main_fn mpv_main, int argc, char *argv[])
|
|||
macosx_finder_args_preinit(&argc, &argv);
|
||||
pthread_create(&playback_thread_id, NULL, playback_thread, &ctx);
|
||||
|
||||
[mpv_shared_app().input_ready lock];
|
||||
while (!mpv_shared_app().inputContext)
|
||||
[mpv_shared_app().input_ready wait];
|
||||
[mpv_shared_app().input_ready unlock];
|
||||
[_eventsResponder.input_ready lock];
|
||||
while (!_eventsResponder.inputContext)
|
||||
[_eventsResponder.input_ready wait];
|
||||
[_eventsResponder.input_ready unlock];
|
||||
|
||||
cocoa_run_runloop();
|
||||
|
||||
|
@ -387,10 +378,10 @@ void cocoa_stop_runloop(void)
|
|||
|
||||
void cocoa_set_input_context(struct input_ctx *input_context)
|
||||
{
|
||||
[mpv_shared_app().input_ready lock];
|
||||
mpv_shared_app().inputContext = input_context;
|
||||
[mpv_shared_app().input_ready signal];
|
||||
[mpv_shared_app().input_ready unlock];
|
||||
[_eventsResponder.input_ready lock];
|
||||
_eventsResponder.inputContext = input_context;
|
||||
[_eventsResponder.input_ready signal];
|
||||
[_eventsResponder.input_ready unlock];
|
||||
}
|
||||
|
||||
void cocoa_post_fake_event(void)
|
||||
|
|
|
@ -18,19 +18,6 @@
|
|||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#include "osdep/macosx_application.h"
|
||||
#import "ar/HIDRemote.h"
|
||||
|
||||
@interface EventsResponder : NSObject <HIDRemoteDelegate>
|
||||
- (BOOL)handleMediaKey:(NSEvent *)event;
|
||||
- (NSEvent *)handleKey:(NSEvent *)event;
|
||||
- (void)startAppleRemote;
|
||||
- (void)stopAppleRemote;
|
||||
- (void)startMediaKeys;
|
||||
- (void)restartMediaKeys;
|
||||
- (void)stopMediaKeys;
|
||||
- (int)mapKeyModifiers:(int)cocoaModifiers;
|
||||
- (int)keyModifierMask:(NSEvent *)event;
|
||||
@end
|
||||
|
||||
@interface Application : NSApplication
|
||||
- (void)initialize_menu;
|
||||
|
@ -38,13 +25,10 @@
|
|||
- (void)stopPlayback;
|
||||
- (void)handleFilesArray:(NSArray *)files;
|
||||
|
||||
@property(nonatomic, assign) struct input_ctx *inputContext;
|
||||
@property(nonatomic, retain) EventsResponder *eventsResponder;
|
||||
@property(nonatomic, retain) NSMutableDictionary *menuItems;
|
||||
@property(nonatomic, retain) NSArray *files;
|
||||
@property(nonatomic, retain) NSMutableArray *argumentsList;
|
||||
@property(nonatomic, assign) BOOL willStopOnOpenEvent;
|
||||
@property(nonatomic, retain) NSCondition *input_ready;
|
||||
@end
|
||||
|
||||
Application *mpv_shared_app(void);
|
||||
|
|
|
@ -27,12 +27,30 @@
|
|||
|
||||
#include "talloc.h"
|
||||
#include "input/input.h"
|
||||
#include "input/keycodes.h"
|
||||
// doesn't make much sense, but needed to access keymap functionality
|
||||
#include "video/out/vo.h"
|
||||
|
||||
#import "osdep/macosx_application_objc.h"
|
||||
#include "osdep/macosx_events.h"
|
||||
#include "osdep/macosx_compat.h"
|
||||
#import "osdep/macosx_events_objc.h"
|
||||
|
||||
@interface EventsResponder ()
|
||||
{
|
||||
CFMachPortRef _mk_tap_port;
|
||||
HIDRemote *_remote;
|
||||
}
|
||||
|
||||
- (BOOL)handleMediaKey:(NSEvent *)event;
|
||||
- (NSEvent *)handleKey:(NSEvent *)event;
|
||||
- (void)startAppleRemote;
|
||||
- (void)stopAppleRemote;
|
||||
- (void)startMediaKeys;
|
||||
- (void)restartMediaKeys;
|
||||
- (void)stopMediaKeys;
|
||||
- (int)mapKeyModifiers:(int)cocoaModifiers;
|
||||
- (int)keyModifierMask:(NSEvent *)event;
|
||||
@end
|
||||
|
||||
|
||||
#define NSLeftAlternateKeyMask (0x000020 | NSAlternateKeyMask)
|
||||
#define NSRightAlternateKeyMask (0x000040 | NSAlternateKeyMask)
|
||||
|
@ -93,14 +111,12 @@ static int convert_key(unsigned key, unsigned charcode)
|
|||
|
||||
void cocoa_init_apple_remote(void)
|
||||
{
|
||||
Application *app = mpv_shared_app();
|
||||
[app.eventsResponder startAppleRemote];
|
||||
[[EventsResponder sharedInstance] startAppleRemote];
|
||||
}
|
||||
|
||||
void cocoa_uninit_apple_remote(void)
|
||||
{
|
||||
Application *app = mpv_shared_app();
|
||||
[app.eventsResponder stopAppleRemote];
|
||||
[[EventsResponder sharedInstance] stopAppleRemote];
|
||||
}
|
||||
|
||||
static int mk_code(NSEvent *event)
|
||||
|
@ -150,34 +166,64 @@ static CGEventRef tap_event_callback(CGEventTapProxy proxy, CGEventType type,
|
|||
}
|
||||
|
||||
void cocoa_init_media_keys(void) {
|
||||
[mpv_shared_app().eventsResponder startMediaKeys];
|
||||
[[EventsResponder sharedInstance] startMediaKeys];
|
||||
}
|
||||
|
||||
void cocoa_uninit_media_keys(void) {
|
||||
[mpv_shared_app().eventsResponder stopMediaKeys];
|
||||
[[EventsResponder sharedInstance] stopMediaKeys];
|
||||
}
|
||||
|
||||
void cocoa_put_key(int keycode)
|
||||
{
|
||||
if (mpv_shared_app().inputContext)
|
||||
mp_input_put_key(mpv_shared_app().inputContext, keycode);
|
||||
struct input_ctx *inputContext = [EventsResponder sharedInstance].inputContext;
|
||||
if (inputContext)
|
||||
mp_input_put_key(inputContext, keycode);
|
||||
}
|
||||
|
||||
void cocoa_put_key_with_modifiers(int keycode, int modifiers)
|
||||
{
|
||||
keycode |= [mpv_shared_app().eventsResponder mapKeyModifiers:modifiers];
|
||||
keycode |= [[EventsResponder sharedInstance] mapKeyModifiers:modifiers];
|
||||
cocoa_put_key(keycode);
|
||||
}
|
||||
|
||||
@implementation EventsResponder {
|
||||
CFMachPortRef _mk_tap_port;
|
||||
HIDRemote *_remote;
|
||||
@implementation EventsResponder
|
||||
|
||||
@synthesize inputContext = _input_context;
|
||||
@synthesize input_ready = _input_ready;
|
||||
|
||||
+ (EventsResponder *)sharedInstance
|
||||
{
|
||||
static EventsResponder *responder = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
responder = [EventsResponder new];
|
||||
});
|
||||
return responder;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_input_ready = [NSCondition new];
|
||||
|
||||
[NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask|NSKeyUpMask
|
||||
handler:^(NSEvent *event) {
|
||||
BOOL equivalent = [[NSApp mainMenu] performKeyEquivalent:event];
|
||||
if (equivalent) {
|
||||
return (NSEvent *)nil;
|
||||
} else {
|
||||
return [self handleKey:event];
|
||||
}
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)useAltGr
|
||||
{
|
||||
if (mpv_shared_app().inputContext)
|
||||
return mp_input_use_alt_gr(mpv_shared_app().inputContext);
|
||||
if (self.inputContext)
|
||||
return mp_input_use_alt_gr(self.inputContext);
|
||||
else
|
||||
return YES;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Cocoa Application Event Handling
|
||||
*
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "ar/HIDRemote.h"
|
||||
#include "osdep/macosx_events.h"
|
||||
|
||||
struct input_ctx;
|
||||
|
||||
@interface EventsResponder : NSObject <HIDRemoteDelegate>
|
||||
|
||||
+ (EventsResponder *)sharedInstance;
|
||||
|
||||
@property(nonatomic, assign) struct input_ctx *inputContext;
|
||||
@property(nonatomic, retain) NSCondition *input_ready;
|
||||
|
||||
@end
|
Loading…
Reference in New Issue