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

Unified Diff: chrome/browser/ui/cocoa/fullscreen/immersive_fullscreen_controller.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/immersive_fullscreen_controller.mm
diff --git a/chrome/browser/ui/cocoa/fullscreen/immersive_fullscreen_controller.mm b/chrome/browser/ui/cocoa/fullscreen/immersive_fullscreen_controller.mm
new file mode 100644
index 0000000000000000000000000000000000000000..766fbff0c2939fe803d33eaf12b2d804bd748b82
--- /dev/null
+++ b/chrome/browser/ui/cocoa/fullscreen/immersive_fullscreen_controller.mm
@@ -0,0 +1,196 @@
+// 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/immersive_fullscreen_controller.h"
+
+#include "base/mac/sdk_forward_declarations.h"
+#import "chrome/browser/ui/cocoa/browser_window_controller.h"
+#import "chrome/browser/ui/cocoa/fullscreen/fullscreen_toolbar_layout_manager.h"
+#import "ui/base/cocoa/tracking_area.h"
+
+namespace {
+
+// The height from the top of the screen that will show the menubar.
+const CGFloat kMenubarShowZoneHeight = 4;
+
+// The height from the top of the screen that will hide the menubar.
+// The height must be greater than the menubar's height.
+const CGFloat kMenubarHideZoneHeight = 28;
+
+} // namespace
+
+@interface ImmersiveFullscreenController () {
+ BrowserWindowController* browserController_; // weak
+
+ // Used to track the mouse movements to show/hide the menu.
+ base::scoped_nsobject<CrTrackingArea> trackingArea_;
+
+ // The content view for the window.
+ NSView* contentView_; // weak
+
+ // Tracks the currently requested system fullscreen mode, used to show or
+ // hide the menubar. Its value is as follows:
+ // + |kFullScreenModeNormal| - when the window is not main or not fullscreen,
+ // + |kFullScreenModeHideDock| - when the user interacts with the top of the
+ // screen
+ // + |kFullScreenModeHideAll| - when the conditions don't meet the first two
+ // modes.
+ base::mac::FullScreenMode systemFullscreenMode_;
+
+ // True if the menubar should be shown on the screen.
+ BOOL shouldShowMenubar_;
+}
+
+// Whether the current screen is expected to have a menu bar, regardless of
+// current visibility of the menu bar.
+- (BOOL)doesScreenHaveMenuBar;
+
+// Returns |kFullScreenModeHideAll| when the menubar is hidden and
+// |kFullScreenModeHideDock| when the menubar is shown.
+- (base::mac::FullScreenMode)desiredSystemFullscreenMode;
+
+// Adjusts the AppKit Fullscreen options of the application.
+- (void)setSystemFullscreenModeTo:(base::mac::FullScreenMode)mode;
+
+// Methods that update and remove the tracking area.
+- (void)updateTrackingArea;
+- (void)removeTrackingArea;
+
+@end
+
+@implementation ImmersiveFullscreenController
+
+- (id)initWithBrowserController:(BrowserWindowController*)bwc {
+ if ((self = [super init])) {
+ browserController_ = bwc;
+ systemFullscreenMode_ = base::mac::kFullScreenModeNormal;
+ contentView_ = [[bwc window] contentView];
+
+ NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
+ NSWindow* window = [browserController_ window];
+
+ [nc addObserver:self
+ selector:@selector(windowDidBecomeMain:)
+ name:NSWindowDidBecomeMainNotification
+ object:window];
+
+ [nc addObserver:self
+ selector:@selector(windowDidResignMain:)
+ name:NSWindowDidResignMainNotification
+ object:window];
+
+ [self updateTrackingArea];
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+ [self removeTrackingArea];
+ [self setSystemFullscreenModeTo:base::mac::kFullScreenModeNormal];
+
+ [super dealloc];
+}
+
+- (void)updateMenuBarAndDockVisibility {
+ BOOL isMouseOnScreen =
+ NSMouseInRect([NSEvent mouseLocation],
+ [[browserController_ window] screen].frame, false);
+
+ if (isMouseOnScreen || ![browserController_ isInImmersiveFullscreen])
+ [self setSystemFullscreenModeTo:base::mac::kFullScreenModeNormal];
+ else if (![self doesScreenHaveMenuBar])
+ [self setSystemFullscreenModeTo:base::mac::kFullScreenModeHideDock];
+ else
+ [self setSystemFullscreenModeTo:[self desiredSystemFullscreenMode]];
+}
+
+- (BOOL)shouldShowMenubar {
+ return [self doesScreenHaveMenuBar] && shouldShowMenubar_;
+}
+
+- (void)windowDidBecomeMain:(NSNotification*)notification {
+ [self updateMenuBarAndDockVisibility];
+}
+
+- (void)windowDidResignMain:(NSNotification*)notification {
+ [self updateMenuBarAndDockVisibility];
+}
+
+- (base::mac::FullScreenMode)desiredSystemFullscreenMode {
+ return [self shouldShowMenubar] ? base::mac::kFullScreenModeHideDock
+ : base::mac::kFullScreenModeHideAll;
+}
+
+- (BOOL)doesScreenHaveMenuBar {
+ NSScreen* screen = [[browserController_ window] screen];
+ NSScreen* primaryScreen = [[NSScreen screens] firstObject];
+ BOOL isWindowOnPrimaryScreen = screen == primaryScreen;
+
+ BOOL eachScreenShouldHaveMenuBar = [NSScreen screensHaveSeparateSpaces];
+ return eachScreenShouldHaveMenuBar ?: isWindowOnPrimaryScreen;
+}
+
+- (void)setSystemFullscreenModeTo:(base::mac::FullScreenMode)mode {
+ if (mode == systemFullscreenMode_)
+ return;
+
+ if (systemFullscreenMode_ == base::mac::kFullScreenModeNormal)
+ base::mac::RequestFullScreen(mode);
+ else if (mode == base::mac::kFullScreenModeNormal)
+ base::mac::ReleaseFullScreen(systemFullscreenMode_);
+ else
+ base::mac::SwitchFullScreenModes(systemFullscreenMode_, mode);
+
+ systemFullscreenMode_ = mode;
+}
+
+- (void)updateTrackingArea {
+ if (trackingArea_)
+ [self removeTrackingArea];
+
+ CGFloat trackingHeight =
+ shouldShowMenubar_ ? kMenubarHideZoneHeight : kMenubarShowZoneHeight;
+ NSRect trackingFrame = [contentView_ bounds];
+ trackingFrame.origin.y = NSMaxY(trackingFrame) - trackingHeight;
+ trackingFrame.size.height = trackingHeight;
+
+ // Create and add a new tracking area for |frame|.
+ trackingArea_.reset([[CrTrackingArea alloc]
+ initWithRect:trackingFrame
+ options:NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow
+ owner:self
+ userInfo:nil]);
+ DCHECK(contentView_);
+ [contentView_ addTrackingArea:trackingArea_];
+}
+
+- (void)removeTrackingArea {
+ if (trackingArea_) {
+ DCHECK(contentView_); // |contentView_| better be valid.
+ [contentView_ removeTrackingArea:trackingArea_];
+ trackingArea_.reset();
+ }
+}
+
+- (void)mouseEntered:(NSEvent*)event {
+ if (shouldShowMenubar_)
+ return;
+
+ shouldShowMenubar_ = YES;
+ [self updateTrackingArea];
+ [self updateMenuBarAndDockVisibility];
+}
+
+- (void)mouseExited:(NSEvent*)event {
+ DCHECK_EQ([event trackingArea], trackingArea_.get());
+
+ shouldShowMenubar_ = NO;
+ [self updateTrackingArea];
+ [self updateMenuBarAndDockVisibility];
+}
+
+@end

Powered by Google App Engine
This is Rietveld 408576698