OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include "ui/base/cocoa/base_view.h" | 5 #include "ui/base/cocoa/base_view.h" |
6 | 6 |
7 NSString* kViewDidBecomeFirstResponder = | 7 NSString* kViewDidBecomeFirstResponder = |
8 @"Chromium.kViewDidBecomeFirstResponder"; | 8 @"Chromium.kViewDidBecomeFirstResponder"; |
9 NSString* kSelectionDirection = @"Chromium.kSelectionDirection"; | 9 NSString* kSelectionDirection = @"Chromium.kSelectionDirection"; |
10 | 10 |
11 const int kTrackingOptions = NSTrackingMouseMoved | | 11 @implementation BaseView |
12 NSTrackingMouseEnteredAndExited | | |
13 NSTrackingActiveAlways; | |
14 | 12 |
15 @implementation BaseView | 13 - (instancetype)initWithFrame:(NSRect)frame |
14 wantsReliableMouseEvents:(BOOL)wantsReliableMouseEvents { | |
15 if ((self = [super initWithFrame:frame])) { | |
16 [self initBaseViewUsingEventTap:wantsReliableMouseEvents]; | |
17 } | |
18 return self; | |
19 } | |
20 | |
21 - (instancetype)initWithFrame:(NSRect)frame { | |
22 if ((self = [super initWithFrame:frame])) { | |
23 [self initBaseViewUsingEventTap:NO]; | |
24 } | |
25 return self; | |
26 } | |
27 | |
28 - (instancetype)initWithCoder:(NSCoder*)decoder { | |
29 if ((self = [super initWithCoder:decoder])) { | |
30 [self initBaseViewUsingEventTap:NO]; | |
31 } | |
32 return self; | |
33 } | |
34 | |
35 - (void)initBaseViewUsingEventTap:(BOOL)wantsReliableMouseEvents { | |
Scott Hess - ex-Googler
2015/02/27 17:56:11
IMHO this should not be called -init*, since the c
| |
36 NSTrackingAreaOptions trackingOptions = NSTrackingMouseEnteredAndExited | | |
37 NSTrackingActiveAlways | | |
38 NSTrackingInVisibleRect; | |
39 if (!wantsReliableMouseEvents) | |
40 trackingOptions |= NSTrackingMouseMoved; | |
Scott Hess - ex-Googler
2015/02/27 17:56:11
If this approach is sufficiently performant to use
| |
41 trackingArea_.reset([[CrTrackingArea alloc] initWithRect:NSZeroRect | |
42 options:trackingOptions | |
43 owner:self | |
44 userInfo:nil]); | |
45 [self addTrackingArea:trackingArea_.get()]; | |
46 | |
47 if (wantsReliableMouseEvents) { | |
48 // Workaround for http://crbug.com/176725 | |
49 // Check if the mouse moved over us. | |
50 // Don't do it if we are firstResponder to avoid processing the event twice. | |
51 eventTap_ = [NSEvent addLocalMonitorForEventsMatchingMask:NSMouseMovedMask | |
52 handler:^NSEvent*(NSEvent* event) { | |
53 NSWindow* window = [self window]; | |
54 if (window && window == [event window] && | |
55 [window firstResponder] != self) { | |
56 NSPoint location = | |
57 [[self superview] convertPoint:[event locationInWindow] | |
58 fromView:nil]; | |
59 if ([self hitTest:location]) | |
60 [self mouseMoved:event]; | |
61 } | |
62 return event; | |
63 }]; | |
64 } | |
65 } | |
16 | 66 |
17 - (void)dealloc { | 67 - (void)dealloc { |
18 if (trackingArea_.get()) | 68 if (trackingArea_.get()) |
19 [self removeTrackingArea:trackingArea_.get()]; | 69 [self removeTrackingArea:trackingArea_.get()]; |
20 trackingArea_.reset(nil); | 70 trackingArea_.reset(nil); |
21 | 71 |
72 if (eventTap_) | |
73 [NSEvent removeMonitor:eventTap_]; | |
74 | |
22 [super dealloc]; | 75 [super dealloc]; |
23 } | 76 } |
24 | 77 |
78 - (void)viewDidMoveToWindow { | |
79 [super viewDidMoveToWindow]; | |
80 | |
81 // Ensure our event tap gets mouse moved events. The mouse moved events are | |
82 // normally sent to the window's firstResponder (like key events, unlike | |
83 // other mouse events). | |
84 if (eventTap_) | |
85 [[self window] setAcceptsMouseMovedEvents:YES]; | |
86 } | |
87 | |
25 - (void)mouseEvent:(NSEvent*)theEvent { | 88 - (void)mouseEvent:(NSEvent*)theEvent { |
26 // This method left intentionally blank. | 89 // This method left intentionally blank. |
27 } | 90 } |
28 | 91 |
29 - (EventHandled)keyEvent:(NSEvent*)theEvent { | 92 - (EventHandled)keyEvent:(NSEvent*)theEvent { |
30 // The default implementation of this method does not handle any key events. | 93 // The default implementation of this method does not handle any key events. |
31 // Derived classes should return kEventHandled if they handled an event, | 94 // Derived classes should return kEventHandled if they handled an event, |
32 // otherwise it will be forwarded on to |super|. | 95 // otherwise it will be forwarded on to |super|. |
33 return kEventNotHandled; | 96 return kEventNotHandled; |
34 } | 97 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
131 new_rect.set_y(NSHeight([self bounds]) - new_rect.bottom()); | 194 new_rect.set_y(NSHeight([self bounds]) - new_rect.bottom()); |
132 return new_rect; | 195 return new_rect; |
133 } | 196 } |
134 | 197 |
135 - (NSRect)flipRectToNSRect:(gfx::Rect)rect { | 198 - (NSRect)flipRectToNSRect:(gfx::Rect)rect { |
136 NSRect new_rect(NSRectFromCGRect(rect.ToCGRect())); | 199 NSRect new_rect(NSRectFromCGRect(rect.ToCGRect())); |
137 new_rect.origin.y = NSHeight([self bounds]) - NSMaxY(new_rect); | 200 new_rect.origin.y = NSHeight([self bounds]) - NSMaxY(new_rect); |
138 return new_rect; | 201 return new_rect; |
139 } | 202 } |
140 | 203 |
141 - (void)updateTrackingAreas { | |
142 [super updateTrackingAreas]; | |
143 | |
144 // NSTrackingInVisibleRect doesn't work correctly with Lion's window resizing, | |
145 // http://crbug.com/176725 / http://openradar.appspot.com/radar?id=2773401 . | |
146 // Tear down old tracking area and create a new one as workaround. | |
147 if (trackingArea_.get()) | |
148 [self removeTrackingArea:trackingArea_.get()]; | |
149 trackingArea_.reset([[CrTrackingArea alloc] initWithRect:[self bounds] | |
150 options:kTrackingOptions | |
151 owner:self | |
152 userInfo:nil]); | |
153 [self addTrackingArea:trackingArea_.get()]; | |
154 } | |
155 | |
156 @end | 204 @end |
OLD | NEW |