7db90de14af1f06092ecd9eb1a984f34f5b1f638
[platform/framework/web/crosswalk.git] / src / ui / aura / window_targeter.cc
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.
4
5 #include "ui/aura/window_targeter.h"
6
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/root_window.h"
11 #include "ui/aura/window.h"
12 #include "ui/aura/window_delegate.h"
13 #include "ui/events/event_target.h"
14
15 namespace aura {
16
17 WindowTargeter::WindowTargeter() {}
18 WindowTargeter::~WindowTargeter() {}
19
20 bool WindowTargeter::WindowCanAcceptEvent(aura::Window* window,
21                                           const ui::LocatedEvent& event) const {
22   if (!window->IsVisible())
23     return false;
24   if (window->ignore_events())
25     return false;
26   client::EventClient* client = client::GetEventClient(window->GetRootWindow());
27   if (client && !client->CanProcessEventsWithinSubtree(window))
28     return false;
29
30   Window* parent = window->parent();
31   if (parent && parent->delegate_ && !parent->delegate_->
32       ShouldDescendIntoChildForEventHandling(window, event.location())) {
33     return false;
34   }
35   return true;
36 }
37
38 bool WindowTargeter::EventLocationInsideBounds(
39     aura::Window* window, const ui::LocatedEvent& event) const {
40   gfx::Point point = event.location();
41   if (window->parent())
42     aura::Window::ConvertPointToTarget(window->parent(), window, &point);
43   return gfx::Rect(window->bounds().size()).Contains(point);
44 }
45
46 ui::EventTarget* WindowTargeter::FindTargetForEvent(ui::EventTarget* root,
47                                                     ui::Event* event) {
48   if (event->IsKeyEvent()) {
49     Window* window = static_cast<Window*>(root);
50     Window* root_window = window->GetRootWindow();
51     const ui::KeyEvent& key = static_cast<const ui::KeyEvent&>(*event);
52     if (key.key_code() == ui::VKEY_UNKNOWN)
53       return NULL;
54     client::EventClient* event_client = client::GetEventClient(root_window);
55     client::FocusClient* focus_client = client::GetFocusClient(root_window);
56     Window* focused_window = focus_client->GetFocusedWindow();
57     if (event_client &&
58         !event_client->CanProcessEventsWithinSubtree(focused_window)) {
59       focus_client->FocusWindow(NULL);
60       return NULL;
61     }
62     return focused_window ? focused_window : window;
63   }
64   return EventTargeter::FindTargetForEvent(root, event);
65 }
66
67 bool WindowTargeter::SubtreeShouldBeExploredForEvent(
68     ui::EventTarget* root,
69     const ui::LocatedEvent& event) {
70   Window* window = static_cast<Window*>(root);
71   if (!WindowCanAcceptEvent(window, event))
72     return false;
73
74   return EventLocationInsideBounds(window, event);
75 }
76
77 ui::EventTarget* WindowTargeter::FindTargetForLocatedEvent(
78     ui::EventTarget* root,
79     ui::LocatedEvent* event) {
80   Window* window = static_cast<Window*>(root);
81   if (!window->parent()) {
82     Window* target = FindTargetInRootWindow(window, *event);
83     if (target) {
84       window->ConvertEventToTarget(target, event);
85       return target;
86     }
87   }
88   return EventTargeter::FindTargetForLocatedEvent(root, event);
89 }
90
91 Window* WindowTargeter::FindTargetInRootWindow(Window* root_window,
92                                                const ui::LocatedEvent& event) {
93   DCHECK_EQ(root_window, root_window->GetRootWindow());
94
95   // Mouse events should be dispatched to the window that processed the
96   // mouse-press events (if any).
97   if (event.IsScrollEvent() || event.IsMouseEvent()) {
98     WindowEventDispatcher* dispatcher = root_window->GetDispatcher();
99     if (dispatcher->mouse_pressed_handler())
100       return dispatcher->mouse_pressed_handler();
101   }
102
103   // All events should be directed towards the capture window (if any).
104   Window* capture_window = client::GetCaptureWindow(root_window);
105   if (capture_window)
106     return capture_window;
107
108   if (event.IsTouchEvent()) {
109     // Query the gesture-recognizer to find targets for touch events.
110     const ui::TouchEvent& touch = static_cast<const ui::TouchEvent&>(event);
111     ui::GestureConsumer* consumer =
112         ui::GestureRecognizer::Get()->GetTouchLockedTarget(touch);
113     if (consumer)
114       return static_cast<Window*>(consumer);
115     consumer =
116         ui::GestureRecognizer::Get()->GetTargetForLocation(
117             event.location(), touch.source_device_id());
118     if (consumer)
119       return static_cast<Window*>(consumer);
120
121     // If the initial touch is outside the root window, target the root.
122     if (!root_window->bounds().Contains(event.location()))
123       return root_window;
124   }
125
126   return NULL;
127 }
128
129 }  // namespace aura