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

Side by Side Diff: ui/aura/window_event_dispatcher.cc

Issue 2933353003: Mark the ET_MOUSE_MOVED created from a pointer grab as synthesized. (Closed)
Patch Set: Investigate use-after-free. 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/aura/window_event_dispatcher.h" 5 #include "ui/aura/window_event_dispatcher.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 gfx::Point location = Env::GetInstance()->last_mouse_location(); 219 gfx::Point location = Env::GetInstance()->last_mouse_location();
220 client::ScreenPositionClient* client = 220 client::ScreenPositionClient* client =
221 client::GetScreenPositionClient(window()); 221 client::GetScreenPositionClient(window());
222 if (client) 222 if (client)
223 client->ConvertPointFromScreen(window(), &location); 223 client->ConvertPointFromScreen(window(), &location);
224 return location; 224 return location;
225 } 225 }
226 226
227 void WindowEventDispatcher::OnHostLostMouseGrab() { 227 void WindowEventDispatcher::OnHostLostMouseGrab() {
228 mouse_pressed_handler_ = NULL; 228 mouse_pressed_handler_ = NULL;
229 LOG(ERROR) << "mouse_moved_handler_ = NULL (was " << mouse_moved_handler_
230 << ")";
229 mouse_moved_handler_ = NULL; 231 mouse_moved_handler_ = NULL;
230 } 232 }
231 233
232 void WindowEventDispatcher::OnCursorMovedToRootLocation( 234 void WindowEventDispatcher::OnCursorMovedToRootLocation(
233 const gfx::Point& root_location) { 235 const gfx::Point& root_location) {
234 Env::GetInstance()->env_controller()->SetLastMouseLocation(window(), 236 Env::GetInstance()->env_controller()->SetLastMouseLocation(window(),
235 root_location); 237 root_location);
236 238
237 // Synthesize a mouse move in case the cursor's location in root coordinates 239 // Synthesize a mouse move in case the cursor's location in root coordinates
238 // changed but its position in WindowTreeHost coordinates did not. 240 // changed but its position in WindowTreeHost coordinates did not.
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 } 322 }
321 return details; 323 return details;
322 } 324 }
323 325
324 void WindowEventDispatcher::OnWindowHidden(Window* invisible, 326 void WindowEventDispatcher::OnWindowHidden(Window* invisible,
325 WindowHiddenReason reason) { 327 WindowHiddenReason reason) {
326 // If the window the mouse was pressed in becomes invisible, it should no 328 // If the window the mouse was pressed in becomes invisible, it should no
327 // longer receive mouse events. 329 // longer receive mouse events.
328 if (invisible->Contains(mouse_pressed_handler_)) 330 if (invisible->Contains(mouse_pressed_handler_))
329 mouse_pressed_handler_ = NULL; 331 mouse_pressed_handler_ = NULL;
330 if (invisible->Contains(mouse_moved_handler_)) 332 if (invisible->Contains(mouse_moved_handler_)) {
333 LOG(ERROR) << "mouse_moved_handler_ = NULL (was " << mouse_moved_handler_
334 << ")";
331 mouse_moved_handler_ = NULL; 335 mouse_moved_handler_ = NULL;
336 }
332 337
333 // If events are being dispatched from a nested message-loop, and the target 338 // If events are being dispatched from a nested message-loop, and the target
334 // of the outer loop is hidden or moved to another dispatcher during 339 // of the outer loop is hidden or moved to another dispatcher during
335 // dispatching events in the inner loop, then reset the target for the outer 340 // dispatching events in the inner loop, then reset the target for the outer
336 // loop. 341 // loop.
337 if (invisible->Contains(old_dispatch_target_)) 342 if (invisible->Contains(old_dispatch_target_))
338 old_dispatch_target_ = NULL; 343 old_dispatch_target_ = NULL;
339 344
340 invisible->CleanupGestureState(); 345 invisible->CleanupGestureState();
341 346
(...skipping 27 matching lines...) Expand all
369 } 374 }
370 375
371 //////////////////////////////////////////////////////////////////////////////// 376 ////////////////////////////////////////////////////////////////////////////////
372 // WindowEventDispatcher, aura::client::CaptureDelegate implementation: 377 // WindowEventDispatcher, aura::client::CaptureDelegate implementation:
373 378
374 void WindowEventDispatcher::UpdateCapture(Window* old_capture, 379 void WindowEventDispatcher::UpdateCapture(Window* old_capture,
375 Window* new_capture) { 380 Window* new_capture) {
376 // |mouse_moved_handler_| may have been set to a Window in a different root 381 // |mouse_moved_handler_| may have been set to a Window in a different root
377 // (see below). Clear it here to ensure we don't end up referencing a stale 382 // (see below). Clear it here to ensure we don't end up referencing a stale
378 // Window. 383 // Window.
379 if (mouse_moved_handler_ && !window()->Contains(mouse_moved_handler_)) 384 if (mouse_moved_handler_ && !window()->Contains(mouse_moved_handler_)) {
385 LOG(ERROR) << "mouse_moved_handler_ = NULL (was " << mouse_moved_handler_
386 << ")";
380 mouse_moved_handler_ = NULL; 387 mouse_moved_handler_ = NULL;
388 }
381 389
382 if (old_capture && old_capture->GetRootWindow() == window() && 390 if (old_capture && old_capture->GetRootWindow() == window() &&
383 old_capture->delegate()) { 391 old_capture->delegate()) {
384 // Send a capture changed event with bogus location data. 392 // Send a capture changed event with bogus location data.
385 ui::MouseEvent event(ui::ET_MOUSE_CAPTURE_CHANGED, gfx::Point(), 393 ui::MouseEvent event(ui::ET_MOUSE_CAPTURE_CHANGED, gfx::Point(),
386 gfx::Point(), ui::EventTimeForNow(), 0, 0); 394 gfx::Point(), ui::EventTimeForNow(), 0, 0);
387 395
388 DispatchDetails details = DispatchEvent(old_capture, &event); 396 DispatchDetails details = DispatchEvent(old_capture, &event);
389 if (details.dispatcher_destroyed) 397 if (details.dispatcher_destroyed)
390 return; 398 return;
391 399
392 if (!details.target_destroyed) 400 if (!details.target_destroyed)
393 old_capture->delegate()->OnCaptureLost(); 401 old_capture->delegate()->OnCaptureLost();
394 } 402 }
395 403
396 if (new_capture) { 404 if (new_capture) {
397 // Make all subsequent mouse events go to the capture window. We shouldn't 405 // Make all subsequent mouse events go to the capture window. We shouldn't
398 // need to send an event here as OnCaptureLost() should take care of that. 406 // need to send an event here as OnCaptureLost() should take care of that.
399 if (mouse_moved_handler_ || Env::GetInstance()->IsMouseButtonDown()) 407 if (mouse_moved_handler_ || Env::GetInstance()->IsMouseButtonDown()) {
408 LOG(ERROR) << "mouse_moved_handler_ = " << new_capture << " (was "
409 << mouse_moved_handler_ << ")";
400 mouse_moved_handler_ = new_capture; 410 mouse_moved_handler_ = new_capture;
411 }
401 } else { 412 } else {
402 // Make sure mouse_moved_handler gets updated. 413 // Make sure mouse_moved_handler gets updated.
403 DispatchDetails details = SynthesizeMouseMoveEvent(); 414 DispatchDetails details = SynthesizeMouseMoveEvent();
404 if (details.dispatcher_destroyed) 415 if (details.dispatcher_destroyed)
405 return; 416 return;
406 } 417 }
407 mouse_pressed_handler_ = NULL; 418 mouse_pressed_handler_ = NULL;
408 } 419 }
409 420
410 void WindowEventDispatcher::OnOtherRootGotCapture() { 421 void WindowEventDispatcher::OnOtherRootGotCapture() {
411 // Windows provides the TrackMouseEvents API which allows us to rely on the 422 // Windows provides the TrackMouseEvents API which allows us to rely on the
412 // OS to send us the mouse exit events (WM_MOUSELEAVE). Additionally on 423 // OS to send us the mouse exit events (WM_MOUSELEAVE). Additionally on
413 // desktop Windows, every top level window could potentially have its own 424 // desktop Windows, every top level window could potentially have its own
414 // root window, in which case this function will get called whenever those 425 // root window, in which case this function will get called whenever those
415 // windows grab mouse capture. Sending mouse exit messages in these cases 426 // windows grab mouse capture. Sending mouse exit messages in these cases
416 // causes subtle bugs like (crbug.com/394672). 427 // causes subtle bugs like (crbug.com/394672).
417 #if !defined(OS_WIN) 428 #if !defined(OS_WIN)
418 if (mouse_moved_handler_) { 429 if (mouse_moved_handler_) {
419 // Dispatch a mouse exit to reset any state associated with hover. This is 430 // Dispatch a mouse exit to reset any state associated with hover. This is
420 // important when going from no window having capture to a window having 431 // important when going from no window having capture to a window having
421 // capture because we do not dispatch ET_MOUSE_CAPTURE_CHANGED in this case. 432 // capture because we do not dispatch ET_MOUSE_CAPTURE_CHANGED in this case.
422 DispatchDetails details = 433 DispatchDetails details =
423 DispatchMouseExitAtPoint(nullptr, GetLastMouseLocationInRoot()); 434 DispatchMouseExitAtPoint(nullptr, GetLastMouseLocationInRoot());
424 if (details.dispatcher_destroyed) 435 if (details.dispatcher_destroyed)
425 return; 436 return;
426 } 437 }
427 #endif 438 #endif
428 439
440 LOG(ERROR) << "mouse_moved_handler_ = NULL (was " << mouse_moved_handler_
441 << ")";
429 mouse_moved_handler_ = NULL; 442 mouse_moved_handler_ = NULL;
430 mouse_pressed_handler_ = NULL; 443 mouse_pressed_handler_ = NULL;
431 } 444 }
432 445
433 void WindowEventDispatcher::SetNativeCapture() { 446 void WindowEventDispatcher::SetNativeCapture() {
434 host_->SetCapture(); 447 host_->SetCapture();
435 } 448 }
436 449
437 void WindowEventDispatcher::ReleaseNativeCapture() { 450 void WindowEventDispatcher::ReleaseNativeCapture() {
438 host_->ReleaseCapture(); 451 host_->ReleaseCapture();
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 return DispatchDetails(); 816 return DispatchDetails();
804 } 817 }
805 818
806 DispatchDetails WindowEventDispatcher::PreDispatchMouseEvent( 819 DispatchDetails WindowEventDispatcher::PreDispatchMouseEvent(
807 Window* target, 820 Window* target,
808 ui::MouseEvent* event) { 821 ui::MouseEvent* event) {
809 client::CursorClient* cursor_client = client::GetCursorClient(window()); 822 client::CursorClient* cursor_client = client::GetCursorClient(window());
810 // We allow synthesized mouse exit events through even if mouse events are 823 // We allow synthesized mouse exit events through even if mouse events are
811 // disabled. This ensures that hover state, etc on controls like buttons is 824 // disabled. This ensures that hover state, etc on controls like buttons is
812 // cleared. 825 // cleared.
826 if (cursor_client)
827 LOG(ERROR) << cursor_client->IsMouseEventsEnabled();
813 if (cursor_client && 828 if (cursor_client &&
814 !cursor_client->IsMouseEventsEnabled() && 829 !cursor_client->IsMouseEventsEnabled() &&
815 (event->flags() & ui::EF_IS_SYNTHESIZED) && 830 (event->flags() & ui::EF_IS_SYNTHESIZED) &&
816 (event->type() != ui::ET_MOUSE_EXITED)) { 831 (event->type() != ui::ET_MOUSE_EXITED)) {
832 LOG(ERROR) << "drop";
817 event->SetHandled(); 833 event->SetHandled();
818 return DispatchDetails(); 834 return DispatchDetails();
819 } 835 }
820 836
821 Env::GetInstance()->env_controller()->UpdateStateForMouseEvent(window(), 837 Env::GetInstance()->env_controller()->UpdateStateForMouseEvent(window(),
822 *event); 838 *event);
823 839
824 if (IsEventCandidateForHold(*event) && !dispatching_held_event_) { 840 if (IsEventCandidateForHold(*event) && !dispatching_held_event_) {
825 if (move_hold_count_) { 841 if (move_hold_count_) {
826 held_move_event_.reset(new ui::MouseEvent(*event, target, window())); 842 held_move_event_.reset(new ui::MouseEvent(*event, target, window()));
843 LOG(ERROR) << "drop";
827 event->SetHandled(); 844 event->SetHandled();
828 return DispatchDetails(); 845 return DispatchDetails();
829 } else { 846 } else {
830 // We may have a held event for a period between the time move_hold_count_ 847 // We may have a held event for a period between the time move_hold_count_
831 // fell to 0 and the DispatchHeldEvents executes. Since we're going to 848 // fell to 0 and the DispatchHeldEvents executes. Since we're going to
832 // dispatch the new event directly below, we can reset the old one. 849 // dispatch the new event directly below, we can reset the old one.
833 held_move_event_.reset(); 850 held_move_event_.reset();
834 } 851 }
835 } 852 }
836 853
837 switch (event->type()) { 854 switch (event->type()) {
838 case ui::ET_MOUSE_EXITED: 855 case ui::ET_MOUSE_EXITED:
839 if (!target || target == window()) { 856 if (!target || target == window()) {
840 DispatchDetails details = 857 DispatchDetails details =
841 DispatchMouseEnterOrExit(target, *event, ui::ET_MOUSE_EXITED); 858 DispatchMouseEnterOrExit(target, *event, ui::ET_MOUSE_EXITED);
842 if (details.dispatcher_destroyed) { 859 if (details.dispatcher_destroyed) {
843 event->SetHandled(); 860 event->SetHandled();
844 return details; 861 return details;
845 } 862 }
863 LOG(ERROR) << "mouse_moved_handler_ = NULL (was "
864 << mouse_moved_handler_ << ")";
846 mouse_moved_handler_ = NULL; 865 mouse_moved_handler_ = NULL;
847 } 866 }
848 break; 867 break;
849 case ui::ET_MOUSE_MOVED: 868 case ui::ET_MOUSE_MOVED:
850 // Send an exit to the current |mouse_moved_handler_| and an enter to 869 // Send an exit to the current |mouse_moved_handler_| and an enter to
851 // |target|. Take care that both us and |target| aren't destroyed during 870 // |target|. Take care that both us and |target| aren't destroyed during
852 // dispatch. 871 // dispatch.
853 if (target != mouse_moved_handler_) { 872 if (target != mouse_moved_handler_) {
854 aura::Window* old_mouse_moved_handler = mouse_moved_handler_; 873 aura::Window* old_mouse_moved_handler = mouse_moved_handler_;
855 WindowTracker live_window; 874 WindowTracker live_window;
856 live_window.Add(target); 875 live_window.Add(target);
857 DispatchDetails details = 876 DispatchDetails details =
858 DispatchMouseEnterOrExit(target, *event, ui::ET_MOUSE_EXITED); 877 DispatchMouseEnterOrExit(target, *event, ui::ET_MOUSE_EXITED);
859 // |details| contains information about |mouse_moved_handler_| being 878 // |details| contains information about |mouse_moved_handler_| being
860 // destroyed which is not our |target|. Return value of this function 879 // destroyed which is not our |target|. Return value of this function
861 // should be about our |target|. 880 // should be about our |target|.
862 DispatchDetails target_details = details; 881 DispatchDetails target_details = details;
863 target_details.target_destroyed = !live_window.Contains(target); 882 target_details.target_destroyed = !live_window.Contains(target);
864 if (details.dispatcher_destroyed) { 883 if (details.dispatcher_destroyed) {
884 LOG(ERROR) << "drop";
865 event->SetHandled(); 885 event->SetHandled();
866 return target_details; 886 return target_details;
867 } 887 }
868 // If the |mouse_moved_handler_| changes out from under us, assume a 888 // If the |mouse_moved_handler_| changes out from under us, assume a
869 // nested run loop ran and we don't need to do anything. 889 // nested run loop ran and we don't need to do anything.
870 if (mouse_moved_handler_ != old_mouse_moved_handler) { 890 if (mouse_moved_handler_ != old_mouse_moved_handler) {
891 LOG(ERROR) << "drop";
871 event->SetHandled(); 892 event->SetHandled();
872 return target_details; 893 return target_details;
873 } 894 }
874 if (details.target_destroyed || target_details.target_destroyed) { 895 if (details.target_destroyed || target_details.target_destroyed) {
896 LOG(ERROR) << "mouse_moved_handler_ = NULL (was "
897 << mouse_moved_handler_ << ")";
875 mouse_moved_handler_ = NULL; 898 mouse_moved_handler_ = NULL;
876 event->SetHandled(); 899 event->SetHandled();
877 return target_details; 900 return target_details;
878 } 901 }
879 live_window.Remove(target); 902 live_window.Remove(target);
880 903
904 LOG(ERROR) << "mouse_moved_handler_ = " << target << " (was "
905 << mouse_moved_handler_ << ")";
881 mouse_moved_handler_ = target; 906 mouse_moved_handler_ = target;
882 details = 907 details =
883 DispatchMouseEnterOrExit(target, *event, ui::ET_MOUSE_ENTERED); 908 DispatchMouseEnterOrExit(target, *event, ui::ET_MOUSE_ENTERED);
884 if (details.dispatcher_destroyed || details.target_destroyed) { 909 if (details.dispatcher_destroyed || details.target_destroyed) {
885 event->SetHandled(); 910 event->SetHandled();
886 return details; 911 return details;
887 } 912 }
888 } 913 }
889 break; 914 break;
890 case ui::ET_MOUSE_PRESSED: 915 case ui::ET_MOUSE_PRESSED:
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 ui::KeyEvent* event) { 962 ui::KeyEvent* event) {
938 if (skip_ime_ || !host_->has_input_method() || 963 if (skip_ime_ || !host_->has_input_method() ||
939 (event->flags() & ui::EF_IS_SYNTHESIZED)) 964 (event->flags() & ui::EF_IS_SYNTHESIZED))
940 return ui::EventDispatchDetails(); 965 return ui::EventDispatchDetails();
941 host_->GetInputMethod()->DispatchKeyEvent(event); 966 host_->GetInputMethod()->DispatchKeyEvent(event);
942 event->StopPropagation(); 967 event->StopPropagation();
943 return ui::EventDispatchDetails(); 968 return ui::EventDispatchDetails();
944 } 969 }
945 970
946 } // namespace aura 971 } // namespace aura
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698