OLD | NEW |
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.h" | 5 #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
6 | 6 |
7 #include <Carbon/Carbon.h> | 7 #include <Carbon/Carbon.h> |
8 | 8 |
9 #include <cmath> | 9 #include <cmath> |
10 #include <numeric> | 10 #include <numeric> |
(...skipping 23 matching lines...) Expand all Loading... |
34 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.h" | 34 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.h" |
35 #import "chrome/browser/ui/cocoa/browser/avatar_button.h" | 35 #import "chrome/browser/ui/cocoa/browser/avatar_button.h" |
36 #import "chrome/browser/ui/cocoa/browser_window_cocoa.h" | 36 #import "chrome/browser/ui/cocoa/browser_window_cocoa.h" |
37 #import "chrome/browser/ui/cocoa/browser_window_controller_private.h" | 37 #import "chrome/browser/ui/cocoa/browser_window_controller_private.h" |
38 #import "chrome/browser/ui/cocoa/dev_tools_controller.h" | 38 #import "chrome/browser/ui/cocoa/dev_tools_controller.h" |
39 #import "chrome/browser/ui/cocoa/download/download_shelf_controller.h" | 39 #import "chrome/browser/ui/cocoa/download/download_shelf_controller.h" |
40 #import "chrome/browser/ui/cocoa/event_utils.h" | 40 #import "chrome/browser/ui/cocoa/event_utils.h" |
41 #import "chrome/browser/ui/cocoa/fast_resize_view.h" | 41 #import "chrome/browser/ui/cocoa/fast_resize_view.h" |
42 #import "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h" | 42 #import "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h" |
43 #import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h" | 43 #import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h" |
44 #import "chrome/browser/ui/cocoa/focus_tracker.h" | 44 #import "chrome/browser/ui/cocoa/framed_browser_window.h" |
45 #import "chrome/browser/ui/cocoa/fullscreen_controller.h" | |
46 #import "chrome/browser/ui/cocoa/fullscreen_window.h" | 45 #import "chrome/browser/ui/cocoa/fullscreen_window.h" |
47 #import "chrome/browser/ui/cocoa/gesture_utils.h" | 46 #import "chrome/browser/ui/cocoa/gesture_utils.h" |
48 #import "chrome/browser/ui/cocoa/image_utils.h" | 47 #import "chrome/browser/ui/cocoa/image_utils.h" |
49 #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" | 48 #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" |
50 #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.h" | 49 #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.h" |
| 50 #import "chrome/browser/ui/cocoa/presentation_mode_controller.h" |
51 #import "chrome/browser/ui/cocoa/sidebar_controller.h" | 51 #import "chrome/browser/ui/cocoa/sidebar_controller.h" |
52 #import "chrome/browser/ui/cocoa/status_bubble_mac.h" | 52 #import "chrome/browser/ui/cocoa/status_bubble_mac.h" |
53 #import "chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.h" | 53 #import "chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.h" |
54 #import "chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h" | 54 #import "chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h" |
55 #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" | 55 #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" |
56 #import "chrome/browser/ui/cocoa/tabpose_window.h" | 56 #import "chrome/browser/ui/cocoa/tabpose_window.h" |
57 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" | 57 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" |
58 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" | 58 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" |
59 #import "chrome/browser/ui/cocoa/tabs/tab_view.h" | 59 #import "chrome/browser/ui/cocoa/tabs/tab_view.h" |
60 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" | 60 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 | 191 |
192 enum { | 192 enum { |
193 NSWindowAnimationBehaviorDefault = 0, | 193 NSWindowAnimationBehaviorDefault = 0, |
194 NSWindowAnimationBehaviorNone = 2, | 194 NSWindowAnimationBehaviorNone = 2, |
195 NSWindowAnimationBehaviorDocumentWindow = 3, | 195 NSWindowAnimationBehaviorDocumentWindow = 3, |
196 NSWindowAnimationBehaviorUtilityWindow = 4, | 196 NSWindowAnimationBehaviorUtilityWindow = 4, |
197 NSWindowAnimationBehaviorAlertPanel = 5 | 197 NSWindowAnimationBehaviorAlertPanel = 5 |
198 }; | 198 }; |
199 typedef NSInteger NSWindowAnimationBehavior; | 199 typedef NSInteger NSWindowAnimationBehavior; |
200 | 200 |
| 201 enum { |
| 202 NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7, |
| 203 NSWindowCollectionBehaviorFullScreenAuxiliary = 1 << 8 |
| 204 }; |
| 205 |
| 206 enum { |
| 207 NSFullScreenWindowMask = 1 << 14 |
| 208 }; |
| 209 |
201 @interface NSWindow (LionSDKDeclarations) | 210 @interface NSWindow (LionSDKDeclarations) |
202 - (void)setRestorable:(BOOL)flag; | 211 - (void)setRestorable:(BOOL)flag; |
203 - (void)setAnimationBehavior:(NSWindowAnimationBehavior)newAnimationBehavior; | 212 - (void)setAnimationBehavior:(NSWindowAnimationBehavior)newAnimationBehavior; |
204 @end | 213 @end |
205 | 214 |
206 #endif // MAC_OS_X_VERSION_10_7 | 215 #endif // MAC_OS_X_VERSION_10_7 |
207 | 216 |
208 @implementation BrowserWindowController | 217 @implementation BrowserWindowController |
209 | 218 |
210 + (BrowserWindowController*)browserWindowControllerForWindow:(NSWindow*)window { | 219 + (BrowserWindowController*)browserWindowControllerForWindow:(NSWindow*)window { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 // functionality appears to be leaky (or at least interacts badly with our | 266 // functionality appears to be leaky (or at least interacts badly with our |
258 // architecture) and thus BrowserWindowController never gets released. This | 267 // architecture) and thus BrowserWindowController never gets released. This |
259 // prevents the browser from being able to quit <http://crbug.com/79113>. | 268 // prevents the browser from being able to quit <http://crbug.com/79113>. |
260 if ([window respondsToSelector:@selector(setRestorable:)]) | 269 if ([window respondsToSelector:@selector(setRestorable:)]) |
261 [window setRestorable:NO]; | 270 [window setRestorable:NO]; |
262 | 271 |
263 // Get the windows to swish in on Lion. | 272 // Get the windows to swish in on Lion. |
264 if ([window respondsToSelector:@selector(setAnimationBehavior:)]) | 273 if ([window respondsToSelector:@selector(setAnimationBehavior:)]) |
265 [window setAnimationBehavior:NSWindowAnimationBehaviorDocumentWindow]; | 274 [window setAnimationBehavior:NSWindowAnimationBehaviorDocumentWindow]; |
266 | 275 |
| 276 // Set the window to participate in Lion Fullscreen mode. Setting this flag |
| 277 // has no effect on Snow Leopard or earlier. |
| 278 NSUInteger collectionBehavior = [window collectionBehavior]; |
| 279 collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary; |
| 280 [window setCollectionBehavior:collectionBehavior]; |
| 281 |
267 // Get the most appropriate size for the window, then enforce the | 282 // Get the most appropriate size for the window, then enforce the |
268 // minimum width and height. The window shim will handle flipping | 283 // minimum width and height. The window shim will handle flipping |
269 // the coordinates for us so we can use it to save some code. | 284 // the coordinates for us so we can use it to save some code. |
270 // Note that this may leave a significant portion of the window | 285 // Note that this may leave a significant portion of the window |
271 // offscreen, but there will always be enough window onscreen to | 286 // offscreen, but there will always be enough window onscreen to |
272 // drag the whole window back into view. | 287 // drag the whole window back into view. |
273 gfx::Rect desiredContentRect = browser_->GetSavedWindowBounds(); | 288 gfx::Rect desiredContentRect = browser_->GetSavedWindowBounds(); |
274 gfx::Rect windowRect = desiredContentRect; | 289 gfx::Rect windowRect = desiredContentRect; |
275 windowRect = [self enforceMinWindowSize:windowRect]; | 290 windowRect = [self enforceMinWindowSize:windowRect]; |
276 | 291 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 addObserver:self | 417 addObserver:self |
403 selector:@selector(applicationDidUnhide:) | 418 selector:@selector(applicationDidUnhide:) |
404 name:NSApplicationDidUnhideNotification | 419 name:NSApplicationDidUnhideNotification |
405 object:nil]; | 420 object:nil]; |
406 | 421 |
407 // This must be done after the view is added to the window since it relies | 422 // This must be done after the view is added to the window since it relies |
408 // on the window bounds to determine whether to show buttons or not. | 423 // on the window bounds to determine whether to show buttons or not. |
409 if ([self hasToolbar]) // Do not create the buttons in popups. | 424 if ([self hasToolbar]) // Do not create the buttons in popups. |
410 [toolbarController_ createBrowserActionButtons]; | 425 [toolbarController_ createBrowserActionButtons]; |
411 | 426 |
412 [self setUpOSFullScreenButton]; | |
413 | |
414 // We are done initializing now. | 427 // We are done initializing now. |
415 initializing_ = NO; | 428 initializing_ = NO; |
416 } | 429 } |
417 return self; | 430 return self; |
418 } | 431 } |
419 | 432 |
420 - (void)awakeFromNib { | 433 - (void)awakeFromNib { |
421 // Set different minimum sizes on tabbed windows vs non-tabbed, e.g. popups. | 434 // Set different minimum sizes on tabbed windows vs non-tabbed, e.g. popups. |
422 NSSize minSize = [self isTabbedWindow] ? | 435 NSSize minSize = [self isTabbedWindow] ? |
423 NSMakeSize(400, 272) : NSMakeSize(100, 122); | 436 NSMakeSize(400, 272) : NSMakeSize(100, 122); |
424 [[self window] setMinSize:minSize]; | 437 [[self window] setMinSize:minSize]; |
425 } | 438 } |
426 | 439 |
427 - (void)dealloc { | 440 - (void)dealloc { |
428 browser_->CloseAllTabs(); | 441 browser_->CloseAllTabs(); |
429 [downloadShelfController_ exiting]; | 442 [downloadShelfController_ exiting]; |
430 | 443 |
431 // Explicitly release |fullscreenController_| here, as it may call back to | 444 // Explicitly release |presentationModeController_| here, as it may call back |
432 // this BWC in |-dealloc|. We are required to call |-exitFullscreen| before | 445 // to this BWC in |-dealloc|. We are required to call |-exitPresentationMode| |
433 // releasing the controller. | 446 // before releasing the controller. |
434 [fullscreenController_ exitFullscreen]; | 447 [presentationModeController_ exitPresentationMode]; |
435 fullscreenController_.reset(); | 448 presentationModeController_.reset(); |
436 | 449 |
437 // Under certain testing configurations we may not actually own the browser. | 450 // Under certain testing configurations we may not actually own the browser. |
438 if (ownsBrowser_ == NO) | 451 if (ownsBrowser_ == NO) |
439 ignore_result(browser_.release()); | 452 ignore_result(browser_.release()); |
440 | 453 |
441 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 454 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
442 | 455 |
443 [super dealloc]; | 456 [super dealloc]; |
444 } | 457 } |
445 | 458 |
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1013 // one tab. | 1026 // one tab. |
1014 enable &= [[self window] isKeyWindow]; | 1027 enable &= [[self window] isKeyWindow]; |
1015 break; | 1028 break; |
1016 case IDC_FULLSCREEN: { | 1029 case IDC_FULLSCREEN: { |
1017 enable &= [self supportsFullscreen]; | 1030 enable &= [self supportsFullscreen]; |
1018 if ([static_cast<NSObject*>(item) isKindOfClass:[NSMenuItem class]]) { | 1031 if ([static_cast<NSObject*>(item) isKindOfClass:[NSMenuItem class]]) { |
1019 NSString* menuTitle = l10n_util::GetNSString( | 1032 NSString* menuTitle = l10n_util::GetNSString( |
1020 [self isFullscreen] ? IDS_EXIT_FULLSCREEN_MAC : | 1033 [self isFullscreen] ? IDS_EXIT_FULLSCREEN_MAC : |
1021 IDS_ENTER_FULLSCREEN_MAC); | 1034 IDS_ENTER_FULLSCREEN_MAC); |
1022 [static_cast<NSMenuItem*>(item) setTitle:menuTitle]; | 1035 [static_cast<NSMenuItem*>(item) setTitle:menuTitle]; |
| 1036 |
| 1037 if (base::mac::IsOSSnowLeopardOrEarlier()) |
| 1038 [static_cast<NSMenuItem*>(item) setHidden:YES]; |
| 1039 } |
| 1040 break; |
| 1041 } |
| 1042 case IDC_PRESENTATION_MODE: { |
| 1043 enable &= [self supportsFullscreen]; |
| 1044 if ([static_cast<NSObject*>(item) isKindOfClass:[NSMenuItem class]]) { |
| 1045 NSString* menuTitle = l10n_util::GetNSString( |
| 1046 [self inPresentationMode] ? IDS_EXIT_PRESENTATION_MAC : |
| 1047 IDS_ENTER_PRESENTATION_MAC); |
| 1048 [static_cast<NSMenuItem*>(item) setTitle:menuTitle]; |
1023 } | 1049 } |
1024 break; | 1050 break; |
1025 } | 1051 } |
1026 case IDC_SYNC_BOOKMARKS: | 1052 case IDC_SYNC_BOOKMARKS: |
1027 enable &= browser_->profile()->IsSyncAccessible(); | 1053 enable &= browser_->profile()->IsSyncAccessible(); |
1028 sync_ui_util::UpdateSyncItem(item, enable, browser_->profile()); | 1054 sync_ui_util::UpdateSyncItem(item, enable, browser_->profile()); |
1029 break; | 1055 break; |
1030 default: | 1056 default: |
1031 // Special handling for the contents of the Text Encoding submenu. On | 1057 // Special handling for the contents of the Text Encoding submenu. On |
1032 // Mac OS, instead of enabling/disabling the top-level menu item, we | 1058 // Mac OS, instead of enabling/disabling the top-level menu item, we |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1406 DCHECK(!findBarCocoaController_.get()); | 1432 DCHECK(!findBarCocoaController_.get()); |
1407 | 1433 |
1408 // Create a controller for the findbar. | 1434 // Create a controller for the findbar. |
1409 findBarCocoaController_.reset([findBarCocoaController retain]); | 1435 findBarCocoaController_.reset([findBarCocoaController retain]); |
1410 NSView *contentView = [[self window] contentView]; | 1436 NSView *contentView = [[self window] contentView]; |
1411 [contentView addSubview:[findBarCocoaController_ view] | 1437 [contentView addSubview:[findBarCocoaController_ view] |
1412 positioned:NSWindowAbove | 1438 positioned:NSWindowAbove |
1413 relativeTo:[infoBarContainerController_ view]]; | 1439 relativeTo:[infoBarContainerController_ view]]; |
1414 | 1440 |
1415 // Place the find bar immediately below the toolbar/attached bookmark bar. In | 1441 // Place the find bar immediately below the toolbar/attached bookmark bar. In |
1416 // fullscreen mode, it hangs off the top of the screen when the bar is hidden. | 1442 // presentation mode, it hangs off the top of the screen when the bar is |
| 1443 // hidden. |
1417 CGFloat maxY = [self placeBookmarkBarBelowInfoBar] ? | 1444 CGFloat maxY = [self placeBookmarkBarBelowInfoBar] ? |
1418 NSMinY([[toolbarController_ view] frame]) : | 1445 NSMinY([[toolbarController_ view] frame]) : |
1419 NSMinY([[bookmarkBarController_ view] frame]); | 1446 NSMinY([[bookmarkBarController_ view] frame]); |
1420 CGFloat maxWidth = NSWidth([contentView frame]); | 1447 CGFloat maxWidth = NSWidth([contentView frame]); |
1421 [findBarCocoaController_ positionFindBarViewAtMaxY:maxY maxWidth:maxWidth]; | 1448 [findBarCocoaController_ positionFindBarViewAtMaxY:maxY maxWidth:maxWidth]; |
1422 | 1449 |
1423 // This allows the FindBarCocoaController to call |layoutSubviews| and get | 1450 // This allows the FindBarCocoaController to call |layoutSubviews| and get |
1424 // its position adjusted. | 1451 // its position adjusted. |
1425 [findBarCocoaController_ setBrowserWindowController:self]; | 1452 [findBarCocoaController_ setBrowserWindowController:self]; |
1426 } | 1453 } |
(...skipping 11 matching lines...) Expand all Loading... |
1438 - (BOOL)hasLiveTabs { | 1465 - (BOOL)hasLiveTabs { |
1439 return !browser_->tabstrip_model()->empty(); | 1466 return !browser_->tabstrip_model()->empty(); |
1440 } | 1467 } |
1441 | 1468 |
1442 - (NSString*)activeTabTitle { | 1469 - (NSString*)activeTabTitle { |
1443 TabContents* contents = browser_->GetSelectedTabContents(); | 1470 TabContents* contents = browser_->GetSelectedTabContents(); |
1444 return base::SysUTF16ToNSString(contents->GetTitle()); | 1471 return base::SysUTF16ToNSString(contents->GetTitle()); |
1445 } | 1472 } |
1446 | 1473 |
1447 - (NSRect)regularWindowFrame { | 1474 - (NSRect)regularWindowFrame { |
1448 return [self isFullscreen] ? [savedRegularWindow_ frame] : | 1475 return [self isFullscreen] ? savedRegularWindowFrame_ : |
1449 [[self window] frame]; | 1476 [[self window] frame]; |
1450 } | 1477 } |
1451 | 1478 |
1452 // (Override of |TabWindowController| method.) | 1479 // (Override of |TabWindowController| method.) |
1453 - (BOOL)hasTabStrip { | 1480 - (BOOL)hasTabStrip { |
1454 return [self supportsWindowFeature:Browser::FEATURE_TABSTRIP]; | 1481 return [self supportsWindowFeature:Browser::FEATURE_TABSTRIP]; |
1455 } | 1482 } |
1456 | 1483 |
1457 // TabContentsControllerDelegate protocol. | 1484 // TabContentsControllerDelegate protocol. |
1458 - (void)tabContentsViewFrameWillChange:(TabContentsController*)source | 1485 - (void)tabContentsViewFrameWillChange:(TabContentsController*)source |
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2021 returnCode:(NSInteger)code | 2048 returnCode:(NSInteger)code |
2022 context:(void*)context { | 2049 context:(void*)context { |
2023 [sheet orderOut:self]; | 2050 [sheet orderOut:self]; |
2024 } | 2051 } |
2025 | 2052 |
2026 @end // @implementation BrowserWindowController | 2053 @end // @implementation BrowserWindowController |
2027 | 2054 |
2028 | 2055 |
2029 @implementation BrowserWindowController(Fullscreen) | 2056 @implementation BrowserWindowController(Fullscreen) |
2030 | 2057 |
2031 - (IBAction)enterFullscreen:(id)sender { | 2058 - (void)handleLionToggleFullscreen { |
| 2059 DCHECK(base::mac::IsOSLionOrLater()); |
2032 browser_->ExecuteCommand(IDC_FULLSCREEN); | 2060 browser_->ExecuteCommand(IDC_FULLSCREEN); |
2033 } | 2061 } |
2034 | 2062 |
| 2063 // On Lion, this method is called by either the Lion fullscreen button or the |
| 2064 // "Enter Full Screen" menu item. On Snow Leopard, this function is never |
| 2065 // called by the UI directly, but it provides the implementation for |
| 2066 // |-setPresentationMode:|. |
2035 - (void)setFullscreen:(BOOL)fullscreen { | 2067 - (void)setFullscreen:(BOOL)fullscreen { |
2036 // The logic in this function is a bit complicated and very carefully | |
2037 // arranged. See the below comments for more details. | |
2038 | |
2039 if (fullscreen == [self isFullscreen]) | 2068 if (fullscreen == [self isFullscreen]) |
2040 return; | 2069 return; |
2041 | 2070 |
2042 if (![self supportsFullscreen]) | 2071 if (![self supportsFullscreen]) |
2043 return; | 2072 return; |
2044 | 2073 |
2045 // Fade to black. | 2074 if (base::mac::IsOSLionOrLater()) { |
2046 const CGDisplayReservationInterval kFadeDurationSeconds = 0.6; | 2075 enteredPresentationModeFromFullscreen_ = YES; |
2047 Boolean didFadeOut = NO; | 2076 if ([[self window] isKindOfClass:[FramedBrowserWindow class]]) |
2048 CGDisplayFadeReservationToken token; | 2077 [static_cast<FramedBrowserWindow*>([self window]) toggleSystemFullScreen]; |
2049 if (CGAcquireDisplayFadeReservation(kFadeDurationSeconds, &token) | 2078 return; |
2050 == kCGErrorSuccess) { | |
2051 didFadeOut = YES; | |
2052 CGDisplayFade(token, kFadeDurationSeconds / 2, kCGDisplayBlendNormal, | |
2053 kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, /*synchronous=*/true); | |
2054 } | 2079 } |
2055 | 2080 |
2056 // Close the bookmark bubble, if it's open. We use |-ok:| instead of | 2081 if (fullscreen) |
2057 // |-cancel:| or |-close| because that matches the behavior when the bubble | 2082 [self enterFullscreenForSnowLeopardOrEarlier]; |
2058 // loses key status. | 2083 else |
2059 [bookmarkBubbleController_ ok:self]; | 2084 [self exitFullscreenForSnowLeopardOrEarlier]; |
| 2085 } |
2060 | 2086 |
2061 // Save the current first responder so we can restore after views are moved. | 2087 - (BOOL)isFullscreen { |
2062 NSWindow* window = [self window]; | 2088 return (fullscreenWindow_.get() != nil) || |
2063 scoped_nsobject<FocusTracker> focusTracker( | 2089 ([[self window] styleMask] & NSFullScreenWindowMask); |
2064 [[FocusTracker alloc] initWithWindow:window]); | 2090 } |
2065 BOOL showDropdown = [self floatingBarHasFocus]; | |
2066 | 2091 |
2067 // While we move views (and focus) around, disable any bar visibility changes. | 2092 - (void)togglePresentationModeForLionOrLater:(id)sender { |
2068 [self disableBarVisibilityUpdates]; | 2093 // Called only by the presentation mode toggle button. |
| 2094 DCHECK(base::mac::IsOSLionOrLater()); |
| 2095 enteredPresentationModeFromFullscreen_ = YES; |
| 2096 browser_->ExecuteCommand(IDC_PRESENTATION_MODE); |
| 2097 } |
2069 | 2098 |
2070 // If we're entering fullscreen, create the fullscreen controller. If we're | 2099 // On Lion, this function is called by either the presentation mode toggle |
2071 // exiting fullscreen, kill the controller. | 2100 // button or the "Enter Presentation Mode" menu item. In the latter case, this |
2072 if (fullscreen) { | 2101 // function also triggers the Lion machinery to enter fullscreen mode as well as |
2073 fullscreenController_.reset([[FullscreenController alloc] | 2102 // set presentation mode. On Snow Leopard, this function is called by the |
2074 initWithBrowserController:self]); | 2103 // "Enter Presentation Mode" menu item, and triggering presentation mode always |
2075 } else { | 2104 // moves the user into fullscreen mode. |
2076 [fullscreenController_ exitFullscreen]; | 2105 - (void)setPresentationMode:(BOOL)presentationMode { |
2077 fullscreenController_.reset(); | 2106 // Presentation mode on Leopard and Snow Leopard maps directly to fullscreen |
| 2107 // mode. |
| 2108 if (base::mac::IsOSSnowLeopardOrEarlier()) { |
| 2109 [self setFullscreen:presentationMode]; |
| 2110 return; |
2078 } | 2111 } |
2079 | 2112 |
2080 // Destroy the tab strip's sheet controller. We will recreate it in the new | 2113 if (presentationMode) { |
2081 // window when needed. | 2114 BOOL fullscreen = [self isFullscreen]; |
2082 [tabStripController_ destroySheetController]; | 2115 [self setShouldUsePresentationModeWhenEnteringFullscreen:YES]; |
| 2116 enteredPresentationModeFromFullscreen_ = fullscreen; |
2083 | 2117 |
2084 // Retain the tab strip view while we remove it from its superview. | 2118 if (fullscreen) { |
2085 scoped_nsobject<NSView> tabStripView; | 2119 // If already in fullscreen mode, just toggle the presentation mode |
2086 if ([self hasTabStrip] && ![self useVerticalTabs]) { | 2120 // setting. Go through an elaborate dance to force the overlay to show, |
2087 tabStripView.reset([[self tabStripView] retain]); | 2121 // then animate out once the mouse moves away. This helps draw attention |
2088 [tabStripView removeFromSuperview]; | 2122 // to the fact that the UI is in an overlay. Focus the tab contents |
2089 } | 2123 // because the omnibox is the most likely source of bar visibility locks, |
2090 | 2124 // and taking focus away from the omnibox releases its lock. |
2091 // Ditto for the content view. | 2125 [self lockBarVisibilityForOwner:self withAnimation:NO delay:NO]; |
2092 scoped_nsobject<NSView> contentView([[window contentView] retain]); | 2126 [self focusTabContents]; |
2093 // Disable autoresizing of subviews while we move views around. This prevents | 2127 [self setPresentationModeInternal:YES forceDropdown:YES]; |
2094 // spurious renderer resizes. | 2128 [self releaseBarVisibilityForOwner:self withAnimation:YES delay:YES]; |
2095 [contentView setAutoresizesSubviews:NO]; | 2129 } else { |
2096 [contentView removeFromSuperview]; | 2130 // If not in fullscreen mode, trigger the Lion fullscreen mode machinery. |
2097 | 2131 // Presentation mode will automatically be enabled in |
2098 NSWindow* destWindow = nil; | 2132 // |-windowWillEnterFullScreen:|. |
2099 if (fullscreen) { | 2133 NSWindow* window = [self window]; |
2100 DCHECK(!savedRegularWindow_); | 2134 if ([window isKindOfClass:[FramedBrowserWindow class]]) |
2101 savedRegularWindow_ = [window retain]; | 2135 [static_cast<FramedBrowserWindow*>(window) toggleSystemFullScreen]; |
2102 destWindow = [self createFullscreenWindow]; | 2136 } |
2103 } else { | 2137 } else { |
2104 DCHECK(savedRegularWindow_); | 2138 if (enteredPresentationModeFromFullscreen_) { |
2105 destWindow = [savedRegularWindow_ autorelease]; | 2139 // The window is currently in fullscreen mode, but the user is choosing to |
2106 savedRegularWindow_ = nil; | 2140 // turn presentation mode off (choosing to always show the UI). Set the |
2107 } | 2141 // preference to ensure that presentation mode will stay off for the next |
2108 DCHECK(destWindow); | 2142 // window that goes fullscreen. |
2109 | 2143 [self setShouldUsePresentationModeWhenEnteringFullscreen:NO]; |
2110 // Have to do this here, otherwise later calls can crash because the window | 2144 [self setPresentationModeInternal:NO forceDropdown:NO]; |
2111 // has no delegate. | 2145 } else { |
2112 [window setDelegate:nil]; | 2146 // The user entered presentation mode directly from non-fullscreen mode |
2113 [destWindow setDelegate:self]; | 2147 // using the "Enter Presentation Mode" menu item and is using that same |
2114 | 2148 // menu item to exit presentation mode. In this case, exit fullscreen |
2115 // With this call, valgrind complains that a "Conditional jump or move depends | 2149 // mode as well (using the Lion machinery). |
2116 // on uninitialised value(s)". The error happens in -[NSThemeFrame | 2150 NSWindow* window = [self window]; |
2117 // drawOverlayRect:]. I'm pretty convinced this is an Apple bug, but there is | 2151 if ([window isKindOfClass:[FramedBrowserWindow class]]) |
2118 // no visual impact. I have been unable to tickle it away with other window | 2152 [static_cast<FramedBrowserWindow*>(window) toggleSystemFullScreen]; |
2119 // or view manipulation Cocoa calls. Stack added to suppressions_mac.txt. | 2153 } |
2120 [contentView setAutoresizesSubviews:YES]; | |
2121 [destWindow setContentView:contentView]; | |
2122 | |
2123 // Move the incognito badge if present. | |
2124 if (avatarButton_.get()) { | |
2125 [avatarButton_ removeFromSuperview]; | |
2126 [avatarButton_ setHidden:YES]; // Will be shown in layout. | |
2127 [[[destWindow contentView] superview] addSubview:avatarButton_]; | |
2128 } | |
2129 | |
2130 // Add the tab strip after setting the content view and moving the incognito | |
2131 // badge (if any), so that the tab strip will be on top (in the z-order). | |
2132 if ([self hasTabStrip] && ![self useVerticalTabs]) | |
2133 [[[destWindow contentView] superview] addSubview:tabStripView]; | |
2134 | |
2135 [window setWindowController:nil]; | |
2136 [self setWindow:destWindow]; | |
2137 [destWindow setWindowController:self]; | |
2138 [self adjustUIForFullscreen:fullscreen]; | |
2139 | |
2140 // Adjust the infobar container. In fullscreen, it needs to be below all | |
2141 // top chrome elements so it only sits atop the web contents. When in normal | |
2142 // mode, it needs to draw over the bookmark bar and part of the toolbar. | |
2143 [[infoBarContainerController_ view] removeFromSuperview]; | |
2144 NSView* infoBarDest = [[destWindow contentView] superview]; | |
2145 [infoBarDest addSubview:[infoBarContainerController_ view] | |
2146 positioned:fullscreen ? NSWindowBelow : NSWindowAbove | |
2147 relativeTo:fullscreen ? floatingBarBackingView_ | |
2148 : [bookmarkBarController_ view]]; | |
2149 | |
2150 // When entering fullscreen mode, the controller forces a layout for us. When | |
2151 // exiting, we need to call layoutSubviews manually. | |
2152 if (fullscreen) { | |
2153 [fullscreenController_ enterFullscreenForContentView:contentView | |
2154 showDropdown:showDropdown]; | |
2155 } else { | |
2156 [self layoutSubviews]; | |
2157 } | |
2158 | |
2159 // Move the status bubble over, if we have one. | |
2160 if (statusBubble_) | |
2161 statusBubble_->SwitchParentWindow(destWindow); | |
2162 | |
2163 // Move the title over. | |
2164 [destWindow setTitle:[window title]]; | |
2165 | |
2166 // The window needs to be onscreen before we can set its first responder. | |
2167 // Ordering the window to the front can change the active Space (either to | |
2168 // the window's old Space or to the application's assigned Space). To prevent | |
2169 // this by temporarily change the collectionBehavior. | |
2170 NSWindowCollectionBehavior behavior = [window collectionBehavior]; | |
2171 [destWindow setCollectionBehavior: | |
2172 NSWindowCollectionBehaviorMoveToActiveSpace]; | |
2173 [destWindow makeKeyAndOrderFront:self]; | |
2174 [destWindow setCollectionBehavior:behavior]; | |
2175 | |
2176 [focusTracker restoreFocusInWindow:destWindow]; | |
2177 [window orderOut:self]; | |
2178 | |
2179 // We're done moving focus, so re-enable bar visibility changes. | |
2180 [self enableBarVisibilityUpdates]; | |
2181 | |
2182 // This needs to be done when leaving full-screen mode to ensure that the | |
2183 // button's action is set properly. | |
2184 [self setUpOSFullScreenButton]; | |
2185 | |
2186 // Fade back in. | |
2187 if (didFadeOut) { | |
2188 CGDisplayFade(token, kFadeDurationSeconds / 2, kCGDisplayBlendSolidColor, | |
2189 kCGDisplayBlendNormal, 0.0, 0.0, 0.0, /*synchronous=*/false); | |
2190 CGReleaseDisplayFadeReservation(token); | |
2191 } | 2154 } |
2192 } | 2155 } |
2193 | 2156 |
2194 - (BOOL)isFullscreen { | 2157 - (BOOL)inPresentationMode { |
2195 return fullscreenController_.get() && [fullscreenController_ isFullscreen]; | 2158 return presentationModeController_.get() && |
| 2159 [presentationModeController_ inPresentationMode]; |
2196 } | 2160 } |
2197 | 2161 |
2198 - (void)resizeFullscreenWindow { | 2162 - (void)resizeFullscreenWindow { |
2199 DCHECK([self isFullscreen]); | 2163 DCHECK([self isFullscreen]); |
2200 if (![self isFullscreen]) | 2164 if (![self isFullscreen]) |
2201 return; | 2165 return; |
2202 | 2166 |
2203 NSWindow* window = [self window]; | 2167 NSWindow* window = [self window]; |
2204 [window setFrame:[[window screen] frame] display:YES]; | 2168 [window setFrame:[[window screen] frame] display:YES]; |
2205 [self layoutSubviews]; | 2169 [self layoutSubviews]; |
(...skipping 13 matching lines...) Expand all Loading... |
2219 DCHECK(barVisibilityLocks_); | 2183 DCHECK(barVisibilityLocks_); |
2220 return [barVisibilityLocks_ containsObject:owner]; | 2184 return [barVisibilityLocks_ containsObject:owner]; |
2221 } | 2185 } |
2222 | 2186 |
2223 - (void)lockBarVisibilityForOwner:(id)owner | 2187 - (void)lockBarVisibilityForOwner:(id)owner |
2224 withAnimation:(BOOL)animate | 2188 withAnimation:(BOOL)animate |
2225 delay:(BOOL)delay { | 2189 delay:(BOOL)delay { |
2226 if (![self isBarVisibilityLockedForOwner:owner]) { | 2190 if (![self isBarVisibilityLockedForOwner:owner]) { |
2227 [barVisibilityLocks_ addObject:owner]; | 2191 [barVisibilityLocks_ addObject:owner]; |
2228 | 2192 |
2229 // If enabled, show the overlay if necessary (and if in fullscreen mode). | 2193 // If enabled, show the overlay if necessary (and if in presentation mode). |
2230 if (barVisibilityUpdatesEnabled_) { | 2194 if (barVisibilityUpdatesEnabled_) { |
2231 [fullscreenController_ ensureOverlayShownWithAnimation:animate | 2195 [presentationModeController_ ensureOverlayShownWithAnimation:animate |
2232 delay:delay]; | 2196 delay:delay]; |
2233 } | 2197 } |
2234 } | 2198 } |
2235 } | 2199 } |
2236 | 2200 |
2237 - (void)releaseBarVisibilityForOwner:(id)owner | 2201 - (void)releaseBarVisibilityForOwner:(id)owner |
2238 withAnimation:(BOOL)animate | 2202 withAnimation:(BOOL)animate |
2239 delay:(BOOL)delay { | 2203 delay:(BOOL)delay { |
2240 if ([self isBarVisibilityLockedForOwner:owner]) { | 2204 if ([self isBarVisibilityLockedForOwner:owner]) { |
2241 [barVisibilityLocks_ removeObject:owner]; | 2205 [barVisibilityLocks_ removeObject:owner]; |
2242 | 2206 |
2243 // If enabled, hide the overlay if necessary (and if in fullscreen mode). | 2207 // If enabled, hide the overlay if necessary (and if in presentation mode). |
2244 if (barVisibilityUpdatesEnabled_ && | 2208 if (barVisibilityUpdatesEnabled_ && |
2245 ![barVisibilityLocks_ count]) { | 2209 ![barVisibilityLocks_ count]) { |
2246 [fullscreenController_ ensureOverlayHiddenWithAnimation:animate | 2210 [presentationModeController_ ensureOverlayHiddenWithAnimation:animate |
2247 delay:delay]; | 2211 delay:delay]; |
2248 } | 2212 } |
2249 } | 2213 } |
2250 } | 2214 } |
2251 | 2215 |
2252 - (BOOL)floatingBarHasFocus { | 2216 - (BOOL)floatingBarHasFocus { |
2253 NSResponder* focused = [[self window] firstResponder]; | 2217 NSResponder* focused = [[self window] firstResponder]; |
2254 return [focused isKindOfClass:[AutocompleteTextFieldEditor class]]; | 2218 return [focused isKindOfClass:[AutocompleteTextFieldEditor class]]; |
2255 } | 2219 } |
2256 | 2220 |
2257 - (void)tabposeWillClose:(NSNotification*)notif { | 2221 - (void)tabposeWillClose:(NSNotification*)notif { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2319 | 2283 |
2320 - (BOOL)supportsBookmarkBar { | 2284 - (BOOL)supportsBookmarkBar { |
2321 return [self supportsWindowFeature:Browser::FEATURE_BOOKMARKBAR]; | 2285 return [self supportsWindowFeature:Browser::FEATURE_BOOKMARKBAR]; |
2322 } | 2286 } |
2323 | 2287 |
2324 - (BOOL)isTabbedWindow { | 2288 - (BOOL)isTabbedWindow { |
2325 return browser_->is_type_tabbed(); | 2289 return browser_->is_type_tabbed(); |
2326 } | 2290 } |
2327 | 2291 |
2328 @end // @implementation BrowserWindowController(WindowType) | 2292 @end // @implementation BrowserWindowController(WindowType) |
OLD | NEW |