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

Side by Side Diff: chrome/browser/ui/cocoa/fullscreen/immersive_fullscreen_controller.mm

Issue 2484973004: [Mac] Refactor Immersive Fullscreen Logic (Closed)
Patch Set: Fix for erikchen Created 4 years, 1 month 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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
5 #import "chrome/browser/ui/cocoa/fullscreen/immersive_fullscreen_controller.h"
6
7 #import "base/mac/mac_util.h"
8 #include "base/mac/sdk_forward_declarations.h"
9 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
10 #import "ui/base/cocoa/tracking_area.h"
11
12 namespace {
13
14 // The height from the top of the screen that will show the menubar.
15 const CGFloat kMenubarShowZoneHeight = 4;
16
17 // The height from the top of the screen that will hide the menubar.
18 // The value must be greater than the menubar's height of 22px.
19 const CGFloat kMenubarHideZoneHeight = 28;
20
21 } // namespace
22
23 @interface ImmersiveFullscreenController () {
24 BrowserWindowController* browserController_; // weak
25
26 // Used to track the mouse movements to show/hide the menu.
27 base::scoped_nsobject<CrTrackingArea> trackingArea_;
28
29 // The content view for the window.
30 NSView* contentView_; // weak
31
32 // Tracks the currently requested system fullscreen mode, used to show or
33 // hide the menubar. Its value is as follows:
34 // + |kFullScreenModeNormal| - when the window is not main or not fullscreen,
35 // + |kFullScreenModeHideDock| - when the user interacts with the top of the
36 // screen
37 // + |kFullScreenModeHideAll| - when the conditions don't meet the first two
38 // modes.
39 base::mac::FullScreenMode systemFullscreenMode_;
40
41 // True if the menubar should be shown on the screen.
42 BOOL isMenubarVisible_;
43 }
44
45 // Whether the current screen is expected to have a menubar, regardless of
46 // current visibility of the menubar.
47 - (BOOL)doesScreenHaveMenubar;
48
49 // Adjusts the AppKit Fullscreen options of the application.
50 - (void)setSystemFullscreenModeTo:(base::mac::FullScreenMode)mode;
51
52 // Sets |isMenubarVisible_|. If the value has changed, update the tracking
53 // area, the dock, and the menubar
54 - (void)setMenubarVisibility:(BOOL)visible;
55
56 // Methods that update and remove the tracking area.
57 - (void)updateTrackingArea;
58 - (void)removeTrackingArea;
59
60 @end
61
62 @implementation ImmersiveFullscreenController
63
64 - (id)initWithBrowserController:(BrowserWindowController*)bwc {
65 if ((self = [super init])) {
66 browserController_ = bwc;
67 systemFullscreenMode_ = base::mac::kFullScreenModeNormal;
68
69 contentView_ = [[bwc window] contentView];
70 DCHECK(contentView_);
71
72 isMenubarVisible_ = NO;
73
74 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
75 NSWindow* window = [browserController_ window];
76
77 [nc addObserver:self
78 selector:@selector(windowDidBecomeMain:)
79 name:NSWindowDidBecomeMainNotification
80 object:window];
81
82 [nc addObserver:self
83 selector:@selector(windowDidResignMain:)
84 name:NSWindowDidResignMainNotification
85 object:window];
86
87 [self updateTrackingArea];
88 }
89
90 return self;
91 }
92
93 - (void)dealloc {
94 [[NSNotificationCenter defaultCenter] removeObserver:self];
95
96 [self removeTrackingArea];
97 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeNormal];
98
99 [super dealloc];
100 }
101
102 - (void)updateMenuBarAndDockVisibility {
103 BOOL isMouseOnScreen =
104 NSMouseInRect([NSEvent mouseLocation],
105 [[browserController_ window] screen].frame, false);
106
107 if (!isMouseOnScreen || ![browserController_ isInImmersiveFullscreen])
108 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeNormal];
109 else if ([self shouldShowMenubar])
110 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeHideDock];
111 else
112 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeHideAll];
113 }
114
115 - (BOOL)shouldShowMenubar {
116 return [self doesScreenHaveMenubar] && isMenubarVisible_;
117 }
118
119 - (void)windowDidBecomeMain:(NSNotification*)notification {
120 [self updateMenuBarAndDockVisibility];
121 }
122
123 - (void)windowDidResignMain:(NSNotification*)notification {
124 [self updateMenuBarAndDockVisibility];
125 }
126
127 - (BOOL)doesScreenHaveMenubar {
128 NSScreen* screen = [[browserController_ window] screen];
129 NSScreen* primaryScreen = [[NSScreen screens] firstObject];
130 BOOL isWindowOnPrimaryScreen = screen == primaryScreen;
Robert Sesek 2016/11/09 19:23:03 Should this use isEqual: instead?
spqchan 2016/11/09 22:34:40 Done.
131
132 BOOL eachScreenShouldHaveMenuBar = [NSScreen screensHaveSeparateSpaces];
133 return eachScreenShouldHaveMenuBar ?: isWindowOnPrimaryScreen;
134 }
135
136 - (void)setSystemFullscreenModeTo:(base::mac::FullScreenMode)mode {
137 if (mode == systemFullscreenMode_)
138 return;
139
140 if (systemFullscreenMode_ == base::mac::kFullScreenModeNormal)
141 base::mac::RequestFullScreen(mode);
142 else if (mode == base::mac::kFullScreenModeNormal)
143 base::mac::ReleaseFullScreen(systemFullscreenMode_);
144 else
145 base::mac::SwitchFullScreenModes(systemFullscreenMode_, mode);
146
147 systemFullscreenMode_ = mode;
148 }
149
150 - (void)setMenubarVisibility:(BOOL)visible {
151 if (isMenubarVisible_ == visible)
152 return;
153
154 isMenubarVisible_ = visible;
155 [self updateTrackingArea];
156 [self updateMenuBarAndDockVisibility];
157 }
158
159 - (void)updateTrackingArea {
160 [self removeTrackingArea];
161
162 CGFloat trackingHeight =
163 isMenubarVisible_ ? kMenubarHideZoneHeight : kMenubarShowZoneHeight;
164 NSRect trackingFrame = [contentView_ bounds];
165 trackingFrame.origin.y = NSMaxY(trackingFrame) - trackingHeight;
166 trackingFrame.size.height = trackingHeight;
167
168 // If we replace the tracking area with a new one under the cursor, the new
169 // tracking area might not receive a |-mouseEntered:| or |-mouseExited| call.
170 // As a result, we should also track the mouse's movements so that the
171 // so the menubar won't get stuck.
172 NSTrackingAreaOptions options =
173 NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow;
174 if (isMenubarVisible_)
175 options |= NSTrackingMouseMoved;
176
177 // Create and add a new tracking area for |frame|.
178 trackingArea_.reset([[CrTrackingArea alloc] initWithRect:trackingFrame
179 options:options
180 owner:self
181 userInfo:nil]);
182 [contentView_ addTrackingArea:trackingArea_];
183 }
184
185 - (void)removeTrackingArea {
186 if (trackingArea_) {
187 [contentView_ removeTrackingArea:trackingArea_];
188 trackingArea_.reset();
189 }
190 }
191
192 - (void)mouseEntered:(NSEvent*)event {
193 [self setMenubarVisibility:YES];
194 }
195
196 - (void)mouseExited:(NSEvent*)event {
197 [self setMenubarVisibility:NO];
198 }
199
200 - (void)mouseMoved:(NSEvent*)event {
201 [self setMenubarVisibility:[trackingArea_
202 mouseInsideTrackingAreaForView:contentView_]];
203 }
204
205 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698