From bbfaac5468a692c98d3016e41010dd7979857e0f Mon Sep 17 00:00:00 2001 From: Aparajita Fishman Date: Tue, 12 Mar 2013 13:49:33 -0400 Subject: [PATCH] Fixed: windows were allowed to extend beyond the usable screen content. Previously, no bounds were placed on the placement or sizing of windows, which allowed them to extend beyond the usable screen content (the area bounded by the menu bar at the top and the platform window on the other sides). Cocoa enforces the following restrictions: - When a window is ordered in, it is forced within the usable screen content (below the menu bar) and its size and width are clipped to the usable screen content as well. - If a window is already visible, any methods that move or resize the window will ensure the top and bottom of the window are within the usable screen content. The width is unchanged. This commit implements Cocoa's restrictions in CPWindow. Fixes #1690 --- AppKit/CPWindow/CPWindow.j | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index dcae48832..c3f0572b5 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -640,6 +640,9 @@ CPTexturedBackgroundWindowMask */ - (void)setFrame:(CGRect)aFrame display:(BOOL)shouldDisplay animate:(BOOL)shouldAnimate { + if (_CGRectEqualToRect(aFrame, _frame)) + return; + aFrame = _CGRectMakeCopy(aFrame); var value = aFrame.origin.x, @@ -666,6 +669,10 @@ CPTexturedBackgroundWindowMask if (delta) aFrame.size.height = value > 0.15 ? CEIL(value) : FLOOR(value); + // In Cocoa, if a window is already visible, only its height is pinned + if (_isVisible) + aFrame = [self _pinFrame:aFrame toUsableScreenWidth:NO andHeight:YES]; + if (shouldAnimate) { [_frameAnimation stopAnimation]; @@ -720,6 +727,30 @@ CPTexturedBackgroundWindowMask } } +- (CGRect)_pinFrame:(CGRect)aFrame toUsableScreenWidth:(BOOL)pinWidth andHeight:(BOOL)pinHeight +{ + var usableRect = [_platformWindow usableContentFrame], + frame = _CGRectMakeCopy(aFrame); + + if (pinWidth) + { + frame.origin.x = MAX(frame.origin.x, usableRect.origin.x); + + var maxX = MIN(_CGRectGetMaxX(frame), _CGRectGetMaxX(usableRect)); + frame.size.width = maxX - frame.origin.x; + } + + if (pinHeight) + { + frame.origin.y = MAX(frame.origin.y, usableRect.origin.y); + + var maxY = MIN(_CGRectGetMaxY(frame), _CGRectGetMaxY(usableRect)); + frame.size.height = maxY - frame.origin.y; + } + + return frame; +} + - (void)_moveChildWindows:(CGPoint)delta { [_childWindows enumerateObjectsUsingBlock:function(childWindow) @@ -788,6 +819,9 @@ CPTexturedBackgroundWindowMask if ([self isSheet]) [_parentView orderFront:self]; + // Cocoa pins windows to the usable screen content during orderFront + [self setFrame:[self _pinFrame:_frame toUsableScreenWidth:YES andHeight:YES]]; + [_platformWindow orderFront:self]; [_platformWindow order:CPWindowAbove window:self relativeTo:nil]; #endif