Commit 40f734ce authored by shrike's avatar shrike Committed by Commit Bot

[Mac] Update tab close button when user drags outside

When clicking inside a button and dragging the mouse out of the button's
bounds, a button should update its appearance to show that its action
will not fire if the user releases the mouse. This cl fixes a problem
with the tab close button where it would always show the mouse down
state, even if you clicked and dragged outside of it.

This cl also does a little refactoring, moving common init-time code to
a commonInit method (like its HoverCloseButton subclass).

R=avi@chromium.org
BUG=647757

Review-Url: https://codereview.chromium.org/2898343002
Cr-Commit-Position: refs/heads/master@{#476463}
parent 165f26ee
......@@ -59,16 +59,18 @@ const SkColor kDefaultIconColor = SkColorSetARGB(0xA0, 0x00, 0x00, 0x00);
gTooltip = [l10n_util::GetNSStringWithFixup(IDS_TOOLTIP_CLOSE_TAB) copy];
}
- (id)initWithFrame:(NSRect)frameRect {
if ((self = [super initWithFrame:frameRect])) {
[self commonInit];
}
return self;
}
- (void)commonInit {
[super commonInit];
[self setAccessibilityTitle:nil];
// Add a tooltip. Using 'owner:self' means that
// -view:stringForToolTip:point:userData: will be called to provide the
// tooltip contents immediately before showing it.
[self addToolTipRect:[self bounds] owner:self userData:NULL];
- (void)awakeFromNib {
[super awakeFromNib];
[self commonInit];
previousState_ = kHoverStateNone;
iconColor_ = kDefaultIconColor;
}
- (void)removeFromSuperview {
......@@ -198,18 +200,6 @@ const SkColor kDefaultIconColor = SkColorSetARGB(0xA0, 0x00, 0x00, 0x00);
}
}
- (void)commonInit {
[self setAccessibilityTitle:nil];
// Add a tooltip. Using 'owner:self' means that
// -view:stringForToolTip:point:userData: will be called to provide the
// tooltip contents immediately before showing it.
[self addToolTipRect:[self bounds] owner:self userData:NULL];
previousState_ = kHoverStateNone;
iconColor_ = kDefaultIconColor;
}
// Called each time a tooltip is about to be shown.
- (NSString*)view:(NSView*)view
stringForToolTip:(NSToolTipTag)tag
......
......@@ -27,10 +27,15 @@ UI_BASE_EXPORT
@private
// Tracking area for button mouseover states. Nil if not enabled.
ui::ScopedCrTrackingArea trackingArea_;
BOOL mouseDown_;
}
@property(nonatomic) HoverState hoverState;
// Common initialization called from initWithFrame: and awakeFromNib.
// Subclassers should call [super commonInit].
- (void)commonInit;
// Text that would be announced by screen readers.
- (void)setAccessibilityTitle:(NSString*)accessibilityTitle;
......
......@@ -10,14 +10,16 @@
- (id)initWithFrame:(NSRect)frameRect {
if ((self = [super initWithFrame:frameRect])) {
[self setTrackingEnabled:YES];
hoverState_ = kHoverStateNone;
[self updateTrackingAreas];
[self commonInit];
}
return self;
}
- (void)awakeFromNib {
[self commonInit];
}
- (void)commonInit {
[self setTrackingEnabled:YES];
self.hoverState = kHoverStateNone;
[self updateTrackingAreas];
......@@ -33,30 +35,53 @@
self.hoverState = kHoverStateMouseOver;
}
- (void)mouseMoved:(NSEvent*)theEvent {
[self checkImageState];
}
- (void)mouseExited:(NSEvent*)theEvent {
if (trackingArea_.get())
self.hoverState = kHoverStateNone;
}
- (void)mouseMoved:(NSEvent*)theEvent {
[self checkImageState];
}
- (void)mouseDown:(NSEvent*)theEvent {
mouseDown_ = YES;
self.hoverState = kHoverStateMouseDown;
// The hover button needs to hold onto itself here for a bit. Otherwise,
// it can be freed while |super mouseDown:| is in its loop, and the
// |checkImageState| call will crash.
// it can be freed while in the tracking loop below.
// http://crbug.com/28220
base::scoped_nsobject<HoverButton> myself([self retain]);
[super mouseDown:theEvent];
// We need to check the image state after the mouseDown event loop finishes.
// It's possible that we won't get a mouseExited event if the button was
// moved under the mouse during tab resize, instead of the mouse moving over
// the button.
// http://crbug.com/31279
// Begin tracking the mouse.
if ([theEvent type] == NSLeftMouseDown) {
NSWindow* window = [self window];
NSEvent* nextEvent = nil;
// For the tracking loop ignore key events so that they don't pile up in
// the queue and get processed after the user releases the mouse.
const NSEventMask eventMask = (NSLeftMouseDraggedMask | NSLeftMouseUpMask |
NSKeyDownMask | NSKeyUpMask);
while ((nextEvent = [window nextEventMatchingMask:eventMask])) {
// Update the image state, which will change if the user moves the mouse
// into or out of the button.
[self checkImageState];
if ([nextEvent type] == NSLeftMouseUp) {
break;
}
}
}
// If the mouse is still over the button, it means the user clicked the
// button.
if (self.hoverState == kHoverStateMouseDown) {
[self performClick:nil];
}
// Clean up.
mouseDown_ = NO;
}
- (void)setAccessibilityTitle:(NSString*)accessibilityTitle {
......@@ -108,8 +133,12 @@
// Update the button's state if the button has moved.
NSPoint mouseLoc = [[self window] mouseLocationOutsideOfEventStream];
mouseLoc = [self convertPoint:mouseLoc fromView:nil];
self.hoverState = NSPointInRect(mouseLoc, [self bounds]) ?
kHoverStateMouseOver : kHoverStateNone;
BOOL mouseInBounds = NSPointInRect(mouseLoc, [self bounds]);
if (mouseDown_ && mouseInBounds) {
self.hoverState = kHoverStateMouseDown;
} else {
self.hoverState = mouseInBounds ? kHoverStateMouseOver : kHoverStateNone;
}
}
- (void)setHoverState:(HoverState)state {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment