1
0
mirror of https://github.com/mpv-player/mpv synced 2025-01-08 16:10:29 +00:00
mpv/video/out/cocoa/window.m
Akemi 47d9fbd133 cocoa: fix display refresh rate retrieval on multi monitor setups
1. this basically reverts commit de4c74e5a4.
even with CVDisplayLinkCreateWithActiveCGDisplays and
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext we still have to
explicitly set the current display ID, otherwise it will just always
choose the display with the lowest refresh rate. another weird thing is,
we still have to set the display ID another time with
CVDisplayLinkSetCurrentCGDisplay after the link was started. otherwise
the display period is 0 and the fallback will be used.
if we ever use the callback method for something useful it's probably
better to use CVDisplayLinkCreateWithActiveCGDisplays since we will need
to keep the display link around instead of releasing it at the end.
in that case we have to call CVDisplayLinkSetCurrentCGDisplay two times,
once before and once after LinkStart.
2. add windowDidChangeScreen delegate to update the display refresh rate
when mpv is moved to a different screen.
2016-06-18 19:15:36 +02:00

190 lines
5.5 KiB
Objective-C

/*
* 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/>.
*/
#include <libavutil/common.h>
#include "input/keycodes.h"
#include "osdep/macosx_events.h"
#include "osdep/macosx_compat.h"
#include "video/out/cocoa_common.h"
#include "window.h"
@interface MpvVideoWindow()
- (NSRect)frameRect:(NSRect)frameRect forCenteredContentSize:(NSSize)newSize;
- (void)setCenteredContentSize:(NSSize)newSize;
@end
@implementation MpvVideoWindow {
NSSize _queued_video_size;
}
@synthesize adapter = _adapter;
- (id)initWithContentRect:(NSRect)content_rect
styleMask:(NSUInteger)style_mask
backing:(NSBackingStoreType)buffering_type
defer:(BOOL)flag
{
if (self = [super initWithContentRect:content_rect
styleMask:style_mask
backing:buffering_type
defer:flag]) {
[self setBackgroundColor:[NSColor blackColor]];
[self setMinSize:NSMakeSize(50,50)];
}
return self;
}
- (void)windowDidChangeBackingProperties:(NSNotification *)notification
{
// XXX: we maybe only need expose for this
[self.adapter setNeedsResize];
}
- (void)windowDidChangeScreen:(NSNotification *)notification
{
[self.adapter windowDidChangeScreen:notification];
}
- (void)windowDidChangeScreenProfile:(NSNotification *)notification
{
[self.adapter didChangeWindowedScreenProfile:[self screen]];
}
- (void)windowDidResignKey:(NSNotification *)notification
{
[self.adapter windowDidResignKey:notification];
}
- (void)windowDidBecomeKey:(NSNotification *)notification
{
[self.adapter windowDidBecomeKey:notification];
}
- (void)windowDidMiniaturize:(NSNotification *)notification
{
[self.adapter windowDidMiniaturize:notification];
}
- (void)windowDidDeminiaturize:(NSNotification *)notification
{
[self.adapter windowDidDeminiaturize:notification];
}
- (BOOL)canBecomeMainWindow { return YES; }
- (BOOL)canBecomeKeyWindow { return YES; }
- (BOOL)windowShouldClose:(id)sender
{
cocoa_put_key(MP_KEY_CLOSE_WIN);
// We have to wait for MPlayer to handle this,
// otherwise we are in trouble if the
// MP_KEY_CLOSE_WIN handler is disabled
return NO;
}
- (void)normalSize { [self mulSize:1.0f]; }
- (void)halfSize { [self mulSize:0.5f];}
- (void)doubleSize { [self mulSize:2.0f];}
- (void)mulSize:(float)multiplier
{
char cmd[50];
snprintf(cmd, sizeof(cmd), "set window-scale %f", multiplier);
[self.adapter putCommand:cmd];
}
- (NSRect)frameRect:(NSRect)f forCenteredContentSize:(NSSize)ns
{
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
{
[self setFrame:[self frameRect:[self frame] forCenteredContentSize:ns]
display:NO
animate:NO];
}
- (NSRect)constrainFrameRect:(NSRect)nf toScreen:(NSScreen *)screen
{
NSRect of = [self frame];
NSRect vf = [screen ?: self.screen ?: [NSScreen mainScreen] visibleFrame];
NSRect ncf = [self contentRectForFrameRect:nf];
// Prevent the window's titlebar from exiting the screen on the top edge.
// This introduces a 'snap to top' behaviour.
if (NSMaxY(nf) > NSMaxY(vf))
nf.origin.y = NSMaxY(vf) - NSHeight(nf);
// Prevent the window's titlebar from exiting the screen on the top edge.
if (NSMaxY(ncf) < NSMinY(vf))
nf.origin.y = NSMinY(vf) + NSMinY(ncf) - NSMaxY(ncf);
// Prevent window from exiting the screen on the right edge
if (NSMinX(nf) > NSMaxX(vf))
nf.origin.x = NSMaxX(vf) - NSWidth(nf);
// Prevent window from exiting the screen on the left
if (NSMaxX(nf) < NSMinX(vf))
nf.origin.x = NSMinX(vf);
if (NSHeight(nf) < NSHeight(vf) && NSHeight(of) > NSHeight(vf))
// If the window height is smaller than the visible frame, but it was
// bigger previously recenter the smaller window vertically. This is
// needed to counter the 'snap to top' behaviour.
nf.origin.y = (NSHeight(vf) - NSHeight(nf)) / 2;
return nf;
}
- (void)windowDidEndLiveResize:(NSNotification *)notification
{
[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;
// XXX find a way to kill this state
if (![self.adapter isInFullScreenMode]) {
[self setContentAspectRatio:_queued_video_size];
[self setCenteredContentSize:_queued_video_size];
_queued_video_size = NSZeroSize;
}
}
- (void)queueNewVideoSize:(NSSize)new_size
{
if (NSEqualSizes(_queued_video_size, new_size))
return;
_queued_video_size = new_size;
[self tryDequeueSize];
}
- (void)windowDidBecomeMain:(NSNotification *)notification {
[self tryDequeueSize];
}
@end