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

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

Issue 1605773004: mus: Implement Window Server Capture (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Create InFlightCaptureChange add tests Created 4 years, 10 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
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> 7 #include <set>
8 8
9 #include "base/time/time.h"
9 #include "cc/surfaces/surface_hittest.h" 10 #include "cc/surfaces/surface_hittest.h"
10 #include "components/mus/surfaces/surfaces_state.h" 11 #include "components/mus/surfaces/surfaces_state.h"
11 #include "components/mus/ws/event_dispatcher_delegate.h" 12 #include "components/mus/ws/event_dispatcher_delegate.h"
12 #include "components/mus/ws/server_window.h" 13 #include "components/mus/ws/server_window.h"
13 #include "components/mus/ws/server_window_delegate.h" 14 #include "components/mus/ws/server_window_delegate.h"
14 #include "components/mus/ws/window_coordinate_conversions.h" 15 #include "components/mus/ws/window_coordinate_conversions.h"
15 #include "components/mus/ws/window_finder.h" 16 #include "components/mus/ws/window_finder.h"
16 #include "components/mus/ws/window_tree_host_impl.h" 17 #include "components/mus/ws/window_tree_host_impl.h"
17 #include "mojo/converters/geometry/geometry_type_converters.h" 18 #include "mojo/converters/geometry/geometry_type_converters.h"
18 #include "ui/gfx/geometry/point.h" 19 #include "ui/gfx/geometry/point.h"
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 mojom::KeyboardCode keyboard_code_; 151 mojom::KeyboardCode keyboard_code_;
151 mojom::PointerKind pointer_kind_; 152 mojom::PointerKind pointer_kind_;
152 gfx::RectF pointer_region_; 153 gfx::RectF pointer_region_;
153 }; 154 };
154 155
155 //////////////////////////////////////////////////////////////////////////////// 156 ////////////////////////////////////////////////////////////////////////////////
156 157
157 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) 158 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate)
158 : delegate_(delegate), 159 : delegate_(delegate),
159 root_(nullptr), 160 root_(nullptr),
161 capture_window_(nullptr),
162 capture_window_in_nonclient_area_(false),
160 mouse_button_down_(false), 163 mouse_button_down_(false),
161 mouse_cursor_source_window_(nullptr) {} 164 mouse_cursor_source_window_(nullptr) {}
162 165
163 EventDispatcher::~EventDispatcher() { 166 EventDispatcher::~EventDispatcher() {
164 std::set<ServerWindow*> pointer_targets; 167 std::set<ServerWindow*> pointer_targets;
168 if (capture_window_) {
169 pointer_targets.insert(capture_window_);
170 capture_window_->RemoveObserver(this);
171 capture_window_ = nullptr;
172 }
165 for (const auto& pair : pointer_targets_) { 173 for (const auto& pair : pointer_targets_) {
166 if (pair.second.window && 174 if (pair.second.window &&
167 pointer_targets.insert(pair.second.window).second) { 175 pointer_targets.insert(pair.second.window).second) {
168 pair.second.window->RemoveObserver(this); 176 pair.second.window->RemoveObserver(this);
169 } 177 }
170 } 178 }
179 pointer_targets_.clear();
180 }
181
182 void EventDispatcher::SetCaptureWindow(ServerWindow* window,
183 bool in_nonclient_area) {
184 if (window == capture_window_)
185 return;
186
187 if (capture_window_) {
188 // Stop observing old capture window. |pointer_targets_| are cleared on
189 // intial setting of a capture window.
190 delegate_->OnLostCapture(capture_window_);
191 capture_window_->RemoveObserver(this);
192 } else {
193 // Cancel implicit capture to all other windows.
194 std::set<ServerWindow*> unobserved_windows;
195 for (const auto& pair : pointer_targets_) {
196 ServerWindow* target = pair.second.window;
197 if (!target)
198 continue;
199 if (unobserved_windows.insert(target).second)
200 target->RemoveObserver(this);
201 if (target == window)
202 continue;
203 mojom::EventPtr cancel_event = mojom::Event::New();
204 cancel_event->action = mojom::EventType::POINTER_CANCEL;
205 cancel_event->flags = mojom::kEventFlagNone;
206 cancel_event->time_stamp = base::TimeTicks::Now().ToInternalValue();
207 cancel_event->pointer_data = mojom::PointerData::New();
208 // TODO(jonross): Track previous location in PointerTarget for sending
209 // cancels
210 cancel_event->pointer_data->location = mojom::LocationData::New();
211 cancel_event->pointer_data->pointer_id = pair.first;
212 DispatchToPointerTarget(pair.second, std::move(cancel_event));
213 }
214 pointer_targets_.clear();
215 }
216 capture_window_ = window;
217 capture_window_in_nonclient_area_ = in_nonclient_area;
218 // Begin tracking the capture window if it is not yet being observed.
219 if (window)
220 window->AddObserver(this);
171 } 221 }
172 222
173 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { 223 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() {
174 if (!mouse_button_down_) { 224 if (!mouse_button_down_) {
175 gfx::Point location = mouse_pointer_last_location_; 225 gfx::Point location = mouse_pointer_last_location_;
176 mouse_cursor_source_window_ = 226 mouse_cursor_source_window_ =
177 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); 227 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location);
178 } 228 }
179 } 229 }
180 230
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 std::move(event)); 280 std::move(event));
231 } 281 }
232 282
233 void EventDispatcher::ProcessPointerEvent(mojom::EventPtr event) { 283 void EventDispatcher::ProcessPointerEvent(mojom::EventPtr event) {
234 const bool is_mouse_event = event->pointer_data && 284 const bool is_mouse_event = event->pointer_data &&
235 event->pointer_data->kind == mojom::PointerKind::MOUSE; 285 event->pointer_data->kind == mojom::PointerKind::MOUSE;
236 286
237 if (is_mouse_event) 287 if (is_mouse_event)
238 mouse_pointer_last_location_ = EventLocationToPoint(*event); 288 mouse_pointer_last_location_ = EventLocationToPoint(*event);
239 289
290 // Release capture on pointer up. For mouse we only release if there are
291 // no buttons down.
292 const bool is_pointer_going_up =
293 (event->action == mojom::EventType::POINTER_UP ||
294 event->action == mojom::EventType::POINTER_CANCEL) &&
295 (event->pointer_data->kind != mojom::PointerKind::MOUSE ||
296 IsOnlyOneMouseButtonDown(event->flags));
297
298 // Update mouse down state upon events which change it.
299 if (is_mouse_event) {
300 if (event->action == mojom::EventType::POINTER_DOWN)
301 mouse_button_down_ = true;
302 else if (is_pointer_going_up)
303 mouse_button_down_ = false;
304 }
305
306 if (capture_window_) {
307 mouse_cursor_source_window_ = capture_window_;
308 PointerTarget pointer_target;
309 pointer_target.window = capture_window_;
310 pointer_target.in_nonclient_area = capture_window_in_nonclient_area_;
311 DispatchToPointerTarget(pointer_target, std::move(event));
312 return;
313 }
314
240 const int32_t pointer_id = event->pointer_data->pointer_id; 315 const int32_t pointer_id = event->pointer_data->pointer_id;
241 if (!IsTrackingPointer(pointer_id) || 316 if (!IsTrackingPointer(pointer_id) ||
242 !pointer_targets_[pointer_id].is_pointer_down) { 317 !pointer_targets_[pointer_id].is_pointer_down) {
243 const bool any_pointers_down = AreAnyPointersDown(); 318 const bool any_pointers_down = AreAnyPointersDown();
244 UpdateTargetForPointer(*event); 319 UpdateTargetForPointer(*event);
245 if (is_mouse_event) 320 if (is_mouse_event)
246 mouse_cursor_source_window_ = pointer_targets_[pointer_id].window; 321 mouse_cursor_source_window_ = pointer_targets_[pointer_id].window;
247 322
248 PointerTarget& pointer_target = pointer_targets_[pointer_id]; 323 PointerTarget& pointer_target = pointer_targets_[pointer_id];
249 if (pointer_target.is_pointer_down) { 324 if (pointer_target.is_pointer_down) {
250 if (is_mouse_event) { 325 if (is_mouse_event)
251 mouse_button_down_ = true;
252 mouse_cursor_source_window_ = pointer_target.window; 326 mouse_cursor_source_window_ = pointer_target.window;
253 }
254 if (!any_pointers_down) 327 if (!any_pointers_down)
255 delegate_->SetFocusedWindowFromEventDispatcher(pointer_target.window); 328 delegate_->SetFocusedWindowFromEventDispatcher(pointer_target.window);
256 } 329 }
257 } 330 }
258 331
259 // Release capture on pointer up. For mouse we only release if there are 332 // When we release the mouse button, we want the cursor to be sourced from
260 // no buttons down. 333 // the window under the mouse pointer, even though we're sending the button
261 const bool is_pointer_going_up = 334 // up event to the window that had implicit capture. We have to set this
262 (event->action == mojom::EventType::POINTER_UP || 335 // before we perform dispatch because the Delegate is going to read this
263 event->action == mojom::EventType::POINTER_CANCEL) && 336 // information from us.
264 (event->pointer_data->kind != mojom::PointerKind::MOUSE || 337 if (is_pointer_going_up && is_mouse_event)
265 IsOnlyOneMouseButtonDown(event->flags)); 338 UpdateCursorProviderByLastKnownLocation();
sky 2016/02/03 21:59:00 You should do this in SetCapture(null) if mouse_bu
266
267 if (is_pointer_going_up && is_mouse_event) {
268 // When we release the mouse button, we want the cursor to be sourced from
269 // the window under the mouse pointer, even though we're sending the button
270 // up event to the window that had implicit capture. We have to set this
271 // before we perform dispatch because the Delegate is going to read this
272 // information from us.
273 mouse_button_down_ = false;
274 gfx::Point location(EventLocationToPoint(*event));
275 mouse_cursor_source_window_ =
276 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location);
277 }
278 339
279 DispatchToPointerTarget(pointer_targets_[pointer_id], std::move(event)); 340 DispatchToPointerTarget(pointer_targets_[pointer_id], std::move(event));
280 341
281 if (is_pointer_going_up) { 342 if (is_pointer_going_up) {
282 if (is_mouse_event) 343 if (is_mouse_event)
283 pointer_targets_[pointer_id].is_pointer_down = false; 344 pointer_targets_[pointer_id].is_pointer_down = false;
284 else 345 else
285 StopTrackingPointer(pointer_id); 346 StopTrackingPointer(pointer_id);
286 } 347 }
287 } 348 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 transform.TransformPoint(&location); 434 transform.TransformPoint(&location);
374 event->pointer_data->location->x = location.x(); 435 event->pointer_data->location->x = location.x();
375 event->pointer_data->location->y = location.y(); 436 event->pointer_data->location->y = location.y();
376 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area, 437 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area,
377 std::move(event)); 438 std::move(event));
378 } 439 }
379 440
380 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) { 441 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) {
381 window->RemoveObserver(this); 442 window->RemoveObserver(this);
382 443
444 if (capture_window_ == window) {
445 capture_window_ = nullptr;
446 // A window only cares to be informed that it lost capture if it explicitly
447 // requested capture. A window can lose capture if another window gains
448 // explicit capture.
449 delegate_->OnLostCapture(window);
450 mouse_button_down_ = false;
451 UpdateCursorProviderByLastKnownLocation();
452 return;
453 }
454
383 for (auto& pair : pointer_targets_) { 455 for (auto& pair : pointer_targets_) {
384 if (pair.second.window == window) 456 if (pair.second.window == window)
385 pair.second.window = nullptr; 457 pair.second.window = nullptr;
386 } 458 }
387 } 459 }
388 460
389 bool EventDispatcher::IsObservingWindow(ServerWindow* window) { 461 bool EventDispatcher::IsObservingWindow(ServerWindow* window) {
390 for (const auto& pair : pointer_targets_) { 462 for (const auto& pair : pointer_targets_) {
391 if (pair.second.window == window) 463 if (pair.second.window == window)
392 return true; 464 return true;
(...skipping 25 matching lines...) Expand all
418 490
419 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { 491 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) {
420 CancelPointerEventsToTarget(window); 492 CancelPointerEventsToTarget(window);
421 493
422 if (mouse_cursor_source_window_ == window) 494 if (mouse_cursor_source_window_ == window)
423 mouse_cursor_source_window_ = nullptr; 495 mouse_cursor_source_window_ = nullptr;
424 } 496 }
425 497
426 } // namespace ws 498 } // namespace ws
427 } // namespace mus 499 } // namespace mus
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698