Commit c22693ca authored by Leonard Grey's avatar Leonard Grey Committed by Commit Bot

Mac: constrainFrameRect:toScreen: rework

When the screen passed to `constrainFrameRect:toScreen:` is nil,
AppKit does some gymnastics to select a screen, only defaulting
to the main screen if there's no result. We don't have access
to these calculations in an override, so we can't use the
screen's frame for heuristics when deciding whether to allow
the constrain to happen or not.

This change removes the previous logic in favor of trying
to test specifically for the large vertical jumps that cause
glitches when detaching tabs.

Bug: 1102925
Change-Id: Ic5653d5fd867da155605cd986ec80c5bb4afd755
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2298056Reviewed-by: default avatarElly Fong-Jones <ellyjones@chromium.org>
Commit-Queue: Leonard Grey <lgrey@chromium.org>
Cr-Commit-Position: refs/heads/master@{#789503}
parent c09a270d
...@@ -67,23 +67,19 @@ ...@@ -67,23 +67,19 @@
// Prevent detached tabs from glitching when the window is partially offscreen. // Prevent detached tabs from glitching when the window is partially offscreen.
// See https://crbug.com/1095717 for details. // See https://crbug.com/1095717 for details.
// This is easy to get wrong so scope very tightly to only disallow large
// vertical jumps.
- (NSRect)constrainFrameRect:(NSRect)rect toScreen:(NSScreen*)screen { - (NSRect)constrainFrameRect:(NSRect)rect toScreen:(NSScreen*)screen {
if (!screen) NSRect proposed = [super constrainFrameRect:rect toScreen:screen];
screen = [NSScreen mainScreen]; // This boils down to: use the small threshold when we're not avoiding a
// A small margin so that constraining kicks in before we're *all the way* // Dock on the bottom, and the big threshold otherwise.
// to the edge of the screen. static constexpr CGFloat kBigThreshold = 200;
static constexpr CGFloat kThreshold = 80; static constexpr CGFloat kSmallThreshold = 50;
NSRect screenFrame = [screen frame]; const CGFloat yDelta = NSMaxY(proposed) - NSMaxY(rect);
// Adjust if either the entire frame is offscreen, or the toolbar is if (yDelta > kBigThreshold ||
// cut off at the top. (yDelta > kSmallThreshold && NSMinY(proposed) == 0))
if (NSMaxY(rect) - kThreshold < NSMinY(screenFrame) || // Below the screen. return rect;
NSMaxX(rect) - kThreshold < NSMinX(screenFrame) || // Left of the screen. return proposed;
NSMinX(rect) + kThreshold >
NSMaxX(screenFrame) || // Right of the screen.
NSMaxY(rect) + kThreshold > NSMaxY(screenFrame)) { // Top above screen.
return [super constrainFrameRect:rect toScreen:screen];
}
return rect;
} }
// NSWindow (PrivateAPI) overrides. // NSWindow (PrivateAPI) overrides.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment