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

Side by Side Diff: components/mus/ws/event_dispatcher.cc

Issue 1425123002: Makes event dispatch implicitly target specific window until release (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cleanup Created 5 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 | « components/mus/ws/event_dispatcher.h ('k') | components/mus/ws/event_dispatcher_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "components/mus/ws/event_dispatcher.h" 5 #include "components/mus/ws/event_dispatcher.h"
6 6
7 #include <set>
8
7 #include "cc/surfaces/surface_hittest.h" 9 #include "cc/surfaces/surface_hittest.h"
8 #include "components/mus/surfaces/surfaces_state.h" 10 #include "components/mus/surfaces/surfaces_state.h"
9 #include "components/mus/ws/event_dispatcher_delegate.h" 11 #include "components/mus/ws/event_dispatcher_delegate.h"
10 #include "components/mus/ws/server_window.h" 12 #include "components/mus/ws/server_window.h"
11 #include "components/mus/ws/server_window_delegate.h" 13 #include "components/mus/ws/server_window_delegate.h"
12 #include "components/mus/ws/window_coordinate_conversions.h" 14 #include "components/mus/ws/window_coordinate_conversions.h"
13 #include "components/mus/ws/window_finder.h" 15 #include "components/mus/ws/window_finder.h"
14 #include "components/mus/ws/window_tree_host_impl.h" 16 #include "components/mus/ws/window_tree_host_impl.h"
15 #include "mojo/converters/geometry/geometry_type_converters.h" 17 #include "mojo/converters/geometry/geometry_type_converters.h"
16 #include "ui/gfx/geometry/point.h" 18 #include "ui/gfx/geometry/point.h"
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 mojo::EventType event_type_; 136 mojo::EventType event_type_;
135 mojo::EventFlags event_flags_; 137 mojo::EventFlags event_flags_;
136 mojo::KeyboardCode keyboard_code_; 138 mojo::KeyboardCode keyboard_code_;
137 mojo::PointerKind pointer_kind_; 139 mojo::PointerKind pointer_kind_;
138 gfx::RectF pointer_region_; 140 gfx::RectF pointer_region_;
139 }; 141 };
140 142
141 //////////////////////////////////////////////////////////////////////////////// 143 ////////////////////////////////////////////////////////////////////////////////
142 144
143 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) 145 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate)
144 : delegate_(delegate), 146 : delegate_(delegate), root_(nullptr) {}
145 root_(nullptr),
146 capture_window_(nullptr),
147 capture_in_nonclient_area_(false) {}
148 147
149 EventDispatcher::~EventDispatcher() {} 148 EventDispatcher::~EventDispatcher() {
149 std::set<ServerWindow*> pointer_targets;
150 for (const auto& pair : pointer_targets_) {
151 if (pair.second.window &&
152 pointer_targets.insert(pair.second.window).second) {
153 pair.second.window->RemoveObserver(this);
154 }
155 }
156 }
150 157
151 void EventDispatcher::AddAccelerator(uint32_t id, 158 void EventDispatcher::AddAccelerator(uint32_t id,
152 mojo::EventMatcherPtr event_matcher) { 159 mojo::EventMatcherPtr event_matcher) {
153 EventMatcher matcher(*event_matcher); 160 EventMatcher matcher(*event_matcher);
154 #if !defined(NDEBUG) 161 #if !defined(NDEBUG)
155 for (const auto& pair : accelerators_) { 162 for (const auto& pair : accelerators_) {
156 DCHECK_NE(pair.first, id); 163 DCHECK_NE(pair.first, id);
157 DCHECK(!matcher.Equals(pair.second)); 164 DCHECK(!matcher.Equals(pair.second));
158 } 165 }
159 #endif 166 #endif
(...skipping 12 matching lines...) Expand all
172 179
173 if (event->action == mojo::EVENT_TYPE_KEY_PRESSED && 180 if (event->action == mojo::EVENT_TYPE_KEY_PRESSED &&
174 !event->key_data->is_char) { 181 !event->key_data->is_char) {
175 uint32_t accelerator = 0u; 182 uint32_t accelerator = 0u;
176 if (FindAccelerator(*event, &accelerator)) { 183 if (FindAccelerator(*event, &accelerator)) {
177 delegate_->OnAccelerator(accelerator, event.Pass()); 184 delegate_->OnAccelerator(accelerator, event.Pass());
178 return; 185 return;
179 } 186 }
180 } 187 }
181 188
182 ServerWindow* target = FindEventTarget(event.get()); 189 if (event->key_data) {
183 bool in_nonclient_area = false; 190 ProcessKeyEvent(event.Pass());
184 191 return;
185 if (IsMouseEventFlag(event->flags)) {
186 if (!capture_window_ && target &&
187 (event->action == mojo::EVENT_TYPE_POINTER_DOWN)) {
188 // TODO(sky): |capture_window_| needs to be reset when window removed
189 // from hierarchy.
190 capture_window_ = target;
191 // TODO(sky): this needs to happen for pointer down events too.
192 capture_in_nonclient_area_ =
193 IsLocationInNonclientArea(target, EventLocationToPoint(*event));
194 in_nonclient_area = capture_in_nonclient_area_;
195 } else if (event->action == mojo::EVENT_TYPE_POINTER_UP &&
196 IsOnlyOneMouseButtonDown(event->flags)) {
197 capture_window_ = nullptr;
198 }
199 in_nonclient_area = capture_in_nonclient_area_;
200 } 192 }
201 193
202 if (target) { 194 if (event->pointer_data.get()) {
203 if (event->action == mojo::EVENT_TYPE_POINTER_DOWN) 195 ProcessPointerEvent(event.Pass());
196 return;
197 }
198
199 NOTREACHED();
200 }
201
202 void EventDispatcher::ProcessKeyEvent(mojo::EventPtr event) {
203 ServerWindow* focused_window =
204 delegate_->GetFocusedWindowForEventDispatcher();
205 if (focused_window)
206 delegate_->DispatchInputEventToWindow(focused_window, false, event.Pass());
207 }
208
209 void EventDispatcher::ProcessPointerEvent(mojo::EventPtr event) {
210 const int32_t pointer_id = event->pointer_data->pointer_id;
211 if (event->action == mojo::EVENT_TYPE_WHEEL ||
212 (event->action == mojo::EVENT_TYPE_POINTER_MOVE &&
213 pointer_targets_.count(pointer_id) == 0)) {
214 PointerTarget pointer_target;
215 if (pointer_targets_.count(pointer_id) != 0) {
216 pointer_target = pointer_targets_[pointer_id];
217 } else {
218 gfx::Point location(EventLocationToPoint(*event));
219 pointer_target.window =
220 FindDeepestVisibleWindow(root_, surface_id_, &location);
221 }
222 DispatchToPointerTarget(pointer_target, event.Pass());
223 return;
224 }
225
226 // Pointer down implicitly captures.
227 if (pointer_targets_.count(pointer_id) == 0) {
228 DCHECK(event->action == mojo::EVENT_TYPE_POINTER_DOWN);
229 const bool is_first_pointer_down = pointer_targets_.empty();
230 gfx::Point location(EventLocationToPoint(*event));
231 ServerWindow* target =
232 FindDeepestVisibleWindow(root_, surface_id_, &location);
233 DCHECK(target);
234 if (!IsSendingPointerEventsToTarget(target))
235 target->AddObserver(this);
236
237 pointer_targets_[pointer_id].window = target;
238 pointer_targets_[pointer_id].in_nonclient_area =
239 IsLocationInNonclientArea(target, location);
240
241 if (is_first_pointer_down)
204 delegate_->SetFocusedWindowFromEventDispatcher(target); 242 delegate_->SetFocusedWindowFromEventDispatcher(target);
243 }
205 244
206 delegate_->DispatchInputEventToWindow(target, in_nonclient_area, 245 // Release capture on pointer up. For mouse we only release if there are
207 event.Pass()); 246 // no buttons down.
247 const bool should_reset_target =
248 (event->action == mojo::EVENT_TYPE_POINTER_UP ||
249 event->action == mojo::EVENT_TYPE_POINTER_CANCEL) &&
250 (event->pointer_data->kind != mojo::POINTER_KIND_MOUSE ||
251 IsOnlyOneMouseButtonDown(event->flags));
252
253 DispatchToPointerTarget(pointer_targets_[pointer_id], event.Pass());
254
255 if (should_reset_target) {
256 ServerWindow* target = pointer_targets_[pointer_id].window;
257 pointer_targets_.erase(pointer_id);
258 if (target && !IsSendingPointerEventsToTarget(target))
259 target->RemoveObserver(this);
208 } 260 }
209 } 261 }
210 262
263 void EventDispatcher::DispatchToPointerTarget(const PointerTarget& target,
264 mojo::EventPtr event) {
265 if (!target.window)
266 return;
267
268 gfx::Point location(EventLocationToPoint(*event));
269 gfx::Transform transform(GetTransformToWindow(surface_id_, target.window));
270 transform.TransformPoint(&location);
271 event->pointer_data->location->x = location.x();
272 event->pointer_data->location->y = location.y();
273 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area,
274 event.Pass());
275 }
276
277 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) {
278 window->RemoveObserver(this);
279
280 for (auto& pair : pointer_targets_) {
281 if (pair.second.window == window)
282 pair.second.window = nullptr;
283 }
284 }
285
286 bool EventDispatcher::IsSendingPointerEventsToTarget(ServerWindow* window) {
sadrul 2015/10/29 00:48:25 Would IsObservingWindow() better explain what this
sky 2015/10/29 14:54:16 Done.
287 for (const auto& pair : pointer_targets_) {
288 if (pair.second.window == window)
289 return true;
290 }
291 return false;
292 }
293
211 bool EventDispatcher::FindAccelerator(const mojo::Event& event, 294 bool EventDispatcher::FindAccelerator(const mojo::Event& event,
212 uint32_t* accelerator_id) { 295 uint32_t* accelerator_id) {
213 DCHECK(event.key_data); 296 DCHECK(event.key_data);
214 for (const auto& pair : accelerators_) { 297 for (const auto& pair : accelerators_) {
215 if (pair.second.MatchesEvent(event)) { 298 if (pair.second.MatchesEvent(event)) {
216 *accelerator_id = pair.first; 299 *accelerator_id = pair.first;
217 return true; 300 return true;
218 } 301 }
219 } 302 }
220 return false; 303 return false;
221 } 304 }
222 305
223 ServerWindow* EventDispatcher::FindEventTarget(mojo::Event* event) { 306 void EventDispatcher::OnWillChangeWindowHierarchy(ServerWindow* window,
224 ServerWindow* focused_window = 307 ServerWindow* new_parent,
225 delegate_->GetFocusedWindowForEventDispatcher(); 308 ServerWindow* old_parent) {
226 if (event->key_data) 309 CancelPointerEventsToTarget(window);
227 return focused_window; 310 }
228 311
229 DCHECK(event->pointer_data) << "Unknown event type: " << event->action; 312 void EventDispatcher::OnWindowVisibilityChanged(ServerWindow* window) {
230 mojo::LocationData* event_location = event->pointer_data->location.get(); 313 CancelPointerEventsToTarget(window);
231 DCHECK(event_location); 314 }
232 gfx::Point location(static_cast<int>(event_location->x),
233 static_cast<int>(event_location->y));
234 315
235 ServerWindow* target = capture_window_; 316 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) {
236 317 CancelPointerEventsToTarget(window);
237 if (!target) {
238 target = FindDeepestVisibleWindow(root_, surface_id_, &location);
239 } else {
240 gfx::Transform transform(GetTransformToWindow(surface_id_, target));
241 transform.TransformPoint(&location);
242 }
243
244 event_location->x = location.x();
245 event_location->y = location.y();
246
247 return target;
248 } 318 }
249 319
250 } // namespace ws 320 } // namespace ws
251 } // namespace mus 321 } // namespace mus
OLDNEW
« no previous file with comments | « components/mus/ws/event_dispatcher.h ('k') | components/mus/ws/event_dispatcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698