window_event_dispatcher.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/aura/window_event_dispatcher.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/debug/trace_event.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/message_loop/message_loop.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/capture_client.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/aura/client/cursor_client.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/aura/client/event_client.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/focus_client.h" 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/aura/client/screen_position_client.h" 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/aura/env.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window.h" 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/aura/window_delegate.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window_targeter.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window_tracker.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window_tree_host.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/hit_test.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/dip_util.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/events/event.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/events/gestures/gesture_recognizer.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/events/gestures/gesture_types.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef ui::EventDispatchDetails DispatchDetails; 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace aura { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns true if |target| has a non-client (frame) component at |location|, 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// in window coordinates. 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsNonClientLocation(Window* target, const gfx::Point& location) { 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!target->delegate()) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int hit_test_code = target->delegate()->GetNonClientComponent(location); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return hit_test_code != HTCLIENT && hit_test_code != HTNOWHERE; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Window* ConsumerToWindow(ui::GestureConsumer* consumer) { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return consumer ? static_cast<Window*>(consumer) : NULL; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SetLastMouseLocation(const Window* root_window, 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Point& location_in_root) { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client::ScreenPositionClient* client = 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client::GetScreenPositionClient(root_window); 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (client) { 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point location_in_screen = location_in_root; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client->ConvertPointToScreen(root_window, &location_in_screen); 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Env::GetInstance()->set_last_mouse_location(location_in_screen); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Env::GetInstance()->set_last_mouse_location(location_in_root); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsEventCandidateForHold(const ui::Event& event) { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event.type() == ui::ET_TOUCH_MOVED) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event.type() == ui::ET_MOUSE_DRAGGED) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event.IsMouseEvent() && (event.flags() & ui::EF_IS_SYNTHESIZED)) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WindowEventDispatcher, public: 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WindowEventDispatcher::WindowEventDispatcher(WindowTreeHost* host) 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : host_(host), 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) touch_ids_down_(0), 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mouse_pressed_handler_(NULL), 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mouse_moved_handler_(NULL), 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_dispatch_target_(NULL), 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) old_dispatch_target_(NULL), 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) synthesize_mouse_move_(false), 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) move_hold_count_(0), 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dispatching_held_event_(false), 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observer_manager_(this), 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) repost_event_factory_(this), 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) held_event_factory_(this) { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::GestureRecognizer::Get()->AddGestureEventHelper(this); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Env::GetInstance()->AddObserver(this); 906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)WindowEventDispatcher::~WindowEventDispatcher() { 936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) TRACE_EVENT0("shutdown", "WindowEventDispatcher::Destructor"); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Env::GetInstance()->RemoveObserver(this); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::GestureRecognizer::Get()->RemoveGestureEventHelper(this); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 98e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid WindowEventDispatcher::RepostEvent(const ui::LocatedEvent& event) { 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(event.type() == ui::ET_MOUSE_PRESSED || 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event.type() == ui::ET_GESTURE_TAP_DOWN); 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // We allow for only one outstanding repostable event. This is used 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // in exiting context menus. A dropped repost request is allowed. 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (event.type() == ui::ET_MOUSE_PRESSED) { 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) held_repostable_event_.reset( 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new ui::MouseEvent( 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<const ui::MouseEvent&>(event), 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<aura::Window*>(event.target()), 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window())); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoop::current()->PostNonNestableTask( 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind( 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::IgnoreResult(&WindowEventDispatcher::DispatchHeldEvents), 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) repost_event_factory_.GetWeakPtr())); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(event.type() == ui::ET_GESTURE_TAP_DOWN); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) held_repostable_event_.reset(); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(rbyers): Reposing of gestures is tricky to get 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // right, so it's not yet supported. crbug.com/170987. 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::OnMouseEventsEnableStateChanged(bool enabled) { 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send entered / exited so that visual state can be updated to match 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // mouse events state. 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostSynthesizeMouseMove(); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(mazda): Add code to disable mouse events when |enabled| == false. 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::DispatchCancelModeEvent() { 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::CancelModeEvent event; 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Window* focused_window = client::GetFocusClient(window())->GetFocusedWindow(); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (focused_window && !window()->Contains(focused_window)) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) focused_window = NULL; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchDetails details = 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchEvent(focused_window ? focused_window : window(), &event); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (details.dispatcher_destroyed) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::DispatchGestureEvent(ui::GestureEvent* event) { 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchDetails details = DispatchHeldEvents(); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (details.dispatcher_destroyed) 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Window* target = GetGestureTarget(event); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (target) { 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->ConvertLocationToTarget(window(), target); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchDetails details = DispatchEvent(target, event); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (details.dispatcher_destroyed) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::DispatchMouseExitAtPoint(const gfx::Point& point) { 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::MouseEvent event(ui::ET_MOUSE_EXITED, point, point, ui::EF_NONE, 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::EF_NONE); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchDetails details = 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchMouseEnterOrExit(event, ui::ET_MOUSE_EXITED); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (details.dispatcher_destroyed) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::ProcessedTouchEvent(ui::TouchEvent* event, 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Window* window, 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::EventResult result) { 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::GestureRecognizer::Gestures> gestures; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gestures.reset(ui::GestureRecognizer::Get()-> 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProcessTouchEventForGesture(*event, result, window)); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchDetails details = ProcessGestures(gestures.get()); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (details.dispatcher_destroyed) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::HoldPointerMoves() { 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!move_hold_count_) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) held_event_factory_.InvalidateWeakPtrs(); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++move_hold_count_; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_EVENT_ASYNC_BEGIN0("ui", "WindowEventDispatcher::HoldPointerMoves", 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::ReleasePointerMoves() { 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) --move_hold_count_; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(move_hold_count_, 0); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!move_hold_count_ && held_move_event_) { 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We don't want to call DispatchHeldEvents directly, because this might be 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // called from a deep stack while another event, in which case dispatching 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // another one may not be safe/expected. Instead we post a task, that we 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // may cancel if HoldPointerMoves is called again before it executes. 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoop::current()->PostNonNestableTask( 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind( 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::IgnoreResult(&WindowEventDispatcher::DispatchHeldEvents), 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) held_event_factory_.GetWeakPtr())); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_EVENT_ASYNC_END0("ui", "WindowEventDispatcher::HoldPointerMoves", this); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Point WindowEventDispatcher::GetLastMouseLocationInRoot() const { 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point location = Env::GetInstance()->last_mouse_location(); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client::ScreenPositionClient* client = 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client::GetScreenPositionClient(window()); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (client) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client->ConvertPointFromScreen(window(), &location); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return location; 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::OnHostLostMouseGrab() { 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mouse_pressed_handler_ = NULL; 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mouse_moved_handler_ = NULL; 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::OnCursorMovedToRootLocation( 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Point& root_location) { 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetLastMouseLocation(window(), root_location); 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) synthesize_mouse_move_ = false; 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::OnPostNotifiedWindowDestroying(Window* window) { 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnWindowHidden(window, WINDOW_DESTROYED); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WindowEventDispatcher, private: 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Window* WindowEventDispatcher::window() { 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return host_->window(); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const Window* WindowEventDispatcher::window() const { 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return host_->window(); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::TransformEventForDeviceScaleFactor( 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::LocatedEvent* event) { 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->UpdateForRootTransform(host_->GetInverseRootTransform()); 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::DispatchMouseExitToHidingWindow(Window* window) { 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The mouse capture is intentionally ignored. Think that a mouse enters 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to a window, the window sets the capture, the mouse exits the window, 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // and then it releases the capture. In that case OnMouseExited won't 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // be called. So it is natural not to emit OnMouseExited even though 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |window| is the capture window. 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point last_mouse_location = GetLastMouseLocationInRoot(); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (window->Contains(mouse_moved_handler_) && 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->ContainsPointInRoot(last_mouse_location)) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchMouseExitAtPoint(last_mouse_location); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ui::EventDispatchDetails WindowEventDispatcher::DispatchMouseEnterOrExit( 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ui::MouseEvent& event, 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::EventType type) { 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event.type() != ui::ET_MOUSE_CAPTURE_CHANGED && 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !(event.flags() & ui::EF_IS_SYNTHESIZED)) { 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetLastMouseLocation(window(), event.root_location()); 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!mouse_moved_handler_ || !mouse_moved_handler_->delegate() || 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !window()->Contains(mouse_moved_handler_)) 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return DispatchDetails(); 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |event| may be an event in the process of being dispatched to a target (in 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // which case its locations will be in the event's target's coordinate 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // system), or a synthetic event created in root-window (in which case, the 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // event's target will be NULL, and the event will be in the root-window's 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // coordinate system. 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::Window* target = static_cast<Window*>(event.target()); 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!target) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target = window(); 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::MouseEvent translated_event(event, 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target, 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mouse_moved_handler_, 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type, 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event.flags() | ui::EF_IS_SYNTHESIZED); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return DispatchEvent(mouse_moved_handler_, &translated_event); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ui::EventDispatchDetails WindowEventDispatcher::ProcessGestures( 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::GestureRecognizer::Gestures* gestures) { 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchDetails details; 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!gestures || gestures->empty()) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return details; 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Window* target = GetGestureTarget(gestures->get().at(0)); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < gestures->size(); ++i) { 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::GestureEvent* event = gestures->get().at(i); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->ConvertLocationToTarget(window(), target); 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) details = DispatchEvent(target, event); 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (details.dispatcher_destroyed || details.target_destroyed) 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return details; 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::OnWindowHidden(Window* invisible, 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WindowHiddenReason reason) { 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the window the mouse was pressed in becomes invisible, it should no 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // longer receive mouse events. 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (invisible->Contains(mouse_pressed_handler_)) 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mouse_pressed_handler_ = NULL; 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (invisible->Contains(mouse_moved_handler_)) 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mouse_moved_handler_ = NULL; 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If events are being dispatched from a nested message-loop, and the target 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // of the outer loop is hidden or moved to another dispatcher during 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // dispatching events in the inner loop, then reset the target for the outer 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // loop. 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (invisible->Contains(old_dispatch_target_)) 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) old_dispatch_target_ = NULL; 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) invisible->CleanupGestureState(); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Do not clear the capture, and the |event_dispatch_target_| if the 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // window is moving across hosts, because the target itself is actually still 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // visible and clearing them stops further event processing, which can cause 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // unexpected behaviors. See crbug.com/157583 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (reason != WINDOW_MOVING) { 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We don't ask |invisible| here, because invisible may have been removed 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // from the window hierarchy already by the time this function is called 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (OnWindowDestroyed). 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client::CaptureClient* capture_client = 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client::GetCaptureClient(host_->window()); 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Window* capture_window = 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) capture_client ? capture_client->GetCaptureWindow() : NULL; 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (invisible->Contains(event_dispatch_target_)) 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_dispatch_target_ = NULL; 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the ancestor of the capture window is hidden, release the capture. 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note that this may delete the window so do not use capture_window 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // after this. 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (invisible->Contains(capture_window) && invisible != window()) 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) capture_window->ReleaseCapture(); 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Window* WindowEventDispatcher::GetGestureTarget(ui::GestureEvent* event) { 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Window* target = NULL; 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!event->IsEndingEvent()) { 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The window that received the start event (e.g. scroll begin) needs to 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // receive the end event (e.g. scroll end). 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target = client::GetCaptureWindow(window()); 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!target) { 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target = ConsumerToWindow( 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::GestureRecognizer::Get()->GetTargetForGestureEvent(*event)); 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return target; 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WindowEventDispatcher, aura::client::CaptureDelegate implementation: 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::UpdateCapture(Window* old_capture, 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Window* new_capture) { 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |mouse_moved_handler_| may have been set to a Window in a different root 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (see below). Clear it here to ensure we don't end up referencing a stale 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Window. 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mouse_moved_handler_ && !window()->Contains(mouse_moved_handler_)) 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mouse_moved_handler_ = NULL; 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (old_capture && old_capture->GetRootWindow() == window() && 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) old_capture->delegate()) { 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send a capture changed event with bogus location data. 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::MouseEvent event(ui::ET_MOUSE_CAPTURE_CHANGED, gfx::Point(), 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point(), 0, 0); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchDetails details = DispatchEvent(old_capture, &event); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (details.dispatcher_destroyed) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) old_capture->delegate()->OnCaptureLost(); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (new_capture) { 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make all subsequent mouse events go to the capture window. We shouldn't 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // need to send an event here as OnCaptureLost() should take care of that. 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mouse_moved_handler_ || Env::GetInstance()->IsMouseButtonDown()) 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mouse_moved_handler_ = new_capture; 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure mouse_moved_handler gets updated. 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchDetails details = SynthesizeMouseMoveEvent(); 383effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (details.dispatcher_destroyed) 384effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return; 385effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 386effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch mouse_pressed_handler_ = NULL; 387effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 388effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::OnOtherRootGotCapture() { 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mouse_moved_handler_ = NULL; 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mouse_pressed_handler_ = NULL; 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WindowEventDispatcher::SetNativeCapture() { 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host_->SetCapture(); 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::ReleaseNativeCapture() { 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host_->ReleaseCapture(); 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WindowEventDispatcher, ui::EventProcessor implementation: 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ui::EventTarget* WindowEventDispatcher::GetRootTarget() { 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return window(); 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::PrepareEventForDispatch(ui::Event* event) { 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dispatching_held_event_) { 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The held events are already in |window()|'s coordinate system. So it is 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // not necessary to apply the transform to convert from the host's 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // coordinate system to |window()|'s coordinate system. 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event->IsMouseEvent() || 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->IsScrollEvent() || 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->IsTouchEvent() || 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->IsGestureEvent()) { 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransformEventForDeviceScaleFactor(static_cast<ui::LocatedEvent*>(event)); 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WindowEventDispatcher, ui::EventDispatcherDelegate implementation: 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool WindowEventDispatcher::CanDispatchToTarget(ui::EventTarget* target) { 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return event_dispatch_target_ == target; 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ui::EventDispatchDetails WindowEventDispatcher::PreDispatchEvent( 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::EventTarget* target, 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::Event* event) { 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Window* target_window = static_cast<Window*>(target); 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(window()->Contains(target_window)); 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dispatching_held_event_) { 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool can_be_held = IsEventCandidateForHold(*event); 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!move_hold_count_ || !can_be_held) { 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (can_be_held) 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) held_move_event_.reset(); 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchDetails details = DispatchHeldEvents(); 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (details.dispatcher_destroyed || details.target_destroyed) 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return details; 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event->IsMouseEvent()) { 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PreDispatchMouseEvent(target_window, static_cast<ui::MouseEvent*>(event)); 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (event->IsScrollEvent()) { 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PreDispatchLocatedEvent(target_window, 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<ui::ScrollEvent*>(event)); 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (event->IsTouchEvent()) { 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PreDispatchTouchEvent(target_window, static_cast<ui::TouchEvent*>(event)); 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) old_dispatch_target_ = event_dispatch_target_; 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_dispatch_target_ = static_cast<Window*>(target); 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return DispatchDetails(); 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ui::EventDispatchDetails WindowEventDispatcher::PostDispatchEvent( 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::EventTarget* target, 462d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const ui::Event& event) { 463d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DispatchDetails details; 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!target || target != event_dispatch_target_) 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) details.target_destroyed = true; 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_dispatch_target_ = old_dispatch_target_; 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) old_dispatch_target_ = NULL; 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NDEBUG 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!event_dispatch_target_ || window()->Contains(event_dispatch_target_)); 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event.IsTouchEvent() && !details.target_destroyed) { 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Do not let 'held' touch events contribute to any gestures unless it is 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // being dispatched. 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dispatching_held_event_ || !held_move_event_ || 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !held_move_event_->IsTouchEvent()) { 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::TouchEvent orig_event(static_cast<const ui::TouchEvent&>(event), 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<Window*>(event.target()), window()); 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Get the list of GestureEvents from GestureRecognizer. 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::GestureRecognizer::Gestures> gestures; 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gestures.reset(ui::GestureRecognizer::Get()-> 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProcessTouchEventForGesture(orig_event, event.result(), 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<Window*>(target))); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ProcessGestures(gestures.get()); 4850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return details; 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WindowEventDispatcher, ui::GestureEventHelper implementation: 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool WindowEventDispatcher::CanDispatchToConsumer( 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::GestureConsumer* consumer) { 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Window* consumer_window = ConsumerToWindow(consumer); 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (consumer_window && consumer_window->GetRootWindow() == window()); 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::DispatchCancelTouchEvent(ui::TouchEvent* event) { 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchDetails details = OnEventFromSource(event); 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (details.dispatcher_destroyed) 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WindowEventDispatcher, WindowObserver implementation: 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::OnWindowDestroying(Window* window) { 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!host_->window()->Contains(window)) 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchMouseExitToHidingWindow(window); 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SynthesizeMouseMoveAfterChangeToWindow(window); 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::OnWindowDestroyed(Window* window) { 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We observe all windows regardless of what root Window (if any) they're 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // attached to. 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observer_manager_.Remove(window); 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::OnWindowAddedToRootWindow(Window* attached) { 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!observer_manager_.IsObserving(attached)) 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observer_manager_.Add(attached); 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!host_->window()->Contains(attached)) 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SynthesizeMouseMoveAfterChangeToWindow(attached); 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::OnWindowRemovingFromRootWindow(Window* detached, 534d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Window* new_root) { 535d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!host_->window()->Contains(detached)) 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(client::GetCaptureWindow(window()) != window()); 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchMouseExitToHidingWindow(detached); 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SynthesizeMouseMoveAfterChangeToWindow(detached); 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Hiding the window releases capture which can implicitly destroy the window 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // so the window may no longer be valid after this call. 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnWindowHidden(detached, new_root ? WINDOW_MOVING : WINDOW_HIDDEN); 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::OnWindowVisibilityChanging(Window* window, 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool visible) { 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!host_->window()->Contains(window)) 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 552d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 553d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DispatchMouseExitToHidingWindow(window); 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::OnWindowVisibilityChanged(Window* window, 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool visible) { 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!host_->window()->Contains(window)) 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (window->ContainsPointInRoot(GetLastMouseLocationInRoot())) 562010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) PostSynthesizeMouseMove(); 563010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 564010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Hiding the window releases capture which can implicitly destroy the window 565010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // so the window may no longer be valid after this call. 566010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!visible) 567010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) OnWindowHidden(window, WINDOW_HIDDEN); 568010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 569010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 570010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void WindowEventDispatcher::OnWindowBoundsChanged(Window* window, 571010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const gfx::Rect& old_bounds, 572010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const gfx::Rect& new_bounds) { 573010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!host_->window()->Contains(window)) 574010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 575010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 576010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (window == host_->window()) { 577010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TRACE_EVENT1("ui", "WindowEventDispatcher::OnWindowBoundsChanged(root)", 578010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "size", new_bounds.size().ToString()); 579010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 580010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DispatchDetails details = DispatchHeldEvents(); 581010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (details.dispatcher_destroyed) 582010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 583010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 584010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) synthesize_mouse_move_ = false; 585010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 586010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (window->IsVisible() && !window->ignore_events()) { 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect old_bounds_in_root = old_bounds, new_bounds_in_root = new_bounds; 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Window::ConvertRectToTarget(window->parent(), host_->window(), 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &old_bounds_in_root); 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Window::ConvertRectToTarget(window->parent(), host_->window(), 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &new_bounds_in_root); 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point last_mouse_location = GetLastMouseLocationInRoot(); 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (old_bounds_in_root.Contains(last_mouse_location) != 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_bounds_in_root.Contains(last_mouse_location)) { 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostSynthesizeMouseMove(); 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::OnWindowTransforming(Window* window) { 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!host_->window()->Contains(window)) 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SynthesizeMouseMoveAfterChangeToWindow(window); 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::OnWindowTransformed(Window* window) { 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!host_->window()->Contains(window)) 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SynthesizeMouseMoveAfterChangeToWindow(window); 613b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 614b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 615b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 616b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// WindowEventDispatcher, EnvObserver implementation: 617b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 618b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void WindowEventDispatcher::OnWindowInitialized(Window* window) { 619b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) observer_manager_.Add(window); 620b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 621b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 622b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 623b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// WindowEventDispatcher, private: 624b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 625b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)ui::EventDispatchDetails WindowEventDispatcher::DispatchHeldEvents() { 626a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!held_repostable_event_ && !held_move_event_) 627a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return DispatchDetails(); 628a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 629a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CHECK(!dispatching_held_event_); 630a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) dispatching_held_event_ = true; 631a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 632a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DispatchDetails dispatch_details; 633a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (held_repostable_event_) { 634a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (held_repostable_event_->type() == ui::ET_MOUSE_PRESSED) { 635a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<ui::MouseEvent> mouse_event( 636a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) static_cast<ui::MouseEvent*>(held_repostable_event_.release())); 637a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) dispatch_details = OnEventFromSource(mouse_event.get()); 638a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } else { 639a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // TODO(rbyers): GESTURE_TAP_DOWN not yet supported: crbug.com/170987. 640a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOTREACHED(); 641a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 642a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (dispatch_details.dispatcher_destroyed) 643a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return dispatch_details; 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (held_move_event_) { 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If a mouse move has been synthesized, the target location is suspect, 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // so drop the held mouse event. 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (held_move_event_->IsTouchEvent() || 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (held_move_event_->IsMouseEvent() && !synthesize_mouse_move_)) { 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dispatch_details = OnEventFromSource(held_move_event_.get()); 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dispatch_details.dispatcher_destroyed) 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) held_move_event_.reset(); 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dispatch_details.dispatcher_destroyed) 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dispatching_held_event_ = false; 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dispatch_details; 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::PostSynthesizeMouseMove() { 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (synthesize_mouse_move_) 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) synthesize_mouse_move_ = true; 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoop::current()->PostNonNestableTask( 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(base::IgnoreResult( 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &WindowEventDispatcher::SynthesizeMouseMoveEvent), 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) held_event_factory_.GetWeakPtr())); 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::SynthesizeMouseMoveAfterChangeToWindow( 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Window* window) { 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (window->IsVisible() && 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->ContainsPointInRoot(GetLastMouseLocationInRoot())) { 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostSynthesizeMouseMove(); 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ui::EventDispatchDetails WindowEventDispatcher::SynthesizeMouseMoveEvent() { 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchDetails details; 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!synthesize_mouse_move_) 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return details; 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) synthesize_mouse_move_ = false; 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point root_mouse_location = GetLastMouseLocationInRoot(); 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!window()->bounds().Contains(root_mouse_location)) 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return details; 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point host_mouse_location = root_mouse_location; 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host_->ConvertPointToHost(&host_mouse_location); 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::MouseEvent event(ui::ET_MOUSE_MOVED, 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host_mouse_location, 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host_mouse_location, 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::EF_IS_SYNTHESIZED, 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0); 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return OnEventFromSource(&event); 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WindowEventDispatcher::PreDispatchLocatedEvent(Window* target, 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::LocatedEvent* event) { 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int flags = event->flags(); 7020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (IsNonClientLocation(target, event->location())) 7030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch flags |= ui::EF_IS_NON_CLIENT; 7040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch event->set_flags(flags); 7050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 7060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!dispatching_held_event_ && 7070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch (event->IsMouseEvent() || event->IsScrollEvent()) && 7080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch !(event->flags() & ui::EF_IS_SYNTHESIZED)) { 7090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (event->type() != ui::ET_MOUSE_CAPTURE_CHANGED) 7100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch SetLastMouseLocation(window(), event->root_location()); 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) synthesize_mouse_move_ = false; 7120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 7130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WindowEventDispatcher::PreDispatchMouseEvent(Window* target, 7160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ui::MouseEvent* event) { 7170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch client::CursorClient* cursor_client = client::GetCursorClient(window()); 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We allow synthesized mouse exit events through even if mouse events are 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // disabled. This ensures that hover state, etc on controls like buttons is 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // cleared. 7210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (cursor_client && 7220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch !cursor_client->IsMouseEventsEnabled() && 7230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch (event->flags() & ui::EF_IS_SYNTHESIZED) && 7240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch (event->type() != ui::ET_MOUSE_EXITED)) { 7250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch event->SetHandled(); 7260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IsEventCandidateForHold(*event) && !dispatching_held_event_) { 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (move_hold_count_) { 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!(event->flags() & ui::EF_IS_SYNTHESIZED) && 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->type() != ui::ET_MOUSE_CAPTURE_CHANGED) { 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetLastMouseLocation(window(), event->root_location()); 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) held_move_event_.reset(new ui::MouseEvent(*event, target, window())); 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->SetHandled(); 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We may have a held event for a period between the time move_hold_count_ 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // fell to 0 and the DispatchHeldEvents executes. Since we're going to 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // dispatch the new event directly below, we can reset the old one. 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) held_move_event_.reset(); 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kMouseButtonFlagMask = ui::EF_LEFT_MOUSE_BUTTON | 747effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ui::EF_MIDDLE_MOUSE_BUTTON | 748effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ui::EF_RIGHT_MOUSE_BUTTON; 749effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch switch (event->type()) { 750effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch case ui::ET_MOUSE_EXITED: 751effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!target || target == window()) { 752effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DispatchDetails details = 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchMouseEnterOrExit(*event, ui::ET_MOUSE_EXITED); 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (details.dispatcher_destroyed) { 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->SetHandled(); 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mouse_moved_handler_ = NULL; 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ui::ET_MOUSE_MOVED: 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send an exit to the current |mouse_moved_handler_| and an enter to 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |target|. Take care that both us and |target| aren't destroyed during 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // dispatch. 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (target != mouse_moved_handler_) { 766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::Window* old_mouse_moved_handler = mouse_moved_handler_; 767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WindowTracker live_window; 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) live_window.Add(target); 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchDetails details = 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchMouseEnterOrExit(*event, ui::ET_MOUSE_EXITED); 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (details.dispatcher_destroyed) { 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->SetHandled(); 7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the |mouse_moved_handler_| changes out from under us, assume a 7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // nested message loop ran and we don't need to do anything. 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mouse_moved_handler_ != old_mouse_moved_handler) { 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->SetHandled(); 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!live_window.Contains(target) || details.target_destroyed) { 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mouse_moved_handler_ = NULL; 7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->SetHandled(); 784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 786868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) live_window.Remove(target); 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mouse_moved_handler_ = target; 7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) details = DispatchMouseEnterOrExit(*event, ui::ET_MOUSE_ENTERED); 790868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (details.dispatcher_destroyed || details.target_destroyed) { 791868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) event->SetHandled(); 792868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 793868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 794d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ui::ET_MOUSE_PRESSED: 7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't set the mouse pressed handler for non client mouse down events. 7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These are only sent by Windows and are not always followed with non 7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // client mouse up events which causes subsequent mouse events to be 8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // sent to the wrong target. 8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!(event->flags() & ui::EF_IS_NON_CLIENT) && !mouse_pressed_handler_) 802d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mouse_pressed_handler_ = target; 8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Env::GetInstance()->set_mouse_button_flags( 804010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) event->flags() & kMouseButtonFlagMask); 805010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) break; 806010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case ui::ET_MOUSE_RELEASED: 807010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mouse_pressed_handler_ = NULL; 808010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Env::GetInstance()->set_mouse_button_flags(event->flags() & 809010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kMouseButtonFlagMask & ~event->changed_button_flags()); 8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PreDispatchLocatedEvent(target, event); 8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 818010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void WindowEventDispatcher::PreDispatchTouchEvent(Window* target, 819010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::TouchEvent* event) { 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (event->type()) { 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ui::ET_TOUCH_PRESSED: 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) touch_ids_down_ |= (1 << event->touch_id()); 8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Env::GetInstance()->set_touch_down(touch_ids_down_ != 0); 8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Handle ET_TOUCH_CANCELLED only if it has a native event. 8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ui::ET_TOUCH_CANCELLED: 8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!event->HasNativeEvent()) 8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // fallthrough 8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ui::ET_TOUCH_RELEASED: 8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) touch_ids_down_ = (touch_ids_down_ | (1 << event->touch_id())) ^ 8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (1 << event->touch_id()); 8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Env::GetInstance()->set_touch_down(touch_ids_down_ != 0); 8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ui::ET_TOUCH_MOVED: 8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (move_hold_count_ && !dispatching_held_event_) { 8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) held_move_event_.reset(new ui::TouchEvent(*event, target, window())); 8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->SetHandled(); 8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 848e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 849e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch PreDispatchLocatedEvent(target, event); 8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace aura 8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)