Index: chrome/browser/ui/cocoa/fullscreen/fullscreen_toolbar_mouse_tracker.mm |
diff --git a/chrome/browser/ui/cocoa/fullscreen/fullscreen_toolbar_mouse_tracker.mm b/chrome/browser/ui/cocoa/fullscreen/fullscreen_toolbar_mouse_tracker.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..98c0372068212217a4e9052e1520414245a77028 |
--- /dev/null |
+++ b/chrome/browser/ui/cocoa/fullscreen/fullscreen_toolbar_mouse_tracker.mm |
@@ -0,0 +1,130 @@ |
+// 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_toolbar_mouse_tracker.h" |
+ |
+#include "chrome/browser/ui/cocoa/fullscreen/fullscreen_toolbar_animation_manager.h" |
+#import "chrome/browser/ui/cocoa/fullscreen/fullscreen_toolbar_layout_manager.h" |
+#import "ui/base/cocoa/tracking_area.h" |
+ |
+namespace { |
+ |
+// Additional height threshold added at the toolbar's bottom. This is to mimic |
+// threshold the mouse position needs to be at before the menubar automatically |
+// hides. |
+const CGFloat kTrackingAreaAdditionalThreshold = 20; |
+ |
+} // namespace |
+ |
+@interface FullscreenToolbarMouseTracker () { |
+ // The frame for the tracking area. The value is the toolbar overlay's frame |
+ // with additional height added at the bottom. |
+ NSRect trackingAreaFrame_; |
+ |
+ // The tracking area associated with the toolbar overlay bar. This tracking |
+ // area is used to keep the toolbar active if the menubar had animated out |
+ // but the mouse is still on the toolbar. |
+ base::scoped_nsobject<CrTrackingArea> trackingArea_; |
+ |
+ // The content view for the window. |
+ NSView* contentView_; // weak |
+ |
+ // The owner of this class. |
+ FullscreenToolbarLayoutManager* owner_; // weak |
+ |
+ // The object managing the fullscreen toolbar's animations. |
+ FullscreenToolbarAnimationManager* animationManager_; // weak |
+} |
+ |
+@end |
+ |
+@implementation FullscreenToolbarMouseTracker |
+ |
+- (id)initWithFullscreenToolbarLayoutManager: |
+ (FullscreenToolbarLayoutManager*)owner |
+ toolbarAnimationManager: |
+ (FullscreenToolbarAnimationManager*)animationManager { |
+ if ((self = [super init])) { |
+ owner_ = owner; |
+ contentView_ = [[owner_->browser_window_controller() window] contentView]; |
+ animationManager_ = animationManager; |
+ } |
+ |
+ return self; |
+} |
+ |
+- (void)dealloc { |
+ [self removeTrackingArea]; |
+ [super dealloc]; |
+} |
+ |
+- (void)updateTrackingArea { |
+ // Remove the tracking area if the toolbar isn't fully shown. |
+ FullscreenToolbarLayout layout = owner_->ComputeToolbarLayout(); |
+ if (!base::mac::IsCGFloatEqual(layout.toolbarFraction, 1.0)) { |
+ [self removeTrackingArea]; |
+ return; |
+ } |
+ |
+ if (trackingArea_) { |
+ // If the tracking rectangle is already |trackingAreaBounds_|, quit early. |
+ NSRect oldRect = [trackingArea_ rect]; |
+ if (NSEqualRects(trackingAreaFrame_, oldRect)) |
+ return; |
+ |
+ [self removeTrackingArea]; |
+ } |
+ |
+ // Create and add a new tracking area for |frame|. |
+ trackingArea_.reset([[CrTrackingArea alloc] |
+ initWithRect:trackingAreaFrame_ |
+ options:NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow |
+ owner:self |
+ userInfo:nil]); |
+ DCHECK(contentView_); |
+ [contentView_ addTrackingArea:trackingArea_]; |
+} |
+ |
+- (void)updateToolbarFrame:(NSRect)frame { |
+ NSRect contentBounds = [contentView_ bounds]; |
+ trackingAreaFrame_ = frame; |
+ trackingAreaFrame_.origin.y -= kTrackingAreaAdditionalThreshold; |
+ trackingAreaFrame_.size.height = |
+ NSMaxY(contentBounds) - trackingAreaFrame_.origin.y; |
+ |
+ [self updateTrackingArea]; |
+} |
+ |
+- (void)removeTrackingArea { |
+ if (!trackingArea_) |
+ return; |
+ |
+ DCHECK(contentView_); |
+ [contentView_ removeTrackingArea:trackingArea_]; |
+ trackingArea_.reset(); |
+} |
+ |
+- (BOOL)mouseInsideTrackingArea { |
+ if (!trackingArea_) |
+ return NO; |
+ |
+ NSPoint mouseLoc = [[contentView_ window] mouseLocationOutsideOfEventStream]; |
+ NSPoint mousePos = [contentView_ convertPoint:mouseLoc fromView:nil]; |
+ return NSMouseInRect(mousePos, trackingAreaFrame_, [contentView_ isFlipped]); |
+} |
+ |
+- (void)mouseEntered:(NSEvent*)event { |
+ // Empty implementation. Required for CrTrackingArea. |
+} |
+ |
+- (void)mouseExited:(NSEvent*)event { |
+ DCHECK_EQ([event trackingArea], trackingArea_.get()); |
+ |
+ animationManager_->AnimateToolbarOutIfPossible(); |
+ |
+ owner_->Layout(); |
+ [self removeTrackingArea]; |
+} |
+ |
+@end |