From 2878c2a914a0fae9342ab4d88e238f82a33b9d86 Mon Sep 17 00:00:00 2001 From: Ryan Goulden Date: Wed, 12 Mar 2014 23:34:56 -0400 Subject: cocoa: fix native fullscreen This fixes a couple of issues with the Cocoa `--native-fs` mode, primarily: - A ghost titlebar at the top of the screen in full screen: This was caused by the window constraining code kicking in during fullscreen. Simply returning the unconstrained rect from the constraining method fixes the problem. - Incorrect behavior when using the titlebar buttons to enter/exit fullscreen, as opposed to the OSD button. This was caused by mpv's internal fullscreen state going out of sync with the NSWindow's one. This was the case because `toggleFullScreen:` completely bypassed the normal event flow that mpv expects. Signed-off-by: Ryan Goulden Change style for mpv, simplify and refactor some of the constraining code. Signed-off-by: Stefano Pigozzi --- video/out/cocoa/window.h | 6 +-- video/out/cocoa/window.m | 119 ++++++++++++++++++++++++++--------------------- video/out/cocoa_common.m | 8 ++-- 3 files changed, 71 insertions(+), 62 deletions(-) (limited to 'video') diff --git a/video/out/cocoa/window.h b/video/out/cocoa/window.h index d6c753cc1b..88c054ac8d 100644 --- a/video/out/cocoa/window.h +++ b/video/out/cocoa/window.h @@ -24,11 +24,7 @@ - (BOOL)canBecomeKeyWindow; - (BOOL)canBecomeMainWindow; - (void)mulSize:(float)multiplier; +- (NSRect)frameRect:(NSRect)frameRect forCenteredContentSize:(NSSize)newSize; - (void)setCenteredContentSize:(NSSize)newSize; - - (void)queueNewVideoSize:(NSSize)newSize; -- (void)dispatchNewVideoSize; - -// This really needs to use KVO -- (void)didChangeFullScreenState; @end diff --git a/video/out/cocoa/window.m b/video/out/cocoa/window.m index 009315d7ac..9290c446d8 100644 --- a/video/out/cocoa/window.m +++ b/video/out/cocoa/window.m @@ -30,8 +30,6 @@ @implementation MpvVideoWindow { NSSize _queued_video_size; - bool _fs_resize_scheduled; - bool _recenter_window_during_constraint; } @synthesize adapter = _adapter; @@ -45,6 +43,7 @@ backing:buffering_type defer:flag]) { [self setBackgroundColor:[NSColor blackColor]]; + [self setMinSize:NSMakeSize(50,50)]; } return self; } @@ -66,22 +65,22 @@ - (BOOL)isInFullScreenMode { - return (([self styleMask] & NSFullScreenWindowMask) == - NSFullScreenWindowMask); + return !!([self styleMask] & NSFullScreenWindowMask); } - (void)setFullScreen:(BOOL)willBeFullscreen { - if (willBeFullscreen && ![self isInFullScreenMode]) { - [self setContentResizeIncrements:NSMakeSize(1, 1)]; - [self toggleFullScreen:nil]; + if (willBeFullscreen != [self isInFullScreenMode]) { + [super toggleFullScreen:nil]; } +} - if (!willBeFullscreen && [self isInFullScreenMode]) { - [self setContentAspectRatio:self->_queued_video_size]; - [self toggleFullScreen:nil]; +- (void)toggleFullScreen:(id)sender { + if ([self isInFullScreenMode]) { + [self.adapter putCommand:"set fullscreen no"]; + } else { + [self.adapter putCommand:"set fullscreen yes"]; } - } - (BOOL)canBecomeMainWindow { return YES; } @@ -103,74 +102,90 @@ - (void)mulSize:(float)multiplier { - char *cmd = ta_asprintf(NULL, "set window-scale %f", multiplier); + char cmd[50]; + snprintf(cmd, sizeof(cmd), "set window-scale %f", multiplier); [self.adapter putCommand:cmd]; } -- (int)titleHeight +- (NSRect)frameRect:(NSRect)f forCenteredContentSize:(NSSize)ns { - NSRect of = [self frame]; - NSRect cb = [[self contentView] bounds]; - return of.size.height - cb.size.height; + NSRect cr = [self contentRectForFrameRect:f]; + CGFloat dx = (cr.size.width - ns.width) / 2; + CGFloat dy = (cr.size.height - ns.height) / 2; + return NSInsetRect(f, dx, dy); } - (void)setCenteredContentSize:(NSSize)ns { - NSRect f = [self frame]; - CGFloat dx = (f.size.width - ns.width) / 2; - CGFloat dy = (f.size.height - ns.height - [self titleHeight]) / 2; - NSRect nf = NSRectFromCGRect(CGRectInset(NSRectToCGRect(f), dx, dy)); - self->_recenter_window_during_constraint = true; - [self setFrame:nf display:NO animate:NO]; + [self setFrame:[self frameRect:[self frame] forCenteredContentSize:ns] + display:NO + animate:NO]; } - (NSRect)constrainFrameRect:(NSRect)nf toScreen:(NSScreen *)screen { - NSRect s = [[self screen] visibleFrame]; - if (nf.origin.y + nf.size.height > s.origin.y + s.size.height) { - if (self->_recenter_window_during_constraint) - nf.size.height = s.size.height; - nf.origin.y = s.origin.y + s.size.height - nf.size.height; + if ([self isInFullScreenMode]) + return [super constrainFrameRect:nf toScreen:screen]; + + NSRect of = [self frame]; + NSRect vf = [[self screen] visibleFrame]; + + if (NSMaxY(nf) > NSMaxY(vf)) { + // If the new window is bigger than the visible frame, make sure it's + // titlebar is visible and at the top of the visible frame. + nf.origin.y = NSMaxY(vf) - NSHeight(nf); + } else if (NSHeight(of) > NSHeight(vf)) { + // If the window is smaller than the visible frame, but it was bigger + // previously (so we ran the previous conditional branch), recenter + // the smaller window vertically. + nf.origin.y = (NSHeight(vf) - NSHeight(nf)) / 2; } + return nf; } -- (void)setFrame:(NSRect)frame display:(BOOL)display animate:(BOOL)animate +- (void)windowDidEndLiveResize:(NSNotification *)notification { - [super setFrame:frame display:display animate:animate]; - self->_recenter_window_during_constraint = false; + [self setFrame:[self constrainFrameRect:self.frame toScreen:self.screen] + display:NO]; +} + +- (void)tryDequeueSize { + if (_queued_video_size.width <= 0.0 || _queued_video_size.height <= 0.0) + return; + + if (![self.adapter isInFullScreenMode]) { + [self setContentAspectRatio:_queued_video_size]; + [self setCenteredContentSize:_queued_video_size]; + _queued_video_size = NSZeroSize; + } } - (void)queueNewVideoSize:(NSSize)new_size { - NSSize prev_size = self->_queued_video_size; - self->_queued_video_size = new_size; + if (NSEqualSizes(_queued_video_size, new_size)) + return; + _queued_video_size = new_size; + [self tryDequeueSize]; +} - if (!CGSizeEqualToSize(prev_size, new_size)) - [self dispatchNewVideoSize]; +- (void)windowDidBecomeMain:(NSNotification *)notification { + [self tryDequeueSize]; } -- (void)dispatchNewVideoSize -{ - if ([self.adapter isInFullScreenMode]) { - self->_fs_resize_scheduled = true; - } else { - [self applyNewVideoSize]; - } +- (NSSize)window:(NSWindow *)window willUseFullScreenContentSize:(NSSize)size { + return window.screen.frame.size; } -- (void)applyNewVideoSize -{ - [self setCenteredContentSize:self->_queued_video_size]; - [self setContentAspectRatio:self->_queued_video_size]; +- (NSApplicationPresentationOptions)window:(NSWindow *)window + willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)opts { + return NSApplicationPresentationFullScreen | + NSApplicationPresentationAutoHideDock | + NSApplicationPresentationAutoHideMenuBar | + NSApplicationPresentationAutoHideToolbar; } -- (void)didChangeFullScreenState -{ - if (![self.adapter isInFullScreenMode] && self->_fs_resize_scheduled) { - self->_fs_resize_scheduled = false; - [self applyNewVideoSize]; - } +- (void)windowDidExitFullScreen:(NSNotification *)notification { + [self tryDequeueSize]; } @end - diff --git a/video/out/cocoa_common.m b/video/out/cocoa_common.m index 7e660e9fae..8b6bea66dd 100644 --- a/video/out/cocoa_common.m +++ b/video/out/cocoa_common.m @@ -315,7 +315,6 @@ static void create_window(struct vo *vo, uint32_t d_width, uint32_t d_height, if (opts->native_fs) { [s->window setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary]; - [NSApp setPresentationOptions:NSFullScreenWindowMask]; } } @@ -552,8 +551,6 @@ static void vo_cocoa_fullscreen(struct vo *vo) if (s->icc_fs_profile_path != s->icc_wnd_profile_path) s->icc_profile_path_changed = true; - [s->window didChangeFullScreenState]; - // Make the core aware of the view size change. resize_window(vo); } @@ -791,9 +788,10 @@ int vo_cocoa_cgl_color_size(struct vo *vo) - (void)putCommand:(char*)cmd { - mp_cmd_t *cmdt = mp_input_parse_cmd(self.vout->input_ctx, bstr0(cmd), ""); + char *cmd_ = ta_strdup(NULL, cmd); + mp_cmd_t *cmdt = mp_input_parse_cmd(self.vout->input_ctx, bstr0(cmd_), ""); mp_input_queue_cmd(self.vout->input_ctx, cmdt); - ta_free(cmd); + ta_free(cmd_); } - (void)performAsyncResize:(NSSize)size { -- cgit v1.2.3