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

Side by Side Diff: chrome/browser/ui/cocoa/fullscreen_toolbar_controller.mm

Issue 2446313005: [Mac] Refactor the fullscreen toolbar mouse tracker (Closed)
Patch Set: Fix for rsesek 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
« no previous file with comments | « chrome/browser/ui/cocoa/fullscreen_toolbar_controller.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "chrome/browser/ui/cocoa/fullscreen_toolbar_controller.h" 5 #import "chrome/browser/ui/cocoa/fullscreen_toolbar_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #import "base/mac/mac_util.h" 10 #import "base/mac/mac_util.h"
11 #include "base/mac/sdk_forward_declarations.h" 11 #include "base/mac/sdk_forward_declarations.h"
12 #import "chrome/browser/ui/cocoa/browser_window_controller.h" 12 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
13 #import "chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.h" 13 #import "chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.h"
14 #import "chrome/browser/ui/cocoa/fullscreen/fullscreen_toolbar_animation_control ler.h" 14 #import "chrome/browser/ui/cocoa/fullscreen/fullscreen_toolbar_animation_control ler.h"
15 #import "chrome/browser/ui/cocoa/fullscreen/fullscreen_toolbar_mouse_tracker.h"
15 #include "chrome/common/chrome_switches.h" 16 #include "chrome/common/chrome_switches.h"
16 #include "ui/base/cocoa/appkit_utils.h" 17 #include "ui/base/cocoa/appkit_utils.h"
17 #import "ui/base/cocoa/nsview_additions.h" 18 #import "ui/base/cocoa/nsview_additions.h"
18 #import "ui/base/cocoa/tracking_area.h" 19 #import "ui/base/cocoa/tracking_area.h"
19 20
20 namespace { 21 namespace {
21 22
22 // Additional height threshold added at the toolbar's bottom. This is to mimic
23 // threshold the mouse position needs to be at before the menubar automatically
24 // hides.
25 const CGFloat kTrackingAreaAdditionalThreshold = 20;
26
27 // Visibility fractions for the menubar and toolbar. 23 // Visibility fractions for the menubar and toolbar.
28 const CGFloat kHideFraction = 0.0; 24 const CGFloat kHideFraction = 0.0;
29 const CGFloat kShowFraction = 1.0; 25 const CGFloat kShowFraction = 1.0;
30 26
31 // The amount by which the toolbar is offset downwards (to avoid the menu) 27 // The amount by which the toolbar is offset downwards (to avoid the menu)
32 // when the toolbar style is OMNIBOX_TABS_HIDDEN. (We can't use 28 // when the toolbar style is OMNIBOX_TABS_HIDDEN. (We can't use
33 // |-[NSMenu menuBarHeight]| since it returns 0 when the menu bar is hidden.) 29 // |-[NSMenu menuBarHeight]| since it returns 0 when the menu bar is hidden.)
34 const CGFloat kToolbarVerticalOffset = 22; 30 const CGFloat kToolbarVerticalOffset = 22;
35 31
36 } // end namespace 32 } // end namespace
37 33
38 @interface FullscreenToolbarController (PrivateMethods) 34 @interface FullscreenToolbarController (PrivateMethods)
39 35
40 // Updates the visibility of the menu bar and the dock. 36 // Updates the visibility of the menu bar and the dock.
41 - (void)updateMenuBarAndDockVisibility; 37 - (void)updateMenuBarAndDockVisibility;
42 38
43 // Methods to set up or remove the tracking area.
44 - (void)updateTrackingArea;
45 - (void)removeTrackingAreaIfNecessary;
46
47 // Returns YES if the mouse is inside the tracking area.
48 - (BOOL)mouseInsideTrackingArea;
49
50 // Whether the current screen is expected to have a menu bar, regardless of 39 // Whether the current screen is expected to have a menu bar, regardless of
51 // current visibility of the menu bar. 40 // current visibility of the menu bar.
52 - (BOOL)doesScreenHaveMenuBar; 41 - (BOOL)doesScreenHaveMenuBar;
53 42
54 // Returns YES if the window is on the primary screen. 43 // Returns YES if the window is on the primary screen.
55 - (BOOL)isWindowOnPrimaryScreen; 44 - (BOOL)isWindowOnPrimaryScreen;
56 45
57 // Returns |kFullScreenModeHideAll| when the overlay is hidden and 46 // Returns |kFullScreenModeHideAll| when the overlay is hidden and
58 // |kFullScreenModeHideDock| when the overlay is shown. 47 // |kFullScreenModeHideDock| when the overlay is shown.
59 - (base::mac::FullScreenMode)desiredSystemFullscreenMode; 48 - (base::mac::FullScreenMode)desiredSystemFullscreenMode;
(...skipping 21 matching lines...) Expand all
81 } 70 }
82 71
83 return self; 72 return self;
84 } 73 }
85 74
86 - (void)dealloc { 75 - (void)dealloc {
87 DCHECK(!inFullscreenMode_); 76 DCHECK(!inFullscreenMode_);
88 [super dealloc]; 77 [super dealloc];
89 } 78 }
90 79
91 - (void)setupFullscreenToolbarForContentView:(NSView*)contentView { 80 - (void)enterFullscreenMode {
92 DCHECK(!inFullscreenMode_); 81 DCHECK(!inFullscreenMode_);
93 contentView_ = contentView;
94 inFullscreenMode_ = YES; 82 inFullscreenMode_ = YES;
95 83
96 menubarTracker_.reset([[FullscreenMenubarTracker alloc] 84 menubarTracker_.reset([[FullscreenMenubarTracker alloc]
97 initWithFullscreenToolbarController:self]); 85 initWithFullscreenToolbarController:self]);
86 mouseTracker_.reset([[FullscreenToolbarMouseTracker alloc]
87 initWithFullscreenToolbarController:self
88 animationController:animationController_.get()]);
98 89
99 [self updateMenuBarAndDockVisibility]; 90 [self updateMenuBarAndDockVisibility];
100 91
101 // Register for notifications. Self is removed as an observer in |-cleanup|. 92 // Register for notifications. Self is removed as an observer in |-cleanup|.
102 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; 93 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
103 NSWindow* window = [browserController_ window]; 94 NSWindow* window = [browserController_ window];
104 95
105 [nc addObserver:self 96 [nc addObserver:self
106 selector:@selector(windowDidBecomeMain:) 97 selector:@selector(windowDidBecomeMain:)
107 name:NSWindowDidBecomeMainNotification 98 name:NSWindowDidBecomeMainNotification
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 return; 154 return;
164 if (systemFullscreenMode_ == base::mac::kFullScreenModeNormal) 155 if (systemFullscreenMode_ == base::mac::kFullScreenModeNormal)
165 base::mac::RequestFullScreen(mode); 156 base::mac::RequestFullScreen(mode);
166 else if (mode == base::mac::kFullScreenModeNormal) 157 else if (mode == base::mac::kFullScreenModeNormal)
167 base::mac::ReleaseFullScreen(systemFullscreenMode_); 158 base::mac::ReleaseFullScreen(systemFullscreenMode_);
168 else 159 else
169 base::mac::SwitchFullScreenModes(systemFullscreenMode_, mode); 160 base::mac::SwitchFullScreenModes(systemFullscreenMode_, mode);
170 systemFullscreenMode_ = mode; 161 systemFullscreenMode_ = mode;
171 } 162 }
172 163
173 - (void)mouseEntered:(NSEvent*)event {
174 // Empty implementation. Required for CrTrackingArea.
175 }
176
177 - (void)mouseExited:(NSEvent*)event {
178 DCHECK(inFullscreenMode_);
179 DCHECK_EQ([event trackingArea], trackingArea_.get());
180
181 if ([browserController_ isBarVisibilityLockedForOwner:nil])
182 return;
183
184 // If the menubar is gone, animate the toolbar out.
185 if ([menubarTracker_ state] == FullscreenMenubarState::HIDDEN)
186 [self ensureOverlayHiddenWithAnimation:YES];
187
188 [self removeTrackingAreaIfNecessary];
189 }
190
191 - (void)updateToolbar { 164 - (void)updateToolbar {
192 [browserController_ layoutSubviews]; 165 [browserController_ layoutSubviews];
193 [self updateTrackingArea];
194 animationController_->ToolbarDidUpdate(); 166 animationController_->ToolbarDidUpdate();
167 [mouseTracker_ updateTrackingArea];
195 168
196 // In AppKit fullscreen, moving the mouse to the top of the screen toggles 169 // In AppKit fullscreen, moving the mouse to the top of the screen toggles
197 // menu visibility. Replicate the same effect for immersive fullscreen. 170 // menu visibility. Replicate the same effect for immersive fullscreen.
198 if ([browserController_ isInImmersiveFullscreen]) 171 if ([browserController_ isInImmersiveFullscreen])
199 [self updateMenuBarAndDockVisibility]; 172 [self updateMenuBarAndDockVisibility];
200 } 173 }
201 174
202 - (BrowserWindowController*)browserWindowController { 175 - (BrowserWindowController*)browserWindowController {
203 return browserController_; 176 return browserController_;
204 } 177 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 return NO; 222 return NO;
250 223
251 if (slidingStyle_ == FullscreenSlidingStyle::OMNIBOX_TABS_PRESENT) 224 if (slidingStyle_ == FullscreenSlidingStyle::OMNIBOX_TABS_PRESENT)
252 return YES; 225 return YES;
253 226
254 if (slidingStyle_ == FullscreenSlidingStyle::OMNIBOX_TABS_NONE) 227 if (slidingStyle_ == FullscreenSlidingStyle::OMNIBOX_TABS_NONE)
255 return NO; 228 return NO;
256 229
257 FullscreenMenubarState menubarState = [menubarTracker_ state]; 230 FullscreenMenubarState menubarState = [menubarTracker_ state];
258 return menubarState == FullscreenMenubarState::SHOWN || 231 return menubarState == FullscreenMenubarState::SHOWN ||
259 [self mouseInsideTrackingArea] || 232 [mouseTracker_ mouseInsideTrackingArea] ||
260 [browserController_ isBarVisibilityLockedForOwner:nil]; 233 [browserController_ isBarVisibilityLockedForOwner:nil];
261 } 234 }
262 235
263 - (BOOL)isFullscreenTransitionInProgress { 236 - (BOOL)isFullscreenTransitionInProgress {
264 return [browserController_ isFullscreenTransitionInProgress]; 237 return [browserController_ isFullscreenTransitionInProgress];
265 } 238 }
266 239
267 - (BOOL)isInFullscreen { 240 - (BOOL)isInFullscreen {
268 return inFullscreenMode_; 241 return inFullscreenMode_;
269 } 242 }
270 243
271 - (BOOL)isMouseOnScreen { 244 - (BOOL)isMouseOnScreen {
272 return NSMouseInRect([NSEvent mouseLocation], 245 return NSMouseInRect([NSEvent mouseLocation],
273 [[browserController_ window] screen].frame, false); 246 [[browserController_ window] screen].frame, false);
274 } 247 }
275 248
276 - (void)setTrackingAreaFromOverlayFrame:(NSRect)frame { 249 - (void)updateToolbarFrame:(NSRect)frame {
277 NSRect contentBounds = [contentView_ bounds]; 250 if (mouseTracker_.get())
278 trackingAreaFrame_ = frame; 251 [mouseTracker_ updateToolbarFrame:frame];
279 trackingAreaFrame_.origin.y -= kTrackingAreaAdditionalThreshold;
280 trackingAreaFrame_.size.height =
281 NSMaxY(contentBounds) - trackingAreaFrame_.origin.y;
282 } 252 }
283 253
284 @end 254 @end
285 255
286 @implementation FullscreenToolbarController (PrivateMethods) 256 @implementation FullscreenToolbarController (PrivateMethods)
287 257
288 - (void)updateMenuBarAndDockVisibility { 258 - (void)updateMenuBarAndDockVisibility {
289 if (![self isMouseOnScreen] || 259 if (![self isMouseOnScreen] ||
290 ![browserController_ isInImmersiveFullscreen]) { 260 ![browserController_ isInImmersiveFullscreen]) {
291 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeNormal]; 261 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeNormal];
292 return; 262 return;
293 } 263 }
294 264
295 // The screen does not have a menu bar, so there's no need to hide it. 265 // The screen does not have a menu bar, so there's no need to hide it.
296 if (![self doesScreenHaveMenuBar]) { 266 if (![self doesScreenHaveMenuBar]) {
297 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeHideDock]; 267 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeHideDock];
298 return; 268 return;
299 } 269 }
300 270
301 [self setSystemFullscreenModeTo:[self desiredSystemFullscreenMode]]; 271 [self setSystemFullscreenModeTo:[self desiredSystemFullscreenMode]];
302 } 272 }
303 273
304 - (void)updateTrackingArea {
305 // Remove the tracking area if the toolbar isn't fully shown.
306 if (!ui::IsCGFloatEqual([self toolbarFraction], kShowFraction)) {
307 [self removeTrackingAreaIfNecessary];
308 return;
309 }
310
311 if (trackingArea_) {
312 // If the tracking rectangle is already |trackingAreaBounds_|, quit early.
313 NSRect oldRect = [trackingArea_ rect];
314 if (NSEqualRects(trackingAreaFrame_, oldRect))
315 return;
316
317 // Otherwise, remove it.
318 [self removeTrackingAreaIfNecessary];
319 }
320
321 // Create and add a new tracking area for |frame|.
322 trackingArea_.reset([[CrTrackingArea alloc]
323 initWithRect:trackingAreaFrame_
324 options:NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow
325 owner:self
326 userInfo:nil]);
327 DCHECK(contentView_);
328 [contentView_ addTrackingArea:trackingArea_];
329 }
330
331 - (void)removeTrackingAreaIfNecessary {
332 if (trackingArea_) {
333 DCHECK(contentView_); // |contentView_| better be valid.
334 [contentView_ removeTrackingArea:trackingArea_];
335 trackingArea_.reset();
336 }
337 }
338
339 - (BOOL)mouseInsideTrackingArea {
340 if (!trackingArea_)
341 return NO;
342
343 NSWindow* window = [browserController_ window];
344 NSPoint mouseLoc = [window mouseLocationOutsideOfEventStream];
345 NSPoint mousePos = [contentView_ convertPoint:mouseLoc fromView:nil];
346 return NSMouseInRect(mousePos, trackingAreaFrame_, [contentView_ isFlipped]);
347 }
348
349 - (BOOL)doesScreenHaveMenuBar { 274 - (BOOL)doesScreenHaveMenuBar {
350 if (![[NSScreen class] 275 if (![[NSScreen class]
351 respondsToSelector:@selector(screensHaveSeparateSpaces)]) 276 respondsToSelector:@selector(screensHaveSeparateSpaces)])
352 return [self isWindowOnPrimaryScreen]; 277 return [self isWindowOnPrimaryScreen];
353 278
354 BOOL eachScreenShouldHaveMenuBar = [NSScreen screensHaveSeparateSpaces]; 279 BOOL eachScreenShouldHaveMenuBar = [NSScreen screensHaveSeparateSpaces];
355 return eachScreenShouldHaveMenuBar ?: [self isWindowOnPrimaryScreen]; 280 return eachScreenShouldHaveMenuBar ?: [self isWindowOnPrimaryScreen];
356 } 281 }
357 282
358 - (BOOL)isWindowOnPrimaryScreen { 283 - (BOOL)isWindowOnPrimaryScreen {
359 NSScreen* screen = [[browserController_ window] screen]; 284 NSScreen* screen = [[browserController_ window] screen];
360 NSScreen* primaryScreen = [[NSScreen screens] firstObject]; 285 NSScreen* primaryScreen = [[NSScreen screens] firstObject];
361 return (screen == primaryScreen); 286 return (screen == primaryScreen);
362 } 287 }
363 288
364 - (base::mac::FullScreenMode)desiredSystemFullscreenMode { 289 - (base::mac::FullScreenMode)desiredSystemFullscreenMode {
365 if ([self shouldShowMenubarInImmersiveFullscreen]) 290 if ([self shouldShowMenubarInImmersiveFullscreen])
366 return base::mac::kFullScreenModeHideDock; 291 return base::mac::kFullScreenModeHideDock;
367 return base::mac::kFullScreenModeHideAll; 292 return base::mac::kFullScreenModeHideAll;
368 } 293 }
369 294
370 - (void)cleanup { 295 - (void)cleanup {
371 animationController_->StopAnimationAndTimer(); 296 animationController_->StopAnimationAndTimer();
372 [[NSNotificationCenter defaultCenter] removeObserver:self]; 297 [[NSNotificationCenter defaultCenter] removeObserver:self];
373 298
374 [self removeTrackingAreaIfNecessary];
375
376 // Call the main status resignation code to perform the associated cleanup, 299 // Call the main status resignation code to perform the associated cleanup,
377 // since we will no longer be receiving actual status resignation 300 // since we will no longer be receiving actual status resignation
378 // notifications. 301 // notifications.
379 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeNormal]; 302 [self setSystemFullscreenModeTo:base::mac::kFullScreenModeNormal];
380 303
381 menubarTracker_.reset(); 304 menubarTracker_.reset();
305 mouseTracker_.reset();
382 306
383 // No more calls back up to the BWC. 307 // No more calls back up to the BWC.
384 browserController_ = nil; 308 browserController_ = nil;
385 } 309 }
386 310
387 - (BOOL)shouldShowMenubarInImmersiveFullscreen { 311 - (BOOL)shouldShowMenubarInImmersiveFullscreen {
388 return [self doesScreenHaveMenuBar] && [self toolbarFraction] > 0.99; 312 return [self doesScreenHaveMenuBar] && [self toolbarFraction] > 0.99;
389 } 313 }
390 314
391 @end 315 @end
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/fullscreen_toolbar_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698