From c2eca2e4b7320324c1c1d78d432dc6358fa860c2 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 12 Oct 2014 00:17:48 +0200 Subject: libmpv/cocoa: allow clients to use mpv event system This allows mpv's view to take key and send events to mpv's core. To set key status correctly, clients must call -[NSWindow selectNextKeyView:] during reconfig on the main thread. All is 'documented' in the cocoabasic example. If someone knows a better way to handle giving key to the embedded view, let me know! --- DOCS/client_api_examples/cocoabasic.m | 37 +++++++++++++++++-------- video/out/cocoa/events_view.m | 1 + video/out/cocoa_common.m | 52 ++++++++++++++++++----------------- 3 files changed, 54 insertions(+), 36 deletions(-) diff --git a/DOCS/client_api_examples/cocoabasic.m b/DOCS/client_api_examples/cocoabasic.m index 35637f0a9f..8235f4b323 100644 --- a/DOCS/client_api_examples/cocoabasic.m +++ b/DOCS/client_api_examples/cocoabasic.m @@ -45,6 +45,7 @@ static void wakeup(void *); defer:NO]; [self->w setTitle:@"cocoabasic example"]; + [self->w makeMainWindow]; [self->w makeKeyAndOrderFront:nil]; [NSApp activateIgnoringOtherApps:YES]; } @@ -92,6 +93,10 @@ static void wakeup(void *); // for testing! check_error(mpv_set_option_string(mpv, "input-media-keys", "yes")); + check_error(mpv_set_option_string(mpv, "input-vo-keyboard", "yes")); + + // request important errors + check_error(mpv_request_log_messages(mpv, "warn")); check_error(mpv_initialize(mpv)); @@ -107,17 +112,27 @@ static void wakeup(void *); - (void) handleEvent:(mpv_event *)event { switch (event->event_id) { - case MPV_EVENT_SHUTDOWN: - // Clean up and shut down. - mpv_terminate_destroy(mpv); - mpv = NULL; - dispatch_async(dispatch_get_main_queue(), ^{ - [[NSApplication sharedApplication] terminate:nil]; - }); - break; - - default: - printf("event: %s\n", mpv_event_name(event->event_id)); + case MPV_EVENT_SHUTDOWN: + // Clean up and shut down. + mpv_terminate_destroy(mpv); + mpv = NULL; + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSApplication sharedApplication] terminate:nil]; + }); + break; + + case MPV_EVENT_LOG_MESSAGE: { + struct mpv_event_log_message *msg = (struct mpv_event_log_message *)event->data; + printf("[%s] %s: %s", msg->prefix, msg->level, msg->text); + } + + case MPV_EVENT_VIDEO_RECONFIG: + dispatch_async(dispatch_get_main_queue(), ^{ + [self->w selectNextKeyView:nil]; + }); + + default: + printf("event: %s\n", mpv_event_name(event->event_id)); } } diff --git a/video/out/cocoa/events_view.m b/video/out/cocoa/events_view.m index cbc7223098..fd088cb5e6 100644 --- a/video/out/cocoa/events_view.m +++ b/video/out/cocoa/events_view.m @@ -43,6 +43,7 @@ if (self) { [self registerForDraggedTypes:@[NSFilenamesPboardType, NSURLPboardType]]; + [self setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; } return self; } diff --git a/video/out/cocoa_common.m b/video/out/cocoa_common.m index ec0a61055b..537388ffd9 100644 --- a/video/out/cocoa_common.m +++ b/video/out/cocoa_common.m @@ -183,14 +183,8 @@ void vo_cocoa_uninit(struct vo *vo) cocoa_rm_fs_screen_profile_observer(vo); [s->video release]; - - if (!s->embedded) { - if ([s->view isInFullScreenMode]) - [[s->view window] release]; - - [s->window release]; - s->window = nil; - } + [s->view release]; + [s->window release]; }); } @@ -307,22 +301,27 @@ static void create_ui(struct vo *vo, struct mp_rect *win, int geo_flags) struct mp_vo_opts *opts = vo->opts; MpvCocoaAdapter *adapter = [[[MpvCocoaAdapter alloc] init] autorelease]; - const NSRect contentRect = - NSMakeRect(win->x0, win->y0, win->x1 - win->x0, win->y1 - win->y0); adapter.vout = vo; + NSView *parent; if (s->embedded) { - s->view = (NSView *) (intptr_t) opts->WinID; + parent = (NSView *) (intptr_t) opts->WinID; } else { - s->window = create_window(contentRect, s->current_screen, - opts->border, adapter); - - MpvEventsView *view = [[MpvEventsView alloc] initWithFrame:contentRect]; - [view autorelease]; - view.adapter = adapter; - s->view = view; + const NSRect wr = + NSMakeRect(win->x0, win->y0, win->x1 - win->x0, win->y1 - win->y0); + s->window = create_window(wr, s->current_screen, opts->border, adapter); + parent = [s->window contentView]; } + MpvEventsView *view = [[MpvEventsView alloc] initWithFrame:[parent bounds]]; + view.adapter = adapter; + s->view = view; + [parent addSubview:s->view]; + + // insert ourselves as the next key view so that clients can give key + // focus to the mpv view by calling -[NSWindow selectNextKeyView:] + [parent setNextKeyView:s->view]; + #if HAVE_COCOA_APPLICATION cocoa_register_menu_item_action(MPM_H_SIZE, @selector(halfSize)); cocoa_register_menu_item_action(MPM_N_SIZE, @selector(normalSize)); @@ -335,8 +334,6 @@ static void create_ui(struct vo *vo, struct mp_rect *win, int geo_flags) [s->video setWantsBestResolutionOpenGLSurface:YES]; [s->view addSubview:s->video]; - [s->view setAutoresizesSubviews:YES]; - [s->window setContentView:s->view]; [s->gl_ctx setView:s->video]; s->video.adapter = adapter; @@ -715,23 +712,28 @@ void *vo_cocoa_cgl_pixel_format(struct vo *vo) } - (void)signalMouseMovement:(NSPoint)point { - mp_input_set_mouse_pos(self.vout->input_ctx, point.x, point.y); - [self recalcMovableByWindowBackground:point]; + if (mp_input_mouse_enabled(self.vout->input_ctx)) { + mp_input_set_mouse_pos(self.vout->input_ctx, point.x, point.y); + [self recalcMovableByWindowBackground:point]; + } } - (void)putKeyEvent:(NSEvent*)event { - cocoa_put_key_event(event); + if (mp_input_vo_keyboard_enabled(self.vout->input_ctx)) + cocoa_put_key_event(event); } - (void)putKey:(int)mpkey withModifiers:(int)modifiers { - cocoa_put_key_with_modifiers(mpkey, modifiers); + if (mp_input_vo_keyboard_enabled(self.vout->input_ctx)) + cocoa_put_key_with_modifiers(mpkey, modifiers); } - (void)putAxis:(int)mpkey delta:(float)delta; { - mp_input_put_axis(self.vout->input_ctx, mpkey, delta); + if (mp_input_mouse_enabled(self.vout->input_ctx)) + mp_input_put_axis(self.vout->input_ctx, mpkey, delta); } - (void)putCommand:(char*)cmd -- cgit v1.2.3