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

Side by Side Diff: ui/base/cocoa/hover_button.mm

Issue 2898343002: [Mac] Update tab close button when user drags outside (Closed)
Patch Set: Created 3 years, 6 months 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 | « ui/base/cocoa/hover_button.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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "ui/base/cocoa/hover_button.h" 5 #import "ui/base/cocoa/hover_button.h"
6 6
7 @implementation HoverButton 7 @implementation HoverButton
8 8
9 @synthesize hoverState = hoverState_; 9 @synthesize hoverState = hoverState_;
10 10
11 - (id)initWithFrame:(NSRect)frameRect { 11 - (id)initWithFrame:(NSRect)frameRect {
12 if ((self = [super initWithFrame:frameRect])) { 12 if ((self = [super initWithFrame:frameRect])) {
13 [self setTrackingEnabled:YES]; 13 [self commonInit];
14 hoverState_ = kHoverStateNone;
15 [self updateTrackingAreas];
16 } 14 }
17 return self; 15 return self;
18 } 16 }
19 17
20 - (void)awakeFromNib { 18 - (void)awakeFromNib {
19 [self commonInit];
20 }
21
22 - (void)commonInit {
21 [self setTrackingEnabled:YES]; 23 [self setTrackingEnabled:YES];
22 self.hoverState = kHoverStateNone; 24 self.hoverState = kHoverStateNone;
23 [self updateTrackingAreas]; 25 [self updateTrackingAreas];
24 } 26 }
25 27
26 - (void)dealloc { 28 - (void)dealloc {
27 [self setTrackingEnabled:NO]; 29 [self setTrackingEnabled:NO];
28 [super dealloc]; 30 [super dealloc];
29 } 31 }
30 32
31 - (void)mouseEntered:(NSEvent*)theEvent { 33 - (void)mouseEntered:(NSEvent*)theEvent {
32 if (trackingArea_.get()) 34 if (trackingArea_.get())
33 self.hoverState = kHoverStateMouseOver; 35 self.hoverState = kHoverStateMouseOver;
34 } 36 }
35 37
38 - (void)mouseMoved:(NSEvent*)theEvent {
39 [self checkImageState];
40 }
41
36 - (void)mouseExited:(NSEvent*)theEvent { 42 - (void)mouseExited:(NSEvent*)theEvent {
37 if (trackingArea_.get()) 43 if (trackingArea_.get())
38 self.hoverState = kHoverStateNone; 44 self.hoverState = kHoverStateNone;
39 } 45 }
40 46
41 - (void)mouseMoved:(NSEvent*)theEvent { 47 - (void)mouseDown:(NSEvent*)theEvent {
42 [self checkImageState]; 48 mouseDown_ = YES;
43 } 49 self.hoverState = kHoverStateMouseDown;
44 50
45 - (void)mouseDown:(NSEvent*)theEvent { 51 // Begin tracking the mouse.
46 self.hoverState = kHoverStateMouseDown; 52 if ([theEvent type] == NSLeftMouseDown) {
47 // The hover button needs to hold onto itself here for a bit. Otherwise, 53 NSWindow* window = [self window];
48 // it can be freed while |super mouseDown:| is in its loop, and the 54 NSEvent* nextEvent = nil;
49 // |checkImageState| call will crash.
50 // http://crbug.com/28220
Avi (use Gerrit) 2017/05/25 03:59:54 The crash in this bug seems plausible with your ne
shrike 2017/05/25 17:07:22 The comment says that the button can get freed wit
Avi (use Gerrit) 2017/05/25 18:24:23 Right, but this moves the functionality of [super
shrike 2017/05/25 18:31:00 I see. I thought the issue was what was happening
51 base::scoped_nsobject<HoverButton> myself([self retain]);
52 55
53 [super mouseDown:theEvent]; 56 while ((nextEvent = [window
54 // We need to check the image state after the mouseDown event loop finishes. 57 nextEventMatchingMask:(NSLeftMouseDraggedMask |
55 // It's possible that we won't get a mouseExited event if the button was 58 NSLeftMouseUpMask | NSKeyDownMask)])) {
56 // moved under the mouse during tab resize, instead of the mouse moving over 59 // Update the image state, which will change if the user moves the mouse
57 // the button. 60 // into or out of the button.
58 // http://crbug.com/31279 61 [self checkImageState];
59 [self checkImageState]; 62
63 if ([nextEvent type] == NSLeftMouseUp) {
64 break;
65 }
66 }
67 }
68
69 // If the mouse is still over the button, it means the user clicked the
70 // button.
71 if (self.hoverState == kHoverStateMouseDown) {
72 [self performClick:nil];
73 }
74
75 // Clean up.
76 mouseDown_ = NO;
60 } 77 }
61 78
62 - (void)setAccessibilityTitle:(NSString*)accessibilityTitle { 79 - (void)setAccessibilityTitle:(NSString*)accessibilityTitle {
63 NSCell* cell = [self cell]; 80 NSCell* cell = [self cell];
64 [cell accessibilitySetOverrideValue:accessibilityTitle 81 [cell accessibilitySetOverrideValue:accessibilityTitle
65 forAttribute:NSAccessibilityTitleAttribute]; 82 forAttribute:NSAccessibilityTitleAttribute];
66 } 83 }
67 84
68 - (void)setTrackingEnabled:(BOOL)enabled { 85 - (void)setTrackingEnabled:(BOOL)enabled {
69 if (enabled) { 86 if (enabled) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 [self checkImageState]; 118 [self checkImageState];
102 } 119 }
103 120
104 - (void)checkImageState { 121 - (void)checkImageState {
105 if (!trackingArea_.get()) 122 if (!trackingArea_.get())
106 return; 123 return;
107 124
108 // Update the button's state if the button has moved. 125 // Update the button's state if the button has moved.
109 NSPoint mouseLoc = [[self window] mouseLocationOutsideOfEventStream]; 126 NSPoint mouseLoc = [[self window] mouseLocationOutsideOfEventStream];
110 mouseLoc = [self convertPoint:mouseLoc fromView:nil]; 127 mouseLoc = [self convertPoint:mouseLoc fromView:nil];
111 self.hoverState = NSPointInRect(mouseLoc, [self bounds]) ? 128 BOOL mouseInBounds = NSPointInRect(mouseLoc, [self bounds]);
112 kHoverStateMouseOver : kHoverStateNone; 129 if (mouseDown_ && mouseInBounds) {
130 self.hoverState = kHoverStateMouseDown;
131 } else {
132 self.hoverState = mouseInBounds ? kHoverStateMouseOver : kHoverStateNone;
133 }
113 } 134 }
114 135
115 - (void)setHoverState:(HoverState)state { 136 - (void)setHoverState:(HoverState)state {
116 BOOL stateChanged = (hoverState_ != state); 137 BOOL stateChanged = (hoverState_ != state);
117 hoverState_ = state; 138 hoverState_ = state;
118 [self setNeedsDisplay:stateChanged]; 139 [self setNeedsDisplay:stateChanged];
119 } 140 }
120 141
121 @end 142 @end
OLDNEW
« no previous file with comments | « ui/base/cocoa/hover_button.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698