OLD | NEW |
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/browser_window_controller_private.h" | 5 #import "chrome/browser/ui/cocoa/browser_window_controller_private.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #import "base/memory/scoped_nsobject.h" | 10 #import "base/memory/scoped_nsobject.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #import "chrome/browser/ui/cocoa/fullscreen_window.h" | 25 #import "chrome/browser/ui/cocoa/fullscreen_window.h" |
26 #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" | 26 #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" |
27 #import "chrome/browser/ui/cocoa/nsview_additions.h" | 27 #import "chrome/browser/ui/cocoa/nsview_additions.h" |
28 #import "chrome/browser/ui/cocoa/presentation_mode_controller.h" | 28 #import "chrome/browser/ui/cocoa/presentation_mode_controller.h" |
29 #import "chrome/browser/ui/cocoa/status_bubble_mac.h" | 29 #import "chrome/browser/ui/cocoa/status_bubble_mac.h" |
30 #import "chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.h" | 30 #import "chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.h" |
31 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" | 31 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" |
32 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" | 32 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" |
33 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" | 33 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" |
34 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h" | 34 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h" |
| 35 #include "chrome/browser/ui/search/search_model.h" |
35 #include "chrome/browser/ui/search/search_ui.h" | 36 #include "chrome/browser/ui/search/search_ui.h" |
36 #include "chrome/common/chrome_switches.h" | 37 #include "chrome/common/chrome_switches.h" |
37 #include "chrome/common/pref_names.h" | 38 #include "chrome/common/pref_names.h" |
38 #include "content/public/browser/render_widget_host_view.h" | 39 #include "content/public/browser/render_widget_host_view.h" |
39 #include "content/public/browser/web_contents.h" | 40 #include "content/public/browser/web_contents.h" |
40 #include "content/public/browser/web_contents_view.h" | 41 #include "content/public/browser/web_contents_view.h" |
41 #import "ui/base/cocoa/focus_tracker.h" | 42 #import "ui/base/cocoa/focus_tracker.h" |
42 #include "ui/base/ui_base_types.h" | 43 #include "ui/base/ui_base_types.h" |
43 | 44 |
44 using content::RenderWidgetHostView; | 45 using content::RenderWidgetHostView; |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 NSView* contentView = [window contentView]; | 170 NSView* contentView = [window contentView]; |
170 NSRect contentBounds = [contentView bounds]; | 171 NSRect contentBounds = [contentView bounds]; |
171 CGFloat minX = NSMinX(contentBounds); | 172 CGFloat minX = NSMinX(contentBounds); |
172 CGFloat minY = NSMinY(contentBounds); | 173 CGFloat minY = NSMinY(contentBounds); |
173 CGFloat width = NSWidth(contentBounds); | 174 CGFloat width = NSWidth(contentBounds); |
174 | 175 |
175 // Suppress title drawing if necessary. | 176 // Suppress title drawing if necessary. |
176 if ([window respondsToSelector:@selector(setShouldHideTitle:)]) | 177 if ([window respondsToSelector:@selector(setShouldHideTitle:)]) |
177 [(id)window setShouldHideTitle:![self hasTitleBar]]; | 178 [(id)window setShouldHideTitle:![self hasTitleBar]]; |
178 | 179 |
| 180 // Update z-order. The code below depends on this. |
| 181 [self updateSubviewZOrder]; |
| 182 |
179 BOOL inPresentationMode = [self inPresentationMode]; | 183 BOOL inPresentationMode = [self inPresentationMode]; |
180 CGFloat floatingBarHeight = [self floatingBarHeight]; | 184 CGFloat floatingBarHeight = [self floatingBarHeight]; |
181 // In presentation mode, |yOffset| accounts for the sliding position of the | 185 // In presentation mode, |yOffset| accounts for the sliding position of the |
182 // floating bar and the extra offset needed to dodge the menu bar. | 186 // floating bar and the extra offset needed to dodge the menu bar. |
183 CGFloat yOffset = inPresentationMode ? | 187 CGFloat yOffset = inPresentationMode ? |
184 (std::floor((1 - floatingBarShownFraction_) * floatingBarHeight) - | 188 (std::floor((1 - floatingBarShownFraction_) * floatingBarHeight) - |
185 [presentationModeController_ floatingBarVerticalOffset]) : 0; | 189 [presentationModeController_ floatingBarVerticalOffset]) : 0; |
186 CGFloat maxY = NSMaxY(contentBounds) + yOffset; | 190 CGFloat maxY = NSMaxY(contentBounds) + yOffset; |
187 | 191 |
188 if ([self hasTabStrip]) { | 192 if ([self hasTabStrip]) { |
189 // If we need to lay out the top tab strip, replace |maxY| with a higher | 193 // If we need to lay out the top tab strip, replace |maxY| with a higher |
190 // value, and then lay out the tab strip. | 194 // value, and then lay out the tab strip. |
191 NSRect windowFrame = [contentView convertRect:[window frame] fromView:nil]; | 195 NSRect windowFrame = [contentView convertRect:[window frame] fromView:nil]; |
192 maxY = NSHeight(windowFrame) + yOffset; | 196 maxY = NSHeight(windowFrame) + yOffset; |
193 maxY = [self layoutTabStripAtMaxY:maxY | 197 maxY = [self layoutTabStripAtMaxY:maxY |
194 width:width | 198 width:width |
195 fullscreen:[self isFullscreen]]; | 199 fullscreen:[self isFullscreen]]; |
196 } | 200 } |
197 | 201 |
198 // Sanity-check |maxY|. | 202 // Sanity-check |maxY|. |
199 DCHECK_GE(maxY, minY); | 203 DCHECK_GE(maxY, minY); |
200 DCHECK_LE(maxY, NSMaxY(contentBounds) + yOffset); | 204 DCHECK_LE(maxY, NSMaxY(contentBounds) + yOffset); |
201 | 205 |
202 // Place the toolbar at the top of the reserved area. | 206 // Place the toolbar at the top of the reserved area. |
203 maxY = [self layoutToolbarAtMinX:minX maxY:maxY width:width]; | 207 maxY = [self layoutToolbarAtMinX:minX maxY:maxY width:width]; |
| 208 CGFloat toolbarBottomY = maxY; |
204 | 209 |
205 // If we're not displaying the bookmark bar below the infobar, then it goes | 210 // If we're not displaying the bookmark bar below the infobar, then it goes |
206 // immediately below the toolbar. | 211 // immediately below the toolbar. |
207 BOOL placeBookmarkBarBelowInfoBar = [self placeBookmarkBarBelowInfoBar]; | 212 BOOL placeBookmarkBarBelowInfoBar = [self placeBookmarkBarBelowInfoBar]; |
208 if (!placeBookmarkBarBelowInfoBar) | 213 if (!placeBookmarkBarBelowInfoBar) |
209 maxY = [self layoutTopBookmarkBarAtMinX:minX maxY:maxY width:width]; | 214 maxY = [self layoutTopBookmarkBarAtMinX:minX maxY:maxY width:width]; |
210 | 215 |
211 // The floating bar backing view doesn't actually add any height. | 216 // The floating bar backing view doesn't actually add any height. |
212 NSRect floatingBarBackingRect = | 217 NSRect floatingBarBackingRect = |
213 NSMakeRect(minX, maxY, width, floatingBarHeight); | 218 NSMakeRect(minX, maxY, width, floatingBarHeight); |
(...skipping 21 matching lines...) Expand all Loading... |
235 // Place the bookmark bar. | 240 // Place the bookmark bar. |
236 if (placeBookmarkBarBelowInfoBar) { | 241 if (placeBookmarkBarBelowInfoBar) { |
237 if ([bookmarkBarController_ shouldShowAtBottomWhenDetached]) { | 242 if ([bookmarkBarController_ shouldShowAtBottomWhenDetached]) { |
238 [self layoutBottomBookmarkBarInContentFrame: | 243 [self layoutBottomBookmarkBarInContentFrame: |
239 NSMakeRect(minX, minY, width, maxY - minY)]; | 244 NSMakeRect(minX, minY, width, maxY - minY)]; |
240 } else { | 245 } else { |
241 maxY = [self layoutTopBookmarkBarAtMinX:minX maxY:maxY width:width]; | 246 maxY = [self layoutTopBookmarkBarAtMinX:minX maxY:maxY width:width]; |
242 } | 247 } |
243 } | 248 } |
244 | 249 |
245 // Finally, the content area takes up all of the remaining space. | 250 // In presentation mode the content area takes up all the remaining space |
246 NSRect contentAreaRect = NSMakeRect(minX, minY, width, maxY - minY); | 251 // (from the bottom of the infobar down). In normal mode the content area |
| 252 // takes up the space between the bottom of the toolbar down. |
| 253 CGFloat contentAreaTop = 0; |
| 254 if (inPresentationMode) { |
| 255 toolbarToWebContentsOffset_ = 0; |
| 256 contentAreaTop = maxY; |
| 257 } else { |
| 258 toolbarToWebContentsOffset_ = toolbarBottomY - maxY; |
| 259 contentAreaTop = toolbarBottomY; |
| 260 } |
| 261 [self updateContentOffsets]; |
| 262 |
| 263 NSRect contentAreaRect = NSMakeRect(minX, minY, width, contentAreaTop - minY); |
247 [self layoutTabContentArea:contentAreaRect]; | 264 [self layoutTabContentArea:contentAreaRect]; |
248 | 265 |
249 // Normally, we don't need to tell the toolbar whether or not to show the | 266 // Normally, we don't need to tell the toolbar whether or not to show the |
250 // divider, but things break down during animation. | 267 // divider, but things break down during animation. |
251 [toolbarController_ | 268 [toolbarController_ setDividerOpacity:[self toolbarDividerOpacity]]; |
252 setDividerOpacity:[bookmarkBarController_ toolbarDividerOpacity]]; | |
253 } | 269 } |
254 | 270 |
255 - (CGFloat)floatingBarHeight { | 271 - (CGFloat)floatingBarHeight { |
256 if (![self inPresentationMode]) | 272 if (![self inPresentationMode]) |
257 return 0; | 273 return 0; |
258 | 274 |
259 CGFloat totalHeight = [presentationModeController_ floatingBarVerticalOffset]; | 275 CGFloat totalHeight = [presentationModeController_ floatingBarVerticalOffset]; |
260 | 276 |
261 if ([self hasTabStrip]) | 277 if ([self hasTabStrip]) |
262 totalHeight += NSHeight([[self tabStripView] frame]); | 278 totalHeight += NSHeight([[self tabStripView] frame]); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 } | 434 } |
419 | 435 |
420 - (void)layoutFloatingBarBackingView:(NSRect)frame | 436 - (void)layoutFloatingBarBackingView:(NSRect)frame |
421 presentationMode:(BOOL)presentationMode { | 437 presentationMode:(BOOL)presentationMode { |
422 // Only display when in presentation mode. | 438 // Only display when in presentation mode. |
423 if (presentationMode) { | 439 if (presentationMode) { |
424 // For certain window types such as app windows (e.g., the dev tools | 440 // For certain window types such as app windows (e.g., the dev tools |
425 // window), there's no actual overlay. (Displaying one would result in an | 441 // window), there's no actual overlay. (Displaying one would result in an |
426 // overly sliding in only under the menu, which gives an ugly effect.) | 442 // overly sliding in only under the menu, which gives an ugly effect.) |
427 if (floatingBarBackingView_.get()) { | 443 if (floatingBarBackingView_.get()) { |
428 BOOL aboveBookmarkBar = [self placeBookmarkBarBelowInfoBar]; | |
429 | |
430 // Insert it into the view hierarchy if necessary. | |
431 if (![floatingBarBackingView_ superview] || | |
432 aboveBookmarkBar != floatingBarAboveBookmarkBar_) { | |
433 NSView* contentView = [[self window] contentView]; | |
434 // z-order gets messed up unless we explicitly remove the floatingbar | |
435 // view and re-add it. | |
436 [floatingBarBackingView_ removeFromSuperview]; | |
437 [contentView addSubview:floatingBarBackingView_ | |
438 positioned:(aboveBookmarkBar ? | |
439 NSWindowAbove : NSWindowBelow) | |
440 relativeTo:[bookmarkBarController_ view]]; | |
441 floatingBarAboveBookmarkBar_ = aboveBookmarkBar; | |
442 } | |
443 | |
444 // Set its frame. | 444 // Set its frame. |
445 [floatingBarBackingView_ setFrame:frame]; | 445 [floatingBarBackingView_ setFrame:frame]; |
446 } | 446 } |
447 | 447 |
448 // But we want the logic to work as usual (for show/hide/etc. purposes). | 448 // But we want the logic to work as usual (for show/hide/etc. purposes). |
449 [presentationModeController_ overlayFrameChanged:frame]; | 449 [presentationModeController_ overlayFrameChanged:frame]; |
450 } else { | 450 } else { |
451 // Okay to call even if |floatingBarBackingView_| is nil. | 451 // Okay to call even if |floatingBarBackingView_| is nil. |
452 if ([floatingBarBackingView_ superview]) | 452 if ([floatingBarBackingView_ superview]) |
453 [floatingBarBackingView_ removeFromSuperview]; | 453 [floatingBarBackingView_ removeFromSuperview]; |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 - (void)adjustUIForPresentationMode:(BOOL)fullscreen { | 721 - (void)adjustUIForPresentationMode:(BOOL)fullscreen { |
722 // Create the floating bar backing view if necessary. | 722 // Create the floating bar backing view if necessary. |
723 if (fullscreen && !floatingBarBackingView_.get() && | 723 if (fullscreen && !floatingBarBackingView_.get() && |
724 ([self hasTabStrip] || [self hasToolbar] || [self hasLocationBar])) { | 724 ([self hasTabStrip] || [self hasToolbar] || [self hasLocationBar])) { |
725 floatingBarBackingView_.reset( | 725 floatingBarBackingView_.reset( |
726 [[FloatingBarBackingView alloc] initWithFrame:NSZeroRect]); | 726 [[FloatingBarBackingView alloc] initWithFrame:NSZeroRect]); |
727 [floatingBarBackingView_ setAutoresizingMask:(NSViewWidthSizable | | 727 [floatingBarBackingView_ setAutoresizingMask:(NSViewWidthSizable | |
728 NSViewMinYMargin)]; | 728 NSViewMinYMargin)]; |
729 } | 729 } |
730 | 730 |
731 // Adjust the infobar container. In fullscreen, it needs to be below all | 731 // Force the bookmark bar z-order to update. |
732 // top chrome elements so it only sits atop the web contents. When in normal | 732 [[bookmarkBarController_ view] removeFromSuperview]; |
733 // mode, it needs to draw over the bookmark bar and part of the toolbar. | 733 [self updateSubviewZOrder]; |
734 [[infoBarContainerController_ view] removeFromSuperview]; | |
735 NSView* infoBarDest = [[self window] contentView]; | |
736 [infoBarDest addSubview:[infoBarContainerController_ view] | |
737 positioned:fullscreen ? NSWindowBelow : NSWindowAbove | |
738 relativeTo:fullscreen ? nil | |
739 : [toolbarController_ view]]; | |
740 } | 734 } |
741 | 735 |
742 - (void)showFullscreenExitBubbleIfNecessary { | 736 - (void)showFullscreenExitBubbleIfNecessary { |
743 // This method is called in response to | 737 // This method is called in response to |
744 // |-updateFullscreenExitBubbleURL:bubbleType:|. If on Lion the system is | 738 // |-updateFullscreenExitBubbleURL:bubbleType:|. If on Lion the system is |
745 // transitioning, do not show the bubble because it will cause visual jank | 739 // transitioning, do not show the bubble because it will cause visual jank |
746 // <http://crbug.com/130649>. This will be called again as part of | 740 // <http://crbug.com/130649>. This will be called again as part of |
747 // |-windowDidEnterFullScreen:|, so arrange to do that work then instead. | 741 // |-windowDidEnterFullScreen:|, so arrange to do that work then instead. |
748 if (enteringFullscreen_) | 742 if (enteringFullscreen_) |
749 return; | 743 return; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 | 860 |
867 - (void)disableBarVisibilityUpdates { | 861 - (void)disableBarVisibilityUpdates { |
868 // Early escape if there's nothing to do. | 862 // Early escape if there's nothing to do. |
869 if (!barVisibilityUpdatesEnabled_) | 863 if (!barVisibilityUpdatesEnabled_) |
870 return; | 864 return; |
871 | 865 |
872 barVisibilityUpdatesEnabled_ = NO; | 866 barVisibilityUpdatesEnabled_ = NO; |
873 [presentationModeController_ cancelAnimationAndTimers]; | 867 [presentationModeController_ cancelAnimationAndTimers]; |
874 } | 868 } |
875 | 869 |
| 870 - (CGFloat)toolbarDividerOpacity { |
| 871 if ([self isShowingInstantResults]) |
| 872 return 1; |
| 873 return [bookmarkBarController_ toolbarDividerOpacity]; |
| 874 } |
| 875 |
| 876 - (BOOL)isShowingInstantResults { |
| 877 if (!browser_->search_model()->mode().is_search_suggestions()) |
| 878 return NO; |
| 879 |
| 880 // If the search suggestions are already being displayed in the preview |
| 881 // contents then return YES. |
| 882 if ([previewableContentsController_ isShowingPreview]) |
| 883 return YES; |
| 884 |
| 885 // Search suggestions might be shown directly in the web contents in some |
| 886 // cases. |
| 887 return browser_->search_model()->mode().origin == |
| 888 chrome::search::Mode::ORIGIN_SEARCH; |
| 889 } |
| 890 |
| 891 - (void)updateContentOffsets { |
| 892 // Normally the preview contents is used to show instant results which must |
| 893 // obscure the bookmark bar. This is achieved by setting the offset to 0 |
| 894 // so that it overlaps the bookmark bar. The only exception is when the |
| 895 // preview contents is showing the NTP which must sit below the bookmark bar. |
| 896 CGFloat previewOffset = 0; |
| 897 if (browser_->search_model()->mode().is_ntp()) |
| 898 previewOffset = toolbarToWebContentsOffset_; |
| 899 [previewableContentsController_ setPreviewOffset:previewOffset]; |
| 900 |
| 901 // Normally the tab contents sits below the bookmark bar. This is achieved by |
| 902 // setting the offset to the height of the bookmark bar. The only exception |
| 903 // is on the search results page where the instant results are shown inside |
| 904 // the page and not in the preview contents as usual. |
| 905 CGFloat tabContentsOffset = toolbarToWebContentsOffset_; |
| 906 if (browser_->search_model()->mode().is_search_suggestions() && |
| 907 browser_->search_model()->mode().origin == |
| 908 chrome::search::Mode::ORIGIN_SEARCH) { |
| 909 tabContentsOffset = 0; |
| 910 } |
| 911 [previewableContentsController_ setActiveContainerOffset:tabContentsOffset]; |
| 912 |
| 913 // Prevent the fast resize view from drawing white over the bookmark bar. |
| 914 [[self tabContentArea] setContentOffset:toolbarToWebContentsOffset_]; |
| 915 } |
| 916 |
| 917 - (void)updateSubviewZOrder { |
| 918 NSView* contentView = [[self window] contentView]; |
| 919 NSView* toolbarView = [toolbarController_ view]; |
| 920 |
| 921 if ([self inPresentationMode]) { |
| 922 // Toolbar is above tab contents so that it can slide down from top of |
| 923 // screen. |
| 924 [contentView cr_ensureSubview:toolbarView |
| 925 isPositioned:NSWindowAbove |
| 926 relativeTo:[self tabContentArea]]; |
| 927 } else { |
| 928 // Toolbar is below tab contents so that the infobar arrow can appear above |
| 929 // it. Unlike other views the toolbar never overlaps the actual web |
| 930 // content. |
| 931 [contentView cr_ensureSubview:toolbarView |
| 932 isPositioned:NSWindowBelow |
| 933 relativeTo:[self tabContentArea]]; |
| 934 } |
| 935 |
| 936 // The bookmark bar is always below the toolbar. In normal mode this means |
| 937 // that it is below tab contents. This allows instant results to be above |
| 938 // the bookmark bar. |
| 939 [contentView cr_ensureSubview:[bookmarkBarController_ view] |
| 940 isPositioned:NSWindowBelow |
| 941 relativeTo:toolbarView]; |
| 942 |
| 943 if ([self inPresentationMode]) { |
| 944 // In presentation mode the infobar is below all other views. |
| 945 [contentView cr_ensureSubview:[infoBarContainerController_ view] |
| 946 isPositioned:NSWindowBelow |
| 947 relativeTo:[self tabContentArea]]; |
| 948 } else { |
| 949 // Above the toolbar but still below tab contents. Similar to the bookmark |
| 950 // bar, this allows instant results to be above the info bar. |
| 951 [contentView cr_ensureSubview:[infoBarContainerController_ view] |
| 952 isPositioned:NSWindowAbove |
| 953 relativeTo:toolbarView]; |
| 954 } |
| 955 |
| 956 // The find bar is above everything except instant search results. |
| 957 if (findBarCocoaController_) { |
| 958 NSView* relativeView = nil; |
| 959 if ([self inPresentationMode]) |
| 960 relativeView = toolbarView; |
| 961 else if ([self isShowingInstantResults]) |
| 962 relativeView = [infoBarContainerController_ view]; |
| 963 else |
| 964 relativeView = [self tabContentArea]; |
| 965 [contentView cr_ensureSubview:[findBarCocoaController_ view] |
| 966 isPositioned:NSWindowAbove |
| 967 relativeTo:relativeView]; |
| 968 } |
| 969 |
| 970 if (floatingBarBackingView_) { |
| 971 if ([self placeBookmarkBarBelowInfoBar]) { |
| 972 [contentView cr_ensureSubview:floatingBarBackingView_ |
| 973 isPositioned:NSWindowAbove |
| 974 relativeTo:[bookmarkBarController_ view]]; |
| 975 } else { |
| 976 [contentView cr_ensureSubview:floatingBarBackingView_ |
| 977 isPositioned:NSWindowBelow |
| 978 relativeTo:[bookmarkBarController_ view]]; |
| 979 } |
| 980 } |
| 981 } |
| 982 |
876 @end // @implementation BrowserWindowController(Private) | 983 @end // @implementation BrowserWindowController(Private) |
OLD | NEW |