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

Unified Diff: chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.mm

Issue 2355413007: [Mac] Refactor the Fullscreen Toolbar (Closed)
Patch Set: Nits and grits Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..a1c7e5d80defada88b3600f4be40cdc865715657
--- /dev/null
+++ b/chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.mm
@@ -0,0 +1,155 @@
+// 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/fullscreen_toolbar_layout_manager.h"
+
+namespace {
+
+// The event kind value for a undocumented menubar show/hide Carbon event.
+const CGFloat kMenuBarRevealEventKind = 2004;
+
+// Visibility fractions for the menubar and toolbar.
+const CGFloat kHideFraction = 0.0;
+const CGFloat kShowFraction = 1.0;
+
+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 > kHideFraction && revealFraction < kShowFraction)
+ [self setMenubarProgress:revealFraction];
+ } else if (GetEventKind(event) == kEventMenuBarShown) {
+ [self setMenubarProgress:kShowFraction];
+ } else {
+ [self setMenubarProgress:kHideFraction];
+ }
+
+ return CallNextEventHandler(handler, event);
+}
+
+} // end namespace
+
+@interface FullscreenMenubarTracker () {
+ // Our owner.
+ FullscreenToolbarLayoutManager* 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)initWithFullscreenToolbarLayoutManager:
+ (FullscreenToolbarLayoutManager*)owner {
+ if ((self = [super init])) {
+ owner_ = owner;
+ browserController_ = owner_->browser_window_controller();
+ state_ = FullscreenMenubarState::HIDDEN;
+ }
+
+ // Install the Carbon event handler for the menubar show, hide and
+ // 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,
+ 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, kShowFraction))
+ state_ = FullscreenMenubarState::SHOWN;
+ else if (base::mac::IsCGFloatEqual(progress, kHideFraction))
+ state_ = FullscreenMenubarState::HIDDEN;
+ else if (progress < menubarFraction_)
+ state_ = FullscreenMenubarState::HIDING;
+ else if (progress > menubarFraction_)
+ state_ = FullscreenMenubarState::SHOWING;
+
+ menubarFraction_ = progress;
+
+ owner_->Layout();
+}
+
+- (BOOL)isMouseOnScreen {
+ return NSMouseInRect([NSEvent mouseLocation],
+ [[browserController_ window] screen].frame, false);
+}
+
+- (void)activeSpaceDidChange:(NSNotification*)notification {
+ menubarFraction_ = kHideFraction;
+ state_ = FullscreenMenubarState::HIDDEN;
+ owner_->Layout();
+}
+
+@end

Powered by Google App Engine
This is Rietveld 408576698