Chromium Code Reviews| Index: chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.mm |
| diff --git a/chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.mm b/chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.mm |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..9c538ca83f99695877b0340a96042464716954a6 |
| --- /dev/null |
| +++ b/chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.mm |
| @@ -0,0 +1,150 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#import "chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.h" |
| + |
| +#import "chrome/browser/ui/cocoa/browser_window_controller.h" |
| +#import "chrome/browser/ui/cocoa/fullscreen_toolbar_controller.h" |
| + |
| +namespace { |
| + |
| +// The event kind value for a undocumented menubar show/hide Carbon event. |
| +const CGFloat kMenuBarRevealEventKind = 2004; |
| + |
| +OSStatus MenuBarRevealHandler(EventHandlerCallRef handler, |
| + EventRef event, |
| + void* context) { |
| + FullscreenMenubarTracker* self = |
| + static_cast<FullscreenMenubarTracker*>(context); |
| + |
| + // If Chrome has multiple fullscreen windows in their own space, the Handler |
| + // becomes flaky and might start receiving kMenuBarRevealEventKind events |
| + // from another space. Since the menubar in the another space is in either a |
| + // shown or hidden state, it will give us a reveal fraction of 0.0 or 1.0. |
| + // As such, we should ignore the kMenuBarRevealEventKind event if it gives |
| + // us a fraction of 0.0 or 1.0, and rely on kEventMenuBarShown and |
| + // kEventMenuBarHidden to set these values. |
| + if (GetEventKind(event) == kMenuBarRevealEventKind) { |
| + CGFloat revealFraction = 0; |
| + GetEventParameter(event, FOUR_CHAR_CODE('rvlf'), typeCGFloat, NULL, |
| + sizeof(CGFloat), NULL, &revealFraction); |
| + if (revealFraction > 0.0 && revealFraction < 1.0) |
| + [self setMenubarProgress:revealFraction]; |
| + } else if (GetEventKind(event) == kEventMenuBarShown) { |
| + [self setMenubarProgress:1.0]; |
| + } else { |
| + [self setMenubarProgress:0.0]; |
| + } |
| + |
| + return CallNextEventHandler(handler, event); |
| +} |
| + |
| +} // end namespace |
| + |
| +@interface FullscreenMenubarTracker () { |
| + // Our owner. |
| + FullscreenToolbarController* owner_; // weak |
| + |
| + // The window's controller. |
| + BrowserWindowController* browserController_; // weak |
| + |
| + // A Carbon event handler that tracks the revealed fraction of the menu bar. |
| + EventHandlerRef menuBarTrackingHandler_; |
| +} |
| + |
| +// Returns YES if the mouse is on the same screen as the window. |
| +- (BOOL)isMouseOnScreen; |
| + |
| +@end |
| + |
| +@implementation FullscreenMenubarTracker |
| + |
| +@synthesize state = state_; |
| +@synthesize menubarFraction = menubarFraction_; |
| + |
| +- (id)initWithFullscreenToolbarController:(FullscreenToolbarController*)owner { |
| + if ((self = [super init])) { |
| + owner_ = owner; |
| + browserController_ = [owner_ browserWindowController]; |
|
Robert Sesek
2016/10/19 18:49:21
naming: browserWindowController_ instead
spqchan
2016/10/19 19:28:42
Done.
|
| + state_ = FullscreenMenubarState::HIDDEN; |
| + } |
| + |
| + // Install the Carbon event handler for the menubar show, hide and |
|
Robert Sesek
2016/10/19 18:49:21
Move this code into the if block as well?
spqchan
2016/10/19 19:28:42
Done.
|
| + // undocumented reveal event. |
| + EventTypeSpec eventSpecs[3]; |
| + |
| + eventSpecs[0].eventClass = kEventClassMenu; |
| + eventSpecs[0].eventKind = kMenuBarRevealEventKind; |
| + |
| + eventSpecs[1].eventClass = kEventClassMenu; |
| + eventSpecs[1].eventKind = kEventMenuBarShown; |
| + |
| + eventSpecs[2].eventClass = kEventClassMenu; |
| + eventSpecs[2].eventKind = kEventMenuBarHidden; |
| + |
| + InstallApplicationEventHandler(NewEventHandlerUPP(&MenuBarRevealHandler), 3, |
|
Robert Sesek
2016/10/19 18:49:21
arraysize() instead of 3
spqchan
2016/10/19 19:28:42
Done.
|
| + eventSpecs, self, &menuBarTrackingHandler_); |
| + |
| + // Register for Active Space change notifications. |
| + [[[NSWorkspace sharedWorkspace] notificationCenter] |
| + addObserver:self |
| + selector:@selector(activeSpaceDidChange:) |
| + name:NSWorkspaceActiveSpaceDidChangeNotification |
| + object:nil]; |
| + |
| + return self; |
| +} |
| + |
| +- (void)dealloc { |
| + RemoveEventHandler(menuBarTrackingHandler_); |
| + [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self]; |
| + |
| + [super dealloc]; |
| +} |
| + |
| +- (CGFloat)menubarFraction { |
| + return menubarFraction_; |
| +} |
| + |
| +- (void)setMenubarProgress:(CGFloat)progress { |
| + if (![browserController_ isInAnyFullscreenMode] || |
| + [browserController_ isFullscreenTransitionInProgress]) { |
| + return; |
| + } |
| + |
| + // If the menubarFraction increases, check if we are in the right screen |
| + // so that the toolbar is not revealed on the wrong screen. |
| + if (![self isMouseOnScreen] && progress > menubarFraction_) |
| + return; |
| + |
| + // Ignore the menubarFraction changes if the Space is inactive. |
| + if (![[browserController_ window] isOnActiveSpace]) |
| + return; |
| + |
| + if (base::mac::IsCGFloatEqual(progress, 1.0)) |
| + state_ = FullscreenMenubarState::SHOWN; |
| + else if (base::mac::IsCGFloatEqual(progress, 0.0)) |
| + state_ = FullscreenMenubarState::HIDDEN; |
| + else if (progress < menubarFraction_) |
| + state_ = FullscreenMenubarState::HIDING; |
| + else if (progress > menubarFraction_) |
| + state_ = FullscreenMenubarState::SHOWING; |
| + |
| + menubarFraction_ = progress; |
| + |
| + [owner_ updateToolbar]; |
| +} |
| + |
| +- (BOOL)isMouseOnScreen { |
| + return NSMouseInRect([NSEvent mouseLocation], |
| + [[browserController_ window] screen].frame, false); |
| +} |
| + |
| +- (void)activeSpaceDidChange:(NSNotification*)notification { |
| + menubarFraction_ = 0.0; |
| + state_ = FullscreenMenubarState::HIDDEN; |
| + [owner_ updateToolbar]; |
| +} |
| + |
| +@end |