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

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

Powered by Google App Engine
This is Rietveld 408576698