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

Side by Side 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, 9 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h" 5 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h"
6 6
7 #include "base/mac/bundle_locations.h" 7 #include "base/mac/bundle_locations.h"
8 #include "base/strings/sys_string_conversions.h" 8 #include "base/strings/sys_string_conversions.h"
9 #import "chrome/browser/bookmarks/bookmark_model_factory.h" 9 #import "chrome/browser/bookmarks/bookmark_model_factory.h"
10 #import "chrome/browser/bookmarks/chrome_bookmark_client.h" 10 #import "chrome/browser/bookmarks/chrome_bookmark_client.h"
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 } 122 }
123 123
124 } // namespace 124 } // namespace
125 125
126 126
127 // Required to set the right tracking bounds for our fake menus. 127 // Required to set the right tracking bounds for our fake menus.
128 @interface NSView(Private) 128 @interface NSView(Private)
129 - (void)_updateTrackingAreas; 129 - (void)_updateTrackingAreas;
130 @end 130 @end
131 131
132 @interface BookmarkBarFolderController(Private) 132 @interface BookmarkBarFolderController ()
133 - (void)configureWindow; 133 - (void)configureWindow;
134 - (void)addOrUpdateScrollTracking; 134 - (void)addOrUpdateScrollTracking;
135 - (void)removeScrollTracking; 135 - (void)removeScrollTracking;
136 - (void)endScroll; 136 - (void)endScroll;
137 - (void)addScrollTimerWithDelta:(CGFloat)delta; 137 - (void)addScrollTimerWithDelta:(CGFloat)delta;
138 138
139 // Return the screen to which the menu should be restricted. The screen list is
140 // very volatile and can change with very short notice so it isn't worth
141 // caching. http://crbug.com/463458
142 - (NSScreen*)menuScreen;
143
139 // Helper function to configureWindow which performs a basic layout of 144 // Helper function to configureWindow which performs a basic layout of
140 // the window subviews, in particular the menu buttons and the window width. 145 // the window subviews, in particular the menu buttons and the window width.
141 - (void)layOutWindowWithHeight:(CGFloat)height; 146 - (void)layOutWindowWithHeight:(CGFloat)height;
142 147
143 // Determine the best button width (which will be the widest button or the 148 // Determine the best button width (which will be the widest button or the
144 // maximum allowable button width, whichever is less) and resize all buttons. 149 // maximum allowable button width, whichever is less) and resize all buttons.
145 // Return the new width so that the window can be adjusted. 150 // Return the new width so that the window can be adjusted.
146 - (CGFloat)adjustButtonWidths; 151 - (CGFloat)adjustButtonWidths;
147 152
148 // Returns the total menu height needed to display |buttonCount| buttons. 153 // Returns the total menu height needed to display |buttonCount| buttons.
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 ofType:@"nib"]; 259 ofType:@"nib"];
255 if ((self = [super initWithWindowNibPath:nibPath owner:self])) { 260 if ((self = [super initWithWindowNibPath:nibPath owner:self])) {
256 parentButton_.reset([button retain]); 261 parentButton_.reset([button retain]);
257 selectedIndex_ = -1; 262 selectedIndex_ = -1;
258 263
259 profile_ = profile; 264 profile_ = profile;
260 265
261 // We want the button to remain bordered as part of the menu path. 266 // We want the button to remain bordered as part of the menu path.
262 [button forceButtonBorderToStayOnAlways:YES]; 267 [button forceButtonBorderToStayOnAlways:YES];
263 268
264 // Pick the parent button's screen to be the screen upon which all display
265 // happens. This loop over all screens is not equivalent to
266 // |[[button window] screen]|. BookmarkButtons are commonly positioned near
267 // the edge of their windows (both in the bookmark bar and in other bookmark
268 // menus), and |[[button window] screen]| would return the screen that the
269 // majority of their window was on even if the parent button were clearly
270 // contained within a different screen.
271 NSRect parentButtonGlobalFrame =
272 [button convertRect:[button bounds] toView:nil];
273 parentButtonGlobalFrame.origin =
274 [[button window] convertBaseToScreen:parentButtonGlobalFrame.origin];
275 for (NSScreen* screen in [NSScreen screens]) {
276 if (NSIntersectsRect([screen frame], parentButtonGlobalFrame)) {
277 screen_ = screen;
278 break;
279 }
280 }
281 if (!screen_) {
282 // The parent button is offscreen. The ideal thing to do would be to
283 // calculate the "closest" screen, the screen which has an edge parallel
284 // to, and the least distance from, one of the edges of the button.
285 // However, popping a subfolder from an offscreen button is an unrealistic
286 // edge case and so this ideal remains unrealized. Cheat instead; this
287 // code is wrong but a lot simpler.
288 screen_ = [[button window] screen];
289 }
290
291 parentController_.reset([parentController retain]); 269 parentController_.reset([parentController retain]);
292 if (!parentController_) 270 if (!parentController_)
293 [self setSubFolderGrowthToRight:YES]; 271 [self setSubFolderGrowthToRight:YES];
294 else 272 else
295 [self setSubFolderGrowthToRight:[parentController 273 [self setSubFolderGrowthToRight:[parentController
296 subFolderGrowthToRight]]; 274 subFolderGrowthToRight]];
297 barController_ = barController; // WEAK 275 barController_ = barController; // WEAK
298 buttons_.reset([[NSMutableArray alloc] init]); 276 buttons_.reset([[NSMutableArray alloc] init]);
299 folderTarget_.reset( 277 folderTarget_.reset(
300 [[BookmarkFolderTarget alloc] initWithController:self profile:profile]); 278 [[BookmarkFolderTarget alloc] initWithController:self profile:profile]);
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 // since it looks much more menu-like than with none. If we would 439 // since it looks much more menu-like than with none. If we would
462 // grow off the screen, switch growth to the other direction. Growth 440 // grow off the screen, switch growth to the other direction. Growth
463 // direction sticks for folder windows which are descendents of us. 441 // direction sticks for folder windows which are descendents of us.
464 // If we have tried both directions and neither fits, degrade to a 442 // If we have tried both directions and neither fits, degrade to a
465 // default. 443 // default.
466 - (CGFloat)childFolderWindowLeftForWidth:(int)windowWidth { 444 - (CGFloat)childFolderWindowLeftForWidth:(int)windowWidth {
467 // We may legitimately need to try two times (growth to right and 445 // We may legitimately need to try two times (growth to right and
468 // left but not in that order). Limit us to three tries in case 446 // left but not in that order). Limit us to three tries in case
469 // the folder window can't fit on either side of the screen; we 447 // the folder window can't fit on either side of the screen; we
470 // don't want to loop forever. 448 // don't want to loop forever.
449 NSRect screenVisibleFrame = [[self menuScreen] visibleFrame];
471 CGFloat x; 450 CGFloat x;
472 int tries = 0; 451 int tries = 0;
473 while (tries < 2) { 452 while (tries < 2) {
474 // Try to grow right. 453 // Try to grow right.
475 if ([self subFolderGrowthToRight]) { 454 if ([self subFolderGrowthToRight]) {
476 tries++; 455 tries++;
477 x = NSMaxX([[parentButton_ window] frame]) - 456 x = NSMaxX([[parentButton_ window] frame]) -
478 bookmarks::kBookmarkMenuOverlap; 457 bookmarks::kBookmarkMenuOverlap;
479 // If off the screen, switch direction. 458 // If off the screen, switch direction.
480 if ((x + windowWidth + 459 if ((x + windowWidth + bookmarks::kBookmarkHorizontalScreenPadding) >
481 bookmarks::kBookmarkHorizontalScreenPadding) > 460 NSMaxX(screenVisibleFrame)) {
482 NSMaxX([screen_ visibleFrame])) {
483 [self setSubFolderGrowthToRight:NO]; 461 [self setSubFolderGrowthToRight:NO];
484 } else { 462 } else {
485 return x; 463 return x;
486 } 464 }
487 } 465 }
488 // Try to grow left. 466 // Try to grow left.
489 if (![self subFolderGrowthToRight]) { 467 if (![self subFolderGrowthToRight]) {
490 tries++; 468 tries++;
491 x = NSMinX([[parentButton_ window] frame]) + 469 x = NSMinX([[parentButton_ window] frame]) +
492 bookmarks::kBookmarkMenuOverlap - 470 bookmarks::kBookmarkMenuOverlap -
493 windowWidth; 471 windowWidth;
494 // If off the screen, switch direction. 472 // If off the screen, switch direction.
495 if (x < NSMinX([screen_ visibleFrame])) { 473 if (x < NSMinX(screenVisibleFrame)) {
496 [self setSubFolderGrowthToRight:YES]; 474 [self setSubFolderGrowthToRight:YES];
497 } else { 475 } else {
498 return x; 476 return x;
499 } 477 }
500 } 478 }
501 } 479 }
502 // Unhappy; do the best we can. 480 // Unhappy; do the best we can.
503 return NSMaxX([screen_ visibleFrame]) - windowWidth; 481 return NSMaxX(screenVisibleFrame) - windowWidth;
504 } 482 }
505 483
506 484
507 // Compute and return the top left point of our window (screen 485 // Compute and return the top left point of our window (screen
508 // coordinates). The top left is positioned in a manner similar to 486 // coordinates). The top left is positioned in a manner similar to
509 // cascading menus. Windows may grow to either the right or left of 487 // cascading menus. Windows may grow to either the right or left of
510 // their parent (if a sub-folder) so we need to know |windowWidth|. 488 // their parent (if a sub-folder) so we need to know |windowWidth|.
511 - (NSPoint)windowTopLeftForWidth:(int)windowWidth height:(int)windowHeight { 489 - (NSPoint)windowTopLeftForWidth:(int)windowWidth height:(int)windowHeight {
512 CGFloat kMinSqueezedMenuHeight = bookmarks::kBookmarkFolderButtonHeight * 2.0; 490 CGFloat kMinSqueezedMenuHeight = bookmarks::kBookmarkFolderButtonHeight * 2.0;
513 NSPoint newWindowTopLeft; 491 NSPoint newWindowTopLeft;
514 if (![parentController_ isKindOfClass:[self class]]) { 492 if (![parentController_ isKindOfClass:[self class]]) {
515 // If we're not popping up from one of ourselves, we must be 493 // If we're not popping up from one of ourselves, we must be
516 // popping up from the bookmark bar itself. In this case, start 494 // popping up from the bookmark bar itself. In this case, start
517 // BELOW the parent button. Our left is the button left; our top 495 // BELOW the parent button. Our left is the button left; our top
518 // is bottom of button's parent view. 496 // is bottom of button's parent view.
519 NSPoint buttonBottomLeftInScreen = 497 NSPoint buttonBottomLeftInScreen =
520 [[parentButton_ window] 498 [[parentButton_ window]
521 convertBaseToScreen:[parentButton_ 499 convertBaseToScreen:[parentButton_
522 convertPoint:NSZeroPoint toView:nil]]; 500 convertPoint:NSZeroPoint toView:nil]];
523 NSPoint bookmarkBarBottomLeftInScreen = 501 NSPoint bookmarkBarBottomLeftInScreen =
524 [[parentButton_ window] 502 [[parentButton_ window]
525 convertBaseToScreen:[[parentButton_ superview] 503 convertBaseToScreen:[[parentButton_ superview]
526 convertPoint:NSZeroPoint toView:nil]]; 504 convertPoint:NSZeroPoint toView:nil]];
527 newWindowTopLeft = NSMakePoint( 505 newWindowTopLeft = NSMakePoint(
528 buttonBottomLeftInScreen.x + bookmarks::kBookmarkBarButtonOffset, 506 buttonBottomLeftInScreen.x + bookmarks::kBookmarkBarButtonOffset,
529 bookmarkBarBottomLeftInScreen.y + bookmarks::kBookmarkBarMenuOffset); 507 bookmarkBarBottomLeftInScreen.y + bookmarks::kBookmarkBarMenuOffset);
530 // Make sure the window is on-screen; if not, push left or right. It is 508 // Make sure the window is on-screen; if not, push left or right. It is
531 // intentional that top level folders "push left" or "push right" slightly 509 // intentional that top level folders "push left" or "push right" slightly
532 // different than subfolders. 510 // different than subfolders.
533 NSRect screenFrame = [screen_ visibleFrame]; 511 NSRect screenVisibleFrame = [[self menuScreen] visibleFrame];
534 // Test if window goes off-screen on the right side. 512 // Test if window goes off-screen on the right side.
535 CGFloat spillOff = (newWindowTopLeft.x + windowWidth) - NSMaxX(screenFrame); 513 CGFloat spillOff =
514 newWindowTopLeft.x + windowWidth - NSMaxX(screenVisibleFrame);
536 if (spillOff > 0.0) { 515 if (spillOff > 0.0) {
537 newWindowTopLeft.x = std::max(newWindowTopLeft.x - spillOff, 516 newWindowTopLeft.x = std::max(newWindowTopLeft.x - spillOff,
538 NSMinX(screenFrame)); 517 NSMinX(screenVisibleFrame));
539 } else if (newWindowTopLeft.x < NSMinX(screenFrame)) { 518 } else if (newWindowTopLeft.x < NSMinX(screenVisibleFrame)) {
540 // For left side. 519 // For left side.
541 newWindowTopLeft.x = NSMinX(screenFrame); 520 newWindowTopLeft.x = NSMinX(screenVisibleFrame);
542 } 521 }
543 // The menu looks bad when it is squeezed up against the bottom of the 522 // The menu looks bad when it is squeezed up against the bottom of the
544 // screen and ends up being only a few pixels tall. If it meets the 523 // screen and ends up being only a few pixels tall. If it meets the
545 // threshold for this case, instead show the menu above the button. 524 // threshold for this case, instead show the menu above the button.
546 CGFloat availableVerticalSpace = newWindowTopLeft.y - 525 CGFloat availableVerticalSpace = newWindowTopLeft.y -
547 (NSMinY(screenFrame) + bookmarks::kScrollWindowVerticalMargin); 526 (NSMinY(screenVisibleFrame) + bookmarks::kScrollWindowVerticalMargin);
548 if ((availableVerticalSpace < kMinSqueezedMenuHeight) && 527 if ((availableVerticalSpace < kMinSqueezedMenuHeight) &&
549 (windowHeight > availableVerticalSpace)) { 528 (windowHeight > availableVerticalSpace)) {
550 newWindowTopLeft.y = std::min( 529 newWindowTopLeft.y = std::min(
551 newWindowTopLeft.y + windowHeight + NSHeight([parentButton_ frame]), 530 newWindowTopLeft.y + windowHeight + NSHeight([parentButton_ frame]),
552 NSMaxY(screenFrame)); 531 NSMaxY(screenVisibleFrame));
553 } 532 }
554 } else { 533 } else {
555 // Parent is a folder: expose as much as we can vertically; grow right/left. 534 // Parent is a folder: expose as much as we can vertically; grow right/left.
556 newWindowTopLeft.x = [self childFolderWindowLeftForWidth:windowWidth]; 535 newWindowTopLeft.x = [self childFolderWindowLeftForWidth:windowWidth];
557 NSPoint topOfWindow = NSMakePoint(0, 536 NSPoint topOfWindow = NSMakePoint(0,
558 NSMaxY([parentButton_ frame]) - 537 NSMaxY([parentButton_ frame]) -
559 bookmarks::kBookmarkVerticalPadding); 538 bookmarks::kBookmarkVerticalPadding);
560 topOfWindow = [[parentButton_ window] 539 topOfWindow = [[parentButton_ window]
561 convertBaseToScreen:[[parentButton_ superview] 540 convertBaseToScreen:[[parentButton_ superview]
562 convertPoint:topOfWindow toView:nil]]; 541 convertPoint:topOfWindow toView:nil]];
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 metrics.couldScrollUp = ![scrollUpArrowView_ isHidden]; 587 metrics.couldScrollUp = ![scrollUpArrowView_ isHidden];
609 metrics.couldScrollDown = ![scrollDownArrowView_ isHidden]; 588 metrics.couldScrollDown = ![scrollDownArrowView_ isHidden];
610 589
611 metrics.deltaWindowHeight = 0.0; 590 metrics.deltaWindowHeight = 0.0;
612 metrics.deltaWindowY = 0.0; 591 metrics.deltaWindowY = 0.0;
613 metrics.deltaVisibleHeight = 0.0; 592 metrics.deltaVisibleHeight = 0.0;
614 metrics.deltaVisibleY = 0.0; 593 metrics.deltaVisibleY = 0.0;
615 metrics.deltaScrollerHeight = 0.0; 594 metrics.deltaScrollerHeight = 0.0;
616 metrics.deltaScrollerY = 0.0; 595 metrics.deltaScrollerY = 0.0;
617 596
618 metrics.minimumY = NSMinY([screen_ visibleFrame]) + 597 metrics.minimumY = NSMinY([[self menuScreen] visibleFrame]) +
619 bookmarks::kScrollWindowVerticalMargin; 598 bookmarks::kScrollWindowVerticalMargin;
620 metrics.screenBottomY = NSMinY([screen_ frame]); 599 metrics.screenBottomY = NSMinY([[self menuScreen] frame]);
621 metrics.oldWindowY = NSMinY(metrics.windowFrame); 600 metrics.oldWindowY = NSMinY(metrics.windowFrame);
622 metrics.folderY = 601 metrics.folderY =
623 metrics.scrollerFrame.origin.y + metrics.visibleFrame.origin.y + 602 metrics.scrollerFrame.origin.y + metrics.visibleFrame.origin.y +
624 metrics.oldWindowY - metrics.scrollPoint.y; 603 metrics.oldWindowY - metrics.scrollPoint.y;
625 metrics.folderTop = metrics.folderY + NSHeight([folderView_ frame]); 604 metrics.folderTop = metrics.folderY + NSHeight([folderView_ frame]);
626 } 605 }
627 606
628 - (void)adjustMetrics:(LayoutMetrics*)layoutMetrics { 607 - (void)adjustMetrics:(LayoutMetrics*)layoutMetrics {
629 LayoutMetrics& metrics(*layoutMetrics); 608 LayoutMetrics& metrics(*layoutMetrics);
630 CGFloat effectiveFolderY = metrics.folderY; 609 CGFloat effectiveFolderY = metrics.folderY;
631 if (!metrics.couldScrollUp && !metrics.couldScrollDown) 610 if (!metrics.couldScrollUp && !metrics.couldScrollDown)
632 effectiveFolderY -= metrics.windowSize.height; 611 effectiveFolderY -= metrics.windowSize.height;
633 metrics.canScrollUp = effectiveFolderY < metrics.minimumY; 612 metrics.canScrollUp = effectiveFolderY < metrics.minimumY;
634 CGFloat maximumY = 613 CGFloat maximumY =
635 NSMaxY([screen_ visibleFrame]) - bookmarks::kScrollWindowVerticalMargin; 614 NSMaxY([[self menuScreen] visibleFrame]) -
615 bookmarks::kScrollWindowVerticalMargin;
636 metrics.canScrollDown = metrics.folderTop > maximumY; 616 metrics.canScrollDown = metrics.folderTop > maximumY;
637 617
638 // Accommodate changes in the bottom of the menu. 618 // Accommodate changes in the bottom of the menu.
639 [self adjustMetricsForMenuBottomChanges:layoutMetrics]; 619 [self adjustMetricsForMenuBottomChanges:layoutMetrics];
640 620
641 // Accommodate changes in the top of the menu. 621 // Accommodate changes in the top of the menu.
642 [self adjustMetricsForMenuTopChanges:layoutMetrics]; 622 [self adjustMetricsForMenuTopChanges:layoutMetrics];
643 623
644 metrics.scrollerFrame.origin.y += metrics.deltaScrollerY; 624 metrics.scrollerFrame.origin.y += metrics.deltaScrollerY;
645 metrics.scrollerFrame.size.height += metrics.deltaScrollerHeight; 625 metrics.scrollerFrame.size.height += metrics.deltaScrollerHeight;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 - (void)adjustMetricsForMenuTopChanges:(LayoutMetrics*)layoutMetrics { 680 - (void)adjustMetricsForMenuTopChanges:(LayoutMetrics*)layoutMetrics {
701 LayoutMetrics& metrics(*layoutMetrics); 681 LayoutMetrics& metrics(*layoutMetrics);
702 if (metrics.canScrollDown == metrics.couldScrollDown) { 682 if (metrics.canScrollDown == metrics.couldScrollDown) {
703 if (!metrics.canScrollDown) { 683 if (!metrics.canScrollDown) {
704 // Not scroll-down-able but the menu top has changed. 684 // Not scroll-down-able but the menu top has changed.
705 metrics.deltaWindowHeight += metrics.scrollDelta; 685 metrics.deltaWindowHeight += metrics.scrollDelta;
706 } 686 }
707 } else { 687 } else {
708 if (metrics.canScrollDown) { 688 if (metrics.canScrollDown) {
709 // Couldn't -> Can 689 // Couldn't -> Can
710 const CGFloat maximumY = NSMaxY([screen_ visibleFrame]); 690 const CGFloat maximumY = NSMaxY([[self menuScreen] visibleFrame]);
711 metrics.deltaWindowHeight += (maximumY - NSMaxY(metrics.windowFrame)); 691 metrics.deltaWindowHeight += (maximumY - NSMaxY(metrics.windowFrame));
712 metrics.deltaVisibleHeight -= bookmarks::kScrollWindowVerticalMargin; 692 metrics.deltaVisibleHeight -= bookmarks::kScrollWindowVerticalMargin;
713 metrics.deltaScrollerHeight -= verticalScrollArrowHeight_; 693 metrics.deltaScrollerHeight -= verticalScrollArrowHeight_;
714 } else { 694 } else {
715 // Could -> Can't 695 // Could -> Can't
716 metrics.deltaWindowHeight -= bookmarks::kScrollWindowVerticalMargin; 696 metrics.deltaWindowHeight -= bookmarks::kScrollWindowVerticalMargin;
717 metrics.deltaVisibleHeight += bookmarks::kScrollWindowVerticalMargin; 697 metrics.deltaVisibleHeight += bookmarks::kScrollWindowVerticalMargin;
718 metrics.deltaScrollerHeight += verticalScrollArrowHeight_; 698 metrics.deltaScrollerHeight += verticalScrollArrowHeight_;
719 } 699 }
720 } 700 }
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 // Lay out the window by adjusting all button widths to be consistent, then 812 // Lay out the window by adjusting all button widths to be consistent, then
833 // base the window width on this ideal button width. 813 // base the window width on this ideal button width.
834 CGFloat buttonWidth = [self adjustButtonWidths]; 814 CGFloat buttonWidth = [self adjustButtonWidths];
835 CGFloat windowWidth = buttonWidth + padding_; 815 CGFloat windowWidth = buttonWidth + padding_;
836 NSPoint newWindowTopLeft = [self windowTopLeftForWidth:windowWidth 816 NSPoint newWindowTopLeft = [self windowTopLeftForWidth:windowWidth
837 height:height]; 817 height:height];
838 818
839 // Make sure as much of a submenu is exposed (which otherwise would be a 819 // Make sure as much of a submenu is exposed (which otherwise would be a
840 // problem if the parent button is close to the bottom of the screen). 820 // problem if the parent button is close to the bottom of the screen).
841 if ([parentController_ isKindOfClass:[self class]]) { 821 if ([parentController_ isKindOfClass:[self class]]) {
842 CGFloat minimumY = NSMinY([screen_ visibleFrame]) + 822 CGFloat minimumY = NSMinY([[self menuScreen] visibleFrame]) +
843 bookmarks::kScrollWindowVerticalMargin + 823 bookmarks::kScrollWindowVerticalMargin +
844 height; 824 height;
845 newWindowTopLeft.y = MAX(newWindowTopLeft.y, minimumY); 825 newWindowTopLeft.y = MAX(newWindowTopLeft.y, minimumY);
846 } 826 }
847 827
848 NSWindow* window = [self window]; 828 NSWindow* window = [self window];
849 NSRect windowFrame = NSMakeRect(newWindowTopLeft.x, 829 NSRect windowFrame = NSMakeRect(newWindowTopLeft.x,
850 newWindowTopLeft.y - height, 830 newWindowTopLeft.y - height,
851 windowWidth, height); 831 windowWidth, height);
852 [window setFrame:windowFrame display:NO]; 832 [window setFrame:windowFrame display:NO];
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 index++; 957 index++;
978 } 958 }
979 } 959 }
980 } 960 }
981 961
982 - (CGFloat)determineFinalScrollDelta:(CGFloat)delta { 962 - (CGFloat)determineFinalScrollDelta:(CGFloat)delta {
983 if ((delta > 0.0 && ![scrollUpArrowView_ isHidden]) || 963 if ((delta > 0.0 && ![scrollUpArrowView_ isHidden]) ||
984 (delta < 0.0 && ![scrollDownArrowView_ isHidden])) { 964 (delta < 0.0 && ![scrollDownArrowView_ isHidden])) {
985 NSWindow* window = [self window]; 965 NSWindow* window = [self window];
986 NSRect windowFrame = [window frame]; 966 NSRect windowFrame = [window frame];
967 NSRect screenVisibleFrame = [[self menuScreen] visibleFrame];
987 NSPoint scrollPosition = [scrollView_ documentVisibleRect].origin; 968 NSPoint scrollPosition = [scrollView_ documentVisibleRect].origin;
988 CGFloat scrollY = scrollPosition.y; 969 CGFloat scrollY = scrollPosition.y;
989 NSRect scrollerFrame = [scrollView_ frame]; 970 NSRect scrollerFrame = [scrollView_ frame];
990 CGFloat scrollerY = NSMinY(scrollerFrame); 971 CGFloat scrollerY = NSMinY(scrollerFrame);
991 NSRect visibleFrame = [visibleView_ frame]; 972 NSRect visibleFrame = [visibleView_ frame];
992 CGFloat visibleY = NSMinY(visibleFrame); 973 CGFloat visibleY = NSMinY(visibleFrame);
993 CGFloat windowY = NSMinY(windowFrame); 974 CGFloat windowY = NSMinY(windowFrame);
994 CGFloat offset = scrollerY + visibleY + windowY; 975 CGFloat offset = scrollerY + visibleY + windowY;
995 976
996 if (delta > 0.0) { 977 if (delta > 0.0) {
997 // Scrolling up. 978 // Scrolling up.
998 CGFloat minimumY = NSMinY([screen_ visibleFrame]) + 979 CGFloat minimumY = NSMinY(screenVisibleFrame) +
999 bookmarks::kScrollWindowVerticalMargin; 980 bookmarks::kScrollWindowVerticalMargin;
1000 CGFloat maxUpDelta = scrollY - offset + minimumY; 981 CGFloat maxUpDelta = scrollY - offset + minimumY;
1001 delta = MIN(delta, maxUpDelta); 982 delta = MIN(delta, maxUpDelta);
1002 } else { 983 } else {
1003 // Scrolling down. 984 // Scrolling down.
1004 NSRect screenFrame = [screen_ visibleFrame]; 985 CGFloat topOfScreen = NSMaxY(screenVisibleFrame);
1005 CGFloat topOfScreen = NSMaxY(screenFrame);
1006 NSRect folderFrame = [folderView_ frame]; 986 NSRect folderFrame = [folderView_ frame];
1007 CGFloat folderHeight = NSHeight(folderFrame); 987 CGFloat folderHeight = NSHeight(folderFrame);
1008 CGFloat folderTop = folderHeight - scrollY + offset; 988 CGFloat folderTop = folderHeight - scrollY + offset;
1009 CGFloat maxDownDelta = 989 CGFloat maxDownDelta =
1010 topOfScreen - folderTop - bookmarks::kScrollWindowVerticalMargin; 990 topOfScreen - folderTop - bookmarks::kScrollWindowVerticalMargin;
1011 delta = MAX(delta, maxDownDelta); 991 delta = MAX(delta, maxDownDelta);
1012 } 992 }
1013 } else { 993 } else {
1014 delta = 0.0; 994 delta = 0.0;
1015 } 995 }
(...skipping 17 matching lines...) Expand all
1033 verticalScrollDelta_ = delta; 1013 verticalScrollDelta_ = delta;
1034 scrollTimer_ = [NSTimer timerWithTimeInterval:kBookmarkBarFolderScrollInterval 1014 scrollTimer_ = [NSTimer timerWithTimeInterval:kBookmarkBarFolderScrollInterval
1035 target:self 1015 target:self
1036 selector:@selector(performScroll:) 1016 selector:@selector(performScroll:)
1037 userInfo:nil 1017 userInfo:nil
1038 repeats:YES]; 1018 repeats:YES];
1039 1019
1040 [[NSRunLoop mainRunLoop] addTimer:scrollTimer_ forMode:NSRunLoopCommonModes]; 1020 [[NSRunLoop mainRunLoop] addTimer:scrollTimer_ forMode:NSRunLoopCommonModes];
1041 } 1021 }
1042 1022
1023 - (NSScreen*)menuScreen {
1024 // Return the parent button's screen for use as the screen upon which all
1025 // display happens. This loop over all screens is not equivalent to
1026 // |[[button window] screen]|. BookmarkButtons are commonly positioned near
1027 // the edge of their windows (both in the bookmark bar and in other bookmark
1028 // menus), and |[[button window] screen]| would return the screen that the
1029 // majority of their window was on even if the parent button were clearly
1030 // contained within a different screen.
1031 NSButton* button = parentButton_.get();
1032 NSRect parentButtonGlobalFrame =
1033 [button convertRect:[button bounds] toView:nil];
1034 parentButtonGlobalFrame.origin =
1035 [[button window] convertBaseToScreen:parentButtonGlobalFrame.origin];
1036 for (NSScreen* screen in [NSScreen screens]) {
1037 if (NSIntersectsRect([screen frame], parentButtonGlobalFrame))
1038 return screen;
1039 }
1040
1041 // The parent button is offscreen. The ideal thing to do would be to calculate
1042 // the "closest" screen, the screen which has an edge parallel to, and the
1043 // least distance from, one of the edges of the button. However, popping a
1044 // subfolder from an offscreen button is an unrealistic edge case and so this
1045 // ideal remains unrealized. Cheat instead; this code is wrong but a lot
1046 // simpler.
1047 return [[button window] screen];
1048 }
1043 1049
1044 // Called as a result of our tracking area. Warning: on the main 1050 // Called as a result of our tracking area. Warning: on the main
1045 // screen (of a single-screened machine), the minimum mouse y value is 1051 // screen (of a single-screened machine), the minimum mouse y value is
1046 // 1, not 0. Also, we do not get events when the mouse is above the 1052 // 1, not 0. Also, we do not get events when the mouse is above the
1047 // menubar (to be fixed by setting the proper window level; see 1053 // menubar (to be fixed by setting the proper window level; see
1048 // initializer). 1054 // initializer).
1049 // Note [theEvent window] may not be our window, as we also get these messages 1055 // Note [theEvent window] may not be our window, as we also get these messages
1050 // forwarded from BookmarkButton's mouse tracking loop. 1056 // forwarded from BookmarkButton's mouse tracking loop.
1051 - (void)mouseMovedOrDragged:(NSEvent*)theEvent { 1057 - (void)mouseMovedOrDragged:(NSEvent*)theEvent {
1052 NSPoint eventScreenLocation = 1058 NSPoint eventScreenLocation =
(...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after
2013 2019
2014 - (void)setIgnoreAnimations:(BOOL)ignore { 2020 - (void)setIgnoreAnimations:(BOOL)ignore {
2015 ignoreAnimations_ = ignore; 2021 ignoreAnimations_ = ignore;
2016 } 2022 }
2017 2023
2018 - (BookmarkButton*)buttonThatMouseIsIn { 2024 - (BookmarkButton*)buttonThatMouseIsIn {
2019 return buttonThatMouseIsIn_; 2025 return buttonThatMouseIsIn_;
2020 } 2026 }
2021 2027
2022 @end // BookmarkBarFolderController 2028 @end // BookmarkBarFolderController
OLDNEW
« 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