Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(822)

Unified Diff: chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm

Issue 976903003: Do not cache NSScreens. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm
index a0da0c0a6cdbf80225eedea43d9fb33ab7490ec8..ca1997740c1e134a73cc59f7e82fdbea52d9115d 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm
@@ -129,13 +129,18 @@ NSRect GetFirstButtonFrameForHeight(CGFloat height) {
- (void)_updateTrackingAreas;
@end
-@interface BookmarkBarFolderController(Private)
+@interface BookmarkBarFolderController ()
- (void)configureWindow;
- (void)addOrUpdateScrollTracking;
- (void)removeScrollTracking;
- (void)endScroll;
- (void)addScrollTimerWithDelta:(CGFloat)delta;
+// Return the screen to which the menu should be restricted. The screen list is
+// very volatile and can change with very short notice so it isn't worth
+// caching. http://crbug.com/463458
+- (NSScreen*)menuScreen;
+
// Helper function to configureWindow which performs a basic layout of
// the window subviews, in particular the menu buttons and the window width.
- (void)layOutWindowWithHeight:(CGFloat)height;
@@ -261,33 +266,6 @@ NSRect GetFirstButtonFrameForHeight(CGFloat height) {
// We want the button to remain bordered as part of the menu path.
[button forceButtonBorderToStayOnAlways:YES];
- // Pick the parent button's screen to be the screen upon which all display
- // happens. This loop over all screens is not equivalent to
- // |[[button window] screen]|. BookmarkButtons are commonly positioned near
- // the edge of their windows (both in the bookmark bar and in other bookmark
- // menus), and |[[button window] screen]| would return the screen that the
- // majority of their window was on even if the parent button were clearly
- // contained within a different screen.
- NSRect parentButtonGlobalFrame =
- [button convertRect:[button bounds] toView:nil];
- parentButtonGlobalFrame.origin =
- [[button window] convertBaseToScreen:parentButtonGlobalFrame.origin];
- for (NSScreen* screen in [NSScreen screens]) {
- if (NSIntersectsRect([screen frame], parentButtonGlobalFrame)) {
- screen_ = screen;
- break;
- }
- }
- if (!screen_) {
- // The parent button is offscreen. The ideal thing to do would be to
- // calculate the "closest" screen, the screen which has an edge parallel
- // to, and the least distance from, one of the edges of the button.
- // However, popping a subfolder from an offscreen button is an unrealistic
- // edge case and so this ideal remains unrealized. Cheat instead; this
- // code is wrong but a lot simpler.
- screen_ = [[button window] screen];
- }
-
parentController_.reset([parentController retain]);
if (!parentController_)
[self setSubFolderGrowthToRight:YES];
@@ -468,6 +446,7 @@ NSRect GetFirstButtonFrameForHeight(CGFloat height) {
// left but not in that order). Limit us to three tries in case
// the folder window can't fit on either side of the screen; we
// don't want to loop forever.
+ NSRect screenVisibleFrame = [[self menuScreen] visibleFrame];
CGFloat x;
int tries = 0;
while (tries < 2) {
@@ -477,9 +456,8 @@ NSRect GetFirstButtonFrameForHeight(CGFloat height) {
x = NSMaxX([[parentButton_ window] frame]) -
bookmarks::kBookmarkMenuOverlap;
// If off the screen, switch direction.
- if ((x + windowWidth +
- bookmarks::kBookmarkHorizontalScreenPadding) >
- NSMaxX([screen_ visibleFrame])) {
+ if ((x + windowWidth + bookmarks::kBookmarkHorizontalScreenPadding) >
+ NSMaxX(screenVisibleFrame)) {
[self setSubFolderGrowthToRight:NO];
} else {
return x;
@@ -492,7 +470,7 @@ NSRect GetFirstButtonFrameForHeight(CGFloat height) {
bookmarks::kBookmarkMenuOverlap -
windowWidth;
// If off the screen, switch direction.
- if (x < NSMinX([screen_ visibleFrame])) {
+ if (x < NSMinX(screenVisibleFrame)) {
[self setSubFolderGrowthToRight:YES];
} else {
return x;
@@ -500,7 +478,7 @@ NSRect GetFirstButtonFrameForHeight(CGFloat height) {
}
}
// Unhappy; do the best we can.
- return NSMaxX([screen_ visibleFrame]) - windowWidth;
+ return NSMaxX(screenVisibleFrame) - windowWidth;
}
@@ -530,26 +508,27 @@ NSRect GetFirstButtonFrameForHeight(CGFloat height) {
// Make sure the window is on-screen; if not, push left or right. It is
// intentional that top level folders "push left" or "push right" slightly
// different than subfolders.
- NSRect screenFrame = [screen_ visibleFrame];
+ NSRect screenVisibleFrame = [[self menuScreen] visibleFrame];
// Test if window goes off-screen on the right side.
- CGFloat spillOff = (newWindowTopLeft.x + windowWidth) - NSMaxX(screenFrame);
+ CGFloat spillOff =
+ newWindowTopLeft.x + windowWidth - NSMaxX(screenVisibleFrame);
if (spillOff > 0.0) {
newWindowTopLeft.x = std::max(newWindowTopLeft.x - spillOff,
- NSMinX(screenFrame));
- } else if (newWindowTopLeft.x < NSMinX(screenFrame)) {
+ NSMinX(screenVisibleFrame));
+ } else if (newWindowTopLeft.x < NSMinX(screenVisibleFrame)) {
// For left side.
- newWindowTopLeft.x = NSMinX(screenFrame);
+ newWindowTopLeft.x = NSMinX(screenVisibleFrame);
}
// The menu looks bad when it is squeezed up against the bottom of the
// screen and ends up being only a few pixels tall. If it meets the
// threshold for this case, instead show the menu above the button.
CGFloat availableVerticalSpace = newWindowTopLeft.y -
- (NSMinY(screenFrame) + bookmarks::kScrollWindowVerticalMargin);
+ (NSMinY(screenVisibleFrame) + bookmarks::kScrollWindowVerticalMargin);
if ((availableVerticalSpace < kMinSqueezedMenuHeight) &&
(windowHeight > availableVerticalSpace)) {
newWindowTopLeft.y = std::min(
newWindowTopLeft.y + windowHeight + NSHeight([parentButton_ frame]),
- NSMaxY(screenFrame));
+ NSMaxY(screenVisibleFrame));
}
} else {
// Parent is a folder: expose as much as we can vertically; grow right/left.
@@ -615,9 +594,9 @@ NSRect GetFirstButtonFrameForHeight(CGFloat height) {
metrics.deltaScrollerHeight = 0.0;
metrics.deltaScrollerY = 0.0;
- metrics.minimumY = NSMinY([screen_ visibleFrame]) +
+ metrics.minimumY = NSMinY([[self menuScreen] visibleFrame]) +
bookmarks::kScrollWindowVerticalMargin;
- metrics.screenBottomY = NSMinY([screen_ frame]);
+ metrics.screenBottomY = NSMinY([[self menuScreen] frame]);
metrics.oldWindowY = NSMinY(metrics.windowFrame);
metrics.folderY =
metrics.scrollerFrame.origin.y + metrics.visibleFrame.origin.y +
@@ -632,7 +611,8 @@ NSRect GetFirstButtonFrameForHeight(CGFloat height) {
effectiveFolderY -= metrics.windowSize.height;
metrics.canScrollUp = effectiveFolderY < metrics.minimumY;
CGFloat maximumY =
- NSMaxY([screen_ visibleFrame]) - bookmarks::kScrollWindowVerticalMargin;
+ NSMaxY([[self menuScreen] visibleFrame]) -
+ bookmarks::kScrollWindowVerticalMargin;
metrics.canScrollDown = metrics.folderTop > maximumY;
// Accommodate changes in the bottom of the menu.
@@ -707,7 +687,7 @@ NSRect GetFirstButtonFrameForHeight(CGFloat height) {
} else {
if (metrics.canScrollDown) {
// Couldn't -> Can
- const CGFloat maximumY = NSMaxY([screen_ visibleFrame]);
+ const CGFloat maximumY = NSMaxY([[self menuScreen] visibleFrame]);
metrics.deltaWindowHeight += (maximumY - NSMaxY(metrics.windowFrame));
metrics.deltaVisibleHeight -= bookmarks::kScrollWindowVerticalMargin;
metrics.deltaScrollerHeight -= verticalScrollArrowHeight_;
@@ -839,7 +819,7 @@ NSRect GetFirstButtonFrameForHeight(CGFloat height) {
// Make sure as much of a submenu is exposed (which otherwise would be a
// problem if the parent button is close to the bottom of the screen).
if ([parentController_ isKindOfClass:[self class]]) {
- CGFloat minimumY = NSMinY([screen_ visibleFrame]) +
+ CGFloat minimumY = NSMinY([[self menuScreen] visibleFrame]) +
bookmarks::kScrollWindowVerticalMargin +
height;
newWindowTopLeft.y = MAX(newWindowTopLeft.y, minimumY);
@@ -984,6 +964,7 @@ NSRect GetFirstButtonFrameForHeight(CGFloat height) {
(delta < 0.0 && ![scrollDownArrowView_ isHidden])) {
NSWindow* window = [self window];
NSRect windowFrame = [window frame];
+ NSRect screenVisibleFrame = [[self menuScreen] visibleFrame];
NSPoint scrollPosition = [scrollView_ documentVisibleRect].origin;
CGFloat scrollY = scrollPosition.y;
NSRect scrollerFrame = [scrollView_ frame];
@@ -995,14 +976,13 @@ NSRect GetFirstButtonFrameForHeight(CGFloat height) {
if (delta > 0.0) {
// Scrolling up.
- CGFloat minimumY = NSMinY([screen_ visibleFrame]) +
+ CGFloat minimumY = NSMinY(screenVisibleFrame) +
bookmarks::kScrollWindowVerticalMargin;
CGFloat maxUpDelta = scrollY - offset + minimumY;
delta = MIN(delta, maxUpDelta);
} else {
// Scrolling down.
- NSRect screenFrame = [screen_ visibleFrame];
- CGFloat topOfScreen = NSMaxY(screenFrame);
+ CGFloat topOfScreen = NSMaxY(screenVisibleFrame);
NSRect folderFrame = [folderView_ frame];
CGFloat folderHeight = NSHeight(folderFrame);
CGFloat folderTop = folderHeight - scrollY + offset;
@@ -1040,6 +1020,32 @@ NSRect GetFirstButtonFrameForHeight(CGFloat height) {
[[NSRunLoop mainRunLoop] addTimer:scrollTimer_ forMode:NSRunLoopCommonModes];
}
+- (NSScreen*)menuScreen {
+ // Return the parent button's screen for use as the screen upon which all
+ // display happens. This loop over all screens is not equivalent to
+ // |[[button window] screen]|. BookmarkButtons are commonly positioned near
+ // the edge of their windows (both in the bookmark bar and in other bookmark
+ // menus), and |[[button window] screen]| would return the screen that the
+ // majority of their window was on even if the parent button were clearly
+ // contained within a different screen.
+ NSButton* button = parentButton_.get();
+ NSRect parentButtonGlobalFrame =
+ [button convertRect:[button bounds] toView:nil];
+ parentButtonGlobalFrame.origin =
+ [[button window] convertBaseToScreen:parentButtonGlobalFrame.origin];
+ for (NSScreen* screen in [NSScreen screens]) {
+ if (NSIntersectsRect([screen frame], parentButtonGlobalFrame))
+ return screen;
+ }
+
+ // The parent button is offscreen. The ideal thing to do would be to calculate
+ // the "closest" screen, the screen which has an edge parallel to, and the
+ // least distance from, one of the edges of the button. However, popping a
+ // subfolder from an offscreen button is an unrealistic edge case and so this
+ // ideal remains unrealized. Cheat instead; this code is wrong but a lot
+ // simpler.
+ return [[button window] screen];
+}
// Called as a result of our tracking area. Warning: on the main
// screen (of a single-screened machine), the minimum mouse y value is
« no previous file with comments | « chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698