From 547b62f45e8c54dc892ba86b98f5ca7cb3f3beac Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 5 Oct 2014 22:31:33 +0200 Subject: cocoa: separate video view and events view --- video/out/cocoa/events_view.h | 26 +++++ video/out/cocoa/events_view.m | 262 ++++++++++++++++++++++++++++++++++++++++++ video/out/cocoa/video_view.h | 23 ++++ video/out/cocoa/video_view.m | 38 ++++++ video/out/cocoa/view.h | 30 ----- video/out/cocoa/view.m | 256 ----------------------------------------- video/out/cocoa/window.m | 2 +- video/out/cocoa_common.m | 23 ++-- 8 files changed, 366 insertions(+), 294 deletions(-) create mode 100644 video/out/cocoa/events_view.h create mode 100644 video/out/cocoa/events_view.m create mode 100644 video/out/cocoa/video_view.h create mode 100644 video/out/cocoa/video_view.m delete mode 100644 video/out/cocoa/view.h delete mode 100644 video/out/cocoa/view.m (limited to 'video') diff --git a/video/out/cocoa/events_view.h b/video/out/cocoa/events_view.h new file mode 100644 index 0000000000..3dc0e0306e --- /dev/null +++ b/video/out/cocoa/events_view.h @@ -0,0 +1,26 @@ +/* + * 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 . + */ + +#import +#import "video/out/cocoa/mpvadapter.h" + +@interface MpvEventsView : NSView +@property(nonatomic, retain) MpvCocoaAdapter *adapter; +- (void)setFullScreen:(BOOL)willBeFullscreen; +- (NSRect)frameInPixels; +- (BOOL)canHideCursor; +@end diff --git a/video/out/cocoa/events_view.m b/video/out/cocoa/events_view.m new file mode 100644 index 0000000000..6e1b470d13 --- /dev/null +++ b/video/out/cocoa/events_view.m @@ -0,0 +1,262 @@ +/* + * 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 . + */ + +#include + +#include "input/input.h" +#include "input/keycodes.h" + +#include "osdep/macosx_compat.h" +#include "video/out/cocoa_common.h" +#import "video/out/cocoa/additions.h" + +#include "events_view.h" + +@interface MpvEventsView() +@property(nonatomic, assign) BOOL hasMouseDown; +@property(nonatomic, retain) NSTrackingArea *tracker; +- (void)signalMousePosition; +@end + +@implementation MpvEventsView +@synthesize adapter = _adapter; +@synthesize tracker = _tracker; +@synthesize hasMouseDown = _mouse_down; + +- (id)initWithFrame:(NSRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self registerForDraggedTypes:@[NSFilenamesPboardType, + NSURLPboardType]]; + } + return self; +} + +- (void)setFullScreen:(BOOL)willBeFullscreen +{ + if (willBeFullscreen && ![self isInFullScreenMode]) { + NSApplicationPresentationOptions popts = + NSApplicationPresentationDefault; + + if ([[self.adapter fsScreen] hasMenubar]) + // Cocoa raises an exception when autohiding the menubar but + // not the dock. They probably got bored while programming the + // multi screen support and took some shortcuts (tested on 10.8). + popts |= NSApplicationPresentationAutoHideMenuBar | + NSApplicationPresentationAutoHideDock; + + if ([[self.adapter fsScreen] hasDock]) + popts |= NSApplicationPresentationAutoHideDock; + + NSDictionary *fsopts = @{ + NSFullScreenModeAllScreens : @NO, + NSFullScreenModeApplicationPresentationOptions : @(popts) + }; + + // The original "windowed" window will stay around since sending a + // view fullscreen wraps it in another window. This is noticeable when + // sending the View fullscreen to another screen. Make it go away + // manually. + [self.window orderOut:self]; + + [self enterFullScreenMode:[self.adapter fsScreen] + withOptions:fsopts]; + } + + if (!willBeFullscreen && [self isInFullScreenMode]) { + [self exitFullScreenModeWithOptions:nil]; + + // Show the "windowed" window again. + [self.window makeKeyAndOrderFront:self]; + [self.window makeFirstResponder:self]; + } +} + +// mpv uses flipped coordinates, because X11 uses those. So let's just use them +// as well without having to do any coordinate conversion of mouse positions. +- (BOOL)isFlipped { return YES; } + +- (void)updateTrackingAreas +{ + if (self.tracker) [self removeTrackingArea:self.tracker]; + + NSTrackingAreaOptions trackingOptions = + NSTrackingEnabledDuringMouseDrag | + NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | + NSTrackingActiveAlways; + + self.tracker = + [[[NSTrackingArea alloc] initWithRect:[self bounds] + options:trackingOptions + owner:self + userInfo:nil] autorelease]; + + [self addTrackingArea:self.tracker]; +} + +- (NSPoint)mouseLocation +{ + return [self.window mouseLocationOutsideOfEventStream]; +} + +- (BOOL)containsMouseLocation +{ + NSRect vF = [[self.window screen] visibleFrame]; + NSRect vFW = [self.window convertRectFromScreen:vF]; + NSRect vFV = [self convertRect:vFW fromView:nil]; + NSPoint pt = [self convertPoint:[self mouseLocation] fromView:nil]; + + // clip bounds to current visibleFrame + NSRect clippedBounds = CGRectIntersection([self bounds], vFV); + return CGRectContainsPoint(clippedBounds, pt); +} + +- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { return YES; } +- (BOOL)acceptsFirstResponder { return YES; } +- (BOOL)becomeFirstResponder { return YES; } +- (BOOL)resignFirstResponder { return YES; } + +- (NSRect)frameInPixels +{ + return [self convertRectToBacking:[self frame]]; +} + +- (BOOL)canHideCursor +{ + return self.hasMouseDown && [self containsMouseLocation]; +} + +- (void)mouseEntered:(NSEvent *)event +{ + // do nothing! +} + +- (void)mouseExited:(NSEvent *)event +{ + [self.adapter putKey:MP_KEY_MOUSE_LEAVE withModifiers:0]; +} + +- (void)setFrameSize:(NSSize)size +{ + [super setFrameSize:size]; + [self signalMousePosition]; +} + +- (NSPoint)convertPointToPixels:(NSPoint)point +{ + point = [self convertPoint:point fromView:nil]; + point = [self convertPointToBacking:point]; + // flip y since isFlipped returning YES doesn't affect the backing + // coordinate system + point.y = -point.y; + return point; +} + +- (void)signalMousePosition +{ + NSPoint p = [self convertPointToPixels:[self mouseLocation]]; + [self.adapter signalMouseMovement:p]; +} + +- (void)signalMouseMovement:(NSEvent *)event +{ + NSPoint p = [self convertPointToPixels:[event locationInWindow]]; + [self.adapter signalMouseMovement:p]; +} + +- (void)mouseMoved:(NSEvent *)event { [self signalMouseMovement:event]; } +- (void)mouseDragged:(NSEvent *)event { [self signalMouseMovement:event]; } +- (void)mouseDown:(NSEvent *)evt { [self mouseDownEvent:evt]; } +- (void)mouseUp:(NSEvent *)evt { [self mouseUpEvent:evt]; } +- (void)rightMouseDown:(NSEvent *)evt { [self mouseDownEvent:evt]; } +- (void)rightMouseUp:(NSEvent *)evt { [self mouseUpEvent:evt]; } +- (void)otherMouseDown:(NSEvent *)evt { [self mouseDownEvent:evt]; } +- (void)otherMouseUp:(NSEvent *)evt { [self mouseUpEvent:evt]; } + +- (void)preciseScroll:(NSEvent *)event +{ + CGFloat delta; + int cmd; + + if (FFABS([event deltaY]) >= FFABS([event deltaX])) { + delta = [event deltaY] * 0.1; + cmd = delta > 0 ? MP_AXIS_UP : MP_AXIS_DOWN; + } else { + delta = [event deltaX] * 0.1; + cmd = delta > 0 ? MP_AXIS_RIGHT : MP_AXIS_LEFT; + } + + [self.adapter putAxis:cmd delta:FFABS(delta)]; +} + +- (void)scrollWheel:(NSEvent *)event +{ + if ([event hasPreciseScrollingDeltas]) { + [self preciseScroll:event]; + } else { + const int modifiers = [event modifierFlags]; + const int mpkey = [event deltaY] > 0 ? MP_MOUSE_BTN3 : MP_MOUSE_BTN4; + [self.adapter putKey:mpkey withModifiers:modifiers]; + } +} + +- (void)mouseDownEvent:(NSEvent *)event +{ + [self putMouseEvent:event withState:MP_KEY_STATE_DOWN]; + + if ([event clickCount] > 1) + [self putMouseEvent:event withState:MP_KEY_STATE_UP]; +} + +- (void)mouseUpEvent:(NSEvent *)event +{ + [self putMouseEvent:event withState:MP_KEY_STATE_UP]; +} + +- (void)putMouseEvent:(NSEvent *)event withState:(int)state +{ + self.hasMouseDown = (state == MP_KEY_STATE_DOWN); + int mpkey = (MP_MOUSE_BTN0 + [event mpvButtonNumber]); + [self.adapter putKey:(mpkey | state) withModifiers:[event modifierFlags]]; +} + +- (NSDragOperation)draggingEntered:(id )sender +{ + NSPasteboard *pboard = [sender draggingPasteboard]; + NSArray *types = [pboard types]; + if ([types containsObject:NSFilenamesPboardType] || + [types containsObject:NSURLPboardType]) + return NSDragOperationCopy; + else + return NSDragOperationNone; +} + +- (BOOL)performDragOperation:(id )sender +{ + NSPasteboard *pboard = [sender draggingPasteboard]; + if ([[pboard types] containsObject:NSURLPboardType]) { + NSURL *file_url = [NSURL URLFromPasteboard:pboard]; + [self.adapter handleFilesArray:@[[file_url absoluteString]]]; + return YES; + } else if ([[pboard types] containsObject:NSFilenamesPboardType]) { + NSArray *pbitems = [pboard propertyListForType:NSFilenamesPboardType]; + [self.adapter handleFilesArray:pbitems]; + return YES; + } + return NO; +} +@end diff --git a/video/out/cocoa/video_view.h b/video/out/cocoa/video_view.h new file mode 100644 index 0000000000..d31d1e014e --- /dev/null +++ b/video/out/cocoa/video_view.h @@ -0,0 +1,23 @@ +/* + * 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 . + */ + +#import +#import "video/out/cocoa/mpvadapter.h" + +@interface MpvVideoView : NSView +@property(nonatomic, retain) MpvCocoaAdapter *adapter; +@end diff --git a/video/out/cocoa/video_view.m b/video/out/cocoa/video_view.m new file mode 100644 index 0000000000..851954c167 --- /dev/null +++ b/video/out/cocoa/video_view.m @@ -0,0 +1,38 @@ +/* + * 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 . + */ + +#include "osdep/macosx_compat.h" +#include "video/out/cocoa_common.h" +#include "video_view.h" + +@implementation MpvVideoView +@synthesize adapter = _adapter; + +- (id)initWithFrame:(NSRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; + } + return self; +} + +- (void)setFrameSize:(NSSize)size +{ + [super setFrameSize:size]; + [self.adapter setNeedsResize]; +} +@end diff --git a/video/out/cocoa/view.h b/video/out/cocoa/view.h deleted file mode 100644 index 490af221b1..0000000000 --- a/video/out/cocoa/view.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 . - */ - -#import -#import "video/out/cocoa/mpvadapter.h" - -@interface MpvVideoView : NSView { - BOOL hasMouseDown; -} -@property(nonatomic, retain) MpvCocoaAdapter *adapter; -@property(nonatomic, retain) NSTrackingArea *tracker; -- (void)setFullScreen:(BOOL)willBeFullscreen; -- (NSRect)frameInPixels; -- (BOOL)canHideCursor; -- (void)signalMousePosition; -@end diff --git a/video/out/cocoa/view.m b/video/out/cocoa/view.m deleted file mode 100644 index 7be52b53c9..0000000000 --- a/video/out/cocoa/view.m +++ /dev/null @@ -1,256 +0,0 @@ -/* - * 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 . - */ - -#include - -#include "input/input.h" -#include "input/keycodes.h" - -#include "osdep/macosx_compat.h" -#include "video/out/cocoa_common.h" -#import "video/out/cocoa/additions.h" - -#include "view.h" - -@implementation MpvVideoView -@synthesize adapter = _adapter; -@synthesize tracker = _tracker; - -- (id)initWithFrame:(NSRect)frame { - self = [super initWithFrame:frame]; - if (self) { - [self registerForDraggedTypes:@[NSFilenamesPboardType, - NSURLPboardType]]; - } - return self; -} - -- (void)setFullScreen:(BOOL)willBeFullscreen -{ - if (willBeFullscreen && ![self isInFullScreenMode]) { - NSApplicationPresentationOptions popts = - NSApplicationPresentationDefault; - - if ([[self.adapter fsScreen] hasMenubar]) - // Cocoa raises an exception when autohiding the menubar but - // not the dock. They probably got bored while programming the - // multi screen support and took some shortcuts (tested on 10.8). - popts |= NSApplicationPresentationAutoHideMenuBar | - NSApplicationPresentationAutoHideDock; - - if ([[self.adapter fsScreen] hasDock]) - popts |= NSApplicationPresentationAutoHideDock; - - NSDictionary *fsopts = @{ - NSFullScreenModeAllScreens : @NO, - NSFullScreenModeApplicationPresentationOptions : @(popts) - }; - - // The original "windowed" window will stay around since sending a - // view fullscreen wraps it in another window. This is noticeable when - // sending the View fullscreen to another screen. Make it go away - // manually. - [self.window orderOut:self]; - - [self enterFullScreenMode:[self.adapter fsScreen] - withOptions:fsopts]; - } - - if (!willBeFullscreen && [self isInFullScreenMode]) { - [self exitFullScreenModeWithOptions:nil]; - - // Show the "windowed" window again. - [self.window makeKeyAndOrderFront:self]; - [self.window makeFirstResponder:self]; - } -} - -// mpv uses flipped coordinates, because X11 uses those. So let's just use them -// as well without having to do any coordinate conversion of mouse positions. -- (BOOL)isFlipped { return YES; } - -- (void)updateTrackingAreas -{ - if (self.tracker) [self removeTrackingArea:self.tracker]; - - NSTrackingAreaOptions trackingOptions = - NSTrackingEnabledDuringMouseDrag | - NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | - NSTrackingActiveAlways; - - self.tracker = - [[[NSTrackingArea alloc] initWithRect:[self bounds] - options:trackingOptions - owner:self - userInfo:nil] autorelease]; - - [self addTrackingArea:self.tracker]; -} - -- (NSPoint)mouseLocation -{ - return [self.window mouseLocationOutsideOfEventStream]; -} - -- (BOOL)containsMouseLocation -{ - NSRect vF = [[self.window screen] visibleFrame]; - NSRect vFW = [self.window convertRectFromScreen:vF]; - NSRect vFV = [self convertRect:vFW fromView:nil]; - NSPoint pt = [self convertPoint:[self mouseLocation] fromView:nil]; - - // clip bounds to current visibleFrame - NSRect clippedBounds = CGRectIntersection([self bounds], vFV); - return CGRectContainsPoint(clippedBounds, pt); -} - -- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { return YES; } -- (BOOL)acceptsFirstResponder { return YES; } -- (BOOL)becomeFirstResponder { return YES; } -- (BOOL)resignFirstResponder { return YES; } - -- (NSRect)frameInPixels -{ - return [self convertRectToBacking:[self frame]]; -} - -- (BOOL)canHideCursor -{ - return !self->hasMouseDown && [self containsMouseLocation]; -} - -- (void)mouseEntered:(NSEvent *)event -{ - // do nothing! -} - -- (void)mouseExited:(NSEvent *)event -{ - [self.adapter putKey:MP_KEY_MOUSE_LEAVE withModifiers:0]; -} - -- (void)setFrameSize:(NSSize)size -{ - [super setFrameSize:size]; - [self signalMousePosition]; - [self.adapter setNeedsResize]; -} - -- (NSPoint)convertPointToPixels:(NSPoint)point -{ - point = [self convertPoint:point fromView:nil]; - point = [self convertPointToBacking:point]; - // flip y since isFlipped returning YES doesn't affect the backing - // coordinate system - point.y = -point.y; - return point; -} - -- (void)signalMousePosition -{ - NSPoint p = [self convertPointToPixels:[self mouseLocation]]; - [self.adapter signalMouseMovement:p]; -} - -- (void)signalMouseMovement:(NSEvent *)event -{ - NSPoint p = [self convertPointToPixels:[event locationInWindow]]; - [self.adapter signalMouseMovement:p]; -} - -- (void)mouseMoved:(NSEvent *)event { [self signalMouseMovement:event]; } -- (void)mouseDragged:(NSEvent *)event { [self signalMouseMovement:event]; } -- (void)mouseDown:(NSEvent *)evt { [self mouseDownEvent:evt]; } -- (void)mouseUp:(NSEvent *)evt { [self mouseUpEvent:evt]; } -- (void)rightMouseDown:(NSEvent *)evt { [self mouseDownEvent:evt]; } -- (void)rightMouseUp:(NSEvent *)evt { [self mouseUpEvent:evt]; } -- (void)otherMouseDown:(NSEvent *)evt { [self mouseDownEvent:evt]; } -- (void)otherMouseUp:(NSEvent *)evt { [self mouseUpEvent:evt]; } - -- (void)preciseScroll:(NSEvent *)event -{ - CGFloat delta; - int cmd; - - if (FFABS([event deltaY]) >= FFABS([event deltaX])) { - delta = [event deltaY] * 0.1; - cmd = delta > 0 ? MP_AXIS_UP : MP_AXIS_DOWN; - } else { - delta = [event deltaX] * 0.1; - cmd = delta > 0 ? MP_AXIS_RIGHT : MP_AXIS_LEFT; - } - - [self.adapter putAxis:cmd delta:FFABS(delta)]; -} - -- (void)scrollWheel:(NSEvent *)event -{ - if ([event hasPreciseScrollingDeltas]) { - [self preciseScroll:event]; - } else { - const int modifiers = [event modifierFlags]; - const int mpkey = [event deltaY] > 0 ? MP_MOUSE_BTN3 : MP_MOUSE_BTN4; - [self.adapter putKey:mpkey withModifiers:modifiers]; - } -} - -- (void)mouseDownEvent:(NSEvent *)event -{ - [self putMouseEvent:event withState:MP_KEY_STATE_DOWN]; - - if ([event clickCount] > 1) - [self putMouseEvent:event withState:MP_KEY_STATE_UP]; -} - -- (void)mouseUpEvent:(NSEvent *)event -{ - [self putMouseEvent:event withState:MP_KEY_STATE_UP]; -} - -- (void)putMouseEvent:(NSEvent *)event withState:(int)state -{ - self->hasMouseDown = (state == MP_KEY_STATE_DOWN); - int mpkey = (MP_MOUSE_BTN0 + [event mpvButtonNumber]); - [self.adapter putKey:(mpkey | state) withModifiers:[event modifierFlags]]; -} - -- (NSDragOperation)draggingEntered:(id )sender -{ - NSPasteboard *pboard = [sender draggingPasteboard]; - NSArray *types = [pboard types]; - if ([types containsObject:NSFilenamesPboardType] || - [types containsObject:NSURLPboardType]) - return NSDragOperationCopy; - else - return NSDragOperationNone; -} - -- (BOOL)performDragOperation:(id )sender -{ - NSPasteboard *pboard = [sender draggingPasteboard]; - if ([[pboard types] containsObject:NSURLPboardType]) { - NSURL *file_url = [NSURL URLFromPasteboard:pboard]; - [self.adapter handleFilesArray:@[[file_url absoluteString]]]; - return YES; - } else if ([[pboard types] containsObject:NSFilenamesPboardType]) { - NSArray *pbitems = [pboard propertyListForType:NSFilenamesPboardType]; - [self.adapter handleFilesArray:pbitems]; - return YES; - } - return NO; -} -@end diff --git a/video/out/cocoa/window.m b/video/out/cocoa/window.m index ece6246f34..1540a1b769 100644 --- a/video/out/cocoa/window.m +++ b/video/out/cocoa/window.m @@ -55,7 +55,7 @@ - (void)windowDidChangeBackingProperties:(NSNotification *)notification { // XXX: we maybe only need expose for this - [self.adapter setNeedsResize]; + // [self.adapter setNeedsResize]; } - (void)windowDidChangeScreenProfile:(NSNotification *)notification diff --git a/video/out/cocoa_common.m b/video/out/cocoa_common.m index 30f9cb8e86..0a58cd85b8 100644 --- a/video/out/cocoa_common.m +++ b/video/out/cocoa_common.m @@ -22,9 +22,10 @@ #import #include -#include "cocoa_common.h" -#include "video/out/cocoa/window.h" -#include "video/out/cocoa/view.h" +#import "cocoa_common.h" +#import "video/out/cocoa/window.h" +#import "video/out/cocoa/events_view.h" +#import "video/out/cocoa/video_view.h" #import "video/out/cocoa/mpvadapter.h" #include "osdep/threads.h" @@ -57,7 +58,8 @@ static void cocoa_rm_fs_screen_profile_observer(struct vo *vo); struct vo_cocoa_state { NSWindow *window; - MpvVideoView *view; + MpvEventsView *view; + MpvVideoView *video; NSOpenGLContext *gl_ctx; NSScreen *current_screen; @@ -173,6 +175,8 @@ void vo_cocoa_uninit(struct vo *vo) enable_power_management(vo); cocoa_rm_fs_screen_profile_observer(vo); + [s->video release]; + // XXX: It looks like there are some circular retain cycles for the // video view / video window that cause them to not be deallocated, // This is a workaround to make the fullscreen window be released, @@ -304,7 +308,7 @@ static void create_ui(struct vo *vo, struct mp_rect *win, int geo_flags) s->window = create_window(contentRect, s->current_screen, opts->border, adapter); } - s->view = [[[MpvVideoView alloc] initWithFrame:contentRect] autorelease]; + s->view = [[[MpvEventsView alloc] initWithFrame:contentRect] autorelease]; [s->view setWantsBestResolutionOpenGLSurface:YES]; @@ -316,11 +320,15 @@ static void create_ui(struct vo *vo, struct mp_rect *win, int geo_flags) cocoa_register_menu_item_action(MPM_ZOOM, @selector(performZoom:)); #endif + s->video = [[MpvVideoView alloc] initWithFrame:[s->view bounds]]; + [s->view addSubview:s->video]; + [s->view setAutoresizesSubviews:YES]; [s->window setContentView:s->view]; - [s->gl_ctx setView:s->view]; + [s->gl_ctx setView:s->video]; adapter.vout = vo; s->view.adapter = adapter; + s->video.adapter = adapter; if (!s->embedded) { [s->window setRestorable:NO]; @@ -465,8 +473,9 @@ int vo_cocoa_check_events(struct vo *vo) int events = s->pending_events; s->pending_events = 0; - if (events & VO_EVENT_RESIZE) + if (events & VO_EVENT_RESIZE) { resize_window(vo); + } return events; } -- cgit v1.2.3