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

Side by Side Diff: chrome/browser/ui/cocoa/browser_window_controller_private.mm

Issue 7566016: Fullscreen support for Lion. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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>
8
7 #include "base/command_line.h" 9 #include "base/command_line.h"
8 #import "base/memory/scoped_nsobject.h" 10 #import "base/memory/scoped_nsobject.h"
9 #include "chrome/browser/browser_process.h" 11 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/prefs/pref_service.h" 12 #include "chrome/browser/prefs/pref_service.h"
11 #include "chrome/browser/prefs/scoped_user_pref_update.h" 13 #include "chrome/browser/prefs/scoped_user_pref_update.h"
12 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h" 15 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
14 #include "chrome/browser/ui/browser_list.h" 16 #include "chrome/browser/ui/browser_list.h"
17 #import "chrome/browser/ui/cocoa/browser/avatar_button.h"
15 #import "chrome/browser/ui/cocoa/fast_resize_view.h" 18 #import "chrome/browser/ui/cocoa/fast_resize_view.h"
16 #import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h" 19 #import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h"
17 #import "chrome/browser/ui/cocoa/floating_bar_backing_view.h" 20 #import "chrome/browser/ui/cocoa/floating_bar_backing_view.h"
21 #import "chrome/browser/ui/cocoa/focus_tracker.h"
18 #import "chrome/browser/ui/cocoa/framed_browser_window.h" 22 #import "chrome/browser/ui/cocoa/framed_browser_window.h"
19 #import "chrome/browser/ui/cocoa/fullscreen_controller.h" 23 #import "chrome/browser/ui/cocoa/fullscreen_window.h"
20 #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" 24 #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h"
25 #import "chrome/browser/ui/cocoa/presentation_mode_controller.h"
26 #import "chrome/browser/ui/cocoa/status_bubble_mac.h"
21 #import "chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.h" 27 #import "chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.h"
22 #import "chrome/browser/ui/cocoa/tabs/side_tab_strip_controller.h" 28 #import "chrome/browser/ui/cocoa/tabs/side_tab_strip_controller.h"
23 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" 29 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h"
24 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" 30 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h"
25 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" 31 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
26 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 32 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
27 #include "chrome/common/chrome_switches.h" 33 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/pref_names.h" 34 #include "chrome/common/pref_names.h"
29 #include "content/browser/renderer_host/render_widget_host_view.h" 35 #include "content/browser/renderer_host/render_widget_host_view.h"
30 #include "content/browser/tab_contents/tab_contents.h" 36 #include "content/browser/tab_contents/tab_contents.h"
31 #include "content/browser/tab_contents/tab_contents_view.h" 37 #include "content/browser/tab_contents/tab_contents_view.h"
32 38
33 // Provide the forward-declarations of new 10.7 SDK symbols so they can be 39 // Forward-declare symbols that are part of the 10.6 SDK.
34 // called when building with the 10.5 SDK. 40 #if !defined(MAC_OS_X_VERSION_10_6) || \
35 #if !defined(MAC_OS_X_VERSION_10_7) || \ 41 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
36 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
37
38 @interface NSWindow (LionSDKDeclarations)
39 - (void)toggleFullScreen:(id)sender;
40 @end
41 42
42 enum { 43 enum {
43 NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7, 44 NSApplicationPresentationDefault = 0,
44 NSWindowCollectionBehaviorFullScreenAuxiliary = 1 << 8 45 NSApplicationPresentationAutoHideDock = (1 << 0),
46 NSApplicationPresentationHideDock = (1 << 1),
47 NSApplicationPresentationAutoHideMenuBar = (1 << 2),
48 NSApplicationPresentationHideMenuBar = (1 << 3),
45 }; 49 };
50 typedef NSUInteger NSApplicationPresentationOptions;
46 51
47 enum { 52 #endif // MAC_OS_X_VERSION_10_6
48 NSWindowFullScreenButton = 7
49 };
50
51 #endif // MAC_OS_X_VERSION_10_7
52 53
53 namespace { 54 namespace {
54 55
55 // Space between the incognito badge and the right edge of the window. 56 // Space between the incognito badge and the right edge of the window.
56 const CGFloat kIncognitoBadgeOffset = 4; 57 const CGFloat kAvatarRightOffset = 4;
58
59 // The amount by which to shrink the tab strip (on the right) when the
60 // incognito badge is present.
61 const CGFloat kAvatarTabStripShrink = 18;
62
63 // The amount by which to shift the avatar to the right if on Lion.
64 const CGFloat kAvatarShiftForLion = 20;
57 65
58 // Insets for the location bar, used when the full toolbar is hidden. 66 // Insets for the location bar, used when the full toolbar is hidden.
59 // TODO(viettrungluu): We can argue about the "correct" insetting; I like the 67 // TODO(viettrungluu): We can argue about the "correct" insetting; I like the
60 // following best, though arguably 0 inset is better/more correct. 68 // following best, though arguably 0 inset is better/more correct.
61 const CGFloat kLocBarLeftRightInset = 1; 69 const CGFloat kLocBarLeftRightInset = 1;
62 const CGFloat kLocBarTopInset = 0; 70 const CGFloat kLocBarTopInset = 0;
63 const CGFloat kLocBarBottomInset = 1; 71 const CGFloat kLocBarBottomInset = 1;
64 72
65 } // namespace 73 } // namespace
66 74
67 @implementation BrowserWindowController(Private) 75 @implementation BrowserWindowController(Private)
68 76
69 // Create the appropriate tab strip controller based on whether or not side 77 // Create the appropriate tab strip controller based on whether or not side
70 // tabs are enabled. 78 // tabs are enabled.
71 - (void)createTabStripController { 79 - (void)createTabStripController {
72 Class factory = [TabStripController class]; 80 Class factory = [TabStripController class];
73 if ([self useVerticalTabs]) 81 if ([self useVerticalTabs])
74 factory = [SideTabStripController class]; 82 factory = [SideTabStripController class];
75 83
76 DCHECK([previewableContentsController_ activeContainer]); 84 DCHECK([previewableContentsController_ activeContainer]);
77 DCHECK([[previewableContentsController_ activeContainer] window]); 85 DCHECK([[previewableContentsController_ activeContainer] window]);
78 tabStripController_.reset([[factory alloc] 86 tabStripController_.reset([[factory alloc]
79 initWithView:[self tabStripView] 87 initWithView:[self tabStripView]
80 switchView:[previewableContentsController_ activeContainer] 88 switchView:[previewableContentsController_ activeContainer]
81 browser:browser_.get() 89 browser:browser_.get()
82 delegate:self]); 90 delegate:self]);
83 } 91 }
84 92
93 - (void)createAndInstallPresentationModeToggleButton {
94 DCHECK(base::mac::IsOSLionOrLater());
95 if (presentationModeToggleButton_.get())
96 return;
97
98 // TODO(rohitrao): Make this button prettier.
99 presentationModeToggleButton_.reset(
100 [[NSButton alloc] initWithFrame:NSMakeRect(0, 0, 25, 25)]);
101 NSButton* button = presentationModeToggleButton_.get();
102 [button setButtonType:NSMomentaryLightButton];
103 [button setBezelStyle:NSRegularSquareBezelStyle];
104 [button setBordered:NO];
105 [[button cell] setHighlightsBy:NSContentsCellMask];
106 [[button cell] setShowsStateBy:NSContentsCellMask];
107 [button setImage:[NSImage imageNamed:NSImageNameIChatTheaterTemplate]];
108 [button setTarget:self];
109 [button setAction:@selector(togglePresentationModeForLionOrLater:)];
110 [[[[self window] contentView] superview] addSubview:button];
111 }
112
85 - (void)saveWindowPositionIfNeeded { 113 - (void)saveWindowPositionIfNeeded {
86 if (browser_ != BrowserList::GetLastActive()) 114 if (browser_ != BrowserList::GetLastActive())
87 return; 115 return;
88 116
89 if (!browser_->profile()->GetPrefs() || 117 if (!browser_->profile()->GetPrefs() ||
90 !browser_->ShouldSaveWindowPlacement()) { 118 !browser_->ShouldSaveWindowPlacement()) {
91 return; 119 return;
92 } 120 }
93 121
94 [self saveWindowPositionToPrefs:browser_->profile()->GetPrefs()]; 122 [self saveWindowPositionToPrefs:browser_->profile()->GetPrefs()];
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 NSView* contentView = [window contentView]; 205 NSView* contentView = [window contentView];
178 NSRect contentBounds = [contentView bounds]; 206 NSRect contentBounds = [contentView bounds];
179 CGFloat minX = NSMinX(contentBounds); 207 CGFloat minX = NSMinX(contentBounds);
180 CGFloat minY = NSMinY(contentBounds); 208 CGFloat minY = NSMinY(contentBounds);
181 CGFloat width = NSWidth(contentBounds); 209 CGFloat width = NSWidth(contentBounds);
182 210
183 // Suppress title drawing if necessary. 211 // Suppress title drawing if necessary.
184 if ([window respondsToSelector:@selector(setShouldHideTitle:)]) 212 if ([window respondsToSelector:@selector(setShouldHideTitle:)])
185 [(id)window setShouldHideTitle:![self hasTitleBar]]; 213 [(id)window setShouldHideTitle:![self hasTitleBar]];
186 214
187 BOOL isFullscreen = [self isFullscreen]; 215 BOOL inPresentationMode = [self inPresentationMode];
188 CGFloat floatingBarHeight = [self floatingBarHeight]; 216 CGFloat floatingBarHeight = [self floatingBarHeight];
189 // In fullscreen mode, |yOffset| accounts for the sliding position of the 217 // In presentation mode, |yOffset| accounts for the sliding position of the
190 // floating bar and the extra offset needed to dodge the menu bar. 218 // floating bar and the extra offset needed to dodge the menu bar.
191 CGFloat yOffset = isFullscreen ? 219 CGFloat yOffset = inPresentationMode ?
192 (floor((1 - floatingBarShownFraction_) * floatingBarHeight) - 220 (std::floor((1 - floatingBarShownFraction_) * floatingBarHeight) -
193 [fullscreenController_ floatingBarVerticalOffset]) : 0; 221 [presentationModeController_ floatingBarVerticalOffset]) : 0;
194 CGFloat maxY = NSMaxY(contentBounds) + yOffset; 222 CGFloat maxY = NSMaxY(contentBounds) + yOffset;
195 CGFloat startMaxY = maxY; 223 CGFloat startMaxY = maxY;
196 224
225 CGFloat overlayMaxY =
226 NSMaxY([window frame]) +
227 std::floor((1 - floatingBarShownFraction_) * floatingBarHeight);
228 [self layoutPresentationModeToggleAtOverlayMaxX:NSMaxX([window frame])
229 overlayMaxY:overlayMaxY];
230
197 if ([self hasTabStrip] && ![self useVerticalTabs]) { 231 if ([self hasTabStrip] && ![self useVerticalTabs]) {
198 // If we need to lay out the top tab strip, replace |maxY| and |startMaxY| 232 // If we need to lay out the top tab strip, replace |maxY| and |startMaxY|
199 // with higher values, and then lay out the tab strip. 233 // with higher values, and then lay out the tab strip.
200 NSRect windowFrame = [contentView convertRect:[window frame] fromView:nil]; 234 NSRect windowFrame = [contentView convertRect:[window frame] fromView:nil];
201 startMaxY = maxY = NSHeight(windowFrame) + yOffset; 235 startMaxY = maxY = NSHeight(windowFrame) + yOffset;
202 maxY = [self layoutTabStripAtMaxY:maxY width:width fullscreen:isFullscreen]; 236 maxY = [self layoutTabStripAtMaxY:maxY
237 width:width
238 fullscreen:[self isFullscreen]];
203 } 239 }
204 240
205 // Sanity-check |maxY|. 241 // Sanity-check |maxY|.
206 DCHECK_GE(maxY, minY); 242 DCHECK_GE(maxY, minY);
207 DCHECK_LE(maxY, NSMaxY(contentBounds) + yOffset); 243 DCHECK_LE(maxY, NSMaxY(contentBounds) + yOffset);
208 244
209 // The base class already positions the side tab strip on the left side 245 // The base class already positions the side tab strip on the left side
210 // of the window's content area and sizes it to take the entire vertical 246 // of the window's content area and sizes it to take the entire vertical
211 // height. All that's needed here is to push everything over to the right, 247 // height. All that's needed here is to push everything over to the right,
212 // if necessary. 248 // if necessary.
213 if ([self useVerticalTabs]) { 249 if ([self useVerticalTabs]) {
214 const CGFloat sideTabWidth = [[self tabStripView] bounds].size.width; 250 const CGFloat sideTabWidth = [[self tabStripView] bounds].size.width;
215 minX += sideTabWidth; 251 minX += sideTabWidth;
216 width -= sideTabWidth; 252 width -= sideTabWidth;
217 } 253 }
218 254
219 // Place the toolbar at the top of the reserved area. 255 // Place the toolbar at the top of the reserved area.
220 maxY = [self layoutToolbarAtMinX:minX maxY:maxY width:width]; 256 maxY = [self layoutToolbarAtMinX:minX maxY:maxY width:width];
221 257
222 // If we're not displaying the bookmark bar below the infobar, then it goes 258 // If we're not displaying the bookmark bar below the infobar, then it goes
223 // immediately below the toolbar. 259 // immediately below the toolbar.
224 BOOL placeBookmarkBarBelowInfoBar = [self placeBookmarkBarBelowInfoBar]; 260 BOOL placeBookmarkBarBelowInfoBar = [self placeBookmarkBarBelowInfoBar];
225 if (!placeBookmarkBarBelowInfoBar) 261 if (!placeBookmarkBarBelowInfoBar)
226 maxY = [self layoutBookmarkBarAtMinX:minX maxY:maxY width:width]; 262 maxY = [self layoutBookmarkBarAtMinX:minX maxY:maxY width:width];
227 263
228 // The floating bar backing view doesn't actually add any height. 264 // The floating bar backing view doesn't actually add any height.
229 NSRect floatingBarBackingRect = 265 NSRect floatingBarBackingRect =
230 NSMakeRect(minX, maxY, width, floatingBarHeight); 266 NSMakeRect(minX, maxY, width, floatingBarHeight);
231 [self layoutFloatingBarBackingView:floatingBarBackingRect 267 [self layoutFloatingBarBackingView:floatingBarBackingRect
232 fullscreen:isFullscreen]; 268 presentationMode:inPresentationMode];
233 269
234 // Place the find bar immediately below the toolbar/attached bookmark bar. In 270 // Place the find bar immediately below the toolbar/attached bookmark bar. In
235 // fullscreen mode, it hangs off the top of the screen when the bar is hidden. 271 // presentation mode, it hangs off the top of the screen when the bar is
236 // The find bar is unaffected by the side tab positioning. 272 // hidden. The find bar is unaffected by the side tab positioning.
237 [findBarCocoaController_ positionFindBarViewAtMaxY:maxY maxWidth:width]; 273 [findBarCocoaController_ positionFindBarViewAtMaxY:maxY maxWidth:width];
238 274
239 // If in fullscreen mode, reset |maxY| to top of screen, so that the floating 275 // If in presentation mode, reset |maxY| to top of screen, so that the
240 // bar slides over the things which appear to be in the content area. 276 // floating bar slides over the things which appear to be in the content area.
241 if (isFullscreen) 277 if (inPresentationMode)
242 maxY = NSMaxY(contentBounds); 278 maxY = NSMaxY(contentBounds);
243 279
244 // Also place the infobar container immediate below the toolbar, except in 280 // Also place the infobar container immediate below the toolbar, except in
245 // fullscreen mode in which case it's at the top of the visual content area. 281 // presentation mode in which case it's at the top of the visual content area.
246 maxY = [self layoutInfoBarAtMinX:minX maxY:maxY width:width]; 282 maxY = [self layoutInfoBarAtMinX:minX maxY:maxY width:width];
247 283
248 // If the bookmark bar is detached, place it next in the visual content area. 284 // If the bookmark bar is detached, place it next in the visual content area.
249 if (placeBookmarkBarBelowInfoBar) 285 if (placeBookmarkBarBelowInfoBar)
250 maxY = [self layoutBookmarkBarAtMinX:minX maxY:maxY width:width]; 286 maxY = [self layoutBookmarkBarAtMinX:minX maxY:maxY width:width];
251 287
252 // Place the download shelf, if any, at the bottom of the view. 288 // Place the download shelf, if any, at the bottom of the view.
253 minY = [self layoutDownloadShelfAtMinX:minX minY:minY width:width]; 289 minY = [self layoutDownloadShelfAtMinX:minX minY:minY width:width];
254 290
255 // Finally, the content area takes up all of the remaining space. 291 // Finally, the content area takes up all of the remaining space.
256 NSRect contentAreaRect = NSMakeRect(minX, minY, width, maxY - minY); 292 NSRect contentAreaRect = NSMakeRect(minX, minY, width, maxY - minY);
257 [self layoutTabContentArea:contentAreaRect]; 293 [self layoutTabContentArea:contentAreaRect];
258 294
259 // Normally, we don't need to tell the toolbar whether or not to show the 295 // Normally, we don't need to tell the toolbar whether or not to show the
260 // divider, but things break down during animation. 296 // divider, but things break down during animation.
261 [toolbarController_ 297 [toolbarController_
262 setDividerOpacity:[bookmarkBarController_ toolbarDividerOpacity]]; 298 setDividerOpacity:[bookmarkBarController_ toolbarDividerOpacity]];
263 } 299 }
264 300
265 - (CGFloat)floatingBarHeight { 301 - (CGFloat)floatingBarHeight {
266 if (![self isFullscreen]) 302 if (![self inPresentationMode])
267 return 0; 303 return 0;
268 304
269 CGFloat totalHeight = [fullscreenController_ floatingBarVerticalOffset]; 305 CGFloat totalHeight = [presentationModeController_ floatingBarVerticalOffset];
270 306
271 if ([self hasTabStrip]) 307 if ([self hasTabStrip])
272 totalHeight += NSHeight([[self tabStripView] frame]); 308 totalHeight += NSHeight([[self tabStripView] frame]);
273 309
274 if ([self hasToolbar]) { 310 if ([self hasToolbar]) {
275 totalHeight += NSHeight([[toolbarController_ view] frame]); 311 totalHeight += NSHeight([[toolbarController_ view] frame]);
276 } else if ([self hasLocationBar]) { 312 } else if ([self hasLocationBar]) {
277 totalHeight += NSHeight([[toolbarController_ view] frame]) + 313 totalHeight += NSHeight([[toolbarController_ view] frame]) +
278 kLocBarTopInset + kLocBarBottomInset; 314 kLocBarTopInset + kLocBarBottomInset;
279 } 315 }
280 316
281 if (![self placeBookmarkBarBelowInfoBar]) 317 if (![self placeBookmarkBarBelowInfoBar])
282 totalHeight += NSHeight([[bookmarkBarController_ view] frame]); 318 totalHeight += NSHeight([[bookmarkBarController_ view] frame]);
283 319
284 return totalHeight; 320 return totalHeight;
285 } 321 }
286 322
323 - (void)layoutPresentationModeToggleAtOverlayMaxX:(CGFloat)maxX
324 overlayMaxY:(CGFloat)maxY {
325 // Lay out the presentation mode toggle button at the very top of the
326 // tab strip.
327 if ([self shouldShowPresentationModeToggle]) {
328 [self createAndInstallPresentationModeToggleButton];
329
330 NSPoint origin =
331 NSMakePoint(maxX - NSWidth([presentationModeToggleButton_ frame]),
332 maxY - NSHeight([presentationModeToggleButton_ frame]));
333 [presentationModeToggleButton_ setFrameOrigin:origin];
334 } else {
335 [presentationModeToggleButton_ removeFromSuperview];
336 presentationModeToggleButton_.reset();
337 }
338 }
339
287 - (CGFloat)layoutTabStripAtMaxY:(CGFloat)maxY 340 - (CGFloat)layoutTabStripAtMaxY:(CGFloat)maxY
288 width:(CGFloat)width 341 width:(CGFloat)width
289 fullscreen:(BOOL)fullscreen { 342 fullscreen:(BOOL)fullscreen {
290 // Nothing to do if no tab strip. 343 // Nothing to do if no tab strip.
291 if (![self hasTabStrip]) 344 if (![self hasTabStrip])
292 return maxY; 345 return maxY;
293 346
294 NSView* tabStripView = [self tabStripView]; 347 NSView* tabStripView = [self tabStripView];
295 CGFloat tabStripHeight = NSHeight([tabStripView frame]); 348 CGFloat tabStripHeight = NSHeight([tabStripView frame]);
296 maxY -= tabStripHeight; 349 maxY -= tabStripHeight;
297 [tabStripView setFrame:NSMakeRect(0, maxY, width, tabStripHeight)]; 350 [tabStripView setFrame:NSMakeRect(0, maxY, width, tabStripHeight)];
298 351
299 // Set indentation. 352 // Set left indentation based on fullscreen mode status.
300 [tabStripController_ setIndentForControls:(fullscreen ? 0 : 353 [tabStripController_ setLeftIndentForControls:(fullscreen ? 0 :
301 [[tabStripController_ class] defaultIndentForControls])]; 354 [[tabStripController_ class] defaultLeftIndentForControls])];
302 355
303 // TODO(viettrungluu): Seems kind of bad -- shouldn't |-layoutSubviews| do 356 // Calculate the right indentation. The default indentation built into the
304 // this? Moreover, |-layoutTabs| will try to animate.... 357 // tabstrip leaves enough room for the fullscreen button or presentation mode
305 [tabStripController_ layoutTabs]; 358 // toggle button on Lion. On non-Lion systems, the default indentation also
359 // looks fine. If an avatar button is present, indent enough to account for
360 // its width.
361 const CGFloat possibleExtraShiftForLion =
362 base::mac::IsOSLionOrLater() ? kAvatarShiftForLion : 0;
363
364 CGFloat rightIndent = 0;
365 if ([self shouldShowAvatar])
366 rightIndent += (kAvatarTabStripShrink + possibleExtraShiftForLion);
367 [tabStripController_ setRightIndentForControls:rightIndent];
368
369 // Go ahead and layout the tabs.
370 [tabStripController_ layoutTabsWithoutAnimation];
306 371
307 // Now lay out incognito badge together with the tab strip. 372 // Now lay out incognito badge together with the tab strip.
308 if (avatarButton_.get()) { 373 if (avatarButton_.get()) {
309 // Set the size of the avatar to be the (height of the tabstrip) - (padding)
310 // to let large icons fit.
311 CGFloat sizeSquare = tabStripHeight - 5.0; 374 CGFloat sizeSquare = tabStripHeight - 5.0;
312 [avatarButton_ setFrameSize:NSMakeSize(sizeSquare, sizeSquare)]; 375 [avatarButton_ setFrameSize:NSMakeSize(sizeSquare, sizeSquare)];
313 376
314 // Actually place the badge *above* |maxY|, by +2 to miss the divider. 377 // Actually place the badge *above* |maxY|, by +2 to miss the divider. On
315 NSPoint origin = NSMakePoint(width - NSWidth([avatarButton_ frame]) - 378 // Lion or later, shift the badge left to move it away from the fullscreen
316 kIncognitoBadgeOffset, 379 // button.
317 maxY + 2); 380 CGFloat badgeOffset = kAvatarRightOffset + possibleExtraShiftForLion;
381 NSPoint origin =
382 NSMakePoint(width - NSWidth([avatarButton_ frame]) - badgeOffset,
383 maxY + 2);
318 [avatarButton_ setFrameOrigin:origin]; 384 [avatarButton_ setFrameOrigin:origin];
319 [avatarButton_ setHidden:NO]; // Make sure it's shown. 385 [avatarButton_ setHidden:NO]; // Make sure it's shown.
320 } 386 }
321 387
322 return maxY; 388 return maxY;
323 } 389 }
324 390
325 - (CGFloat)layoutToolbarAtMinX:(CGFloat)minX 391 - (CGFloat)layoutToolbarAtMinX:(CGFloat)minX
326 maxY:(CGFloat)maxY 392 maxY:(CGFloat)maxY
327 width:(CGFloat)width { 393 width:(CGFloat)width {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 maxY -= NSHeight(bookmarkBarFrame); 445 maxY -= NSHeight(bookmarkBarFrame);
380 446
381 // TODO(viettrungluu): Does this really belong here? Calling it shouldn't be 447 // TODO(viettrungluu): Does this really belong here? Calling it shouldn't be
382 // necessary in the non-NTP case. 448 // necessary in the non-NTP case.
383 [bookmarkBarController_ layoutSubviews]; 449 [bookmarkBarController_ layoutSubviews];
384 450
385 return maxY; 451 return maxY;
386 } 452 }
387 453
388 - (void)layoutFloatingBarBackingView:(NSRect)frame 454 - (void)layoutFloatingBarBackingView:(NSRect)frame
389 fullscreen:(BOOL)fullscreen { 455 presentationMode:(BOOL)presentationMode {
390 // Only display when in fullscreen mode. 456 // Only display when in presentation mode.
391 if (fullscreen) { 457 if (presentationMode) {
392 // For certain window types such as app windows (e.g., the dev tools 458 // For certain window types such as app windows (e.g., the dev tools
393 // window), there's no actual overlay. (Displaying one would result in an 459 // window), there's no actual overlay. (Displaying one would result in an
394 // overly sliding in only under the menu, which gives an ugly effect.) 460 // overly sliding in only under the menu, which gives an ugly effect.)
395 if (floatingBarBackingView_.get()) { 461 if (floatingBarBackingView_.get()) {
396 BOOL aboveBookmarkBar = [self placeBookmarkBarBelowInfoBar]; 462 BOOL aboveBookmarkBar = [self placeBookmarkBarBelowInfoBar];
397 463
398 // Insert it into the view hierarchy if necessary. 464 // Insert it into the view hierarchy if necessary.
399 if (![floatingBarBackingView_ superview] || 465 if (![floatingBarBackingView_ superview] ||
400 aboveBookmarkBar != floatingBarAboveBookmarkBar_) { 466 aboveBookmarkBar != floatingBarAboveBookmarkBar_) {
401 NSView* contentView = [[self window] contentView]; 467 NSView* contentView = [[self window] contentView];
402 // z-order gets messed up unless we explicitly remove the floatingbar 468 // z-order gets messed up unless we explicitly remove the floatingbar
403 // view and re-add it. 469 // view and re-add it.
404 [floatingBarBackingView_ removeFromSuperview]; 470 [floatingBarBackingView_ removeFromSuperview];
405 [contentView addSubview:floatingBarBackingView_ 471 [contentView addSubview:floatingBarBackingView_
406 positioned:(aboveBookmarkBar ? 472 positioned:(aboveBookmarkBar ?
407 NSWindowAbove : NSWindowBelow) 473 NSWindowAbove : NSWindowBelow)
408 relativeTo:[bookmarkBarController_ view]]; 474 relativeTo:[bookmarkBarController_ view]];
409 floatingBarAboveBookmarkBar_ = aboveBookmarkBar; 475 floatingBarAboveBookmarkBar_ = aboveBookmarkBar;
410 } 476 }
411 477
412 // Set its frame. 478 // Set its frame.
413 [floatingBarBackingView_ setFrame:frame]; 479 [floatingBarBackingView_ setFrame:frame];
414 } 480 }
415 481
416 // But we want the logic to work as usual (for show/hide/etc. purposes). 482 // But we want the logic to work as usual (for show/hide/etc. purposes).
417 [fullscreenController_ overlayFrameChanged:frame]; 483 [presentationModeController_ overlayFrameChanged:frame];
418 } else { 484 } else {
419 // Okay to call even if |floatingBarBackingView_| is nil. 485 // Okay to call even if |floatingBarBackingView_| is nil.
420 if ([floatingBarBackingView_ superview]) 486 if ([floatingBarBackingView_ superview])
421 [floatingBarBackingView_ removeFromSuperview]; 487 [floatingBarBackingView_ removeFromSuperview];
422 } 488 }
423 } 489 }
424 490
425 - (CGFloat)layoutInfoBarAtMinX:(CGFloat)minX 491 - (CGFloat)layoutInfoBarAtMinX:(CGFloat)minX
426 maxY:(CGFloat)maxY 492 maxY:(CGFloat)maxY
427 width:(CGFloat)width { 493 width:(CGFloat)width {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 return; 564 return;
499 565
500 toolbarFrame.size.height = newHeight; 566 toolbarFrame.size.height = newHeight;
501 NSRect bookmarkFrame = [[bookmarkBarController_ view] frame]; 567 NSRect bookmarkFrame = [[bookmarkBarController_ view] frame];
502 bookmarkFrame.size.height = bookmarkFrame.size.height - deltaH; 568 bookmarkFrame.size.height = bookmarkFrame.size.height - deltaH;
503 [[toolbarController_ view] setFrame:toolbarFrame]; 569 [[toolbarController_ view] setFrame:toolbarFrame];
504 [[bookmarkBarController_ view] setFrame:bookmarkFrame]; 570 [[bookmarkBarController_ view] setFrame:bookmarkFrame];
505 [self layoutSubviews]; 571 [self layoutSubviews];
506 } 572 }
507 573
574 // Fullscreen and presentation mode methods
575
576 - (BOOL)shouldUsePresentationModeWhenEnteringFullscreen {
577 return browser_->profile()->GetPrefs()->GetBoolean(
578 prefs::kPresentationModeEnabled);
579 }
580
581 - (void)setShouldUsePresentationModeWhenEnteringFullscreen:(BOOL)flag {
582 browser_->profile()->GetPrefs()->SetBoolean(
583 prefs::kPresentationModeEnabled, flag);
584 }
585
586 - (BOOL)shouldShowPresentationModeToggle {
587 return base::mac::IsOSLionOrLater() && [self isFullscreen];
588 }
589
590 - (void)moveViewsForFullscreenForSnowLeopardOrEarlier:(BOOL)fullscreen
591 regularWindow:(NSWindow*)regularWindow
592 fullscreenWindow:(NSWindow*)fullscreenWindow {
593 // This method is only for Snow Leopard and earlier.
594 DCHECK(base::mac::IsOSSnowLeopardOrEarlier());
595
596 NSWindow* sourceWindow = fullscreen ? regularWindow : fullscreenWindow;
597 NSWindow* destWindow = fullscreen ? fullscreenWindow : regularWindow;
598
599 // Close the bookmark bubble, if it's open. Use |-ok:| instead of |-cancel:|
600 // or |-close| because that matches the behavior when the bubble loses key
601 // status.
602 [bookmarkBubbleController_ ok:self];
603
604 // Save the current first responder so we can restore after views are moved.
605 scoped_nsobject<FocusTracker> focusTracker(
606 [[FocusTracker alloc] initWithWindow:sourceWindow]);
607
608 // While we move views (and focus) around, disable any bar visibility changes.
609 [self disableBarVisibilityUpdates];
610
611 // Destroy the tab strip's sheet controller. We will recreate it in the new
612 // window when needed.
613 [tabStripController_ destroySheetController];
614
615 // Retain the tab strip view while we remove it from its superview.
616 scoped_nsobject<NSView> tabStripView;
617 if ([self hasTabStrip] && ![self useVerticalTabs]) {
618 tabStripView.reset([[self tabStripView] retain]);
619 [tabStripView removeFromSuperview];
620 }
621
622 // Ditto for the content view.
623 scoped_nsobject<NSView> contentView([[sourceWindow contentView] retain]);
624 // Disable autoresizing of subviews while we move views around. This prevents
625 // spurious renderer resizes.
626 [contentView setAutoresizesSubviews:NO];
627 [contentView removeFromSuperview];
628
629 // Have to do this here, otherwise later calls can crash because the window
630 // has no delegate.
631 [sourceWindow setDelegate:nil];
632 [destWindow setDelegate:self];
633
634 // With this call, valgrind complains that a "Conditional jump or move depends
635 // on uninitialised value(s)". The error happens in -[NSThemeFrame
636 // drawOverlayRect:]. I'm pretty convinced this is an Apple bug, but there is
637 // no visual impact. I have been unable to tickle it away with other window
638 // or view manipulation Cocoa calls. Stack added to suppressions_mac.txt.
639 [contentView setAutoresizesSubviews:YES];
640 [destWindow setContentView:contentView];
641
642 // Move the incognito badge if present.
643 if (avatarButton_.get()) {
644 [avatarButton_ removeFromSuperview];
645 [avatarButton_ setHidden:YES]; // Will be shown in layout.
646 [[[destWindow contentView] superview] addSubview:avatarButton_];
647 }
648
649 // Add the tab strip after setting the content view and moving the incognito
650 // badge (if any), so that the tab strip will be on top (in the z-order).
651 if ([self hasTabStrip] && ![self useVerticalTabs])
652 [[[destWindow contentView] superview] addSubview:tabStripView];
653
654 [sourceWindow setWindowController:nil];
655 [self setWindow:destWindow];
656 [destWindow setWindowController:self];
657
658 // Move the status bubble over, if we have one.
659 if (statusBubble_)
660 statusBubble_->SwitchParentWindow(destWindow);
661
662 // Move the title over.
663 [destWindow setTitle:[sourceWindow title]];
664
665 // The window needs to be onscreen before we can set its first responder.
666 // Ordering the window to the front can change the active Space (either to
667 // the window's old Space or to the application's assigned Space). To prevent
668 // this by temporarily change the collectionBehavior.
669 NSWindowCollectionBehavior behavior = [sourceWindow collectionBehavior];
670 [destWindow setCollectionBehavior:
671 NSWindowCollectionBehaviorMoveToActiveSpace];
672 [destWindow makeKeyAndOrderFront:self];
673 [destWindow setCollectionBehavior:behavior];
674
675 [focusTracker restoreFocusInWindow:destWindow];
676 [sourceWindow orderOut:self];
677
678 // We're done moving focus, so re-enable bar visibility changes.
679 [self enableBarVisibilityUpdates];
680 }
681
682 - (void)setPresentationModeInternal:(BOOL)presentationMode
683 forceDropdown:(BOOL)forceDropdown {
684 if (presentationMode == [self inPresentationMode])
685 return;
686
687 if (presentationMode) {
688 BOOL showDropdown = forceDropdown || [self floatingBarHasFocus];
689 NSView* contentView = [[self window] contentView];
690 presentationModeController_.reset(
691 [[PresentationModeController alloc] initWithBrowserController:self]);
692 [presentationModeController_ enterPresentationModeForContentView:contentView
693 showDropdown:showDropdown];
694 } else {
695 [presentationModeController_ exitPresentationMode];
696 presentationModeController_.reset();
697 }
698
699 [self adjustUIForPresentationMode:presentationMode];
700 [self layoutSubviews];
701 }
702
703 - (void)enterFullscreenForSnowLeopardOrEarlier {
704 DCHECK(base::mac::IsOSSnowLeopardOrEarlier());
705
706 // Fade to black.
707 const CGDisplayReservationInterval kFadeDurationSeconds = 0.6;
708 Boolean didFadeOut = NO;
709 CGDisplayFadeReservationToken token;
710 if (CGAcquireDisplayFadeReservation(kFadeDurationSeconds, &token)
711 == kCGErrorSuccess) {
712 didFadeOut = YES;
713 CGDisplayFade(token, kFadeDurationSeconds / 2, kCGDisplayBlendNormal,
714 kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, /*synchronous=*/true);
715 }
716
717 // Create the fullscreen window. After this line, isFullscreen will return
718 // YES.
719 fullscreenWindow_.reset([[self createFullscreenWindow] retain]);
720 savedRegularWindow_ = [[self window] retain];
721 savedRegularWindowFrame_ = [savedRegularWindow_ frame];
722
723 [self moveViewsForFullscreenForSnowLeopardOrEarlier:YES
724 regularWindow:[self window]
725 fullscreenWindow:fullscreenWindow_.get()];
726 [self adjustUIForPresentationMode:YES];
727 [self setPresentationModeInternal:YES forceDropdown:NO];
728 [self layoutSubviews];
729
730 // Fade back in.
731 if (didFadeOut) {
732 CGDisplayFade(token, kFadeDurationSeconds / 2, kCGDisplayBlendSolidColor,
733 kCGDisplayBlendNormal, 0.0, 0.0, 0.0, /*synchronous=*/false);
734 CGReleaseDisplayFadeReservation(token);
735 }
736 }
737
738 - (void)exitFullscreenForSnowLeopardOrEarlier {
739 DCHECK(base::mac::IsOSSnowLeopardOrEarlier());
740
741 // Fade to black.
742 const CGDisplayReservationInterval kFadeDurationSeconds = 0.6;
743 Boolean didFadeOut = NO;
744 CGDisplayFadeReservationToken token;
745 if (CGAcquireDisplayFadeReservation(kFadeDurationSeconds, &token)
746 == kCGErrorSuccess) {
747 didFadeOut = YES;
748 CGDisplayFade(token, kFadeDurationSeconds / 2, kCGDisplayBlendNormal,
749 kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, /*synchronous=*/true);
750 }
751
752 [self setPresentationModeInternal:NO forceDropdown:NO];
753 [self moveViewsForFullscreenForSnowLeopardOrEarlier:NO
754 regularWindow:savedRegularWindow_
755 fullscreenWindow:fullscreenWindow_.get()];
756
757 // When exiting fullscreen mode, we need to call layoutSubviews manually.
758 [savedRegularWindow_ autorelease];
759 savedRegularWindow_ = nil;
760 fullscreenWindow_.reset();
761 [self layoutSubviews];
762
763 // Fade back in.
764 if (didFadeOut) {
765 CGDisplayFade(token, kFadeDurationSeconds / 2, kCGDisplayBlendSolidColor,
766 kCGDisplayBlendNormal, 0.0, 0.0, 0.0, /*synchronous=*/false);
767 CGReleaseDisplayFadeReservation(token);
768 }
769 }
770
508 // TODO(rohitrao): This function has shrunk into uselessness, and 771 // TODO(rohitrao): This function has shrunk into uselessness, and
509 // |-setFullscreen:| has grown rather large. Find a good way to break up 772 // |-setFullscreen:| has grown rather large. Find a good way to break up
510 // |-setFullscreen:| into smaller pieces. http://crbug.com/36449 773 // |-setFullscreen:| into smaller pieces. http://crbug.com/36449
511 - (void)adjustUIForFullscreen:(BOOL)fullscreen { 774 - (void)adjustUIForPresentationMode:(BOOL)fullscreen {
512 // Create the floating bar backing view if necessary. 775 // Create the floating bar backing view if necessary.
513 if (fullscreen && !floatingBarBackingView_.get() && 776 if (fullscreen && !floatingBarBackingView_.get() &&
514 ([self hasTabStrip] || [self hasToolbar] || [self hasLocationBar])) { 777 ([self hasTabStrip] || [self hasToolbar] || [self hasLocationBar])) {
515 floatingBarBackingView_.reset( 778 floatingBarBackingView_.reset(
516 [[FloatingBarBackingView alloc] initWithFrame:NSZeroRect]); 779 [[FloatingBarBackingView alloc] initWithFrame:NSZeroRect]);
517 } 780 [floatingBarBackingView_ setAutoresizingMask:(NSViewWidthSizable |
781 NSViewMinYMargin)];
782 }
783
784 // Adjust the infobar container. In fullscreen, it needs to be below all
785 // top chrome elements so it only sits atop the web contents. When in normal
786 // mode, it needs to draw over the bookmark bar and part of the toolbar.
787 [[infoBarContainerController_ view] removeFromSuperview];
788 NSView* infoBarDest = [[self window] contentView];
789 [infoBarDest addSubview:[infoBarContainerController_ view]
790 positioned:fullscreen ? NSWindowBelow : NSWindowAbove
791 relativeTo:fullscreen ? nil
792 : [bookmarkBarController_ view]];
793 }
794
795 - (void)contentViewDidResize:(NSNotification*)notification {
796 [self layoutSubviews];
797 }
798
799 - (void)registerForContentViewResizeNotifications {
800 [[NSNotificationCenter defaultCenter]
801 addObserver:self
802 selector:@selector(contentViewDidResize:)
803 name:NSViewFrameDidChangeNotification
804 object:[[self window] contentView]];
805 }
806
807 - (void)deregisterForContentViewResizeNotifications {
808 [[NSNotificationCenter defaultCenter]
809 removeObserver:self
810 name:NSViewFrameDidChangeNotification
811 object:[[self window] contentView]];
812 }
813
814 - (NSSize)window:(NSWindow*)window
815 willUseFullScreenContentSize:(NSSize)proposedSize {
816 return proposedSize;
817 }
818
819 - (NSApplicationPresentationOptions)window:(NSWindow*)window
820 willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)opt {
821 return (opt |
822 NSApplicationPresentationAutoHideDock |
823 NSApplicationPresentationAutoHideMenuBar);
824 }
825
826 - (void)windowWillEnterFullScreen:(NSNotification*)notification {
827 [self registerForContentViewResizeNotifications];
828
829 NSWindow* window = [self window];
830 savedRegularWindowFrame_ = [window frame];
831 BOOL mode = [self shouldUsePresentationModeWhenEnteringFullscreen];
832 [self setPresentationModeInternal:mode forceDropdown:NO];
833 }
834
835 - (void)windowDidEnterFullScreen:(NSNotification*)notification {
836 [self deregisterForContentViewResizeNotifications];
837 }
838
839 - (void)windowWillExitFullScreen:(NSNotification*)notification {
840 [self registerForContentViewResizeNotifications];
841 [self setPresentationModeInternal:NO forceDropdown:NO];
842 }
843
844 - (void)windowDidExitFullScreen:(NSNotification*)notification {
845 [self deregisterForContentViewResizeNotifications];
846 }
847
848 - (void)windowDidFailToEnterFullScreen:(NSWindow*)window {
849 [self deregisterForContentViewResizeNotifications];
850 [self setPresentationModeInternal:NO forceDropdown:NO];
851 }
852
853 - (void)windowDidFailToExitFullScreen:(NSWindow*)window {
854 [self deregisterForContentViewResizeNotifications];
518 } 855 }
519 856
520 - (void)enableBarVisibilityUpdates { 857 - (void)enableBarVisibilityUpdates {
521 // Early escape if there's nothing to do. 858 // Early escape if there's nothing to do.
522 if (barVisibilityUpdatesEnabled_) 859 if (barVisibilityUpdatesEnabled_)
523 return; 860 return;
524 861
525 barVisibilityUpdatesEnabled_ = YES; 862 barVisibilityUpdatesEnabled_ = YES;
526 863
527 if ([barVisibilityLocks_ count]) 864 if ([barVisibilityLocks_ count])
528 [fullscreenController_ ensureOverlayShownWithAnimation:NO delay:NO]; 865 [presentationModeController_ ensureOverlayShownWithAnimation:NO delay:NO];
529 else 866 else
530 [fullscreenController_ ensureOverlayHiddenWithAnimation:NO delay:NO]; 867 [presentationModeController_ ensureOverlayHiddenWithAnimation:NO delay:NO];
531 } 868 }
532 869
533 - (void)disableBarVisibilityUpdates { 870 - (void)disableBarVisibilityUpdates {
534 // Early escape if there's nothing to do. 871 // Early escape if there's nothing to do.
535 if (!barVisibilityUpdatesEnabled_) 872 if (!barVisibilityUpdatesEnabled_)
536 return; 873 return;
537 874
538 barVisibilityUpdatesEnabled_ = NO; 875 barVisibilityUpdatesEnabled_ = NO;
539 [fullscreenController_ cancelAnimationAndTimers]; 876 [presentationModeController_ cancelAnimationAndTimers];
540 }
541
542 - (void)setUpOSFullScreenButton {
543 // TOOD(rsesek): Properly implement Lion fullscreen <http://crbug.com/74065>.
544 } 877 }
545 878
546 @end // @implementation BrowserWindowController(Private) 879 @end // @implementation BrowserWindowController(Private)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698