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

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

Issue 2484973004: [Mac] Refactor Immersive Fullscreen Logic (Closed)
Patch Set: Refactored 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 shouldShowMenubar_;
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 |shouldShowMenubar_|. 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 contentView_ = [[bwc window] contentView];
69 shouldShowMenubar_ = NO;
70
71 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
72 NSWindow* window = [browserController_ window];
73
74 [nc addObserver:self
75 selector:@selector(windowDidBecomeMain:)
76 name:NSWindowDidBecomeMainNotification
77 object:window];
78
79 [nc addObserver:self
80 selector:@selector(windowDidResignMain:)
81 name:NSWindowDidResignMainNotification
82 object:window];
83
84 [self updateTrackingArea];
85 }
86
87 return self;
88 }
89
90 - (void)dealloc {
91 [[NSNotificationCenter defaultCenter] removeObserver:self];
92
93 [self removeTrackingArea];
94 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeNormal];
95
96 [super dealloc];
97 }
98
99 - (void)updateMenuBarAndDockVisibility {
100 BOOL isMouseOnScreen =
101 NSMouseInRect([NSEvent mouseLocation],
102 [[browserController_ window] screen].frame, false);
103
104 if (!isMouseOnScreen || ![browserController_ isInImmersiveFullscreen])
105 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeNormal];
106 else if ([self shouldShowMenubar])
107 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeHideDock];
108 else
109 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeHideAll];
110 }
111
112 - (BOOL)shouldShowMenubar {
113 return [self doesScreenHaveMenubar] && shouldShowMenubar_;
erikchen 2016/11/09 00:39:43 This method nomenclature is very confusing. I thin
spqchan 2016/11/09 17:26:06 Done.
114 }
115
116 - (void)windowDidBecomeMain:(NSNotification*)notification {
117 [self updateMenuBarAndDockVisibility];
118 }
119
120 - (void)windowDidResignMain:(NSNotification*)notification {
121 [self updateMenuBarAndDockVisibility];
122 }
123
124 - (BOOL)doesScreenHaveMenubar {
125 NSScreen* screen = [[browserController_ window] screen];
126 NSScreen* primaryScreen = [[NSScreen screens] firstObject];
127 BOOL isWindowOnPrimaryScreen = screen == primaryScreen;
128
129 BOOL eachScreenShouldHaveMenuBar = [NSScreen screensHaveSeparateSpaces];
130 return eachScreenShouldHaveMenuBar ?: isWindowOnPrimaryScreen;
131 }
132
133 - (void)setSystemFullscreenModeTo:(base::mac::FullScreenMode)mode {
134 if (mode == systemFullscreenMode_)
135 return;
136
137 if (systemFullscreenMode_ == base::mac::kFullScreenModeNormal)
138 base::mac::RequestFullScreen(mode);
139 else if (mode == base::mac::kFullScreenModeNormal)
140 base::mac::ReleaseFullScreen(systemFullscreenMode_);
141 else
142 base::mac::SwitchFullScreenModes(systemFullscreenMode_, mode);
143
144 systemFullscreenMode_ = mode;
145 }
146
147 - (void)setMenubarVisibility:(BOOL)visible {
148 if (shouldShowMenubar_ == visible)
149 return;
150
151 shouldShowMenubar_ = visible;
152 [self updateTrackingArea];
153 [self updateMenuBarAndDockVisibility];
154 }
155
156 - (void)updateTrackingArea {
157 if (trackingArea_)
158 [self removeTrackingArea];
erikchen 2016/11/09 00:39:43 removeTrackingArea already does the conditional ch
spqchan 2016/11/09 17:26:06 Done.
159
160 CGFloat trackingHeight =
161 shouldShowMenubar_ ? kMenubarHideZoneHeight : kMenubarShowZoneHeight;
162 NSRect trackingFrame = [contentView_ bounds];
163 trackingFrame.origin.y = NSMaxY(trackingFrame) - trackingHeight;
164 trackingFrame.size.height = trackingHeight;
165
166 // If we replace the tracking area with a new one under the cursor, the new
167 // tracking area might not receive a |-mouseEntered:| or |-mouseExited| call.
168 // As a result, we should also track the mouse's movements so that the
169 // so the menubar won't get stuck.
170 NSTrackingAreaOptions options =
171 NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow;
172 if (shouldShowMenubar_)
173 options |= NSTrackingMouseMoved;
174
175 // Create and add a new tracking area for |frame|.
176 trackingArea_.reset([[CrTrackingArea alloc] initWithRect:trackingFrame
177 options:options
178 owner:self
179 userInfo:nil]);
180 DCHECK(contentView_);
181 [contentView_ addTrackingArea:trackingArea_];
182 }
183
184 - (void)removeTrackingArea {
185 if (trackingArea_) {
186 DCHECK(contentView_); // |contentView_| better be valid.
erikchen 2016/11/09 00:39:43 Rather than having checks here and line 180, maybe
spqchan 2016/11/09 17:26:06 Done.
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