Change layout of app list items in experimental app list.
[chromium-blink-merge.git] / ui / aura / window_targeter.cc
blobd5c939352797c778039ffeeb85637ebb912185bc
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/aura/window_targeter.h"
7 #include "ui/aura/client/capture_client.h"
8 #include "ui/aura/client/event_client.h"
9 #include "ui/aura/client/focus_client.h"
10 #include "ui/aura/window.h"
11 #include "ui/aura/window_delegate.h"
12 #include "ui/aura/window_event_dispatcher.h"
13 #include "ui/aura/window_tree_host.h"
14 #include "ui/events/event_target.h"
16 namespace aura {
18 namespace {
20 bool IsLocatedEvent(const ui::Event& event) {
21 return event.IsMouseEvent() || event.IsTouchEvent() ||
22 event.IsScrollEvent() || event.IsGestureEvent();
25 } // namespace
27 WindowTargeter::WindowTargeter() {}
28 WindowTargeter::~WindowTargeter() {}
30 ui::EventTarget* WindowTargeter::FindTargetForEvent(ui::EventTarget* root,
31 ui::Event* event) {
32 Window* window = static_cast<Window*>(root);
33 Window* target = event->IsKeyEvent() ?
34 FindTargetForKeyEvent(window, *static_cast<ui::KeyEvent*>(event)) :
35 static_cast<Window*>(EventTargeter::FindTargetForEvent(root, event));
36 if (target && !window->parent() && !window->Contains(target)) {
37 // |window| is the root window, but |target| is not a descendent of
38 // |window|. So do not allow dispatching from here. Instead, dispatch the
39 // event through the WindowEventDispatcher that owns |target|.
40 aura::Window* new_root = target->GetRootWindow();
41 if (IsLocatedEvent(*event)) {
42 // The event has been transformed to be in |target|'s coordinate system.
43 // But dispatching the event through the EventProcessor requires the event
44 // to be in the host's coordinate system. So, convert the event to be in
45 // the root's coordinate space, and then to the host's coordinate space by
46 // applying the host's transform.
47 ui::LocatedEvent* located_event = static_cast<ui::LocatedEvent*>(event);
48 located_event->ConvertLocationToTarget(target, new_root);
49 located_event->UpdateForRootTransform(
50 new_root->GetHost()->GetRootTransform());
52 ui::EventDispatchDetails details ALLOW_UNUSED =
53 new_root->GetHost()->event_processor()->OnEventFromSource(event);
54 target = NULL;
56 return target;
59 bool WindowTargeter::SubtreeCanAcceptEvent(
60 ui::EventTarget* target,
61 const ui::LocatedEvent& event) const {
62 aura::Window* window = static_cast<aura::Window*>(target);
63 if (!window->IsVisible())
64 return false;
65 if (window->ignore_events())
66 return false;
67 client::EventClient* client = client::GetEventClient(window->GetRootWindow());
68 if (client && !client->CanProcessEventsWithinSubtree(window))
69 return false;
71 Window* parent = window->parent();
72 if (parent && parent->delegate_ && !parent->delegate_->
73 ShouldDescendIntoChildForEventHandling(window, event.location())) {
74 return false;
76 return true;
79 bool WindowTargeter::EventLocationInsideBounds(
80 ui::EventTarget* target,
81 const ui::LocatedEvent& event) const {
82 aura::Window* window = static_cast<aura::Window*>(target);
83 gfx::Point point = event.location();
84 if (window->parent())
85 aura::Window::ConvertPointToTarget(window->parent(), window, &point);
86 return gfx::Rect(window->bounds().size()).Contains(point);
89 ui::EventTarget* WindowTargeter::FindTargetForLocatedEvent(
90 ui::EventTarget* root,
91 ui::LocatedEvent* event) {
92 Window* window = static_cast<Window*>(root);
93 if (!window->parent()) {
94 Window* target = FindTargetInRootWindow(window, *event);
95 if (target) {
96 window->ConvertEventToTarget(target, event);
97 return target;
100 return EventTargeter::FindTargetForLocatedEvent(root, event);
103 Window* WindowTargeter::FindTargetForKeyEvent(Window* window,
104 const ui::KeyEvent& key) {
105 Window* root_window = window->GetRootWindow();
106 if (key.key_code() == ui::VKEY_UNKNOWN &&
107 (key.flags() & ui::EF_IME_FABRICATED_KEY) == 0 &&
108 key.GetCharacter() == 0)
109 return NULL;
110 client::FocusClient* focus_client = client::GetFocusClient(root_window);
111 Window* focused_window = focus_client->GetFocusedWindow();
112 if (!focused_window)
113 return window;
115 client::EventClient* event_client = client::GetEventClient(root_window);
116 if (event_client &&
117 !event_client->CanProcessEventsWithinSubtree(focused_window)) {
118 focus_client->FocusWindow(NULL);
119 return NULL;
121 return focused_window ? focused_window : window;
124 Window* WindowTargeter::FindTargetInRootWindow(Window* root_window,
125 const ui::LocatedEvent& event) {
126 DCHECK_EQ(root_window, root_window->GetRootWindow());
128 // Mouse events should be dispatched to the window that processed the
129 // mouse-press events (if any).
130 if (event.IsScrollEvent() || event.IsMouseEvent()) {
131 WindowEventDispatcher* dispatcher = root_window->GetHost()->dispatcher();
132 if (dispatcher->mouse_pressed_handler())
133 return dispatcher->mouse_pressed_handler();
136 // All events should be directed towards the capture window (if any).
137 Window* capture_window = client::GetCaptureWindow(root_window);
138 if (capture_window)
139 return capture_window;
141 if (event.IsTouchEvent()) {
142 // Query the gesture-recognizer to find targets for touch events.
143 const ui::TouchEvent& touch = static_cast<const ui::TouchEvent&>(event);
144 ui::GestureConsumer* consumer =
145 ui::GestureRecognizer::Get()->GetTouchLockedTarget(touch);
146 if (consumer)
147 return static_cast<Window*>(consumer);
148 consumer =
149 ui::GestureRecognizer::Get()->GetTargetForLocation(
150 event.location(), touch.source_device_id());
151 if (consumer)
152 return static_cast<Window*>(consumer);
154 // If the initial touch is outside the root window, target the root.
155 if (!root_window->bounds().Contains(event.location()))
156 return root_window;
159 return NULL;
162 } // namespace aura