diff options
Diffstat (limited to 'chromium/components/exo/shell_surface_util.cc')
-rw-r--r-- | chromium/components/exo/shell_surface_util.cc | 58 |
1 files changed, 46 insertions, 12 deletions
diff --git a/chromium/components/exo/shell_surface_util.cc b/chromium/components/exo/shell_surface_util.cc index b53d60c62a2..a6a523d83e3 100644 --- a/chromium/components/exo/shell_surface_util.cc +++ b/chromium/components/exo/shell_surface_util.cc @@ -17,6 +17,7 @@ #include "ui/aura/client/capture_client.h" #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" +#include "ui/aura/window_targeter.h" #include "ui/events/event.h" #include "ui/views/widget/widget.h" #include "ui/wm/core/window_util.h" @@ -57,6 +58,18 @@ bool ShouldHTComponentBlocked(int component) { } } +// Find the lowest targeter in the parent chain. +aura::WindowTargeter* FindTargeter(ui::EventTarget* target) { + do { + ui::EventTargeter* targeter = target->GetEventTargeter(); + if (targeter) + return static_cast<aura::WindowTargeter*>(targeter); + target = target->GetParentTarget(); + } while (target); + + return nullptr; +} + } // namespace void SetShellApplicationId(aura::Window* window, @@ -130,13 +143,14 @@ ShellSurfaceBase* GetShellSurfaceBaseForWindow(aura::Window* window) { return static_cast<ShellSurfaceBase*>(widget->widget_delegate()); } -Surface* GetTargetSurfaceForLocatedEvent(ui::LocatedEvent* event) { +Surface* GetTargetSurfaceForLocatedEvent( + const ui::LocatedEvent* original_event) { aura::Window* window = WMHelper::GetInstance()->GetCaptureClient()->GetCaptureWindow(); - gfx::PointF location_in_target_f = event->location_f(); - - if (!window) - return Surface::AsSurface(static_cast<aura::Window*>(event->target())); + if (!window) { + return Surface::AsSurface( + static_cast<aura::Window*>(original_event->target())); + } Surface* main_surface = GetShellMainSurface(window); // Skip if the event is captured by non exo windows. @@ -148,13 +162,33 @@ Surface* GetTargetSurfaceForLocatedEvent(ui::LocatedEvent* event) { if (!main_surface) return nullptr; } + DCHECK_EQ(window, static_cast<aura::Window*>(original_event->target())); - while (true) { - gfx::Point location_in_target = gfx::ToFlooredPoint(location_in_target_f); - aura::Window* focused = window->GetEventHandlerForPoint(location_in_target); + // Create a clone of the event as targeter may update it during the + // search. + auto cloned = ui::Event::Clone(*original_event); + ui::LocatedEvent* event = cloned->AsLocatedEvent(); - if (focused) - return Surface::AsSurface(focused); + while (true) { + gfx::PointF location_in_target_f = event->location_f(); + gfx::Point location_in_target = event->location(); + ui::EventTarget* event_target = window; + aura::WindowTargeter* targeter = FindTargeter(event_target); + DCHECK(targeter); + + aura::Window* focused = + static_cast<aura::Window*>(targeter->FindTargetForEvent(window, event)); + + if (focused) { + Surface* surface = Surface::AsSurface(focused); + if (focused != window) + return surface; + else if (surface && surface->HitTest(location_in_target)) { + // If the targeting fallback to the root (first) window, test the + // hit region again. + return surface; + } + } // If the event falls into the place where the window system should care // about (i.e. window caption), do not check the transient parent but just @@ -170,8 +204,8 @@ Surface* GetTargetSurfaceForLocatedEvent(ui::LocatedEvent* event) { if (!parent_window) return main_surface; - aura::Window::ConvertPointToTarget(window, parent_window, - &location_in_target_f); + event->set_location_f(location_in_target_f); + event_target->ConvertEventToTarget(parent_window, event); window = parent_window; } } |