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

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;
Robert Sesek 2011/08/04 14:43:41 Is this used?
rohitrao (ping after 24h) 2011/08/04 18:18:26 It is now =)
60
58 // Insets for the location bar, used when the full toolbar is hidden. 61 // 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 62 // TODO(viettrungluu): We can argue about the "correct" insetting; I like the
60 // following best, though arguably 0 inset is better/more correct. 63 // following best, though arguably 0 inset is better/more correct.
61 const CGFloat kLocBarLeftRightInset = 1; 64 const CGFloat kLocBarLeftRightInset = 1;
62 const CGFloat kLocBarTopInset = 0; 65 const CGFloat kLocBarTopInset = 0;
63 const CGFloat kLocBarBottomInset = 1; 66 const CGFloat kLocBarBottomInset = 1;
64 67
65 } // namespace 68 } // namespace
66 69
67 @implementation BrowserWindowController(Private) 70 @implementation BrowserWindowController(Private)
68 71
69 // Create the appropriate tab strip controller based on whether or not side 72 // Create the appropriate tab strip controller based on whether or not side
70 // tabs are enabled. 73 // tabs are enabled.
71 - (void)createTabStripController { 74 - (void)createTabStripController {
72 Class factory = [TabStripController class]; 75 Class factory = [TabStripController class];
73 if ([self useVerticalTabs]) 76 if ([self useVerticalTabs])
74 factory = [SideTabStripController class]; 77 factory = [SideTabStripController class];
75 78
76 DCHECK([previewableContentsController_ activeContainer]); 79 DCHECK([previewableContentsController_ activeContainer]);
77 DCHECK([[previewableContentsController_ activeContainer] window]); 80 DCHECK([[previewableContentsController_ activeContainer] window]);
78 tabStripController_.reset([[factory alloc] 81 tabStripController_.reset([[factory alloc]
79 initWithView:[self tabStripView] 82 initWithView:[self tabStripView]
80 switchView:[previewableContentsController_ activeContainer] 83 switchView:[previewableContentsController_ activeContainer]
81 browser:browser_.get() 84 browser:browser_.get()
82 delegate:self]); 85 delegate:self]);
83 } 86 }
84 87
88 - (void)createAndInstallPresentationModeToggleButton {
89 DCHECK(base::mac::IsOSLionOrLater());
90 if (presentationModeToggleButton_.get())
91 return;
92
93 // TODO(rohitrao): Make this button prettier.
94 presentationModeToggleButton_.reset(
95 [[NSButton alloc] initWithFrame:NSMakeRect(0, 0, 25, 25)]);
96 [presentationModeToggleButton_ setButtonType:NSMomentaryLightButton];
97 [presentationModeToggleButton_ setBezelStyle:NSRegularSquareBezelStyle];
98 [presentationModeToggleButton_ setBordered:NO];
99 [presentationModeToggleButton_
100 setImage:[NSImage imageNamed:NSImageNameIChatTheaterTemplate]];
Robert Sesek 2011/08/04 14:43:41 I was hoping you'd choose this one :)
101 [presentationModeToggleButton_ setTarget:self];
102 [presentationModeToggleButton_
Robert Sesek 2011/08/04 14:43:41 [[button cell] setHighlightsBy:NSContentsCellMask]
rohitrao (ping after 24h) 2011/08/04 18:18:26 Done.
103 setAction:@selector(togglePresentationMode:)];
104 [[[[self window] contentView] superview]
105 addSubview:presentationModeToggleButton_];
106 }
107
85 - (void)saveWindowPositionIfNeeded { 108 - (void)saveWindowPositionIfNeeded {
86 if (browser_ != BrowserList::GetLastActive()) 109 if (browser_ != BrowserList::GetLastActive())
87 return; 110 return;
88 111
89 if (!browser_->profile()->GetPrefs() || 112 if (!browser_->profile()->GetPrefs() ||
90 !browser_->ShouldSaveWindowPlacement()) { 113 !browser_->ShouldSaveWindowPlacement()) {
91 return; 114 return;
92 } 115 }
93 116
94 [self saveWindowPositionToPrefs:browser_->profile()->GetPrefs()]; 117 [self saveWindowPositionToPrefs:browser_->profile()->GetPrefs()];
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 NSView* contentView = [window contentView]; 200 NSView* contentView = [window contentView];
178 NSRect contentBounds = [contentView bounds]; 201 NSRect contentBounds = [contentView bounds];
179 CGFloat minX = NSMinX(contentBounds); 202 CGFloat minX = NSMinX(contentBounds);
180 CGFloat minY = NSMinY(contentBounds); 203 CGFloat minY = NSMinY(contentBounds);
181 CGFloat width = NSWidth(contentBounds); 204 CGFloat width = NSWidth(contentBounds);
182 205
183 // Suppress title drawing if necessary. 206 // Suppress title drawing if necessary.
184 if ([window respondsToSelector:@selector(setShouldHideTitle:)]) 207 if ([window respondsToSelector:@selector(setShouldHideTitle:)])
185 [(id)window setShouldHideTitle:![self hasTitleBar]]; 208 [(id)window setShouldHideTitle:![self hasTitleBar]];
186 209
187 BOOL isFullscreen = [self isFullscreen]; 210 BOOL inPresentationMode = [self inPresentationMode];
188 CGFloat floatingBarHeight = [self floatingBarHeight]; 211 CGFloat floatingBarHeight = [self floatingBarHeight];
189 // In fullscreen mode, |yOffset| accounts for the sliding position of the 212 // In presentation mode, |yOffset| accounts for the sliding position of the
190 // floating bar and the extra offset needed to dodge the menu bar. 213 // floating bar and the extra offset needed to dodge the menu bar.
191 CGFloat yOffset = isFullscreen ? 214 CGFloat yOffset = inPresentationMode ?
192 (floor((1 - floatingBarShownFraction_) * floatingBarHeight) - 215 (floor((1 - floatingBarShownFraction_) * floatingBarHeight) -
193 [fullscreenController_ floatingBarVerticalOffset]) : 0; 216 [presentationModeController_ floatingBarVerticalOffset]) : 0;
194 CGFloat maxY = NSMaxY(contentBounds) + yOffset; 217 CGFloat maxY = NSMaxY(contentBounds) + yOffset;
195 CGFloat startMaxY = maxY; 218 CGFloat startMaxY = maxY;
196 219
220 CGFloat overlayMaxY =
221 NSMaxY([window frame]) +
222 floor((1 - floatingBarShownFraction_) * floatingBarHeight);
223 [self layoutPresentationModeToggleAtOverlayMaxX:NSMaxX([window frame])
224 OverlayMaxY:overlayMaxY];
225
197 if ([self hasTabStrip] && ![self useVerticalTabs]) { 226 if ([self hasTabStrip] && ![self useVerticalTabs]) {
198 // If we need to lay out the top tab strip, replace |maxY| and |startMaxY| 227 // 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. 228 // with higher values, and then lay out the tab strip.
200 NSRect windowFrame = [contentView convertRect:[window frame] fromView:nil]; 229 NSRect windowFrame = [contentView convertRect:[window frame] fromView:nil];
201 startMaxY = maxY = NSHeight(windowFrame) + yOffset; 230 startMaxY = maxY = NSHeight(windowFrame) + yOffset;
202 maxY = [self layoutTabStripAtMaxY:maxY width:width fullscreen:isFullscreen]; 231 maxY = [self layoutTabStripAtMaxY:maxY
232 width:width
233 fullscreen:[self isFullscreen]];
203 } 234 }
204 235
205 // Sanity-check |maxY|. 236 // Sanity-check |maxY|.
206 DCHECK_GE(maxY, minY); 237 DCHECK_GE(maxY, minY);
207 DCHECK_LE(maxY, NSMaxY(contentBounds) + yOffset); 238 DCHECK_LE(maxY, NSMaxY(contentBounds) + yOffset);
208 239
209 // The base class already positions the side tab strip on the left side 240 // 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 241 // 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, 242 // height. All that's needed here is to push everything over to the right,
212 // if necessary. 243 // if necessary.
213 if ([self useVerticalTabs]) { 244 if ([self useVerticalTabs]) {
214 const CGFloat sideTabWidth = [[self tabStripView] bounds].size.width; 245 const CGFloat sideTabWidth = [[self tabStripView] bounds].size.width;
215 minX += sideTabWidth; 246 minX += sideTabWidth;
216 width -= sideTabWidth; 247 width -= sideTabWidth;
217 } 248 }
218 249
219 // Place the toolbar at the top of the reserved area. 250 // Place the toolbar at the top of the reserved area.
220 maxY = [self layoutToolbarAtMinX:minX maxY:maxY width:width]; 251 maxY = [self layoutToolbarAtMinX:minX maxY:maxY width:width];
221 252
222 // If we're not displaying the bookmark bar below the infobar, then it goes 253 // If we're not displaying the bookmark bar below the infobar, then it goes
223 // immediately below the toolbar. 254 // immediately below the toolbar.
224 BOOL placeBookmarkBarBelowInfoBar = [self placeBookmarkBarBelowInfoBar]; 255 BOOL placeBookmarkBarBelowInfoBar = [self placeBookmarkBarBelowInfoBar];
225 if (!placeBookmarkBarBelowInfoBar) 256 if (!placeBookmarkBarBelowInfoBar)
226 maxY = [self layoutBookmarkBarAtMinX:minX maxY:maxY width:width]; 257 maxY = [self layoutBookmarkBarAtMinX:minX maxY:maxY width:width];
227 258
228 // The floating bar backing view doesn't actually add any height. 259 // The floating bar backing view doesn't actually add any height.
229 NSRect floatingBarBackingRect = 260 NSRect floatingBarBackingRect =
230 NSMakeRect(minX, maxY, width, floatingBarHeight); 261 NSMakeRect(minX, maxY, width, floatingBarHeight);
231 [self layoutFloatingBarBackingView:floatingBarBackingRect 262 [self layoutFloatingBarBackingView:floatingBarBackingRect
232 fullscreen:isFullscreen]; 263 presentationMode:inPresentationMode];
233 264
234 // Place the find bar immediately below the toolbar/attached bookmark bar. In 265 // 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. 266 // 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. 267 // hidden. The find bar is unaffected by the side tab positioning.
237 [findBarCocoaController_ positionFindBarViewAtMaxY:maxY maxWidth:width]; 268 [findBarCocoaController_ positionFindBarViewAtMaxY:maxY maxWidth:width];
238 269
239 // If in fullscreen mode, reset |maxY| to top of screen, so that the floating 270 // 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. 271 // floating bar slides over the things which appear to be in the content area.
241 if (isFullscreen) 272 if (inPresentationMode)
242 maxY = NSMaxY(contentBounds); 273 maxY = NSMaxY(contentBounds);
243 274
244 // Also place the infobar container immediate below the toolbar, except in 275 // 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. 276 // presentation mode in which case it's at the top of the visual content area.
246 maxY = [self layoutInfoBarAtMinX:minX maxY:maxY width:width]; 277 maxY = [self layoutInfoBarAtMinX:minX maxY:maxY width:width];
247 278
248 // If the bookmark bar is detached, place it next in the visual content area. 279 // If the bookmark bar is detached, place it next in the visual content area.
249 if (placeBookmarkBarBelowInfoBar) 280 if (placeBookmarkBarBelowInfoBar)
250 maxY = [self layoutBookmarkBarAtMinX:minX maxY:maxY width:width]; 281 maxY = [self layoutBookmarkBarAtMinX:minX maxY:maxY width:width];
251 282
252 // Place the download shelf, if any, at the bottom of the view. 283 // Place the download shelf, if any, at the bottom of the view.
253 minY = [self layoutDownloadShelfAtMinX:minX minY:minY width:width]; 284 minY = [self layoutDownloadShelfAtMinX:minX minY:minY width:width];
254 285
255 // Finally, the content area takes up all of the remaining space. 286 // Finally, the content area takes up all of the remaining space.
256 NSRect contentAreaRect = NSMakeRect(minX, minY, width, maxY - minY); 287 NSRect contentAreaRect = NSMakeRect(minX, minY, width, maxY - minY);
257 [self layoutTabContentArea:contentAreaRect]; 288 [self layoutTabContentArea:contentAreaRect];
258 289
259 // Normally, we don't need to tell the toolbar whether or not to show the 290 // Normally, we don't need to tell the toolbar whether or not to show the
260 // divider, but things break down during animation. 291 // divider, but things break down during animation.
261 [toolbarController_ 292 [toolbarController_
262 setDividerOpacity:[bookmarkBarController_ toolbarDividerOpacity]]; 293 setDividerOpacity:[bookmarkBarController_ toolbarDividerOpacity]];
263 } 294 }
264 295
265 - (CGFloat)floatingBarHeight { 296 - (CGFloat)floatingBarHeight {
266 if (![self isFullscreen]) 297 if (![self inPresentationMode])
267 return 0; 298 return 0;
268 299
269 CGFloat totalHeight = [fullscreenController_ floatingBarVerticalOffset]; 300 CGFloat totalHeight = [presentationModeController_ floatingBarVerticalOffset];
270 301
271 if ([self hasTabStrip]) 302 if ([self hasTabStrip])
272 totalHeight += NSHeight([[self tabStripView] frame]); 303 totalHeight += NSHeight([[self tabStripView] frame]);
273 304
274 if ([self hasToolbar]) { 305 if ([self hasToolbar]) {
275 totalHeight += NSHeight([[toolbarController_ view] frame]); 306 totalHeight += NSHeight([[toolbarController_ view] frame]);
276 } else if ([self hasLocationBar]) { 307 } else if ([self hasLocationBar]) {
277 totalHeight += NSHeight([[toolbarController_ view] frame]) + 308 totalHeight += NSHeight([[toolbarController_ view] frame]) +
278 kLocBarTopInset + kLocBarBottomInset; 309 kLocBarTopInset + kLocBarBottomInset;
279 } 310 }
280 311
281 if (![self placeBookmarkBarBelowInfoBar]) 312 if (![self placeBookmarkBarBelowInfoBar])
282 totalHeight += NSHeight([[bookmarkBarController_ view] frame]); 313 totalHeight += NSHeight([[bookmarkBarController_ view] frame]);
283 314
284 return totalHeight; 315 return totalHeight;
285 } 316 }
286 317
318 - (void)layoutPresentationModeToggleAtOverlayMaxX:(CGFloat)maxX
319 OverlayMaxY:(CGFloat)maxY {
320 // Lay out the presentation mode toggle button at the very top of the
321 // tabstrip.
322 if ([self shouldShowPresentationModeToggle]) {
323 [self createAndInstallPresentationModeToggleButton];
324
325 NSPoint origin =
326 NSMakePoint(maxX - NSWidth([presentationModeToggleButton_ frame]),
327 maxY - NSHeight([presentationModeToggleButton_ frame]));
328 [presentationModeToggleButton_ setFrameOrigin:origin];
329 } else {
330 [presentationModeToggleButton_ removeFromSuperview];
331 presentationModeToggleButton_.reset();
332 }
333 }
334
287 - (CGFloat)layoutTabStripAtMaxY:(CGFloat)maxY 335 - (CGFloat)layoutTabStripAtMaxY:(CGFloat)maxY
288 width:(CGFloat)width 336 width:(CGFloat)width
289 fullscreen:(BOOL)fullscreen { 337 fullscreen:(BOOL)fullscreen {
290 // Nothing to do if no tab strip. 338 // Nothing to do if no tab strip.
291 if (![self hasTabStrip]) 339 if (![self hasTabStrip])
292 return maxY; 340 return maxY;
293 341
294 NSView* tabStripView = [self tabStripView]; 342 NSView* tabStripView = [self tabStripView];
295 CGFloat tabStripHeight = NSHeight([tabStripView frame]); 343 CGFloat tabStripHeight = NSHeight([tabStripView frame]);
296 maxY -= tabStripHeight; 344 maxY -= tabStripHeight;
297 [tabStripView setFrame:NSMakeRect(0, maxY, width, tabStripHeight)]; 345 [tabStripView setFrame:NSMakeRect(0, maxY, width, tabStripHeight)];
298 346
299 // Set indentation. 347 // Set left indentation based on fullscreen mode status.
300 [tabStripController_ setIndentForControls:(fullscreen ? 0 : 348 [tabStripController_ setLeftIndentForControls:(fullscreen ? 0 :
301 [[tabStripController_ class] defaultIndentForControls])]; 349 [[tabStripController_ class] defaultLeftIndentForControls])];
302 350
303 // TODO(viettrungluu): Seems kind of bad -- shouldn't |-layoutSubviews| do 351 // Calculate the right indentation. The default indentation built into the
304 // this? Moreover, |-layoutTabs| will try to animate.... 352 // tabstrip leaves enough room for the fullscreen button or presentation mode
305 [tabStripController_ layoutTabs]; 353 // toggle button on Lion. On non-Lion systems, the default indentation also
354 // looks fine. If an avatar button is present, indent enough to account for
355 // its width.
356 CGFloat rightIndent = 0;
357
358 // Set the size of the avatar to be the (height of the tabstrip) - (padding)
359 // to let large icons fit.
360 CGFloat avatarSize = tabStripHeight - 5.0;
361
362 if ([self shouldShowAvatar])
363 rightIndent += avatarSize;
364
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;
379 if (base::mac::IsOSLionOrLater())
380 badgeOffset += avatarSize;
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)moveViewsForFullscreen:(BOOL)fullscreen
591 regularWindow:(NSWindow*)regularWindow
592 fullscreenWindow:(NSWindow*)fullscreenWindow {
593 // This method is only for Snow Leopard and earlier.
594 DCHECK(!base::mac::IsOSLionOrLater());
Robert Sesek 2011/08/04 14:43:41 IsOSSnowLeopardOrEarlier()
rohitrao (ping after 24h) 2011/08/04 18:18:26 Cool, I meant to go look for that function, but fo
595
596 NSWindow* sourceWindow = fullscreen ? regularWindow : fullscreenWindow;
597 NSWindow* destWindow = fullscreen ? fullscreenWindow : regularWindow;
598
599 // Close the bookmark bubble, if it's open. We use |-ok:| instead of
Robert Sesek 2011/08/04 14:43:41 Mark is going to tell you to not use 'we'
rohitrao (ping after 24h) 2011/08/04 18:18:26 Ook.
600 // |-cancel:| or |-close| because that matches the behavior when the bubble
601 // loses key 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::IsOSLionOrLater());
Robert Sesek 2011/08/04 14:43:41 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 moveViewsForFullscreen: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::IsOSLionOrLater());
Robert Sesek 2011/08/04 14:43:41 here too
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 moveViewsForFullscreen: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