CTPresentationModeController.m 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  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
  3. // found in the LICENSE file.
  4. #import "CTPresentationModeController.h"
  5. #import "CTBrowserWindowController.h"
  6. #import "GTMNSAnimation+Duration.h"
  7. #import "common.h"
  8. NSString* const kWillEnterFullscreenNotification = @"WillEnterFullscreenNotification";
  9. NSString* const kWillLeaveFullscreenNotification = @"WillLeaveFullscreenNotification";
  10. // Full screen modes, in increasing order of priority. More permissive modes
  11. // take predecence.
  12. typedef enum {
  13. kFullScreenModeHideAll = 0,
  14. kFullScreenModeHideDock = 1,
  15. kFullScreenModeAutoHideAll = 2,
  16. kNumFullScreenModes = 3,
  17. // kFullScreenModeNormal is not a valid FullScreenMode, but it is useful to
  18. // other classes, so we include it here.
  19. kFullScreenModeNormal = 10,
  20. } FullScreenMode;
  21. // The activation zone for the main menu is 4 pixels high; if we make it any
  22. // smaller, then the menu can be made to appear without the bar sliding down.
  23. const CGFloat kDropdownActivationZoneHeight = 4;
  24. const NSTimeInterval kDropdownAnimationDuration = 0.12;
  25. const NSTimeInterval kMouseExitCheckDelay = 0.1;
  26. // This show delay attempts to match the delay for the main menu.
  27. const NSTimeInterval kDropdownShowDelay = 0.3;
  28. const NSTimeInterval kDropdownHideDelay = 0.2;
  29. // The amount by which the floating bar is offset downwards (to avoid the menu)
  30. // in presentation mode. (We can't use |-[NSMenu menuBarHeight]| since it
  31. // returns 0 when the menu bar is hidden.)
  32. const CGFloat kFloatingBarVerticalOffset = 22;
  33. // Helper class to manage animations for the dropdown bar. Calls
  34. // [PresentationModeController changeFloatingBarShownFraction] once per
  35. // animation step.
  36. @interface DropdownAnimation : NSAnimation {
  37. @private
  38. __weak CTPresentationModeController* controller_;
  39. CGFloat startFraction_;
  40. CGFloat endFraction_;
  41. }
  42. @property(readonly, nonatomic) CGFloat startFraction;
  43. @property(readonly, nonatomic) CGFloat endFraction;
  44. // Designated initializer. Asks |controller| for the current shown fraction, so
  45. // if the bar is already partially shown or partially hidden, the animation
  46. // duration may be less than |fullDuration|.
  47. - (id)initWithFraction:(CGFloat)fromFraction
  48. fullDuration:(CGFloat)fullDuration
  49. animationCurve:(NSInteger)animationCurve
  50. controller:(CTPresentationModeController*)controller;
  51. @end
  52. @implementation DropdownAnimation
  53. @synthesize startFraction = startFraction_;
  54. @synthesize endFraction = endFraction_;
  55. - (id)initWithFraction:(CGFloat)toFraction
  56. fullDuration:(CGFloat)fullDuration
  57. animationCurve:(NSInteger)animationCurve
  58. controller:(CTPresentationModeController*)controller {
  59. // Calculate the effective duration, based on the current shown fraction.
  60. DCHECK(controller);
  61. CGFloat fromFraction = [controller floatingBarShownFraction];
  62. CGFloat effectiveDuration = fabs(fullDuration * (fromFraction - toFraction));
  63. if ((self = [super gtm_initWithDuration:effectiveDuration
  64. eventMask:NSLeftMouseDownMask
  65. animationCurve:animationCurve])) {
  66. startFraction_ = fromFraction;
  67. endFraction_ = toFraction;
  68. controller_ = controller;
  69. }
  70. return self;
  71. }
  72. // Called once per animation step. Overridden to change the floating bar's
  73. // position based on the animation's progress.
  74. - (void)setCurrentProgress:(NSAnimationProgress)progress {
  75. CGFloat fraction =
  76. startFraction_ + (progress * (endFraction_ - startFraction_));
  77. [controller_ changeFloatingBarShownFraction:fraction];
  78. }
  79. @end
  80. @interface CTPresentationModeController (PrivateMethods)
  81. // Returns YES if the window is on the primary screen.
  82. - (BOOL)isWindowOnPrimaryScreen;
  83. // Returns YES if it is ok to show and hide the menu bar in response to the
  84. // overlay opening and closing. Will return NO if the window is not main or not
  85. // on the primary monitor.
  86. - (BOOL)shouldToggleMenuBar;
  87. // Returns |kFullScreenModeHideAll| when the overlay is hidden and
  88. // |kFullScreenModeHideDock| when the overlay is shown.
  89. - (FullScreenMode)desiredSystemFullscreenMode;
  90. // Change the overlay to the given fraction, with or without animation. Only
  91. // guaranteed to work properly with |fraction == 0| or |fraction == 1|. This
  92. // performs the show/hide (animation) immediately. It does not touch the timers.
  93. - (void)changeOverlayToFraction:(CGFloat)fraction
  94. withAnimation:(BOOL)animate;
  95. // Schedule the floating bar to be shown/hidden because of mouse position.
  96. - (void)scheduleShowForMouse;
  97. - (void)scheduleHideForMouse;
  98. // Set up the tracking area used to activate the sliding bar or keep it active
  99. // using with the rectangle in |trackingAreaBounds_|, or remove the tracking
  100. // area if one was previously set up.
  101. - (void)setupTrackingArea;
  102. - (void)removeTrackingAreaIfNecessary;
  103. // Returns YES if the mouse is currently in any current tracking rectangle, NO
  104. // otherwise.
  105. - (BOOL)mouseInsideTrackingRect;
  106. // The tracking area can "falsely" report exits when the menu slides down over
  107. // it. In that case, we have to monitor for a "real" mouse exit on a timer.
  108. // |-setupMouseExitCheck| schedules a check; |-cancelMouseExitCheck| cancels any
  109. // scheduled check.
  110. - (void)setupMouseExitCheck;
  111. - (void)cancelMouseExitCheck;
  112. // Called (after a delay) by |-setupMouseExitCheck|, to check whether the mouse
  113. // has exited or not; if it hasn't, it will schedule another check.
  114. - (void)checkForMouseExit;
  115. // Start timers for showing/hiding the floating bar.
  116. - (void)startShowTimer;
  117. - (void)startHideTimer;
  118. - (void)cancelShowTimer;
  119. - (void)cancelHideTimer;
  120. - (void)cancelAllTimers;
  121. // Methods called when the show/hide timers fire. Do not call directly.
  122. - (void)showTimerFire:(NSTimer*)timer;
  123. - (void)hideTimerFire:(NSTimer*)timer;
  124. // Stops any running animations, removes tracking areas, etc.
  125. - (void)cleanup;
  126. // Shows and hides the UI associated with this window being active (having main
  127. // status). This includes hiding the menu bar. These functions are called when
  128. // the window gains or loses main status as well as in |-cleanup|.
  129. - (void)showActiveWindowUI;
  130. - (void)hideActiveWindowUI;
  131. @end
  132. @implementation CTPresentationModeController {
  133. @private
  134. // Our parent controller.
  135. __weak CTBrowserWindowController* browserController_; // weak
  136. // The content view for the window. This is nil when not in presentation
  137. // mode.
  138. __weak NSView* contentView_; // weak
  139. // YES while this controller is in the process of entering presentation mode.
  140. BOOL enteringPresentationMode_;
  141. // Whether or not we are in presentation mode.
  142. BOOL inPresentationMode_;
  143. // The tracking area associated with the floating dropdown bar. This tracking
  144. // area is attached to |contentView_|, because when the dropdown is completely
  145. // hidden, we still need to keep a 1px tall tracking area visible. Attaching
  146. // to the content view allows us to do this. |trackingArea_| can be nil if
  147. // not in presentation mode or during animations.
  148. NSTrackingArea* trackingArea_;
  149. // Pointer to the currently running animation. Is nil if no animation is
  150. // running.
  151. DropdownAnimation* currentAnimation_;
  152. // Timers for scheduled showing/hiding of the bar (which are always done with
  153. // animation).
  154. NSTimer* showTimer_;
  155. NSTimer* hideTimer_;
  156. // Holds the current bounds of |trackingArea_|, even if |trackingArea_| is
  157. // currently nil. Used to restore the tracking area when an animation
  158. // completes.
  159. NSRect trackingAreaBounds_;
  160. // Tracks the currently requested system fullscreen mode, used to show or hide
  161. // the menubar. This should be |kFullScreenModeNormal| when the window is not
  162. // main or not fullscreen, |kFullScreenModeHideAll| while the overlay is
  163. // hidden, and |kFullScreenModeHideDock| while the overlay is shown. If the
  164. // window is not on the primary screen, this should always be
  165. // |kFullScreenModeNormal|. This value can get out of sync with the correct
  166. // state if we miss a notification (which can happen when a window is closed).
  167. // Used to track the current state and make sure we properly restore the menu
  168. // bar when this controller is destroyed.
  169. FullScreenMode systemFullscreenMode_;
  170. }
  171. @synthesize inPresentationMode = inPresentationMode_;
  172. - (id)initWithBrowserController:(CTBrowserWindowController*)controller {
  173. if ((self = [super init])) {
  174. browserController_ = controller;
  175. systemFullscreenMode_ = kFullScreenModeNormal;
  176. }
  177. // Let the world know what we're up to.
  178. [[NSNotificationCenter defaultCenter] postNotificationName:kWillEnterFullscreenNotification
  179. object:nil];
  180. return self;
  181. }
  182. - (void)enterPresentationModeForContentView:(NSView*)contentView
  183. showDropdown:(BOOL)showDropdown {
  184. DCHECK(!inPresentationMode_);
  185. enteringPresentationMode_ = YES;
  186. inPresentationMode_ = YES;
  187. contentView_ = contentView;
  188. [self changeFloatingBarShownFraction:(showDropdown ? 1 : 0)];
  189. // Register for notifications. Self is removed as an observer in |-cleanup|.
  190. NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
  191. NSWindow* window = [browserController_ window];
  192. [nc addObserver:self
  193. selector:@selector(windowDidBecomeMain:)
  194. name:NSWindowDidBecomeMainNotification
  195. object:window];
  196. [nc addObserver:self
  197. selector:@selector(windowDidResignMain:)
  198. name:NSWindowDidResignMainNotification
  199. object:window];
  200. enteringPresentationMode_ = NO;
  201. }
  202. - (void)exitPresentationMode {
  203. [[NSNotificationCenter defaultCenter]
  204. postNotificationName:kWillLeaveFullscreenNotification
  205. object:nil];
  206. DCHECK(inPresentationMode_);
  207. inPresentationMode_ = NO;
  208. [self cleanup];
  209. }
  210. - (void)windowDidChangeScreen:(NSNotification*)notification {
  211. [browserController_ resizeFullscreenWindow];
  212. }
  213. - (void)windowDidMove:(NSNotification*)notification {
  214. [browserController_ resizeFullscreenWindow];
  215. }
  216. - (void)windowDidBecomeMain:(NSNotification*)notification {
  217. [self showActiveWindowUI];
  218. }
  219. - (void)windowDidResignMain:(NSNotification*)notification {
  220. [self hideActiveWindowUI];
  221. }
  222. - (CGFloat)floatingBarVerticalOffset {
  223. return [self isWindowOnPrimaryScreen] ? kFloatingBarVerticalOffset : 0;
  224. }
  225. - (void)overlayFrameChanged:(NSRect)frame {
  226. if (!inPresentationMode_)
  227. return;
  228. // Make sure |trackingAreaBounds_| always reflects either the tracking area or
  229. // the desired tracking area.
  230. trackingAreaBounds_ = frame;
  231. // The tracking area should always be at least the height of activation zone.
  232. NSRect contentBounds = [contentView_ bounds];
  233. trackingAreaBounds_.origin.y =
  234. MIN(trackingAreaBounds_.origin.y,
  235. NSMaxY(contentBounds) - kDropdownActivationZoneHeight);
  236. trackingAreaBounds_.size.height =
  237. NSMaxY(contentBounds) - trackingAreaBounds_.origin.y + 1;
  238. // If an animation is currently running, do not set up a tracking area now.
  239. // Instead, leave it to be created it in |-animationDidEnd:|.
  240. if (currentAnimation_)
  241. return;
  242. // If this is part of the initial setup, lock bar visibility if the mouse is
  243. // within the tracking area bounds.
  244. if (enteringPresentationMode_ && [self mouseInsideTrackingRect])
  245. [browserController_ lockBarVisibilityForOwner:self
  246. withAnimation:NO
  247. delay:NO];
  248. [self setupTrackingArea];
  249. }
  250. - (void)ensureOverlayShownWithAnimation:(BOOL)animate
  251. delay:(BOOL)delay {
  252. if (!inPresentationMode_)
  253. return;
  254. if (animate) {
  255. if (delay) {
  256. [self startShowTimer];
  257. } else {
  258. [self cancelAllTimers];
  259. [self changeOverlayToFraction:1 withAnimation:YES];
  260. }
  261. } else {
  262. DCHECK(!delay);
  263. [self cancelAllTimers];
  264. [self changeOverlayToFraction:1 withAnimation:NO];
  265. }
  266. }
  267. - (void)ensureOverlayHiddenWithAnimation:(BOOL)animate delay:(BOOL)delay {
  268. if (!inPresentationMode_)
  269. return;
  270. if (animate) {
  271. if (delay) {
  272. [self startHideTimer];
  273. } else {
  274. [self cancelAllTimers];
  275. [self changeOverlayToFraction:0 withAnimation:YES];
  276. }
  277. } else {
  278. DCHECK(!delay);
  279. [self cancelAllTimers];
  280. [self changeOverlayToFraction:0 withAnimation:NO];
  281. }
  282. }
  283. - (void)cancelAnimationAndTimers {
  284. [self cancelAllTimers];
  285. [currentAnimation_ stopAnimation];
  286. currentAnimation_ = nil;
  287. }
  288. - (CGFloat)floatingBarShownFraction {
  289. return [browserController_ floatingBarShownFraction];
  290. }
  291. - (void)changeFloatingBarShownFraction:(CGFloat)fraction {
  292. [browserController_ setFloatingBarShownFraction:fraction];
  293. FullScreenMode desiredMode = [self desiredSystemFullscreenMode];
  294. if (desiredMode != systemFullscreenMode_ && [self shouldToggleMenuBar]) {
  295. // TODO: check what these stuffs do
  296. // if (systemFullscreenMode_ == kFullScreenModeNormal)
  297. // [self requestFullScreen(desiredMode)];
  298. // else
  299. // base::mac::SwitchFullScreenModes(systemFullscreenMode_, desiredMode);
  300. systemFullscreenMode_ = desiredMode;
  301. }
  302. }
  303. // Used to activate the floating bar in presentation mode.
  304. - (void)mouseEntered:(NSEvent*)event {
  305. DCHECK(inPresentationMode_);
  306. // Having gotten a mouse entered, we no longer need to do exit checks.
  307. [self cancelMouseExitCheck];
  308. NSTrackingArea* trackingArea = [event trackingArea];
  309. if (trackingArea == trackingArea_) {
  310. // The tracking area shouldn't be active during animation.
  311. DCHECK(!currentAnimation_);
  312. [self scheduleShowForMouse];
  313. }
  314. }
  315. // Used to deactivate the floating bar in presentation mode.
  316. - (void)mouseExited:(NSEvent*)event {
  317. DCHECK(inPresentationMode_);
  318. NSTrackingArea* trackingArea = [event trackingArea];
  319. if (trackingArea == trackingArea_) {
  320. // The tracking area shouldn't be active during animation.
  321. DCHECK(!currentAnimation_);
  322. // We can get a false mouse exit when the menu slides down, so if the mouse
  323. // is still actually over the tracking area, we ignore the mouse exit, but
  324. // we set up to check the mouse position again after a delay.
  325. if ([self mouseInsideTrackingRect]) {
  326. [self setupMouseExitCheck];
  327. return;
  328. }
  329. [self scheduleHideForMouse];
  330. }
  331. }
  332. - (void)animationDidStop:(NSAnimation*)animation {
  333. // Reset the |currentAnimation_| pointer now that the animation is over.
  334. currentAnimation_ = nil;
  335. // Invariant says that the tracking area is not installed while animations are
  336. // in progress. Ensure this is true.
  337. DCHECK(!trackingArea_);
  338. [self removeTrackingAreaIfNecessary]; // For paranoia.
  339. // Don't automatically set up a new tracking area. When explicitly stopped,
  340. // either another animation is going to start immediately or the state will be
  341. // changed immediately.
  342. }
  343. - (void)animationDidEnd:(NSAnimation*)animation {
  344. [self animationDidStop:animation];
  345. // |trackingAreaBounds_| contains the correct tracking area bounds, including
  346. // |any updates that may have come while the animation was running. Install a
  347. // new tracking area with these bounds.
  348. [self setupTrackingArea];
  349. // TODO(viettrungluu): Better would be to check during the animation; doing it
  350. // here means that the timing is slightly off.
  351. if (![self mouseInsideTrackingRect])
  352. [self scheduleHideForMouse];
  353. }
  354. @end
  355. @implementation CTPresentationModeController (PrivateMethods)
  356. - (BOOL)isWindowOnPrimaryScreen {
  357. NSScreen* screen = [[browserController_ window] screen];
  358. NSScreen* primaryScreen = [[NSScreen screens] objectAtIndex:0];
  359. return (screen == primaryScreen);
  360. }
  361. - (BOOL)shouldToggleMenuBar {
  362. return NO && [self isWindowOnPrimaryScreen] && [[browserController_ window] isMainWindow];
  363. }
  364. - (FullScreenMode)desiredSystemFullscreenMode {
  365. if ([browserController_ floatingBarShownFraction] >= 1.0)
  366. return kFullScreenModeHideDock;
  367. return kFullScreenModeHideAll;
  368. }
  369. - (void)changeOverlayToFraction:(CGFloat)fraction
  370. withAnimation:(BOOL)animate {
  371. // The non-animated case is really simple, so do it and return.
  372. if (!animate) {
  373. [currentAnimation_ stopAnimation];
  374. [self changeFloatingBarShownFraction:fraction];
  375. return;
  376. }
  377. // If we're already animating to the given fraction, then there's nothing more
  378. // to do.
  379. if (currentAnimation_ && [currentAnimation_ endFraction] == fraction)
  380. return;
  381. // In all other cases, we want to cancel any running animation (which may be
  382. // to show or to hide).
  383. [currentAnimation_ stopAnimation];
  384. // Now, if it happens to already be in the right state, there's nothing more
  385. // to do.
  386. if ([browserController_ floatingBarShownFraction] == fraction)
  387. return;
  388. // Create the animation and set it up.
  389. currentAnimation_ = [[DropdownAnimation alloc] initWithFraction:fraction
  390. fullDuration:kDropdownAnimationDuration
  391. animationCurve:NSAnimationEaseOut
  392. controller:self];
  393. DCHECK(currentAnimation_);
  394. [currentAnimation_ setAnimationBlockingMode:NSAnimationNonblocking];
  395. [currentAnimation_ setDelegate:self];
  396. // If there is an existing tracking area, remove it. We do not track mouse
  397. // movements during animations (see class comment in the header file).
  398. [self removeTrackingAreaIfNecessary];
  399. [currentAnimation_ startAnimation];
  400. }
  401. - (void)scheduleShowForMouse {
  402. [browserController_ lockBarVisibilityForOwner:self
  403. withAnimation:YES
  404. delay:YES];
  405. }
  406. - (void)scheduleHideForMouse {
  407. [browserController_ releaseBarVisibilityForOwner:self
  408. withAnimation:YES
  409. delay:YES];
  410. }
  411. - (void)setupTrackingArea {
  412. if (trackingArea_) {
  413. // If the tracking rectangle is already |trackingAreaBounds_|, quit early.
  414. NSRect oldRect = [trackingArea_ rect];
  415. if (NSEqualRects(trackingAreaBounds_, oldRect))
  416. return;
  417. // Otherwise, remove it.
  418. [self removeTrackingAreaIfNecessary];
  419. }
  420. // Create and add a new tracking area for |frame|.
  421. trackingArea_ = [[NSTrackingArea alloc] initWithRect:trackingAreaBounds_
  422. options:NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow
  423. owner:self
  424. userInfo:nil];
  425. DCHECK(contentView_);
  426. [contentView_ addTrackingArea:trackingArea_];
  427. }
  428. - (void)removeTrackingAreaIfNecessary {
  429. if (trackingArea_) {
  430. DCHECK(contentView_); // |contentView_| better be valid.
  431. [contentView_ removeTrackingArea:trackingArea_];
  432. trackingArea_ = nil;
  433. }
  434. }
  435. - (BOOL)mouseInsideTrackingRect {
  436. NSWindow* window = [browserController_ window];
  437. NSPoint mouseLoc = [window mouseLocationOutsideOfEventStream];
  438. NSPoint mousePos = [contentView_ convertPoint:mouseLoc fromView:nil];
  439. return NSMouseInRect(mousePos, trackingAreaBounds_, [contentView_ isFlipped]);
  440. }
  441. - (void)setupMouseExitCheck {
  442. [self performSelector:@selector(checkForMouseExit)
  443. withObject:nil
  444. afterDelay:kMouseExitCheckDelay];
  445. }
  446. - (void)cancelMouseExitCheck {
  447. [NSObject cancelPreviousPerformRequestsWithTarget:self
  448. selector:@selector(checkForMouseExit) object:nil];
  449. }
  450. - (void)checkForMouseExit {
  451. if ([self mouseInsideTrackingRect])
  452. [self setupMouseExitCheck];
  453. else
  454. [self scheduleHideForMouse];
  455. }
  456. - (void)startShowTimer {
  457. // If there's already a show timer going, just keep it.
  458. if (showTimer_) {
  459. DCHECK([showTimer_ isValid]);
  460. DCHECK(!hideTimer_);
  461. return;
  462. }
  463. // Cancel the hide timer (if necessary) and set up the new show timer.
  464. [self cancelHideTimer];
  465. showTimer_ = [NSTimer scheduledTimerWithTimeInterval:kDropdownShowDelay
  466. target:self
  467. selector:@selector(showTimerFire:)
  468. userInfo:nil
  469. repeats:NO];
  470. DCHECK([showTimer_ isValid]); // This also checks that |showTimer_ != nil|.
  471. }
  472. - (void)startHideTimer {
  473. // If there's already a hide timer going, just keep it.
  474. if (hideTimer_) {
  475. DCHECK([hideTimer_ isValid]);
  476. DCHECK(!showTimer_);
  477. return;
  478. }
  479. // Cancel the show timer (if necessary) and set up the new hide timer.
  480. [self cancelShowTimer];
  481. hideTimer_ = [NSTimer scheduledTimerWithTimeInterval:kDropdownHideDelay
  482. target:self
  483. selector:@selector(hideTimerFire:)
  484. userInfo:nil
  485. repeats:NO];
  486. DCHECK([hideTimer_ isValid]); // This also checks that |hideTimer_ != nil|.
  487. }
  488. - (void)cancelShowTimer {
  489. [showTimer_ invalidate];
  490. showTimer_ = nil;
  491. }
  492. - (void)cancelHideTimer {
  493. [hideTimer_ invalidate];
  494. hideTimer_ = nil;
  495. }
  496. - (void)cancelAllTimers {
  497. [self cancelShowTimer];
  498. [self cancelHideTimer];
  499. }
  500. - (void)showTimerFire:(NSTimer*)timer {
  501. DCHECK_EQ(showTimer_, timer); // This better be our show timer.
  502. [showTimer_ invalidate]; // Make sure it doesn't repeat.
  503. showTimer_ = nil; // And get rid of it.
  504. [self changeOverlayToFraction:1 withAnimation:YES];
  505. }
  506. - (void)hideTimerFire:(NSTimer*)timer {
  507. DCHECK_EQ(hideTimer_, timer); // This better be our hide timer.
  508. [hideTimer_ invalidate]; // Make sure it doesn't repeat.
  509. hideTimer_ = nil; // And get rid of it.
  510. [self changeOverlayToFraction:0 withAnimation:YES];
  511. }
  512. - (void)cleanup {
  513. [self cancelMouseExitCheck];
  514. [self cancelAnimationAndTimers];
  515. [[NSNotificationCenter defaultCenter] removeObserver:self];
  516. [self removeTrackingAreaIfNecessary];
  517. contentView_ = nil;
  518. // This isn't tracked when not in presentation mode.
  519. [browserController_ releaseBarVisibilityForOwner:self
  520. withAnimation:NO
  521. delay:NO];
  522. // Call the main status resignation code to perform the associated cleanup,
  523. // since we will no longer be receiving actual status resignation
  524. // notifications.
  525. [self hideActiveWindowUI];
  526. // No more calls back up to the BWC.
  527. browserController_ = nil;
  528. }
  529. - (void)showActiveWindowUI {
  530. DCHECK_EQ(systemFullscreenMode_, kFullScreenModeNormal);
  531. if (systemFullscreenMode_ != kFullScreenModeNormal)
  532. return;
  533. if ([self shouldToggleMenuBar]) {
  534. FullScreenMode desiredMode = [self desiredSystemFullscreenMode];
  535. // TODO: check this!
  536. // base::mac::RequestFullScreen(desiredMode);
  537. systemFullscreenMode_ = desiredMode;
  538. }
  539. // TODO(rohitrao): Insert the Exit Fullscreen button. http://crbug.com/35956
  540. }
  541. - (void)hideActiveWindowUI {
  542. if (systemFullscreenMode_ != kFullScreenModeNormal) {
  543. // TODO: check this!
  544. // base::mac::ReleaseFullScreen(systemFullscreenMode_);
  545. systemFullscreenMode_ = kFullScreenModeNormal;
  546. }
  547. // TODO(rohitrao): Remove the Exit Fullscreen button. http://crbug.com/35956
  548. }
  549. @end