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

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

Issue 2430863002: [Mac] Refactor the fullscreen menubar (Closed)
Patch Set: Fix for rsesek 2 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..ba673bf1434b250ae38ef50ac6059add951ff846
--- /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"
+
+#include <Carbon/Carbon.h>
+
+#include "base/macros.h"
+#import "chrome/browser/ui/cocoa/browser_window_controller.h"
+#import "chrome/browser/ui/cocoa/fullscreen_toolbar_controller.h"
+#include "ui/base/cocoa/appkit_utils.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* browserWindowController_; // weak
+
+ // A Carbon event handler that tracks the revealed fraction of the menubar.
+ 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_;
+
+- (instancetype)initWithFullscreenToolbarController:
+ (FullscreenToolbarController*)owner {
+ if ((self = [super init])) {
+ owner_ = owner;
+ browserWindowController_ = [owner_ browserWindowController];
+ 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),
+ arraysize(eventSpecs), 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 (![browserWindowController_ isInAnyFullscreenMode] ||
+ [browserWindowController_ 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 (![[browserWindowController_ window] isOnActiveSpace])
+ return;
+
+ if (ui::IsCGFloatEqual(progress, 1.0))
+ state_ = FullscreenMenubarState::SHOWN;
+ else if (ui::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],
+ [[browserWindowController_ window] screen].frame, false);
+}
+
+- (void)activeSpaceDidChange:(NSNotification*)notification {
+ menubarFraction_ = 0.0;
+ state_ = FullscreenMenubarState::HIDDEN;
+ [owner_ updateToolbar];
+}
+
+@end

Powered by Google App Engine
This is Rietveld 408576698