Commit 85b33aee authored by Mike Wasserman's avatar Mike Wasserman Committed by Commit Bot

ws: Fix WindowTargeter touch event location check

Use event.location() + ScreenPosition client in FindTargetInRootWindow:
 - location() is in |root_window| coordinates for the ws and clients
 - root_location() is *not* in |root_window| coordinates for clients:
   - |root_window| is the client-root (the top-level client app window)
   - root_location() is Ash's display-root coords (full display bounds)

Add a WindowTreeTest for event locations and root locations.
Add a WindowTargeterTest for FindTargetInRootWindow and regressions.

Bug: 873763, 793916
Test: KSV (Ctrl-Alt-/), Arc, Mash, 2nd display, etc. touch input works.
Change-Id: I7ae541203181f9fc5c65449a10ca927f90d29d96
Reviewed-on: https://chromium-review.googlesource.com/1176462
Commit-Queue: Michael Wasserman <msw@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#583488}
parent d46d0152
......@@ -353,6 +353,45 @@ TEST(WindowTreeTest, WindowToWindowData) {
data->properties[ui::mojom::WindowManager::kAlwaysOnTop_Property]));
}
TEST(WindowTreeTest, EventLocation) {
WindowServiceTestSetup setup;
TestWindowTreeClient* window_tree_client = setup.window_tree_client();
aura::Window* top_level =
setup.window_tree_test_helper()->NewTopLevelWindow();
ASSERT_TRUE(top_level);
top_level->Show();
top_level->SetBounds(gfx::Rect(10, 20, 100, 100));
// Add a child Window that covers the bottom half of the top-level window.
aura::Window* window = setup.window_tree_test_helper()->NewWindow();
ASSERT_TRUE(window);
window->Show();
window->SetBounds(gfx::Rect(0, 50, 100, 50));
top_level->AddChild(window);
test::EventGenerator event_generator(setup.root());
event_generator.MoveMouseTo(33, 44);
ASSERT_EQ(1u, window_tree_client->input_events().size());
TestWindowTreeClient::InputEvent event1 = window_tree_client->PopInputEvent();
ASSERT_TRUE(event1.event->IsLocatedEvent());
ui::LocatedEvent* located_event1 = event1.event->AsLocatedEvent();
// The location is in the top-level's (client-root) coordinate system.
EXPECT_EQ(gfx::Point(23, 24), located_event1->location());
// The root location is in the display's (display-root) coordinate system.
EXPECT_EQ(gfx::Point(33, 44), located_event1->root_location());
event_generator.MoveMouseTo(55, 66);
ASSERT_EQ(1u, window_tree_client->input_events().size());
TestWindowTreeClient::InputEvent event2 = window_tree_client->PopInputEvent();
ASSERT_TRUE(event2.event->IsLocatedEvent());
ui::LocatedEvent* located_event2 = event2.event->AsLocatedEvent();
// The location is in the top-level's (client-root) coordinate system.
EXPECT_EQ(gfx::Point(45, 46), located_event2->location());
// The root location is in the display's (display-root) coordinate system.
EXPECT_EQ(gfx::Point(55, 66), located_event2->root_location());
}
TEST(WindowTreeTest, MovePressDragRelease) {
WindowServiceTestSetup setup;
TestWindowTreeClient* window_tree_client = setup.window_tree_client();
......
......@@ -127,7 +127,11 @@ Window* WindowTargeter::FindTargetInRootWindow(Window* root_window,
// This is used for bezel gesture events (eg. swiping in from screen edge).
display::Display display =
display::Screen::GetScreen()->GetDisplayNearestWindow(root_window);
gfx::Point screen_location = event.root_location();
// event.location() is in |root_window|'s coordinate system at this point.
// Using event.root_location() breaks calculations in mus clients, because
// event.root_location() is in the display-root's coordinate system, but
// |root_window| is actually the top-level window of the mus client.
gfx::Point screen_location = event.location();
if (client::GetScreenPositionClient(root_window)) {
client::GetScreenPositionClient(root_window)
->ConvertPointToScreen(root_window, &screen_location);
......
......@@ -11,6 +11,8 @@
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/events/event_utils.h"
#include "ui/events/test/test_event_handler.h"
......@@ -56,12 +58,10 @@ TEST_P(WindowTargeterTest, Basic) {
Window* one = CreateNormalWindow(2, window.get(), &delegate);
Window* two = CreateNormalWindow(3, window.get(), &delegate);
window->SetBounds(gfx::Rect(0, 0, 100, 100));
window->SetBounds(gfx::Rect(0, 0, 1000, 1000));
one->SetBounds(gfx::Rect(0, 0, 500, 100));
two->SetBounds(gfx::Rect(501, 0, 500, 1000));
root_window()->Show();
ui::test::TestEventHandler handler;
one->AddPreTargetHandler(&handler);
......@@ -78,6 +78,47 @@ TEST_P(WindowTargeterTest, Basic) {
one->RemovePreTargetHandler(&handler);
}
TEST_P(WindowTargeterTest, FindTargetInRootWindow) {
WindowTargeter targeter;
display::Display display =
display::Screen::GetScreen()->GetDisplayNearestWindow(root_window());
EXPECT_EQ(display.bounds(), root_window()->GetBoundsInScreen());
EXPECT_EQ(display.bounds(), gfx::Rect(0, 0, 800, 600));
// Mouse and touch presses inside the display yield null targets.
gfx::Point inside = display.bounds().CenterPoint();
ui::MouseEvent mouse1(ui::ET_MOUSE_PRESSED, inside, inside,
ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
ui::TouchEvent touch1(ui::ET_TOUCH_PRESSED, inside, ui::EventTimeForNow(),
ui::PointerDetails());
touch1.set_root_location(inside);
EXPECT_EQ(nullptr, targeter.FindTargetInRootWindow(root_window(), mouse1));
EXPECT_EQ(nullptr, targeter.FindTargetInRootWindow(root_window(), touch1));
// Touch presses outside the display yields the root window as a target.
gfx::Point outside(display.bounds().right() + 10, inside.y());
ui::MouseEvent mouse2(ui::ET_MOUSE_PRESSED, outside, outside,
ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
ui::TouchEvent touch2(ui::ET_TOUCH_PRESSED, outside, ui::EventTimeForNow(),
ui::PointerDetails());
touch2.set_root_location(outside);
EXPECT_EQ(nullptr, targeter.FindTargetInRootWindow(root_window(), mouse2));
EXPECT_EQ(root_window(),
targeter.FindTargetInRootWindow(root_window(), touch2));
// Simulate a mus client root (top level app window) with bottom-right bounds.
// Touches in the root and display should yield null targets crbug.com/873763.
// (mus clients root locations are display coords, not client-root coords)
root_window()->SetBounds(gfx::Rect(600, 500, 200, 100));
gfx::Point root_touch_coords(199, 99);
gfx::Point display_touch_coords(799, 699);
ui::TouchEvent touch3(ui::ET_TOUCH_PRESSED, root_touch_coords,
ui::EventTimeForNow(), ui::PointerDetails());
touch3.set_root_location(display_touch_coords);
EXPECT_EQ(nullptr, targeter.FindTargetInRootWindow(root_window(), touch3));
}
TEST_P(WindowTargeterTest, ScopedWindowTargeter) {
test::TestWindowDelegate delegate;
std::unique_ptr<Window> window(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment