| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "chrome/browser/ui/cocoa/presentation_mode_controller.h" | 5 #import "chrome/browser/ui/cocoa/fullscreen_toolbar_controller.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #import "base/mac/mac_util.h" | 10 #import "base/mac/mac_util.h" |
| 11 #include "base/mac/sdk_forward_declarations.h" | 11 #include "base/mac/sdk_forward_declarations.h" |
| 12 #import "chrome/browser/ui/cocoa/browser_window_controller.h" | 12 #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
| 13 #include "chrome/common/chrome_switches.h" | 13 #include "chrome/common/chrome_switches.h" |
| 14 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h
" | 14 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h
" |
| 15 #import "ui/base/cocoa/nsview_additions.h" | 15 #import "ui/base/cocoa/nsview_additions.h" |
| 16 | 16 #import "ui/base/cocoa/tracking_area.h" |
| 17 NSString* const kWillEnterFullscreenNotification = | |
| 18 @"WillEnterFullscreenNotification"; | |
| 19 NSString* const kWillLeaveFullscreenNotification = | |
| 20 @"WillLeaveFullscreenNotification"; | |
| 21 | 17 |
| 22 namespace { | 18 namespace { |
| 23 | 19 |
| 24 // The activation zone for the main menu is 4 pixels high; if we make it any | 20 // The activation zone for the main menu is 4 pixels high; if we make it any |
| 25 // smaller, then the menu can be made to appear without the bar sliding down. | 21 // smaller, then the menu can be made to appear without the bar sliding down. |
| 26 const CGFloat kDropdownActivationZoneHeight = 4; | 22 const CGFloat kDropdownActivationZoneHeight = 4; |
| 27 const NSTimeInterval kDropdownAnimationDuration = 0.12; | 23 const NSTimeInterval kDropdownAnimationDuration = 0.12; |
| 28 const NSTimeInterval kMouseExitCheckDelay = 0.1; | 24 const NSTimeInterval kMouseExitCheckDelay = 0.1; |
| 29 // This show delay attempts to match the delay for the main menu. | 25 // This show delay attempts to match the delay for the main menu. |
| 30 const NSTimeInterval kDropdownShowDelay = 0.3; | 26 const NSTimeInterval kDropdownShowDelay = 0.3; |
| 31 const NSTimeInterval kDropdownHideDelay = 0.2; | 27 const NSTimeInterval kDropdownHideDelay = 0.2; |
| 32 | 28 |
| 33 // The duration the toolbar is revealed for tab strip changes. | 29 // The duration the toolbar is revealed for tab strip changes. |
| 34 const NSTimeInterval kDropdownForTabStripChangesDuration = 0.75; | 30 const NSTimeInterval kDropdownForTabStripChangesDuration = 0.75; |
| 35 | 31 |
| 36 // The event kind value for a undocumented menubar show/hide Carbon event. | 32 // The event kind value for a undocumented menubar show/hide Carbon event. |
| 37 const CGFloat kMenuBarRevealEventKind = 2004; | 33 const CGFloat kMenuBarRevealEventKind = 2004; |
| 38 | 34 |
| 39 // The amount by which the floating bar is offset downwards (to avoid the menu) | 35 // The amount by which the floating bar is offset downwards (to avoid the menu) |
| 40 // in presentation mode. (We can't use |-[NSMenu menuBarHeight]| since it | 36 // when the toolbar is hidden. (We can't use |-[NSMenu menuBarHeight]| since it |
| 41 // returns 0 when the menu bar is hidden.) | 37 // returns 0 when the menu bar is hidden.) |
| 42 const CGFloat kFloatingBarVerticalOffset = 22; | 38 const CGFloat kFloatingBarVerticalOffset = 22; |
| 43 | 39 |
| 44 OSStatus MenuBarRevealHandler(EventHandlerCallRef handler, | 40 OSStatus MenuBarRevealHandler(EventHandlerCallRef handler, |
| 45 EventRef event, | 41 EventRef event, |
| 46 void* context) { | 42 void* context) { |
| 47 PresentationModeController* self = | 43 FullscreenToolbarController* self = |
| 48 static_cast<PresentationModeController*>(context); | 44 static_cast<FullscreenToolbarController*>(context); |
| 49 | 45 |
| 50 // If Chrome has multiple fullscreen windows in their own space, the Handler | 46 // If Chrome has multiple fullscreen windows in their own space, the Handler |
| 51 // becomes flaky and might start receiving kMenuBarRevealEventKind events | 47 // becomes flaky and might start receiving kMenuBarRevealEventKind events |
| 52 // from another space. Since the menubar in the another space is in either a | 48 // from another space. Since the menubar in the another space is in either a |
| 53 // shown or hidden state, it will give us a reveal fraction of 0.0 or 1.0. | 49 // shown or hidden state, it will give us a reveal fraction of 0.0 or 1.0. |
| 54 // As such, we should ignore the kMenuBarRevealEventKind event if it gives | 50 // As such, we should ignore the kMenuBarRevealEventKind event if it gives |
| 55 // us a fraction of 0.0 or 1.0, and rely on kEventMenuBarShown and | 51 // us a fraction of 0.0 or 1.0, and rely on kEventMenuBarShown and |
| 56 // kEventMenuBarHidden to set these values. | 52 // kEventMenuBarHidden to set these values. |
| 57 if ([self isMainWindow] && ![self isFullscreenTransitionInProgress]) { | 53 if ([self isMainWindow] && ![self isFullscreenTransitionInProgress]) { |
| 58 if (GetEventKind(event) == kMenuBarRevealEventKind) { | 54 if (GetEventKind(event) == kMenuBarRevealEventKind) { |
| 59 CGFloat revealFraction = 0; | 55 CGFloat revealFraction = 0; |
| 60 GetEventParameter(event, FOUR_CHAR_CODE('rvlf'), typeCGFloat, NULL, | 56 GetEventParameter(event, FOUR_CHAR_CODE('rvlf'), typeCGFloat, NULL, |
| 61 sizeof(CGFloat), NULL, &revealFraction); | 57 sizeof(CGFloat), NULL, &revealFraction); |
| 62 if (revealFraction > 0.0 && revealFraction < 1.0) | 58 if (revealFraction > 0.0 && revealFraction < 1.0) |
| 63 [self setMenuBarRevealProgress:revealFraction]; | 59 [self setMenuBarRevealProgress:revealFraction]; |
| 64 } else if (GetEventKind(event) == kEventMenuBarShown) { | 60 } else if (GetEventKind(event) == kEventMenuBarShown) { |
| 65 [self setMenuBarRevealProgress:1.0]; | 61 [self setMenuBarRevealProgress:1.0]; |
| 66 } else { | 62 } else { |
| 67 [self setMenuBarRevealProgress:0.0]; | 63 [self setMenuBarRevealProgress:0.0]; |
| 68 } | 64 } |
| 69 } | 65 } |
| 70 | 66 |
| 71 return CallNextEventHandler(handler, event); | 67 return CallNextEventHandler(handler, event); |
| 72 } | 68 } |
| 73 | 69 |
| 74 } // end namespace | 70 } // end namespace |
| 75 | 71 |
| 76 // Helper class to manage animations for the dropdown bar. Calls | 72 // Helper class to manage animations for the dropdown bar. Calls |
| 77 // [PresentationModeController changeToolbarFraction] once per | 73 // [FullscreenToolbarController changeToolbarFraction] once per |
| 78 // animation step. | 74 // animation step. |
| 79 @interface DropdownAnimation : NSAnimation { | 75 @interface DropdownAnimation : NSAnimation { |
| 80 @private | 76 @private |
| 81 PresentationModeController* controller_; | 77 FullscreenToolbarController* controller_; |
| 82 CGFloat startFraction_; | 78 CGFloat startFraction_; |
| 83 CGFloat endFraction_; | 79 CGFloat endFraction_; |
| 84 } | 80 } |
| 85 | 81 |
| 86 @property(readonly, nonatomic) CGFloat startFraction; | 82 @property(readonly, nonatomic) CGFloat startFraction; |
| 87 @property(readonly, nonatomic) CGFloat endFraction; | 83 @property(readonly, nonatomic) CGFloat endFraction; |
| 88 | 84 |
| 89 // Designated initializer. Asks |controller| for the current shown fraction, so | 85 // Designated initializer. Asks |controller| for the current shown fraction, so |
| 90 // if the bar is already partially shown or partially hidden, the animation | 86 // if the bar is already partially shown or partially hidden, the animation |
| 91 // duration may be less than |fullDuration|. | 87 // duration may be less than |fullDuration|. |
| 92 - (id)initWithFraction:(CGFloat)fromFraction | 88 - (id)initWithFraction:(CGFloat)fromFraction |
| 93 fullDuration:(CGFloat)fullDuration | 89 fullDuration:(CGFloat)fullDuration |
| 94 animationCurve:(NSAnimationCurve)animationCurve | 90 animationCurve:(NSAnimationCurve)animationCurve |
| 95 controller:(PresentationModeController*)controller; | 91 controller:(FullscreenToolbarController*)controller; |
| 96 | 92 |
| 97 @end | 93 @end |
| 98 | 94 |
| 99 @implementation DropdownAnimation | 95 @implementation DropdownAnimation |
| 100 | 96 |
| 101 @synthesize startFraction = startFraction_; | 97 @synthesize startFraction = startFraction_; |
| 102 @synthesize endFraction = endFraction_; | 98 @synthesize endFraction = endFraction_; |
| 103 | 99 |
| 104 - (id)initWithFraction:(CGFloat)toFraction | 100 - (id)initWithFraction:(CGFloat)toFraction |
| 105 fullDuration:(CGFloat)fullDuration | 101 fullDuration:(CGFloat)fullDuration |
| 106 animationCurve:(NSAnimationCurve)animationCurve | 102 animationCurve:(NSAnimationCurve)animationCurve |
| 107 controller:(PresentationModeController*)controller { | 103 controller:(FullscreenToolbarController*)controller { |
| 108 // Calculate the effective duration, based on the current shown fraction. | 104 // Calculate the effective duration, based on the current shown fraction. |
| 109 DCHECK(controller); | 105 DCHECK(controller); |
| 110 CGFloat fromFraction = controller.toolbarFraction; | 106 CGFloat fromFraction = controller.toolbarFraction; |
| 111 CGFloat effectiveDuration = fabs(fullDuration * (fromFraction - toFraction)); | 107 CGFloat effectiveDuration = fabs(fullDuration * (fromFraction - toFraction)); |
| 112 | 108 |
| 113 if ((self = [super gtm_initWithDuration:effectiveDuration | 109 if ((self = [super gtm_initWithDuration:effectiveDuration |
| 114 eventMask:NSLeftMouseDownMask | 110 eventMask:NSLeftMouseDownMask |
| 115 animationCurve:animationCurve])) { | 111 animationCurve:animationCurve])) { |
| 116 startFraction_ = fromFraction; | 112 startFraction_ = fromFraction; |
| 117 endFraction_ = toFraction; | 113 endFraction_ = toFraction; |
| 118 controller_ = controller; | 114 controller_ = controller; |
| 119 } | 115 } |
| 120 return self; | 116 return self; |
| 121 } | 117 } |
| 122 | 118 |
| 123 // Called once per animation step. Overridden to change the floating bar's | 119 // Called once per animation step. Overridden to change the floating bar's |
| 124 // position based on the animation's progress. | 120 // position based on the animation's progress. |
| 125 - (void)setCurrentProgress:(NSAnimationProgress)progress { | 121 - (void)setCurrentProgress:(NSAnimationProgress)progress { |
| 126 CGFloat fraction = | 122 CGFloat fraction = |
| 127 startFraction_ + (progress * (endFraction_ - startFraction_)); | 123 startFraction_ + (progress * (endFraction_ - startFraction_)); |
| 128 [controller_ changeToolbarFraction:fraction]; | 124 [controller_ changeToolbarFraction:fraction]; |
| 129 } | 125 } |
| 130 | 126 |
| 131 @end | 127 @end |
| 132 | 128 |
| 133 | 129 @interface FullscreenToolbarController (PrivateMethods) |
| 134 @interface PresentationModeController (PrivateMethods) | |
| 135 | 130 |
| 136 // Updates the visibility of the menu bar and the dock. | 131 // Updates the visibility of the menu bar and the dock. |
| 137 - (void)updateMenuBarAndDockVisibility; | 132 - (void)updateMenuBarAndDockVisibility; |
| 138 | 133 |
| 139 // Whether the current screen is expected to have a menu bar, regardless of | 134 // Whether the current screen is expected to have a menu bar, regardless of |
| 140 // current visibility of the menu bar. | 135 // current visibility of the menu bar. |
| 141 - (BOOL)doesScreenHaveMenuBar; | 136 - (BOOL)doesScreenHaveMenuBar; |
| 142 | 137 |
| 143 // Returns YES if the window is on the primary screen. | 138 // Returns YES if the window is on the primary screen. |
| 144 - (BOOL)isWindowOnPrimaryScreen; | 139 - (BOOL)isWindowOnPrimaryScreen; |
| 145 | 140 |
| 146 // Returns |kFullScreenModeHideAll| when the overlay is hidden and | 141 // Returns |kFullScreenModeHideAll| when the overlay is hidden and |
| 147 // |kFullScreenModeHideDock| when the overlay is shown. | 142 // |kFullScreenModeHideDock| when the overlay is shown. |
| 148 - (base::mac::FullScreenMode)desiredSystemFullscreenMode; | 143 - (base::mac::FullScreenMode)desiredSystemFullscreenMode; |
| 149 | 144 |
| 150 // Change the overlay to the given fraction, with or without animation. Only | 145 // Change the overlay to the given fraction, with or without animation. Only |
| 151 // guaranteed to work properly with |fraction == 0| or |fraction == 1|. This | 146 // guaranteed to work properly with |fraction == 0| or |fraction == 1|. This |
| 152 // performs the show/hide (animation) immediately. It does not touch the timers. | 147 // performs the show/hide (animation) immediately. It does not touch the timers. |
| 153 - (void)changeOverlayToFraction:(CGFloat)fraction | 148 - (void)changeOverlayToFraction:(CGFloat)fraction withAnimation:(BOOL)animate; |
| 154 withAnimation:(BOOL)animate; | |
| 155 | 149 |
| 156 // Schedule the floating bar to be shown/hidden because of mouse position. | 150 // Schedule the floating bar to be shown/hidden because of mouse position. |
| 157 - (void)scheduleShowForMouse; | 151 - (void)scheduleShowForMouse; |
| 158 - (void)scheduleHideForMouse; | 152 - (void)scheduleHideForMouse; |
| 159 | 153 |
| 160 // Set up the tracking area used to activate the sliding bar or keep it active | 154 // Set up the tracking area used to activate the sliding bar or keep it active |
| 161 // using with the rectangle in |trackingAreaBounds_|, or remove the tracking | 155 // using with the rectangle in |trackingAreaBounds_|, or remove the tracking |
| 162 // area if one was previously set up. | 156 // area if one was previously set up. |
| 163 - (void)setupTrackingArea; | 157 - (void)setupTrackingArea; |
| 164 - (void)removeTrackingAreaIfNecessary; | 158 - (void)removeTrackingAreaIfNecessary; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 // the window gains or loses main status as well as in |-cleanup|. | 191 // the window gains or loses main status as well as in |-cleanup|. |
| 198 - (void)showActiveWindowUI; | 192 - (void)showActiveWindowUI; |
| 199 - (void)hideActiveWindowUI; | 193 - (void)hideActiveWindowUI; |
| 200 | 194 |
| 201 // Whether the menu bar should be shown in immersive fullscreen for the screen | 195 // Whether the menu bar should be shown in immersive fullscreen for the screen |
| 202 // that contains the window. | 196 // that contains the window. |
| 203 - (BOOL)shouldShowMenubarInImmersiveFullscreen; | 197 - (BOOL)shouldShowMenubarInImmersiveFullscreen; |
| 204 | 198 |
| 205 @end | 199 @end |
| 206 | 200 |
| 207 @implementation PresentationModeController | 201 @implementation FullscreenToolbarController |
| 208 | 202 |
| 209 @synthesize inPresentationMode = inPresentationMode_; | |
| 210 @synthesize slidingStyle = slidingStyle_; | 203 @synthesize slidingStyle = slidingStyle_; |
| 211 @synthesize toolbarFraction = toolbarFraction_; | 204 @synthesize toolbarFraction = toolbarFraction_; |
| 212 | 205 |
| 213 - (id)initWithBrowserController:(BrowserWindowController*)controller | 206 - (id)initWithBrowserController:(BrowserWindowController*)controller |
| 214 style:(fullscreen_mac::SlidingStyle)style { | 207 style:(fullscreen_mac::SlidingStyle)style { |
| 215 if ((self = [super init])) { | 208 if ((self = [super init])) { |
| 216 browserController_ = controller; | 209 browserController_ = controller; |
| 217 systemFullscreenMode_ = base::mac::kFullScreenModeNormal; | 210 systemFullscreenMode_ = base::mac::kFullScreenModeNormal; |
| 218 slidingStyle_ = style; | 211 slidingStyle_ = style; |
| 219 } | 212 } |
| 220 | 213 |
| 221 // Let the world know what we're up to. | |
| 222 [[NSNotificationCenter defaultCenter] | |
| 223 postNotificationName:kWillEnterFullscreenNotification | |
| 224 object:nil]; | |
| 225 | |
| 226 // Install the Carbon event handler for the menubar show, hide and | 214 // Install the Carbon event handler for the menubar show, hide and |
| 227 // undocumented reveal event. | 215 // undocumented reveal event. |
| 228 EventTypeSpec eventSpecs[3]; | 216 EventTypeSpec eventSpecs[3]; |
| 229 | 217 |
| 230 eventSpecs[0].eventClass = kEventClassMenu; | 218 eventSpecs[0].eventClass = kEventClassMenu; |
| 231 eventSpecs[0].eventKind = kMenuBarRevealEventKind; | 219 eventSpecs[0].eventKind = kMenuBarRevealEventKind; |
| 232 | 220 |
| 233 eventSpecs[1].eventClass = kEventClassMenu; | 221 eventSpecs[1].eventClass = kEventClassMenu; |
| 234 eventSpecs[1].eventKind = kEventMenuBarShown; | 222 eventSpecs[1].eventKind = kEventMenuBarShown; |
| 235 | 223 |
| 236 eventSpecs[2].eventClass = kEventClassMenu; | 224 eventSpecs[2].eventClass = kEventClassMenu; |
| 237 eventSpecs[2].eventKind = kEventMenuBarHidden; | 225 eventSpecs[2].eventKind = kEventMenuBarHidden; |
| 238 | 226 |
| 239 InstallApplicationEventHandler(NewEventHandlerUPP(&MenuBarRevealHandler), 3, | 227 InstallApplicationEventHandler(NewEventHandlerUPP(&MenuBarRevealHandler), 3, |
| 240 eventSpecs, self, &menuBarTrackingHandler_); | 228 eventSpecs, self, &menuBarTrackingHandler_); |
| 241 | 229 |
| 242 return self; | 230 return self; |
| 243 } | 231 } |
| 244 | 232 |
| 245 - (void)dealloc { | 233 - (void)dealloc { |
| 246 RemoveEventHandler(menuBarTrackingHandler_); | 234 RemoveEventHandler(menuBarTrackingHandler_); |
| 247 DCHECK(!inPresentationMode_); | 235 DCHECK(!inFullscreenMode_); |
| 248 DCHECK(!trackingArea_); | 236 DCHECK(!trackingArea_); |
| 249 [super dealloc]; | 237 [super dealloc]; |
| 250 } | 238 } |
| 251 | 239 |
| 252 - (void)enterPresentationModeForContentView:(NSView*)contentView | 240 - (void)setupFullscreenToolbarForContentView:(NSView*)contentView |
| 253 showDropdown:(BOOL)showDropdown { | 241 showDropdown:(BOOL)showDropdown { |
| 254 DCHECK(!inPresentationMode_); | 242 DCHECK(!inFullscreenMode_); |
| 255 enteringPresentationMode_ = YES; | 243 settingUp_ = YES; |
| 256 inPresentationMode_ = YES; | 244 inFullscreenMode_ = YES; |
| 257 contentView_ = contentView; | 245 contentView_ = contentView; |
| 258 [self changeToolbarFraction:(showDropdown ? 1 : 0)]; | 246 [self changeToolbarFraction:(showDropdown ? 1 : 0)]; |
| 259 [self updateMenuBarAndDockVisibility]; | 247 [self updateMenuBarAndDockVisibility]; |
| 260 | 248 |
| 261 // Register for notifications. Self is removed as an observer in |-cleanup|. | 249 // Register for notifications. Self is removed as an observer in |-cleanup|. |
| 262 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; | 250 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; |
| 263 NSWindow* window = [browserController_ window]; | 251 NSWindow* window = [browserController_ window]; |
| 264 | 252 |
| 265 [nc addObserver:self | 253 [nc addObserver:self |
| 266 selector:@selector(windowDidBecomeMain:) | 254 selector:@selector(windowDidBecomeMain:) |
| 267 name:NSWindowDidBecomeMainNotification | 255 name:NSWindowDidBecomeMainNotification |
| 268 object:window]; | 256 object:window]; |
| 269 | 257 |
| 270 [nc addObserver:self | 258 [nc addObserver:self |
| 271 selector:@selector(windowDidResignMain:) | 259 selector:@selector(windowDidResignMain:) |
| 272 name:NSWindowDidResignMainNotification | 260 name:NSWindowDidResignMainNotification |
| 273 object:window]; | 261 object:window]; |
| 274 | 262 |
| 275 enteringPresentationMode_ = NO; | 263 settingUp_ = NO; |
| 276 } | 264 } |
| 277 | 265 |
| 278 - (void)exitPresentationMode { | 266 - (void)exitFullscreenMode { |
| 279 [[NSNotificationCenter defaultCenter] | 267 DCHECK(inFullscreenMode_); |
| 280 postNotificationName:kWillLeaveFullscreenNotification | 268 inFullscreenMode_ = NO; |
| 281 object:nil]; | |
| 282 DCHECK(inPresentationMode_); | |
| 283 inPresentationMode_ = NO; | |
| 284 | 269 |
| 285 [self cleanup]; | 270 [self cleanup]; |
| 286 } | 271 } |
| 287 | 272 |
| 288 - (void)windowDidChangeScreen:(NSNotification*)notification { | 273 - (void)windowDidChangeScreen:(NSNotification*)notification { |
| 289 [browserController_ resizeFullscreenWindow]; | 274 [browserController_ resizeFullscreenWindow]; |
| 290 } | 275 } |
| 291 | 276 |
| 292 - (void)windowDidMove:(NSNotification*)notification { | 277 - (void)windowDidMove:(NSNotification*)notification { |
| 293 [browserController_ resizeFullscreenWindow]; | 278 [browserController_ resizeFullscreenWindow]; |
| 294 } | 279 } |
| 295 | 280 |
| 296 - (void)windowDidBecomeMain:(NSNotification*)notification { | 281 - (void)windowDidBecomeMain:(NSNotification*)notification { |
| 297 [self showActiveWindowUI]; | 282 [self showActiveWindowUI]; |
| 298 } | 283 } |
| 299 | 284 |
| 300 - (void)windowDidResignMain:(NSNotification*)notification { | 285 - (void)windowDidResignMain:(NSNotification*)notification { |
| 301 [self hideActiveWindowUI]; | 286 [self hideActiveWindowUI]; |
| 302 } | 287 } |
| 303 | 288 |
| 304 // On OSX 10.8+, the menu bar shows on the secondary screen in fullscreen. | 289 // On OSX 10.8+, the menu bar shows on the secondary screen in fullscreen. |
| 305 - (CGFloat)floatingBarVerticalOffset { | 290 - (CGFloat)floatingBarVerticalOffset { |
| 306 return kFloatingBarVerticalOffset; | 291 return kFloatingBarVerticalOffset; |
| 307 } | 292 } |
| 308 | 293 |
| 309 - (void)overlayFrameChanged:(NSRect)frame { | 294 - (void)overlayFrameChanged:(NSRect)frame { |
| 310 if (!inPresentationMode_) | 295 if (!inFullscreenMode_) |
| 311 return; | 296 return; |
| 312 | 297 |
| 313 // Make sure |trackingAreaBounds_| always reflects either the tracking area or | 298 // Make sure |trackingAreaBounds_| always reflects either the tracking area or |
| 314 // the desired tracking area. | 299 // the desired tracking area. |
| 315 trackingAreaBounds_ = frame; | 300 trackingAreaBounds_ = frame; |
| 316 // The tracking area should always be at least the height of activation zone. | 301 // The tracking area should always be at least the height of activation zone. |
| 317 NSRect contentBounds = [contentView_ bounds]; | 302 NSRect contentBounds = [contentView_ bounds]; |
| 318 trackingAreaBounds_.origin.y = | 303 trackingAreaBounds_.origin.y = |
| 319 std::min(trackingAreaBounds_.origin.y, | 304 std::min(trackingAreaBounds_.origin.y, |
| 320 NSMaxY(contentBounds) - kDropdownActivationZoneHeight); | 305 NSMaxY(contentBounds) - kDropdownActivationZoneHeight); |
| 321 trackingAreaBounds_.size.height = | 306 trackingAreaBounds_.size.height = |
| 322 NSMaxY(contentBounds) - trackingAreaBounds_.origin.y + 1; | 307 NSMaxY(contentBounds) - trackingAreaBounds_.origin.y + 1; |
| 323 | 308 |
| 324 // If an animation is currently running, do not set up a tracking area now. | 309 // If an animation is currently running, do not set up a tracking area now. |
| 325 // Instead, leave it to be created it in |-animationDidEnd:|. | 310 // Instead, leave it to be created it in |-animationDidEnd:|. |
| 326 if (currentAnimation_) | 311 if (currentAnimation_) |
| 327 return; | 312 return; |
| 328 | 313 |
| 329 // If this is part of the initial setup, lock bar visibility if the mouse is | 314 // If this is part of the initial setup, lock bar visibility if the mouse is |
| 330 // within the tracking area bounds. | 315 // within the tracking area bounds. |
| 331 if (enteringPresentationMode_ && [self mouseInsideTrackingRect]) | 316 if (settingUp_ && [self mouseInsideTrackingRect]) |
| 332 [browserController_ lockBarVisibilityForOwner:self | 317 [browserController_ lockBarVisibilityForOwner:self |
| 333 withAnimation:NO | 318 withAnimation:NO |
| 334 delay:NO]; | 319 delay:NO]; |
| 335 [self setupTrackingArea]; | 320 [self setupTrackingArea]; |
| 336 } | 321 } |
| 337 | 322 |
| 338 - (void)ensureOverlayShownWithAnimation:(BOOL)animate delay:(BOOL)delay { | 323 - (void)ensureOverlayShownWithAnimation:(BOOL)animate delay:(BOOL)delay { |
| 339 if (!inPresentationMode_) | 324 if (!inFullscreenMode_) |
| 340 return; | 325 return; |
| 341 | 326 |
| 342 if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode)) | 327 if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode)) |
| 343 return; | 328 return; |
| 344 | 329 |
| 345 if (self.slidingStyle == fullscreen_mac::OMNIBOX_TABS_PRESENT) | 330 if (self.slidingStyle == fullscreen_mac::OMNIBOX_TABS_PRESENT) |
| 346 return; | 331 return; |
| 347 | 332 |
| 348 if (animate) { | 333 if (animate) { |
| 349 if (delay) { | 334 if (delay) { |
| 350 [self startShowTimer]; | 335 [self startShowTimer]; |
| 351 } else { | 336 } else { |
| 352 [self cancelAllTimers]; | 337 [self cancelAllTimers]; |
| 353 [self changeOverlayToFraction:1 withAnimation:YES]; | 338 [self changeOverlayToFraction:1 withAnimation:YES]; |
| 354 } | 339 } |
| 355 } else { | 340 } else { |
| 356 DCHECK(!delay); | 341 DCHECK(!delay); |
| 357 [self cancelAllTimers]; | 342 [self cancelAllTimers]; |
| 358 [self changeOverlayToFraction:1 withAnimation:NO]; | 343 [self changeOverlayToFraction:1 withAnimation:NO]; |
| 359 } | 344 } |
| 360 } | 345 } |
| 361 | 346 |
| 362 - (void)ensureOverlayHiddenWithAnimation:(BOOL)animate delay:(BOOL)delay { | 347 - (void)ensureOverlayHiddenWithAnimation:(BOOL)animate delay:(BOOL)delay { |
| 363 if (!inPresentationMode_) | 348 if (!inFullscreenMode_) |
| 364 return; | 349 return; |
| 365 | 350 |
| 366 if (self.slidingStyle == fullscreen_mac::OMNIBOX_TABS_PRESENT) | 351 if (self.slidingStyle == fullscreen_mac::OMNIBOX_TABS_PRESENT) |
| 367 return; | 352 return; |
| 368 | 353 |
| 369 if (animate) { | 354 if (animate) { |
| 370 if (delay) { | 355 if (delay) { |
| 371 [self startHideTimer]; | 356 [self startHideTimer]; |
| 372 } else { | 357 } else { |
| 373 [self cancelAllTimers]; | 358 [self cancelAllTimers]; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 } | 424 } |
| 440 | 425 |
| 441 - (BOOL)isFullscreenTransitionInProgress { | 426 - (BOOL)isFullscreenTransitionInProgress { |
| 442 return [browserController_ isFullscreenTransitionInProgress]; | 427 return [browserController_ isFullscreenTransitionInProgress]; |
| 443 } | 428 } |
| 444 | 429 |
| 445 - (BOOL)isMainWindow { | 430 - (BOOL)isMainWindow { |
| 446 return [browserController_ window].isMainWindow; | 431 return [browserController_ window].isMainWindow; |
| 447 } | 432 } |
| 448 | 433 |
| 449 // Used to activate the floating bar in presentation mode. | 434 // Used to activate the floating bar if the toolbar is hidden. |
| 450 - (void)mouseEntered:(NSEvent*)event { | 435 - (void)mouseEntered:(NSEvent*)event { |
| 451 DCHECK(inPresentationMode_); | 436 DCHECK(inFullscreenMode_); |
| 452 | 437 |
| 453 // Having gotten a mouse entered, we no longer need to do exit checks. | 438 // Having gotten a mouse entered, we no longer need to do exit checks. |
| 454 [self cancelMouseExitCheck]; | 439 [self cancelMouseExitCheck]; |
| 455 | 440 |
| 456 NSTrackingArea* trackingArea = [event trackingArea]; | 441 if ([event trackingArea] == trackingArea_.get()) { |
| 457 if (trackingArea == trackingArea_) { | |
| 458 // The tracking area shouldn't be active during animation. | 442 // The tracking area shouldn't be active during animation. |
| 459 DCHECK(!currentAnimation_); | 443 DCHECK(!currentAnimation_); |
| 460 | 444 |
| 461 // Don't show anything if the style is set to OMNIBOX_TABS_NONE. | 445 // Don't show anything if the style is set to OMNIBOX_TABS_NONE. |
| 462 if (self.slidingStyle != fullscreen_mac::OMNIBOX_TABS_NONE) | 446 if (self.slidingStyle != fullscreen_mac::OMNIBOX_TABS_NONE) |
| 463 [self scheduleShowForMouse]; | 447 [self scheduleShowForMouse]; |
| 464 } | 448 } |
| 465 } | 449 } |
| 466 | 450 |
| 467 // Used to deactivate the floating bar in presentation mode. | 451 // Used to deactivate the floating bar if the toolbar is hidden. |
| 468 - (void)mouseExited:(NSEvent*)event { | 452 - (void)mouseExited:(NSEvent*)event { |
| 469 DCHECK(inPresentationMode_); | 453 DCHECK(inFullscreenMode_); |
| 470 | 454 |
| 471 NSTrackingArea* trackingArea = [event trackingArea]; | 455 if ([event trackingArea] == trackingArea_.get()) { |
| 472 if (trackingArea == trackingArea_) { | |
| 473 // The tracking area shouldn't be active during animation. | 456 // The tracking area shouldn't be active during animation. |
| 474 DCHECK(!currentAnimation_); | 457 DCHECK(!currentAnimation_); |
| 475 | 458 |
| 476 // We can get a false mouse exit when the menu slides down, so if the mouse | 459 // We can get a false mouse exit when the menu slides down, so if the mouse |
| 477 // is still actually over the tracking area, we ignore the mouse exit, but | 460 // is still actually over the tracking area, we ignore the mouse exit, but |
| 478 // we set up to check the mouse position again after a delay. | 461 // we set up to check the mouse position again after a delay. |
| 479 if ([self mouseInsideTrackingRect]) { | 462 if ([self mouseInsideTrackingRect]) { |
| 480 [self setupMouseExitCheck]; | 463 [self setupMouseExitCheck]; |
| 481 return; | 464 return; |
| 482 } | 465 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 // for each tick of the menu bar reveal. Do that manually. | 518 // for each tick of the menu bar reveal. Do that manually. |
| 536 // TODO(erikchen): The animation is janky. layoutSubviews need a refactor so | 519 // TODO(erikchen): The animation is janky. layoutSubviews need a refactor so |
| 537 // that it calls setFrameOffset: instead of setFrame: if the frame's size has | 520 // that it calls setFrameOffset: instead of setFrame: if the frame's size has |
| 538 // not changed. | 521 // not changed. |
| 539 if (!currentAnimation_.get()) | 522 if (!currentAnimation_.get()) |
| 540 [browserController_ layoutSubviews]; | 523 [browserController_ layoutSubviews]; |
| 541 } | 524 } |
| 542 | 525 |
| 543 @end | 526 @end |
| 544 | 527 |
| 545 | 528 @implementation FullscreenToolbarController (PrivateMethods) |
| 546 @implementation PresentationModeController (PrivateMethods) | |
| 547 | 529 |
| 548 - (void)updateMenuBarAndDockVisibility { | 530 - (void)updateMenuBarAndDockVisibility { |
| 549 if (![self isMainWindow] || ![browserController_ isInImmersiveFullscreen]) { | 531 if (![self isMainWindow] || ![browserController_ isInImmersiveFullscreen]) { |
| 550 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeNormal]; | 532 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeNormal]; |
| 551 return; | 533 return; |
| 552 } | 534 } |
| 553 | 535 |
| 554 // The screen does not have a menu bar, so there's no need to hide it. | 536 // The screen does not have a menu bar, so there's no need to hide it. |
| 555 if (![self doesScreenHaveMenuBar]) { | 537 if (![self doesScreenHaveMenuBar]) { |
| 556 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeHideDock]; | 538 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeHideDock]; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 574 NSScreen* primaryScreen = [[NSScreen screens] firstObject]; | 556 NSScreen* primaryScreen = [[NSScreen screens] firstObject]; |
| 575 return (screen == primaryScreen); | 557 return (screen == primaryScreen); |
| 576 } | 558 } |
| 577 | 559 |
| 578 - (base::mac::FullScreenMode)desiredSystemFullscreenMode { | 560 - (base::mac::FullScreenMode)desiredSystemFullscreenMode { |
| 579 if ([self shouldShowMenubarInImmersiveFullscreen]) | 561 if ([self shouldShowMenubarInImmersiveFullscreen]) |
| 580 return base::mac::kFullScreenModeHideDock; | 562 return base::mac::kFullScreenModeHideDock; |
| 581 return base::mac::kFullScreenModeHideAll; | 563 return base::mac::kFullScreenModeHideAll; |
| 582 } | 564 } |
| 583 | 565 |
| 584 - (void)changeOverlayToFraction:(CGFloat)fraction | 566 - (void)changeOverlayToFraction:(CGFloat)fraction withAnimation:(BOOL)animate { |
| 585 withAnimation:(BOOL)animate { | |
| 586 // The non-animated case is really simple, so do it and return. | 567 // The non-animated case is really simple, so do it and return. |
| 587 if (!animate) { | 568 if (!animate) { |
| 588 [currentAnimation_ stopAnimation]; | 569 [currentAnimation_ stopAnimation]; |
| 589 [self changeToolbarFraction:fraction]; | 570 [self changeToolbarFraction:fraction]; |
| 590 return; | 571 return; |
| 591 } | 572 } |
| 592 | 573 |
| 593 // If we're already animating to the given fraction, then there's nothing more | 574 // If we're already animating to the given fraction, then there's nothing more |
| 594 // to do. | 575 // to do. |
| 595 if (currentAnimation_ && [currentAnimation_ endFraction] == fraction) | 576 if (currentAnimation_ && [currentAnimation_ endFraction] == fraction) |
| 596 return; | 577 return; |
| 597 | 578 |
| 598 // In all other cases, we want to cancel any running animation (which may be | 579 // In all other cases, we want to cancel any running animation (which may be |
| 599 // to show or to hide). | 580 // to show or to hide). |
| 600 [currentAnimation_ stopAnimation]; | 581 [currentAnimation_ stopAnimation]; |
| 601 | 582 |
| 602 // Create the animation and set it up. | 583 // Create the animation and set it up. |
| 603 currentAnimation_.reset( | 584 currentAnimation_.reset([[DropdownAnimation alloc] |
| 604 [[DropdownAnimation alloc] initWithFraction:fraction | 585 initWithFraction:fraction |
| 605 fullDuration:kDropdownAnimationDuration | 586 fullDuration:kDropdownAnimationDuration |
| 606 animationCurve:NSAnimationEaseOut | 587 animationCurve:NSAnimationEaseOut |
| 607 controller:self]); | 588 controller:self]); |
| 608 DCHECK(currentAnimation_); | 589 DCHECK(currentAnimation_); |
| 609 [currentAnimation_ setAnimationBlockingMode:NSAnimationNonblocking]; | 590 [currentAnimation_ setAnimationBlockingMode:NSAnimationNonblocking]; |
| 610 [currentAnimation_ setDelegate:self]; | 591 [currentAnimation_ setDelegate:self]; |
| 611 | 592 |
| 612 // If there is an existing tracking area, remove it. We do not track mouse | 593 // If there is an existing tracking area, remove it. We do not track mouse |
| 613 // movements during animations (see class comment in the header file). | 594 // movements during animations (see class comment in the header file). |
| 614 [self removeTrackingAreaIfNecessary]; | 595 [self removeTrackingAreaIfNecessary]; |
| 615 | 596 |
| 616 [currentAnimation_ startAnimation]; | 597 [currentAnimation_ startAnimation]; |
| 617 } | 598 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 633 // If the tracking rectangle is already |trackingAreaBounds_|, quit early. | 614 // If the tracking rectangle is already |trackingAreaBounds_|, quit early. |
| 634 NSRect oldRect = [trackingArea_ rect]; | 615 NSRect oldRect = [trackingArea_ rect]; |
| 635 if (NSEqualRects(trackingAreaBounds_, oldRect)) | 616 if (NSEqualRects(trackingAreaBounds_, oldRect)) |
| 636 return; | 617 return; |
| 637 | 618 |
| 638 // Otherwise, remove it. | 619 // Otherwise, remove it. |
| 639 [self removeTrackingAreaIfNecessary]; | 620 [self removeTrackingAreaIfNecessary]; |
| 640 } | 621 } |
| 641 | 622 |
| 642 // Create and add a new tracking area for |frame|. | 623 // Create and add a new tracking area for |frame|. |
| 643 trackingArea_.reset( | 624 trackingArea_.reset([[CrTrackingArea alloc] |
| 644 [[NSTrackingArea alloc] initWithRect:trackingAreaBounds_ | 625 initWithRect:trackingAreaBounds_ |
| 645 options:NSTrackingMouseEnteredAndExited | | 626 options:NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow |
| 646 NSTrackingActiveInKeyWindow | 627 owner:self |
| 647 owner:self | 628 userInfo:nil]); |
| 648 userInfo:nil]); | |
| 649 DCHECK(contentView_); | 629 DCHECK(contentView_); |
| 650 [contentView_ addTrackingArea:trackingArea_]; | 630 [contentView_ addTrackingArea:trackingArea_]; |
| 651 } | 631 } |
| 652 | 632 |
| 653 - (void)removeTrackingAreaIfNecessary { | 633 - (void)removeTrackingAreaIfNecessary { |
| 654 if (trackingArea_) { | 634 if (trackingArea_) { |
| 655 DCHECK(contentView_); // |contentView_| better be valid. | 635 DCHECK(contentView_); // |contentView_| better be valid. |
| 656 [contentView_ removeTrackingArea:trackingArea_]; | 636 [contentView_ removeTrackingArea:trackingArea_]; |
| 657 trackingArea_.reset(); | 637 trackingArea_.reset(); |
| 658 } | 638 } |
| 659 } | 639 } |
| 660 | 640 |
| 661 - (BOOL)mouseInsideTrackingRect { | 641 - (BOOL)mouseInsideTrackingRect { |
| 662 NSWindow* window = [browserController_ window]; | 642 NSWindow* window = [browserController_ window]; |
| 663 NSPoint mouseLoc = [window mouseLocationOutsideOfEventStream]; | 643 NSPoint mouseLoc = [window mouseLocationOutsideOfEventStream]; |
| 664 NSPoint mousePos = [contentView_ convertPoint:mouseLoc fromView:nil]; | 644 NSPoint mousePos = [contentView_ convertPoint:mouseLoc fromView:nil]; |
| 665 return NSMouseInRect(mousePos, trackingAreaBounds_, [contentView_ isFlipped]); | 645 return NSMouseInRect(mousePos, trackingAreaBounds_, [contentView_ isFlipped]); |
| 666 } | 646 } |
| 667 | 647 |
| 668 - (void)setupMouseExitCheck { | 648 - (void)setupMouseExitCheck { |
| 669 [self performSelector:@selector(checkForMouseExit) | 649 [self performSelector:@selector(checkForMouseExit) |
| 670 withObject:nil | 650 withObject:nil |
| 671 afterDelay:kMouseExitCheckDelay]; | 651 afterDelay:kMouseExitCheckDelay]; |
| 672 } | 652 } |
| 673 | 653 |
| 674 - (void)cancelMouseExitCheck { | 654 - (void)cancelMouseExitCheck { |
| 675 [NSObject cancelPreviousPerformRequestsWithTarget:self | 655 [NSObject cancelPreviousPerformRequestsWithTarget:self |
| 676 selector:@selector(checkForMouseExit) object:nil]; | 656 selector:@selector(checkForMouseExit) |
| 657 object:nil]; |
| 677 } | 658 } |
| 678 | 659 |
| 679 - (void)checkForMouseExit { | 660 - (void)checkForMouseExit { |
| 680 if ([self mouseInsideTrackingRect]) | 661 if ([self mouseInsideTrackingRect]) |
| 681 [self setupMouseExitCheck]; | 662 [self setupMouseExitCheck]; |
| 682 else | 663 else |
| 683 [self scheduleHideForMouse]; | 664 [self scheduleHideForMouse]; |
| 684 } | 665 } |
| 685 | 666 |
| 686 - (void)startShowTimer { | 667 - (void)startShowTimer { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 } | 732 } |
| 752 | 733 |
| 753 - (void)cleanup { | 734 - (void)cleanup { |
| 754 [self cancelMouseExitCheck]; | 735 [self cancelMouseExitCheck]; |
| 755 [self cancelAnimationAndTimers]; | 736 [self cancelAnimationAndTimers]; |
| 756 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 737 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 757 | 738 |
| 758 [self removeTrackingAreaIfNecessary]; | 739 [self removeTrackingAreaIfNecessary]; |
| 759 contentView_ = nil; | 740 contentView_ = nil; |
| 760 | 741 |
| 761 // This isn't tracked when not in presentation mode. | 742 // This isn't tracked when not in fullscreen mode. |
| 762 [browserController_ releaseBarVisibilityForOwner:self | 743 [browserController_ releaseBarVisibilityForOwner:self |
| 763 withAnimation:NO | 744 withAnimation:NO |
| 764 delay:NO]; | 745 delay:NO]; |
| 765 | 746 |
| 766 // Call the main status resignation code to perform the associated cleanup, | 747 // Call the main status resignation code to perform the associated cleanup, |
| 767 // since we will no longer be receiving actual status resignation | 748 // since we will no longer be receiving actual status resignation |
| 768 // notifications. | 749 // notifications. |
| 769 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeNormal]; | 750 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeNormal]; |
| 770 | 751 |
| 771 // No more calls back up to the BWC. | 752 // No more calls back up to the BWC. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 782 [self updateMenuBarAndDockVisibility]; | 763 [self updateMenuBarAndDockVisibility]; |
| 783 | 764 |
| 784 // TODO(rohitrao): Remove the Exit Fullscreen button. http://crbug.com/35956 | 765 // TODO(rohitrao): Remove the Exit Fullscreen button. http://crbug.com/35956 |
| 785 } | 766 } |
| 786 | 767 |
| 787 - (BOOL)shouldShowMenubarInImmersiveFullscreen { | 768 - (BOOL)shouldShowMenubarInImmersiveFullscreen { |
| 788 return [self doesScreenHaveMenuBar] && toolbarFraction_ > 0.99; | 769 return [self doesScreenHaveMenuBar] && toolbarFraction_ > 0.99; |
| 789 } | 770 } |
| 790 | 771 |
| 791 @end | 772 @end |
| OLD | NEW |