summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorAkemi <der.richter@gmx.de>2017-02-23 20:01:27 +0100
committerAkemi <der.richter@gmx.de>2017-02-28 00:01:15 +0100
commit4fe199c6a06606b0191575b3a0127076135a952c (patch)
treeeb4b2b74a4027cc1cbb76a86050b0321a72a0ca3 /video
parent9d549e68377d3c2164aa7b1ec11d49fe2bdf7a0a (diff)
downloadmpv-4fe199c6a06606b0191575b3a0127076135a952c.tar.bz2
mpv-4fe199c6a06606b0191575b3a0127076135a952c.tar.xz
cocoa: improve calculation of new window position on a different screen
forcibly moving a window from one screen to another is supposed to put it in a position that looks relative the same as on the old screen, as in bottom, top, left and right margin look the same, without changing the window size. in some situations the old code moved the window off screen or on top of the menu bar so it ended up at a somewhat random position. the new code fixes some edge cases but is probably not completely correct since the priority is to make sure that the window ends up on the right screen.
Diffstat (limited to 'video')
-rw-r--r--video/out/cocoa/window.m57
1 files changed, 44 insertions, 13 deletions
diff --git a/video/out/cocoa/window.m b/video/out/cocoa/window.m
index ec4d8ae530..89c9e61d6b 100644
--- a/video/out/cocoa/window.m
+++ b/video/out/cocoa/window.m
@@ -29,6 +29,7 @@
@property(nonatomic, retain) NSScreen *targetScreen;
@property(nonatomic, retain) NSScreen *previousScreen;
@property(nonatomic, retain) NSScreen *currentScreen;
+@property(nonatomic, retain) NSScreen *unfScreen;
- (NSRect)frameRect:(NSRect)frameRect forCenteredContentSize:(NSSize)newSize;
- (void)setCenteredContentSize:(NSSize)newSize;
@@ -37,7 +38,6 @@
@implementation MpvVideoWindow {
NSSize _queued_video_size;
NSRect _unfs_content_frame;
- NSRect _unfs_screen_frame;
int _is_animating;
}
@@ -45,6 +45,7 @@
@synthesize targetScreen = _target_screen;
@synthesize previousScreen = _previous_screen;
@synthesize currentScreen = _current_screen;
+@synthesize unfScreen = _unf_Screen;
- (id)initWithContentRect:(NSRect)content_rect
styleMask:(NSUInteger)style_mask
backing:(NSBackingStoreType)buffering_type
@@ -62,9 +63,9 @@
self.targetScreen = screen;
self.currentScreen = screen;
+ self.unfScreen = screen;
_is_animating = 0;
_unfs_content_frame = [self convertRectToScreen:[[self contentView] frame]];
- _unfs_screen_frame = [screen frame];
}
return self;
}
@@ -88,7 +89,7 @@
if (![self.adapter isInFullScreenMode]) {
_unfs_content_frame = [self convertRectToScreen:[[self contentView] frame]];
- _unfs_screen_frame = [[self screen] frame];
+ self.unfScreen = [self screen];
}
//move window to target screen when going to fullscreen
@@ -284,16 +285,46 @@
{
NSRect frame = [self frameRectForContentRect:_unfs_content_frame];
NSRect targetFrame = [screen frame];
-
- CGFloat x_per = (_unfs_screen_frame.size.width - frame.size.width);
- CGFloat y_per = (_unfs_screen_frame.size.height - frame.size.height);
- if (x_per > 0) x_per = (frame.origin.x - _unfs_screen_frame.origin.x)/x_per;
- if (y_per > 0) y_per = (frame.origin.y - _unfs_screen_frame.origin.y)/y_per;
-
- frame.origin.x = targetFrame.origin.x +
- (targetFrame.size.width - frame.size.width)*x_per;
- frame.origin.y = targetFrame.origin.y +
- (targetFrame.size.height - frame.size.height)*y_per;
+ NSRect targetVisibleFrame = [screen visibleFrame];
+ NSRect unfsScreenFrame = [self.unfScreen frame];
+ NSRect visibleWindow = NSIntersectionRect(unfsScreenFrame, frame);
+
+ // calculate visible area of every side
+ CGFloat left = frame.origin.x - unfsScreenFrame.origin.x;
+ CGFloat right = unfsScreenFrame.size.width -
+ (frame.origin.x - unfsScreenFrame.origin.x + frame.size.width);
+ CGFloat bottom = frame.origin.y - unfsScreenFrame.origin.y;
+ CGFloat top = unfsScreenFrame.size.height -
+ (frame.origin.y - unfsScreenFrame.origin.y + frame.size.height);
+
+ // normalize visible areas, decide which one to take horizontal/vertical
+ CGFloat x_per = (unfsScreenFrame.size.width - visibleWindow.size.width);
+ CGFloat y_per = (unfsScreenFrame.size.height - visibleWindow.size.height);
+ if (x_per != 0) x_per = (left >= 0 || right < 0 ? left : right)/x_per;
+ if (y_per != 0) y_per = (bottom >= 0 || top < 0 ? bottom : top)/y_per;
+
+ // calculate visible area for every side for target screen
+ CGFloat x_new_left = targetFrame.origin.x +
+ (targetFrame.size.width - visibleWindow.size.width)*x_per;
+ CGFloat x_new_right = targetFrame.origin.x + targetFrame.size.width -
+ (targetFrame.size.width - visibleWindow.size.width)*x_per - frame.size.width;
+ CGFloat y_new_bottom = targetFrame.origin.y +
+ (targetFrame.size.height - visibleWindow.size.height)*y_per;
+ CGFloat y_new_top = targetFrame.origin.y + targetFrame.size.height -
+ (targetFrame.size.height - visibleWindow.size.height)*y_per - frame.size.height;
+
+ // calculate new coordinates, decide which one to take horizontal/vertical
+ frame.origin.x = left >= 0 || right < 0 ? x_new_left : x_new_right;
+ frame.origin.y = bottom >= 0 || top < 0 ? y_new_bottom : y_new_top;
+
+ // don't place new window on top of a visible menubar
+ CGFloat top_mar = targetFrame.size.height -
+ (frame.origin.y - targetFrame.origin.y + frame.size.height);
+ CGFloat menuBarHeight = targetFrame.size.height -
+ (targetVisibleFrame.size.height + targetVisibleFrame.origin.y);
+
+ if (top_mar < menuBarHeight)
+ frame.origin.y -= top-menuBarHeight;
if (withoutBounds)
return frame;