[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 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 | |
Scott Violet | 2462c1e | 2018-08-23 21:50:52 | [diff] [blame] | 7 | #include "services/ws/public/mojom/window_tree_constants.mojom.h" |
[email protected] | 4c5d7c9 | 2013-12-13 17:17:39 | [diff] [blame] | 8 | #include "ui/aura/client/capture_client.h" |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 9 | #include "ui/aura/client/event_client.h" |
| 10 | #include "ui/aura/client/focus_client.h" |
Mike Wasserman | 5613aca | 2018-08-09 02:11:07 | [diff] [blame] | 11 | #include "ui/aura/client/screen_position_client.h" |
Jun Mukai | 0f3ae529 | 2018-08-22 16:28:11 | [diff] [blame] | 12 | #include "ui/aura/env.h" |
Scott Violet | 5f7e0b4 | 2018-09-05 18:05:17 | [diff] [blame] | 13 | #include "ui/aura/mus/window_port_mus.h" |
| 14 | #include "ui/aura/mus/window_tree_client.h" |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 15 | #include "ui/aura/window.h" |
| 16 | #include "ui/aura/window_delegate.h" |
[email protected] | fcc51c95 | 2014-02-21 21:31:26 | [diff] [blame] | 17 | #include "ui/aura/window_event_dispatcher.h" |
[email protected] | 7a60cd3a | 2014-03-20 20:54:57 | [diff] [blame] | 18 | #include "ui/aura/window_tree_host.h" |
Mike Wasserman | 5613aca | 2018-08-09 02:11:07 | [diff] [blame] | 19 | #include "ui/display/display.h" |
| 20 | #include "ui/display/screen.h" |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 21 | #include "ui/events/event_target.h" |
varkha | 9c6bcf71 | 2015-06-11 18:32:58 | [diff] [blame] | 22 | #include "ui/events/event_target_iterator.h" |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 23 | |
| 24 | namespace aura { |
Scott Violet | 5f7e0b4 | 2018-09-05 18:05:17 | [diff] [blame] | 25 | namespace { |
| 26 | |
| 27 | bool AreInsetsEmptyOrPositive(const gfx::Insets& insets) { |
| 28 | return insets.left() >= 0 && insets.right() >= 0 && insets.top() >= 0 && |
| 29 | insets.bottom() >= 0; |
| 30 | } |
| 31 | |
Jun Mukai | 832af1359 | 2018-11-30 05:43:44 | [diff] [blame] | 32 | void UpdateMusIfNecessary(aura::Window* window, |
| 33 | const gfx::Insets& mouse_extend, |
| 34 | const gfx::Insets& touch_extend) { |
| 35 | if (!window || window->env()->mode() != Env::Mode::MUS) |
| 36 | return; |
| 37 | |
| 38 | // Negative insets are used solely to extend the hit-test region of child |
| 39 | // windows, which is not needed by code using MUS (negative insets are only |
| 40 | // used in the server). |
| 41 | if (AreInsetsEmptyOrPositive(mouse_extend) && |
| 42 | AreInsetsEmptyOrPositive(touch_extend)) { |
| 43 | WindowPortMus::Get(window)->SetHitTestInsets(mouse_extend, touch_extend); |
| 44 | } |
| 45 | } |
| 46 | |
Scott Violet | 5f7e0b4 | 2018-09-05 18:05:17 | [diff] [blame] | 47 | } // namespace |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 48 | |
| 49 | WindowTargeter::WindowTargeter() {} |
| 50 | WindowTargeter::~WindowTargeter() {} |
| 51 | |
Scott Violet | 91c9d38 | 2017-06-22 16:53:33 | [diff] [blame] | 52 | bool WindowTargeter::SubtreeShouldBeExploredForEvent( |
| 53 | Window* window, |
| 54 | const ui::LocatedEvent& event) { |
| 55 | return SubtreeCanAcceptEvent(window, event) && |
| 56 | EventLocationInsideBounds(window, event); |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 57 | } |
| 58 | |
Valery Arkhangorodsky | 94dd7ba | 2017-07-26 02:19:50 | [diff] [blame] | 59 | bool WindowTargeter::GetHitTestRects(Window* window, |
| 60 | gfx::Rect* hit_test_rect_mouse, |
| 61 | gfx::Rect* hit_test_rect_touch) const { |
| 62 | DCHECK(hit_test_rect_mouse); |
| 63 | DCHECK(hit_test_rect_touch); |
Valery Arkhangorodsky | 34a5863 | 2017-08-16 16:25:48 | [diff] [blame] | 64 | *hit_test_rect_mouse = *hit_test_rect_touch = window->bounds(); |
Valery Arkhangorodsky | 94dd7ba | 2017-07-26 02:19:50 | [diff] [blame] | 65 | |
| 66 | if (ShouldUseExtendedBounds(window)) { |
| 67 | hit_test_rect_mouse->Inset(mouse_extend_); |
| 68 | hit_test_rect_touch->Inset(touch_extend_); |
| 69 | } |
| 70 | |
| 71 | return true; |
| 72 | } |
| 73 | |
Valery Arkhangorodsky | 34a5863 | 2017-08-16 16:25:48 | [diff] [blame] | 74 | std::unique_ptr<WindowTargeter::HitTestRects> |
| 75 | WindowTargeter::GetExtraHitTestShapeRects(Window* target) const { |
| 76 | return nullptr; |
| 77 | } |
| 78 | |
Trent Apted | 274b2a0c | 2018-03-12 00:03:17 | [diff] [blame] | 79 | void WindowTargeter::SetInsets(const gfx::Insets& mouse_and_touch_extend) { |
| 80 | SetInsets(mouse_and_touch_extend, mouse_and_touch_extend); |
| 81 | } |
| 82 | |
| 83 | void WindowTargeter::SetInsets(const gfx::Insets& mouse_extend, |
| 84 | const gfx::Insets& touch_extend) { |
| 85 | if (mouse_extend_ == mouse_extend && touch_extend_ == touch_extend) |
| 86 | return; |
| 87 | |
Trent Apted | 274b2a0c | 2018-03-12 00:03:17 | [diff] [blame] | 88 | mouse_extend_ = mouse_extend; |
| 89 | touch_extend_ = touch_extend; |
Scott Violet | 5f7e0b4 | 2018-09-05 18:05:17 | [diff] [blame] | 90 | UpdateMusIfNecessary(); |
Trent Apted | 274b2a0c | 2018-03-12 00:03:17 | [diff] [blame] | 91 | } |
| 92 | |
Scott Violet | 3b4bffa3 | 2017-09-05 20:35:15 | [diff] [blame] | 93 | Window* WindowTargeter::GetPriorityTargetInRootWindow( |
| 94 | Window* root_window, |
| 95 | const ui::LocatedEvent& event) { |
Scott Violet | 91c9d38 | 2017-06-22 16:53:33 | [diff] [blame] | 96 | DCHECK_EQ(root_window, root_window->GetRootWindow()); |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 97 | |
Scott Violet | 91c9d38 | 2017-06-22 16:53:33 | [diff] [blame] | 98 | // Mouse events should be dispatched to the window that processed the |
| 99 | // mouse-press events (if any). |
| 100 | if (event.IsScrollEvent() || event.IsMouseEvent()) { |
| 101 | WindowEventDispatcher* dispatcher = root_window->GetHost()->dispatcher(); |
| 102 | if (dispatcher->mouse_pressed_handler()) |
| 103 | return dispatcher->mouse_pressed_handler(); |
[email protected] | c981c4f | 2014-05-06 19:16:35 | [diff] [blame] | 104 | } |
[email protected] | c981c4f | 2014-05-06 19:16:35 | [diff] [blame] | 105 | |
Scott Violet | 91c9d38 | 2017-06-22 16:53:33 | [diff] [blame] | 106 | // All events should be directed towards the capture window (if any). |
| 107 | Window* capture_window = client::GetCaptureWindow(root_window); |
| 108 | if (capture_window) |
| 109 | return capture_window; |
| 110 | |
Sean O'Brien | 82a47b8 | 2017-09-28 19:23:09 | [diff] [blame] | 111 | if (event.IsPinchEvent()) { |
| 112 | DCHECK_EQ(event.AsGestureEvent()->details().device_type(), |
| 113 | ui::GestureDeviceType::DEVICE_TOUCHPAD); |
| 114 | WindowEventDispatcher* dispatcher = root_window->GetHost()->dispatcher(); |
| 115 | if (dispatcher->touchpad_pinch_handler()) |
| 116 | return dispatcher->touchpad_pinch_handler(); |
| 117 | } |
| 118 | |
Scott Violet | 91c9d38 | 2017-06-22 16:53:33 | [diff] [blame] | 119 | if (event.IsTouchEvent()) { |
| 120 | // Query the gesture-recognizer to find targets for touch events. |
| 121 | const ui::TouchEvent& touch = *event.AsTouchEvent(); |
| 122 | ui::GestureConsumer* consumer = |
Jun Mukai | 0f3ae529 | 2018-08-22 16:28:11 | [diff] [blame] | 123 | root_window->env()->gesture_recognizer()->GetTouchLockedTarget(touch); |
Scott Violet | 91c9d38 | 2017-06-22 16:53:33 | [diff] [blame] | 124 | if (consumer) |
| 125 | return static_cast<Window*>(consumer); |
Scott Violet | 3b4bffa3 | 2017-09-05 20:35:15 | [diff] [blame] | 126 | } |
| 127 | |
| 128 | return nullptr; |
| 129 | } |
| 130 | |
| 131 | Window* WindowTargeter::FindTargetInRootWindow(Window* root_window, |
| 132 | const ui::LocatedEvent& event) { |
| 133 | DCHECK_EQ(root_window, root_window->GetRootWindow()); |
| 134 | |
| 135 | Window* priority_target = GetPriorityTargetInRootWindow(root_window, event); |
| 136 | if (priority_target) |
| 137 | return priority_target; |
| 138 | |
| 139 | if (event.IsTouchEvent()) { |
| 140 | // Query the gesture-recognizer to find targets for touch events. |
| 141 | const ui::TouchEvent& touch = *event.AsTouchEvent(); |
| 142 | // GetTouchLockedTarget() is handled in GetPriorityTargetInRootWindow(). |
Jun Mukai | 0f3ae529 | 2018-08-22 16:28:11 | [diff] [blame] | 143 | ui::GestureRecognizer* gesture_recognizer = |
| 144 | root_window->env()->gesture_recognizer(); |
| 145 | DCHECK(!gesture_recognizer->GetTouchLockedTarget(touch)); |
| 146 | ui::GestureConsumer* consumer = gesture_recognizer->GetTargetForLocation( |
| 147 | event.location_f(), touch.source_device_id()); |
Scott Violet | 91c9d38 | 2017-06-22 16:53:33 | [diff] [blame] | 148 | if (consumer) |
| 149 | return static_cast<Window*>(consumer); |
| 150 | |
lanwei | 5f78358db | 2018-11-29 01:16:33 | [diff] [blame] | 151 | #if defined(OS_CHROMEOS) |
Mike Wasserman | 5613aca | 2018-08-09 02:11:07 | [diff] [blame] | 152 | // If the initial touch is outside the window's display, target the root. |
| 153 | // This is used for bezel gesture events (eg. swiping in from screen edge). |
| 154 | display::Display display = |
| 155 | display::Screen::GetScreen()->GetDisplayNearestWindow(root_window); |
Mike Wasserman | cc86c54 | 2018-09-28 20:47:56 | [diff] [blame] | 156 | // The window target may be null, so use the root's ScreenPositionClient. |
| 157 | gfx::Point screen_location = event.root_location(); |
| 158 | if (client::GetScreenPositionClient(root_window)) { |
| 159 | client::GetScreenPositionClient(root_window) |
| 160 | ->ConvertPointToScreen(root_window, &screen_location); |
| 161 | } |
Mike Wasserman | 5613aca | 2018-08-09 02:11:07 | [diff] [blame] | 162 | if (!display.bounds().Contains(screen_location)) |
Scott Violet | 91c9d38 | 2017-06-22 16:53:33 | [diff] [blame] | 163 | return root_window; |
lanwei | 5f78358db | 2018-11-29 01:16:33 | [diff] [blame] | 164 | #else |
| 165 | // If the initial touch is outside the root window, target the root. |
| 166 | // TODO: this code is likely not necessarily and will be removed. |
| 167 | if (!root_window->bounds().Contains(event.location())) |
| 168 | return root_window; |
| 169 | #endif |
Scott Violet | 91c9d38 | 2017-06-22 16:53:33 | [diff] [blame] | 170 | } |
| 171 | |
| 172 | return nullptr; |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 173 | } |
| 174 | |
Scott Violet | 3b4bffa3 | 2017-09-05 20:35:15 | [diff] [blame] | 175 | bool WindowTargeter::ProcessEventIfTargetsDifferentRootWindow( |
| 176 | Window* root_window, |
| 177 | Window* target, |
| 178 | ui::Event* event) { |
| 179 | if (root_window->Contains(target)) |
| 180 | return false; |
| 181 | |
| 182 | // |window| is the root window, but |target| is not a descendent of |
| 183 | // |window|. So do not allow dispatching from here. Instead, dispatch the |
| 184 | // event through the WindowEventDispatcher that owns |target|. |
| 185 | Window* new_root = target->GetRootWindow(); |
| 186 | DCHECK(new_root); |
| 187 | if (event->IsLocatedEvent()) { |
| 188 | // The event has been transformed to be in |target|'s coordinate system. |
| 189 | // But dispatching the event through the EventProcessor requires the event |
| 190 | // to be in the host's coordinate system. So, convert the event to be in |
| 191 | // the root's coordinate space, and then to the host's coordinate space by |
| 192 | // applying the host's transform. |
| 193 | ui::LocatedEvent* located_event = event->AsLocatedEvent(); |
| 194 | located_event->ConvertLocationToTarget(target, new_root); |
| 195 | WindowTreeHost* window_tree_host = new_root->GetHost(); |
| 196 | located_event->UpdateForRootTransform( |
| 197 | window_tree_host->GetRootTransform(), |
| 198 | window_tree_host->GetRootTransformForLocalEventCoordinates()); |
| 199 | } |
| 200 | ignore_result(new_root->GetHost()->event_sink()->OnEventFromSource(event)); |
| 201 | return true; |
| 202 | } |
| 203 | |
varkha | 9c6bcf71 | 2015-06-11 18:32:58 | [diff] [blame] | 204 | ui::EventTarget* WindowTargeter::FindTargetForEvent(ui::EventTarget* root, |
| 205 | ui::Event* event) { |
[email protected] | 4c5d7c9 | 2013-12-13 17:17:39 | [diff] [blame] | 206 | Window* window = static_cast<Window*>(root); |
moshayedi | 4e662301 | 2016-03-02 04:53:58 | [diff] [blame] | 207 | Window* target = event->IsKeyEvent() |
Scott Violet | 6c77e2f6 | 2018-10-19 16:38:42 | [diff] [blame] | 208 | ? FindTargetForKeyEvent(window) |
moshayedi | 4e662301 | 2016-03-02 04:53:58 | [diff] [blame] | 209 | : FindTargetForNonKeyEvent(window, event); |
Scott Violet | 3b4bffa3 | 2017-09-05 20:35:15 | [diff] [blame] | 210 | if (target && !window->parent() && |
| 211 | ProcessEventIfTargetsDifferentRootWindow(window, target, event)) { |
| 212 | return nullptr; |
[email protected] | 4c5d7c9 | 2013-12-13 17:17:39 | [diff] [blame] | 213 | } |
varkha | 9c6bcf71 | 2015-06-11 18:32:58 | [diff] [blame] | 214 | return target; |
| 215 | } |
| 216 | |
| 217 | ui::EventTarget* WindowTargeter::FindNextBestTarget( |
| 218 | ui::EventTarget* previous_target, |
| 219 | ui::Event* event) { |
| 220 | return nullptr; |
| 221 | } |
| 222 | |
Scott Violet | 6c77e2f6 | 2018-10-19 16:38:42 | [diff] [blame] | 223 | Window* WindowTargeter::FindTargetForKeyEvent(Window* window) { |
| 224 | Window* root_window = window->GetRootWindow(); |
| 225 | client::FocusClient* focus_client = client::GetFocusClient(root_window); |
| 226 | if (!focus_client) |
| 227 | return window; |
| 228 | Window* focused_window = focus_client->GetFocusedWindow(); |
| 229 | if (!focused_window) |
| 230 | return window; |
| 231 | |
| 232 | client::EventClient* event_client = client::GetEventClient(root_window); |
| 233 | if (event_client && |
| 234 | !event_client->CanProcessEventsWithinSubtree(focused_window)) { |
| 235 | focus_client->FocusWindow(nullptr); |
| 236 | return nullptr; |
| 237 | } |
| 238 | return focused_window ? focused_window : window; |
| 239 | } |
| 240 | |
Scott Violet | aca0bd9 | 2018-09-04 20:14:24 | [diff] [blame] | 241 | void WindowTargeter::OnInstalled(Window* window) { |
Jun Mukai | 832af1359 | 2018-11-30 05:43:44 | [diff] [blame] | 242 | // Needs to clear the existing insets when uninstalled. |
| 243 | if (!window) |
| 244 | aura::UpdateMusIfNecessary(window_, gfx::Insets(), gfx::Insets()); |
Scott Violet | aca0bd9 | 2018-09-04 20:14:24 | [diff] [blame] | 245 | window_ = window; |
Scott Violet | 5f7e0b4 | 2018-09-05 18:05:17 | [diff] [blame] | 246 | UpdateMusIfNecessary(); |
Scott Violet | aca0bd9 | 2018-09-04 20:14:24 | [diff] [blame] | 247 | } |
| 248 | |
Scott Violet | 91c9d38 | 2017-06-22 16:53:33 | [diff] [blame] | 249 | Window* WindowTargeter::FindTargetForLocatedEvent(Window* window, |
| 250 | ui::LocatedEvent* event) { |
| 251 | if (!window->parent()) { |
| 252 | Window* target = FindTargetInRootWindow(window, *event); |
| 253 | if (target) { |
| 254 | window->ConvertEventToTarget(target, event); |
Ahmed Fakhry | 9bd7bf4 | 2017-12-11 19:10:32 | [diff] [blame] | 255 | |
| 256 | #if defined(OS_CHROMEOS) |
| 257 | if (window->IsRootWindow() && event->HasNativeEvent()) { |
| 258 | // If window is root, and the target is in a different host, we need to |
| 259 | // convert the native event to the target's host as well. This happens |
| 260 | // while a widget is being dragged and when the majority of its bounds |
| 261 | // reside in a different display. Setting the widget's bounds at this |
| 262 | // point changes the window's root, and the event's target's root, but |
| 263 | // the events are still being generated relative to the original |
| 264 | // display. crbug.com/714578. |
| 265 | ui::LocatedEvent* e = |
| 266 | static_cast<ui::LocatedEvent*>(event->native_event()); |
| 267 | gfx::PointF native_point = e->location_f(); |
| 268 | aura::Window::ConvertNativePointToTargetHost(window, target, |
| 269 | &native_point); |
| 270 | e->set_location_f(native_point); |
| 271 | } |
| 272 | #endif |
| 273 | |
Scott Violet | 91c9d38 | 2017-06-22 16:53:33 | [diff] [blame] | 274 | return target; |
| 275 | } |
| 276 | } |
| 277 | return FindTargetForLocatedEventRecursively(window, event); |
| 278 | } |
| 279 | |
| 280 | bool WindowTargeter::SubtreeCanAcceptEvent( |
varkha | 9c6bcf71 | 2015-06-11 18:32:58 | [diff] [blame] | 281 | Window* window, |
Scott Violet | 91c9d38 | 2017-06-22 16:53:33 | [diff] [blame] | 282 | const ui::LocatedEvent& event) const { |
| 283 | if (!window->IsVisible()) |
| 284 | return false; |
Scott Violet | ca58856d | 2017-07-23 20:38:10 | [diff] [blame] | 285 | if (window->event_targeting_policy() == |
Scott Violet | 8a3fad5 | 2018-08-24 21:38:55 | [diff] [blame] | 286 | ws::mojom::EventTargetingPolicy::NONE || |
Scott Violet | ca58856d | 2017-07-23 20:38:10 | [diff] [blame] | 287 | window->event_targeting_policy() == |
Scott Violet | 8a3fad5 | 2018-08-24 21:38:55 | [diff] [blame] | 288 | ws::mojom::EventTargetingPolicy::TARGET_ONLY) { |
Scott Violet | 91c9d38 | 2017-06-22 16:53:33 | [diff] [blame] | 289 | return false; |
Scott Violet | ca58856d | 2017-07-23 20:38:10 | [diff] [blame] | 290 | } |
Scott Violet | 91c9d38 | 2017-06-22 16:53:33 | [diff] [blame] | 291 | client::EventClient* client = client::GetEventClient(window->GetRootWindow()); |
| 292 | if (client && !client->CanProcessEventsWithinSubtree(window)) |
| 293 | return false; |
| 294 | |
| 295 | Window* parent = window->parent(); |
| 296 | if (parent && parent->delegate_ && |
| 297 | !parent->delegate_->ShouldDescendIntoChildForEventHandling( |
| 298 | window, event.location())) { |
| 299 | return false; |
| 300 | } |
| 301 | return true; |
| 302 | } |
| 303 | |
| 304 | bool WindowTargeter::EventLocationInsideBounds( |
| 305 | Window* window, |
| 306 | const ui::LocatedEvent& event) const { |
Valery Arkhangorodsky | cac5e0c | 2017-07-24 20:00:45 | [diff] [blame] | 307 | gfx::Rect mouse_rect; |
| 308 | gfx::Rect touch_rect; |
| 309 | if (!GetHitTestRects(window, &mouse_rect, &touch_rect)) |
| 310 | return false; |
| 311 | |
| 312 | const gfx::Vector2d offset = -window->bounds().OffsetFromOrigin(); |
| 313 | mouse_rect.Offset(offset); |
| 314 | touch_rect.Offset(offset); |
Scott Violet | 91c9d38 | 2017-06-22 16:53:33 | [diff] [blame] | 315 | gfx::Point point = event.location(); |
| 316 | if (window->parent()) |
| 317 | Window::ConvertPointToTarget(window->parent(), window, &point); |
Valery Arkhangorodsky | cac5e0c | 2017-07-24 20:00:45 | [diff] [blame] | 318 | |
Valery Arkhangorodsky | 34a5863 | 2017-08-16 16:25:48 | [diff] [blame] | 319 | const bool point_in_rect = event.IsTouchEvent() || event.IsGestureEvent() |
| 320 | ? touch_rect.Contains(point) |
| 321 | : mouse_rect.Contains(point); |
| 322 | if (!point_in_rect) |
| 323 | return false; |
Valery Arkhangorodsky | cac5e0c | 2017-07-24 20:00:45 | [diff] [blame] | 324 | |
Valery Arkhangorodsky | 34a5863 | 2017-08-16 16:25:48 | [diff] [blame] | 325 | auto shape_rects = GetExtraHitTestShapeRects(window); |
| 326 | if (!shape_rects) |
| 327 | return true; |
| 328 | |
| 329 | for (const gfx::Rect& shape_rect : *shape_rects) { |
| 330 | if (shape_rect.Contains(point)) { |
| 331 | return true; |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | return false; |
Valery Arkhangorodsky | cac5e0c | 2017-07-24 20:00:45 | [diff] [blame] | 336 | } |
| 337 | |
Scott Violet | 427807c7 | 2018-09-04 22:15:20 | [diff] [blame] | 338 | bool WindowTargeter::ShouldUseExtendedBounds(const aura::Window* w) const { |
| 339 | // window() is null when this is used as the default targeter (by |
| 340 | // WindowEventDispatcher). Insets should never be set in this case, so the |
| 341 | // return should not matter. |
| 342 | if (!window()) { |
| 343 | DCHECK(mouse_extend_.IsEmpty()); |
| 344 | DCHECK(touch_extend_.IsEmpty()); |
| 345 | return false; |
| 346 | } |
| 347 | |
| 348 | // Insets should only apply to the window. Subclasses may enforce other |
| 349 | // policies. |
| 350 | return window() == w; |
[email protected] | 4c5d7c9 | 2013-12-13 17:17:39 | [diff] [blame] | 351 | } |
| 352 | |
Scott Violet | 5f7e0b4 | 2018-09-05 18:05:17 | [diff] [blame] | 353 | // TODO: this function should go away once https://crbug.com/879308 is fixed. |
| 354 | void WindowTargeter::UpdateMusIfNecessary() { |
Jun Mukai | 832af1359 | 2018-11-30 05:43:44 | [diff] [blame] | 355 | aura::UpdateMusIfNecessary(window_, mouse_extend_, touch_extend_); |
Scott Violet | 5f7e0b4 | 2018-09-05 18:05:17 | [diff] [blame] | 356 | } |
Valery Arkhangorodsky | 94dd7ba | 2017-07-26 02:19:50 | [diff] [blame] | 357 | |
varkha | 9c6bcf71 | 2015-06-11 18:32:58 | [diff] [blame] | 358 | Window* WindowTargeter::FindTargetForNonKeyEvent(Window* root_window, |
| 359 | ui::Event* event) { |
| 360 | if (!event->IsLocatedEvent()) |
| 361 | return root_window; |
| 362 | return FindTargetForLocatedEvent(root_window, |
| 363 | static_cast<ui::LocatedEvent*>(event)); |
| 364 | } |
| 365 | |
varkha | 9c6bcf71 | 2015-06-11 18:32:58 | [diff] [blame] | 366 | Window* WindowTargeter::FindTargetForLocatedEventRecursively( |
| 367 | Window* root_window, |
| 368 | ui::LocatedEvent* event) { |
danakj | 25c52c3 | 2016-04-12 21:51:08 | [diff] [blame] | 369 | std::unique_ptr<ui::EventTargetIterator> iter = |
| 370 | root_window->GetChildIterator(); |
varkha | 9c6bcf71 | 2015-06-11 18:32:58 | [diff] [blame] | 371 | if (iter) { |
| 372 | ui::EventTarget* target = root_window; |
| 373 | for (ui::EventTarget* child = iter->GetNextTarget(); child; |
| 374 | child = iter->GetNextTarget()) { |
| 375 | WindowTargeter* targeter = |
| 376 | static_cast<WindowTargeter*>(child->GetEventTargeter()); |
| 377 | if (!targeter) |
| 378 | targeter = this; |
| 379 | if (!targeter->SubtreeShouldBeExploredForEvent( |
| 380 | static_cast<Window*>(child), *event)) { |
| 381 | continue; |
| 382 | } |
| 383 | target->ConvertEventToTarget(child, event); |
| 384 | target = child; |
| 385 | Window* child_target_window = |
| 386 | static_cast<Window*>(targeter->FindTargetForEvent(child, event)); |
| 387 | if (child_target_window) |
| 388 | return child_target_window; |
| 389 | } |
| 390 | target->ConvertEventToTarget(root_window, event); |
| 391 | } |
| 392 | return root_window->CanAcceptEvent(*event) ? root_window : nullptr; |
[email protected] | 4c5d7c9 | 2013-12-13 17:17:39 | [diff] [blame] | 393 | } |
| 394 | |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 395 | } // namespace aura |