| // Copyright 2012 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include"ash/public/cpp/shell_window_ids.h" |
| #include"ash/root_window_controller.h" |
| #include"ash/shell.h" |
| #include"ash/system/status_area_widget.h" |
| #include"ash/system/status_area_widget_test_helper.h" |
| #include"ash/system/unified/unified_system_tray.h" |
| #include"ash/test/ash_test_base.h" |
| #include"ash/test/test_widget_builder.h" |
| #include"ash/test/test_window_builder.h" |
| #include"ash/wm/desks/desks_util.h" |
| #include"ash/wm/window_properties.h" |
| #include"ash/wm/window_util.h" |
| #include"base/memory/raw_ptr.h" |
| #include"base/run_loop.h" |
| #include"base/strings/string_util.h" |
| #include"base/strings/utf_string_conversions.h" |
| #include"ui/aura/client/capture_client.h" |
| #include"ui/aura/client/focus_client.h" |
| #include"ui/aura/test/test_windows.h" |
| #include"ui/aura/test/window_test_api.h" |
| #include"ui/aura/window.h" |
| #include"ui/aura/window_event_dispatcher.h" |
| #include"ui/base/cursor/cursor.h" |
| #include"ui/base/cursor/mojom/cursor_type.mojom-shared.h" |
| #include"ui/display/display.h" |
| #include"ui/display/display_layout.h" |
| #include"ui/display/manager/display_manager.h" |
| #include"ui/display/screen.h" |
| #include"ui/events/event_handler.h" |
| #include"ui/events/test/event_generator.h" |
| #include"ui/views/controls/textfield/textfield.h" |
| #include"ui/views/widget/widget.h" |
| #include"ui/views/widget/widget_delegate.h" |
| #include"ui/wm/core/window_util.h" |
| #include"ui/wm/public/activation_client.h" |
| |
| namespace ash{ |
| namespace{ |
| |
| voidSetSecondaryDisplayLayout(display::DisplayPlacement::Position position){ |
| std::unique_ptr<display::DisplayLayout> layout= |
| Shell::Get()->display_manager()->GetCurrentDisplayLayout().Copy(); |
| layout->placement_list[0].position= position; |
| Shell::Get()->display_manager()->SetLayoutForCurrentDisplays( |
| std::move(layout)); |
| } |
| |
| // An event handler which moves the target window to the secondary root window |
| // at pre-handle phase of a mouse release event. |
| classMoveWindowByClickEventHandler:public ui::EventHandler{ |
| public: |
| explicitMoveWindowByClickEventHandler(aura::Window* target) |
| : target_(target){} |
| |
| MoveWindowByClickEventHandler(constMoveWindowByClickEventHandler&)=delete; |
| MoveWindowByClickEventHandler&operator=( |
| constMoveWindowByClickEventHandler&)=delete; |
| |
| ~MoveWindowByClickEventHandler() override=default; |
| |
| private: |
| // ui::EventHandler overrides: |
| voidOnMouseEvent(ui::MouseEvent* event) override{ |
| if(event->type()== ui::EventType::kMouseReleased){ |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| DCHECK_LT(1u, root_windows.size()); |
| root_windows[1]->AddChild(target_); |
| } |
| } |
| |
| raw_ptr<aura::Window> target_; |
| }; |
| |
| // An event handler which records the event's locations. |
| classEventLocationRecordingEventHandler:public ui::EventHandler{ |
| public: |
| EventLocationRecordingEventHandler(){Reset();} |
| |
| EventLocationRecordingEventHandler( |
| constEventLocationRecordingEventHandler&)=delete; |
| EventLocationRecordingEventHandler&operator=( |
| constEventLocationRecordingEventHandler&)=delete; |
| |
| ~EventLocationRecordingEventHandler() override=default; |
| |
| // |location_| is relative to the target window. |
| std::stringGetLocation()const{return location_.ToString();} |
| |
| // |root_location_| is relative to the display where the event started. |
| std::stringGetRootLocation()const{return root_location_.ToString();} |
| |
| voidReset(){ |
| location_.SetPoint(-999,-999); |
| root_location_.SetPoint(-999,-999); |
| } |
| |
| private: |
| // ui::EventHandler overrides: |
| voidOnMouseEvent(ui::MouseEvent* event) override{ |
| if(event->type()== ui::EventType::kMouseMoved|| |
| event->type()== ui::EventType::kMouseDragged){ |
| location_= event->location(); |
| root_location_= event->root_location(); |
| } |
| } |
| |
| gfx::Point root_location_; |
| gfx::Point location_; |
| }; |
| |
| classEventLocationHandler:public ui::EventHandler{ |
| public: |
| EventLocationHandler()=default; |
| |
| EventLocationHandler(constEventLocationHandler&)=delete; |
| EventLocationHandler&operator=(constEventLocationHandler&)=delete; |
| |
| ~EventLocationHandler() override=default; |
| |
| const gfx::Point& press_location()const{return press_location_;} |
| const gfx::Point& release_location()const{return release_location_;} |
| |
| private: |
| // ui::EventHandler: |
| voidOnMouseEvent(ui::MouseEvent* event) override{ |
| if(event->type()== ui::EventType::kMousePressed){ |
| press_location_= event->location(); |
| }elseif(event->type()== ui::EventType::kMouseReleased){ |
| release_location_= event->location(); |
| } |
| } |
| |
| gfx::Point press_location_; |
| gfx::Point release_location_; |
| }; |
| |
| }// namespace |
| |
| classExtendedDesktopTest:publicAshTestBase{ |
| public: |
| ExtendedDesktopTest()=default; |
| |
| ExtendedDesktopTest(constExtendedDesktopTest&)=delete; |
| ExtendedDesktopTest&operator=(constExtendedDesktopTest&)=delete; |
| |
| ~ExtendedDesktopTest() override=default; |
| |
| voidSetUp() override{ |
| AshTestBase::SetUp(); |
| |
| // Shell hides the cursor by default; show it for these tests. |
| Shell::Get()->cursor_manager()->ShowCursor(); |
| } |
| |
| views::Widget*CreateTestWidget(const gfx::Rect& bounds){ |
| returnTestWidgetBuilder() |
| .SetBounds(bounds) |
| .SetContext(GetContext()) |
| .BuildOwnedByNativeWidget(); |
| } |
| |
| protected: |
| boolIsBubbleShown(){ |
| returnGetPrimaryUnifiedSystemTray()->IsBubbleShown(); |
| } |
| |
| gfx::RectGetSystemTrayBoundsInScreen(){ |
| returnGetPrimaryUnifiedSystemTray()->GetBoundsInScreen(); |
| } |
| }; |
| |
| // Test conditions that root windows in extended desktop mode must satisfy. |
| TEST_F(ExtendedDesktopTest,Basic){ |
| UpdateDisplay("1000x600,600x400"); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| |
| // All root windows must have a root window controller. |
| ASSERT_EQ(2U, root_windows.size()); |
| EXPECT_TRUE(RootWindowController::ForWindow(root_windows[0])); |
| EXPECT_TRUE(RootWindowController::ForWindow(root_windows[1])); |
| // Make sure root windows share the same controllers. |
| EXPECT_EQ(aura::client::GetFocusClient(root_windows[0]), |
| aura::client::GetFocusClient(root_windows[1])); |
| EXPECT_EQ(::wm::GetActivationClient(root_windows[0]), |
| ::wm::GetActivationClient(root_windows[1])); |
| EXPECT_EQ(aura::client::GetCaptureClient(root_windows[0]), |
| aura::client::GetCaptureClient(root_windows[1])); |
| } |
| |
| TEST_F(ExtendedDesktopTest,Activation){ |
| UpdateDisplay("1000x600,600x400"); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| |
| views::Widget* widget_on_1st=CreateTestWidget(gfx::Rect(10,10,100,100)); |
| views::Widget* widget_on_2nd= |
| CreateTestWidget(gfx::Rect(1200,10,100,100)); |
| EXPECT_EQ(root_windows[0], widget_on_1st->GetNativeView()->GetRootWindow()); |
| EXPECT_EQ(root_windows[1], widget_on_2nd->GetNativeView()->GetRootWindow()); |
| |
| EXPECT_EQ(widget_on_2nd->GetNativeView(), |
| aura::client::GetFocusClient(root_windows[0])->GetFocusedWindow()); |
| EXPECT_TRUE(wm::IsActiveWindow(widget_on_2nd->GetNativeView())); |
| |
| ui::test::EventGenerator* event_generator=GetEventGenerator(); |
| // Clicking a window changes the active window and active root window. |
| event_generator->MoveMouseToCenterOf(widget_on_1st->GetNativeView()); |
| event_generator->ClickLeftButton(); |
| |
| EXPECT_EQ(widget_on_1st->GetNativeView(), |
| aura::client::GetFocusClient(root_windows[0])->GetFocusedWindow()); |
| EXPECT_TRUE(wm::IsActiveWindow(widget_on_1st->GetNativeView())); |
| |
| event_generator->MoveMouseToCenterOf(widget_on_2nd->GetNativeView()); |
| event_generator->ClickLeftButton(); |
| |
| EXPECT_EQ(widget_on_2nd->GetNativeView(), |
| aura::client::GetFocusClient(root_windows[0])->GetFocusedWindow()); |
| EXPECT_TRUE(wm::IsActiveWindow(widget_on_2nd->GetNativeView())); |
| } |
| |
| TEST_F(ExtendedDesktopTest,SystemModal){ |
| UpdateDisplay("1000x600,600x400"); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| |
| views::Widget* widget_on_1st=CreateTestWidget(gfx::Rect(10,10,100,100)); |
| EXPECT_TRUE(wm::IsActiveWindow(widget_on_1st->GetNativeView())); |
| EXPECT_EQ(root_windows[0], widget_on_1st->GetNativeView()->GetRootWindow()); |
| EXPECT_EQ(root_windows[0],Shell::GetRootWindowForNewWindows()); |
| |
| // Open system modal. Make sure it's on 2nd root window and active. |
| autodelegate= std::make_unique<views::WidgetDelegateView>( |
| views::WidgetDelegateView::CreatePassKey()); |
| delegate->SetModalType(ui::mojom::ModalType::kSystem); |
| views::Widget* modal_widget= views::Widget::CreateWindowWithContext( |
| delegate.release(),GetContext(), gfx::Rect(1200,100,100,100)); |
| modal_widget->Show(); |
| EXPECT_TRUE(wm::IsActiveWindow(modal_widget->GetNativeView())); |
| EXPECT_EQ(root_windows[1], modal_widget->GetNativeView()->GetRootWindow()); |
| EXPECT_EQ(root_windows[1],Shell::GetRootWindowForNewWindows()); |
| |
| ui::test::EventGenerator* event_generator=GetEventGenerator(); |
| |
| // Clicking a widget on widget_on_1st display should not change activation. |
| event_generator->MoveMouseToCenterOf(widget_on_1st->GetNativeView()); |
| event_generator->ClickLeftButton(); |
| EXPECT_TRUE(wm::IsActiveWindow(modal_widget->GetNativeView())); |
| EXPECT_EQ(root_windows[1],Shell::GetRootWindowForNewWindows()); |
| |
| // Close system modal and so clicking a widget should work now. |
| modal_widget->Close(); |
| event_generator->MoveMouseToCenterOf(widget_on_1st->GetNativeView()); |
| event_generator->ClickLeftButton(); |
| EXPECT_TRUE(wm::IsActiveWindow(widget_on_1st->GetNativeView())); |
| EXPECT_EQ(root_windows[0],Shell::GetRootWindowForNewWindows()); |
| } |
| |
| TEST_F(ExtendedDesktopTest,TestCursor){ |
| UpdateDisplay("1000x600,600x400"); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| aura::WindowTreeHost* host0= root_windows[0]->GetHost(); |
| aura::WindowTreeHost* host1= root_windows[1]->GetHost(); |
| EXPECT_EQ(ui::mojom::CursorType::kPointer, host0->last_cursor().type()); |
| EXPECT_EQ(ui::mojom::CursorType::kNull, host1->last_cursor().type()); |
| Shell::Get()->cursor_manager()->SetCursor(ui::mojom::CursorType::kCopy); |
| EXPECT_EQ(ui::mojom::CursorType::kCopy, host0->last_cursor().type()); |
| EXPECT_EQ(ui::mojom::CursorType::kCopy, host1->last_cursor().type()); |
| } |
| |
| TEST_F(ExtendedDesktopTest,TestCursorLocation){ |
| UpdateDisplay("1000x600,600x400"); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| aura::test::WindowTestApi root_window0_test_api(root_windows[0]); |
| aura::test::WindowTestApi root_window1_test_api(root_windows[1]); |
| |
| root_windows[0]->MoveCursorTo(gfx::Point(10,10)); |
| EXPECT_EQ("10,10", |
| display::Screen::GetScreen()->GetCursorScreenPoint().ToString()); |
| EXPECT_TRUE(root_window0_test_api.ContainsMouse()); |
| EXPECT_FALSE(root_window1_test_api.ContainsMouse()); |
| root_windows[1]->MoveCursorTo(gfx::Point(10,20)); |
| EXPECT_EQ("1010,20", |
| display::Screen::GetScreen()->GetCursorScreenPoint().ToString()); |
| EXPECT_FALSE(root_window0_test_api.ContainsMouse()); |
| EXPECT_TRUE(root_window1_test_api.ContainsMouse()); |
| root_windows[0]->MoveCursorTo(gfx::Point(20,10)); |
| EXPECT_EQ("20,10", |
| display::Screen::GetScreen()->GetCursorScreenPoint().ToString()); |
| EXPECT_TRUE(root_window0_test_api.ContainsMouse()); |
| EXPECT_FALSE(root_window1_test_api.ContainsMouse()); |
| } |
| |
| TEST_F(ExtendedDesktopTest,GetRootWindowAt){ |
| UpdateDisplay("700x500,600x500"); |
| SetSecondaryDisplayLayout(display::DisplayPlacement::LEFT); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| |
| using window_util::GetRootWindowAt; |
| EXPECT_EQ(root_windows[1],GetRootWindowAt(gfx::Point(-400,100))); |
| EXPECT_EQ(root_windows[1],GetRootWindowAt(gfx::Point(-1,100))); |
| EXPECT_EQ(root_windows[0],GetRootWindowAt(gfx::Point(0,300))); |
| EXPECT_EQ(root_windows[0],GetRootWindowAt(gfx::Point(700,300))); |
| |
| // Zero origin. |
| EXPECT_EQ(root_windows[0],GetRootWindowAt(gfx::Point(0,0))); |
| |
| // Out of range point should return the nearest root window |
| EXPECT_EQ(root_windows[1],GetRootWindowAt(gfx::Point(-600,0))); |
| EXPECT_EQ(root_windows[0],GetRootWindowAt(gfx::Point(701,100))); |
| } |
| |
| TEST_F(ExtendedDesktopTest,GetRootWindowMatching){ |
| UpdateDisplay("700x500,600x500"); |
| SetSecondaryDisplayLayout(display::DisplayPlacement::LEFT); |
| |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| |
| // Containing rect. |
| using window_util::GetRootWindowMatching; |
| EXPECT_EQ(root_windows[1], |
| GetRootWindowMatching(gfx::Rect(-300,10,50,50))); |
| EXPECT_EQ(root_windows[0],GetRootWindowMatching(gfx::Rect(100,10,50,50))); |
| |
| // Intersecting rect. |
| EXPECT_EQ(root_windows[1], |
| GetRootWindowMatching(gfx::Rect(-200,0,300,300))); |
| EXPECT_EQ(root_windows[0], |
| GetRootWindowMatching(gfx::Rect(-100,0,300,300))); |
| |
| // Zero origin. |
| EXPECT_EQ(root_windows[0],GetRootWindowMatching(gfx::Rect(0,0,0,0))); |
| EXPECT_EQ(root_windows[0],GetRootWindowMatching(gfx::Rect(0,0,1,1))); |
| |
| // Empty rect. |
| EXPECT_EQ(root_windows[1],GetRootWindowMatching(gfx::Rect(-400,100,0,0))); |
| EXPECT_EQ(root_windows[0],GetRootWindowMatching(gfx::Rect(100,100,0,0))); |
| |
| // Out of range rect should return the primary root window. |
| EXPECT_EQ(root_windows[0], |
| GetRootWindowMatching(gfx::Rect(-600,-300,50,50))); |
| EXPECT_EQ(root_windows[0],GetRootWindowMatching(gfx::Rect(0,1000,50,50))); |
| } |
| |
| TEST_F(ExtendedDesktopTest,Capture){ |
| // This test deals with input events but not visuals so don't throttle input |
| // on visuals. |
| aura::Env::GetInstance()->set_throttle_input_on_resize_for_testing(false); |
| |
| UpdateDisplay("1000x600,600x400"); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| |
| aura::test::EventCountDelegate r1_d1; |
| aura::test::EventCountDelegate r1_d2; |
| aura::test::EventCountDelegate r2_d1; |
| |
| std::unique_ptr<aura::Window> r1_w1(aura::test::CreateTestWindowWithDelegate( |
| &r1_d1,0, gfx::Rect(10,10,100,100), root_windows[0])); |
| std::unique_ptr<aura::Window> r1_w2(aura::test::CreateTestWindowWithDelegate( |
| &r1_d2,0, gfx::Rect(10,100,100,100), root_windows[0])); |
| std::unique_ptr<aura::Window> r2_w1(aura::test::CreateTestWindowWithDelegate( |
| &r2_d1,0, gfx::Rect(10,10,100,100), root_windows[1])); |
| |
| r1_w1->SetCapture(); |
| |
| EXPECT_EQ(r1_w1.get(), |
| aura::client::GetCaptureWindow(r2_w1->GetRootWindow())); |
| |
| ui::test::EventGenerator* generator=GetEventGenerator(); |
| generator->MoveMouseToCenterOf(r2_w1.get()); |
| // |r1_w1| will receive the events because it has capture. |
| EXPECT_EQ("1 1 0", r1_d1.GetMouseMotionCountsAndReset()); |
| EXPECT_EQ("0 0 0", r1_d2.GetMouseMotionCountsAndReset()); |
| EXPECT_EQ("0 0 0", r2_d1.GetMouseMotionCountsAndReset()); |
| |
| generator->ClickLeftButton(); |
| EXPECT_EQ("0 0 0", r2_d1.GetMouseMotionCountsAndReset()); |
| EXPECT_EQ("0 0", r2_d1.GetMouseButtonCountsAndReset()); |
| // The mouse is outside. On chromeos, the mouse is warped to the |
| // dest root window, but it's not implemented on Win yet, so |
| // no mouse move event on Win. |
| EXPECT_EQ("0 0 0", r1_d1.GetMouseMotionCountsAndReset()); |
| EXPECT_EQ("1 1", r1_d1.GetMouseButtonCountsAndReset()); |
| |
| generator->MoveMouseTo(15,15); |
| EXPECT_EQ("0 1 0", r1_d1.GetMouseMotionCountsAndReset()); |
| EXPECT_EQ("0 0 0", r1_d2.GetMouseMotionCountsAndReset()); |
| |
| r1_w2->SetCapture(); |
| EXPECT_EQ(r1_w2.get(), |
| aura::client::GetCaptureWindow(r2_w1->GetRootWindow())); |
| generator->MoveMouseBy(10,10); |
| // |r1_w2| has the capture. So it will receive the mouse-move event. |
| EXPECT_EQ("0 0 0", r1_d1.GetMouseMotionCountsAndReset()); |
| EXPECT_EQ("0 1 0", r1_d2.GetMouseMotionCountsAndReset()); |
| EXPECT_EQ("0 0 0", r2_d1.GetMouseMotionCountsAndReset()); |
| |
| generator->ClickLeftButton(); |
| EXPECT_EQ("0 0 0", r2_d1.GetMouseMotionCountsAndReset()); |
| EXPECT_EQ("0 0", r2_d1.GetMouseButtonCountsAndReset()); |
| EXPECT_EQ("0 0 0", r1_d2.GetMouseMotionCountsAndReset()); |
| EXPECT_EQ("1 1", r1_d2.GetMouseButtonCountsAndReset()); |
| |
| r1_w2->ReleaseCapture(); |
| EXPECT_EQ(nullptr, aura::client::GetCaptureWindow(r2_w1->GetRootWindow())); |
| |
| generator->MoveMouseToCenterOf(r2_w1.get()); |
| generator->ClickLeftButton(); |
| EXPECT_EQ("1 1 0", r2_d1.GetMouseMotionCountsAndReset()); |
| EXPECT_EQ("1 1", r2_d1.GetMouseButtonCountsAndReset()); |
| // Make sure the mouse_moved_handler_ is properly reset. |
| EXPECT_EQ("0 0 0", r1_d2.GetMouseMotionCountsAndReset()); |
| EXPECT_EQ("0 0", r1_d2.GetMouseButtonCountsAndReset()); |
| } |
| |
| TEST_F(ExtendedDesktopTest,CaptureEventLocation){ |
| UpdateDisplay("1000x600,600x400"); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| |
| aura::test::EventCountDelegate r1_d1; |
| aura::test::EventCountDelegate r1_d2; |
| aura::test::EventCountDelegate r2_d1; |
| |
| std::unique_ptr<aura::Window> r1_w1(aura::test::CreateTestWindowWithDelegate( |
| &r1_d1,0, gfx::Rect(10,10,100,100), root_windows[0])); |
| std::unique_ptr<aura::Window> r1_w2(aura::test::CreateTestWindowWithDelegate( |
| &r1_d2,0, gfx::Rect(10,100,100,100), root_windows[0])); |
| std::unique_ptr<aura::Window> r2_w1(aura::test::CreateTestWindowWithDelegate( |
| &r2_d1,0, gfx::Rect(10,10,100,100), root_windows[1])); |
| |
| r1_w1->SetCapture(); |
| |
| ui::test::EventGenerator* generator=GetEventGenerator(); |
| generator->MoveMouseToCenterOf(r2_w1.get()); |
| EXPECT_EQ(gfx::Point(1060,60).ToString(), |
| generator->current_screen_location().ToString()); |
| |
| EventLocationHandler location_handler; |
| r1_w1->AddPreTargetHandler(&location_handler); |
| generator->ClickLeftButton(); |
| r1_w1->RemovePreTargetHandler(&location_handler); |
| EXPECT_EQ(gfx::Point(1050,50).ToString(), |
| location_handler.press_location().ToString()); |
| EXPECT_EQ(gfx::Point(1050,50).ToString(), |
| location_handler.release_location().ToString()); |
| } |
| |
| TEST_F(ExtendedDesktopTest,CaptureEventLocationHighDPI){ |
| UpdateDisplay("1000x600*2,600x400"); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| |
| aura::test::EventCountDelegate r1_d1; |
| aura::test::EventCountDelegate r1_d2; |
| aura::test::EventCountDelegate r2_d1; |
| |
| std::unique_ptr<aura::Window> r1_w1(aura::test::CreateTestWindowWithDelegate( |
| &r1_d1,0, gfx::Rect(10,10,100,100), root_windows[0])); |
| std::unique_ptr<aura::Window> r1_w2(aura::test::CreateTestWindowWithDelegate( |
| &r1_d2,0, gfx::Rect(10,100,100,100), root_windows[0])); |
| std::unique_ptr<aura::Window> r2_w1(aura::test::CreateTestWindowWithDelegate( |
| &r2_d1,0, gfx::Rect(10,10,100,100), root_windows[1])); |
| |
| r1_w1->SetCapture(); |
| |
| ui::test::EventGenerator* generator=GetEventGenerator(); |
| generator->MoveMouseToCenterOf(r2_w1.get()); |
| EXPECT_EQ(gfx::Point(560,60).ToString(), |
| generator->current_screen_location().ToString()); |
| |
| EventLocationHandler location_handler; |
| r1_w1->AddPreTargetHandler(&location_handler); |
| generator->ClickLeftButton(); |
| r1_w1->RemovePreTargetHandler(&location_handler); |
| EXPECT_EQ(gfx::Point(550,50).ToString(), |
| location_handler.press_location().ToString()); |
| EXPECT_EQ(gfx::Point(550,50).ToString(), |
| location_handler.release_location().ToString()); |
| } |
| |
| TEST_F(ExtendedDesktopTest,CaptureEventLocationHighDPI_2){ |
| UpdateDisplay("1000x600,600x400*2"); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| |
| aura::test::EventCountDelegate r1_d1; |
| aura::test::EventCountDelegate r1_d2; |
| aura::test::EventCountDelegate r2_d1; |
| |
| std::unique_ptr<aura::Window> r1_w1(aura::test::CreateTestWindowWithDelegate( |
| &r1_d1,0, gfx::Rect(10,10,100,100), root_windows[0])); |
| std::unique_ptr<aura::Window> r1_w2(aura::test::CreateTestWindowWithDelegate( |
| &r1_d2,0, gfx::Rect(10,100,100,100), root_windows[0])); |
| std::unique_ptr<aura::Window> r2_w1(aura::test::CreateTestWindowWithDelegate( |
| &r2_d1,0, gfx::Rect(10,10,100,100), root_windows[1])); |
| |
| r1_w1->SetCapture(); |
| |
| ui::test::EventGenerator* generator=GetEventGenerator(); |
| generator->MoveMouseToCenterOf(r2_w1.get()); |
| EXPECT_EQ(gfx::Point(1060,60).ToString(), |
| generator->current_screen_location().ToString()); |
| |
| EventLocationHandler location_handler; |
| r1_w1->AddPreTargetHandler(&location_handler); |
| generator->ClickLeftButton(); |
| r1_w1->RemovePreTargetHandler(&location_handler); |
| // Event-generator dispatches the event in the primary root-window's coord |
| // space. Since the location is (1060, 60), it goes to the secondary |
| // root-window as (30, 30) since the secondary root-window has a device scale |
| // factor of 2. |
| EXPECT_EQ(gfx::Point(1020,20).ToString(), |
| location_handler.press_location().ToString()); |
| EXPECT_EQ(gfx::Point(1020,20).ToString(), |
| location_handler.release_location().ToString()); |
| } |
| |
| TEST_F(ExtendedDesktopTest,MoveWindow){ |
| UpdateDisplay("1000x600,600x400"); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| views::Widget* d1=CreateTestWidget(gfx::Rect(10,10,100,100)); |
| |
| EXPECT_EQ(root_windows[0], d1->GetNativeView()->GetRootWindow()); |
| |
| d1->SetBounds(gfx::Rect(1010,10,100,100)); |
| EXPECT_EQ("1010,10 100x100", d1->GetWindowBoundsInScreen().ToString()); |
| |
| EXPECT_EQ(root_windows[1], d1->GetNativeView()->GetRootWindow()); |
| |
| d1->SetBounds(gfx::Rect(10,10,100,100)); |
| EXPECT_EQ("10,10 100x100", d1->GetWindowBoundsInScreen().ToString()); |
| |
| EXPECT_EQ(root_windows[0], d1->GetNativeView()->GetRootWindow()); |
| |
| // Make sure the bounds which doesn't fit to the root window |
| // works correctly. |
| d1->SetBounds(gfx::Rect(1560,30,100,100)); |
| EXPECT_EQ(root_windows[1], d1->GetNativeView()->GetRootWindow()); |
| EXPECT_EQ("1560,30 100x100", d1->GetWindowBoundsInScreen().ToString()); |
| |
| // Setting outside of root windows will be moved to primary root window. |
| // TODO(oshima): This one probably should pick the closest root window. |
| d1->SetBounds(gfx::Rect(200,10,100,100)); |
| EXPECT_EQ(root_windows[0], d1->GetNativeView()->GetRootWindow()); |
| } |
| |
| // Verifies if the mouse event arrives to the window even when the window |
| // moves to another root in a pre-target handler. See: crbug.com/157583 |
| TEST_F(ExtendedDesktopTest,MoveWindowByMouseClick){ |
| UpdateDisplay("1000x600,600x400"); |
| |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| aura::test::EventCountDelegatedelegate; |
| std::unique_ptr<aura::Window> window(aura::test::CreateTestWindowWithDelegate( |
| &delegate,0, gfx::Rect(10,10,100,100), root_windows[0])); |
| MoveWindowByClickEventHandler event_handler(window.get()); |
| window->AddPreTargetHandler(&event_handler); |
| |
| ui::test::EventGenerator* event_generator=GetEventGenerator(); |
| |
| event_generator->MoveMouseToCenterOf(window.get()); |
| event_generator->ClickLeftButton(); |
| // Both mouse pressed and released arrive at the window and its delegate. |
| EXPECT_EQ("1 1",delegate.GetMouseButtonCountsAndReset()); |
| // Also event_handler moves the window to another root at mouse release. |
| EXPECT_EQ(root_windows[1], window->GetRootWindow()); |
| } |
| |
| TEST_F(ExtendedDesktopTest,MoveWindowToDisplay){ |
| UpdateDisplay("1000x900,1000x900"); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| |
| display::Display display0= display::Screen::GetScreen()->GetDisplayMatching( |
| root_windows[0]->GetBoundsInScreen()); |
| display::Display display1= display::Screen::GetScreen()->GetDisplayMatching( |
| root_windows[1]->GetBoundsInScreen()); |
| EXPECT_NE(display0.id(), display1.id()); |
| |
| views::Widget* d1=CreateTestWidget(gfx::Rect(10,10,1000,100)); |
| EXPECT_EQ(root_windows[0], d1->GetNativeView()->GetRootWindow()); |
| |
| // Move the window where the window spans both root windows. Since the second |
| // parameter is |display1|, the window should be shown on the secondary root. |
| d1->GetNativeWindow()->SetBoundsInScreen(gfx::Rect(500,10,1000,100), |
| display1); |
| EXPECT_EQ("500,10 1000x100", d1->GetWindowBoundsInScreen().ToString()); |
| EXPECT_EQ(root_windows[1], d1->GetNativeView()->GetRootWindow()); |
| |
| // Move to the primary root. |
| d1->GetNativeWindow()->SetBoundsInScreen(gfx::Rect(500,10,1000,100), |
| display0); |
| EXPECT_EQ("500,10 1000x100", d1->GetWindowBoundsInScreen().ToString()); |
| EXPECT_EQ(root_windows[0], d1->GetNativeView()->GetRootWindow()); |
| } |
| |
| TEST_F(ExtendedDesktopTest,MoveWindowWithTransient){ |
| UpdateDisplay("1000x600,600x400"); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| // Create and activate a normal window |w1|. |
| aura::Window* w1= |
| CreateTestWindowInShellWithBounds(gfx::Rect(10,10,100,100)); |
| wm::ActivateWindow(w1); |
| // |w1_t1| is a transient child window of |w1|. |
| std::unique_ptr<aura::Window> w1_t1= |
| ChildTestWindowBuilder(w1, gfx::Rect(50,50,50,50), |
| desks_util::GetActiveDeskContainerId()) |
| .Build(); |
| ::wm::AddTransientChild(w1, w1_t1.get()); |
| // |w1_t11| is a transient child window of transient child window |w1_t1|. |
| std::unique_ptr<aura::Window> w1_t11= |
| ChildTestWindowBuilder(w1_t1.get(), gfx::Rect(2,7,35,35), |
| desks_util::GetActiveDeskContainerId()) |
| .Build(); |
| ::wm::AddTransientChild(w1_t1.get(), w1_t11.get()); |
| |
| // |w11| is a non-transient child window of |w1|. |
| std::unique_ptr<aura::Window> w11= |
| ChildTestWindowBuilder(w1, gfx::Rect(10,10,40,40), |
| desks_util::GetActiveDeskContainerId()) |
| .Build(); |
| // |w11_t1| is a transient child window of |w11|. |
| std::unique_ptr<aura::Window> w11_t1= |
| ChildTestWindowBuilder(w11.get(), gfx::Rect(30,10,80,80), |
| desks_util::GetActiveDeskContainerId()) |
| .Build(); |
| ::wm::AddTransientChild(w11.get(), w11_t1.get()); |
| |
| EXPECT_EQ(root_windows[0], w1->GetRootWindow()); |
| EXPECT_EQ(root_windows[0], w1_t1->GetRootWindow()); |
| EXPECT_EQ(root_windows[0], w1_t11->GetRootWindow()); |
| EXPECT_EQ(root_windows[0], w11->GetRootWindow()); |
| EXPECT_EQ(root_windows[0], w11_t1->GetRootWindow()); |
| EXPECT_EQ("10,10 100x100", w1->GetBoundsInScreen().ToString()); |
| EXPECT_EQ("60,60 50x50", w1_t1->GetBoundsInScreen().ToString()); |
| EXPECT_EQ("62,67 35x35", w1_t11->GetBoundsInScreen().ToString()); |
| EXPECT_EQ("20,20 40x40", w11->GetBoundsInScreen().ToString()); |
| EXPECT_EQ("50,30 80x80", w11_t1->GetBoundsInScreen().ToString()); |
| |
| w1->SetBoundsInScreen(gfx::Rect(1200,10,100,100),GetSecondaryDisplay()); |
| |
| EXPECT_EQ(root_windows[1], w1->GetRootWindow()); |
| EXPECT_EQ(root_windows[1], w1_t1->GetRootWindow()); |
| EXPECT_EQ(root_windows[1], w1_t11->GetRootWindow()); |
| EXPECT_EQ(root_windows[1], w11->GetRootWindow()); |
| EXPECT_EQ(root_windows[1], w11_t1->GetRootWindow()); |
| |
| EXPECT_EQ("1200,10 100x100", w1->GetBoundsInScreen().ToString()); |
| EXPECT_EQ("1250,60 50x50", w1_t1->GetBoundsInScreen().ToString()); |
| EXPECT_EQ("1252,67 35x35", w1_t11->GetBoundsInScreen().ToString()); |
| EXPECT_EQ("1210,20 40x40", w11->GetBoundsInScreen().ToString()); |
| EXPECT_EQ("1240,30 80x80", w11_t1->GetBoundsInScreen().ToString()); |
| } |
| |
| // Test transient child is parented after its transient parent moved to another |
| // root window. |
| TEST_F(ExtendedDesktopTest,PostMoveParentTransientChild){ |
| UpdateDisplay("600x400,600x400"); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| // Create and activate a normal window. |
| aura::Window* window= |
| CreateTestWindowInShellWithBounds(gfx::Rect(10,10,100,100)); |
| wm::ActivateWindow(window); |
| // Create a transient child window of |window| without parenting to |window| |
| // yet. |
| std::unique_ptr<aura::Window> child= std::make_unique<aura::Window>(nullptr); |
| child->SetType(aura::client::WINDOW_TYPE_NORMAL); |
| child->Init(ui::LAYER_TEXTURED); |
| child->SetBounds(gfx::Rect(50,50,50,50)); |
| child->Show(); |
| ::wm::AddTransientChild(window, child.get()); |
| |
| // Move |window| to another display and ensure that crash doesn't happen. |
| window->SetBoundsInScreen(gfx::Rect(610,10,100,100), |
| GetSecondaryDisplay()); |
| |
| // Parent |child| to |window| now. |
| window->AddChild(child.get()); |
| |
| EXPECT_EQ(root_windows[1], window->GetRootWindow()); |
| EXPECT_EQ(root_windows[1], child->GetRootWindow()); |
| EXPECT_EQ("610,10 100x100", window->GetBoundsInScreen().ToString()); |
| EXPECT_EQ("660,60 50x50", child->GetBoundsInScreen().ToString()); |
| } |
| |
| // Test if the Window::ConvertPointToTarget works across root windows. |
| TEST_F(ExtendedDesktopTest,ConvertPoint){ |
| display::Screen* screen= display::Screen::GetScreen(); |
| UpdateDisplay("1000x600,600x400"); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| display::Display display_1= screen->GetDisplayNearestWindow(root_windows[0]); |
| EXPECT_EQ("0,0", display_1.bounds().origin().ToString()); |
| display::Display display_2= screen->GetDisplayNearestWindow(root_windows[1]); |
| EXPECT_EQ("1000,0", display_2.bounds().origin().ToString()); |
| |
| aura::Window* d1= |
| CreateTestWidget(gfx::Rect(10,10,100,100))->GetNativeView(); |
| aura::Window* d2= |
| CreateTestWidget(gfx::Rect(1020,20,100,100))->GetNativeView(); |
| EXPECT_EQ(root_windows[0], d1->GetRootWindow()); |
| EXPECT_EQ(root_windows[1], d2->GetRootWindow()); |
| |
| // Convert point in the Root2's window to the Root1's window Coord. |
| gfx::Point p(0,0); |
| aura::Window::ConvertPointToTarget(root_windows[1], root_windows[0],&p); |
| EXPECT_EQ("1000,0", p.ToString()); |
| p.SetPoint(0,0); |
| aura::Window::ConvertPointToTarget(d2, d1,&p); |
| EXPECT_EQ("1010,10", p.ToString()); |
| |
| // Convert point in the Root1's window to the Root2's window Coord. |
| p.SetPoint(0,0); |
| aura::Window::ConvertPointToTarget(root_windows[0], root_windows[1],&p); |
| EXPECT_EQ("-1000,0", p.ToString()); |
| p.SetPoint(0,0); |
| aura::Window::ConvertPointToTarget(d1, d2,&p); |
| EXPECT_EQ("-1010,-10", p.ToString()); |
| |
| // Move the 2nd display to the bottom and test again. |
| SetSecondaryDisplayLayout(display::DisplayPlacement::BOTTOM); |
| |
| display_2= screen->GetDisplayNearestWindow(root_windows[1]); |
| EXPECT_EQ("0,600", display_2.bounds().origin().ToString()); |
| |
| // Convert point in Root2's window to Root1's window Coord. |
| p.SetPoint(0,0); |
| aura::Window::ConvertPointToTarget(root_windows[1], root_windows[0],&p); |
| EXPECT_EQ("0,600", p.ToString()); |
| p.SetPoint(0,0); |
| aura::Window::ConvertPointToTarget(d2, d1,&p); |
| EXPECT_EQ("10,610", p.ToString()); |
| |
| // Convert point in Root1's window to Root2's window Coord. |
| p.SetPoint(0,0); |
| aura::Window::ConvertPointToTarget(root_windows[0], root_windows[1],&p); |
| EXPECT_EQ("0,-600", p.ToString()); |
| p.SetPoint(0,0); |
| aura::Window::ConvertPointToTarget(d1, d2,&p); |
| EXPECT_EQ("-10,-610", p.ToString()); |
| } |
| |
| TEST_F(ExtendedDesktopTest,OpenSystemTray){ |
| // Two displays side by side and both are high enough for tray bubble. |
| UpdateDisplay("500x600,600x700"); |
| ASSERT_FALSE(IsBubbleShown()); |
| |
| ui::test::EventGenerator* event_generator=GetEventGenerator(); |
| |
| // Opens the tray by a dummy click event and makes sure that adding/removing |
| // displays doesn't break anything. |
| event_generator->MoveMouseTo(GetSystemTrayBoundsInScreen().CenterPoint()); |
| event_generator->ClickLeftButton(); |
| EXPECT_TRUE(IsBubbleShown()); |
| |
| // Verifies that the bubble is within the primary display. |
| const gfx::Rect primary_display_bounds=GetPrimaryDisplay().bounds(); |
| const gfx::Rect tray_bubble_bounds= |
| GetPrimaryUnifiedSystemTray()->GetBubbleBoundsInScreen(); |
| EXPECT_TRUE(primary_display_bounds.Contains(tray_bubble_bounds)) |
| <<"primary display bounds="<< primary_display_bounds.ToString() |
| <<", tray bubble bounds="<< tray_bubble_bounds.ToString(); |
| |
| UpdateDisplay("500x600"); |
| EXPECT_TRUE(IsBubbleShown()); |
| UpdateDisplay("500x600,600x700"); |
| EXPECT_TRUE(IsBubbleShown()); |
| |
| // Closes the tray and again makes sure that adding/removing displays doesn't |
| // break anything. |
| event_generator->ClickLeftButton(); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_FALSE(IsBubbleShown()); |
| |
| UpdateDisplay("500x600"); |
| EXPECT_FALSE(IsBubbleShown()); |
| UpdateDisplay("500x600,600x700"); |
| EXPECT_FALSE(IsBubbleShown()); |
| } |
| |
| TEST_F(ExtendedDesktopTest,StayInSameRootWindow){ |
| UpdateDisplay("200x100,300x200"); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| views::Widget* w1=CreateTestWidget(gfx::Rect(10,10,50,50)); |
| EXPECT_EQ(root_windows[0], w1->GetNativeView()->GetRootWindow()); |
| w1->SetBounds(gfx::Rect(250,10,50,50)); |
| EXPECT_EQ(root_windows[1], w1->GetNativeView()->GetRootWindow()); |
| |
| // The widget stays in the same root if kLockedToRootKey is set to true. |
| w1->GetNativeView()->SetProperty(kLockedToRootKey,true); |
| w1->SetBounds(gfx::Rect(10,10,50,50)); |
| EXPECT_EQ(root_windows[1], w1->GetNativeView()->GetRootWindow()); |
| |
| // The widget should now move to the 1st root window without the property. |
| w1->GetNativeView()->ClearProperty(kLockedToRootKey); |
| w1->SetBounds(gfx::Rect(10,10,50,50)); |
| EXPECT_EQ(root_windows[0], w1->GetNativeView()->GetRootWindow()); |
| |
| // a window in SettingsBubbleContainer, ShelfControlContainer and |
| // OverviewFocusContainer should not move to another root window |
| // regardless of the bounds specified. |
| aura::Window* settings_bubble_container= |
| Shell::GetPrimaryRootWindowController()->GetContainer( |
| kShellWindowId_SettingBubbleContainer); |
| aura::Window* window= |
| aura::test::CreateTestWindowWithId(100, settings_bubble_container); |
| window->SetBoundsInScreen(gfx::Rect(250,10,50,50),GetSecondaryDisplay()); |
| EXPECT_EQ(root_windows[0], window->GetRootWindow()); |
| |
| aura::Window* status_container= |
| Shell::GetPrimaryRootWindowController()->GetContainer( |
| kShellWindowId_ShelfContainer); |
| window= aura::test::CreateTestWindowWithId(100, status_container); |
| window->SetBoundsInScreen(gfx::Rect(250,10,50,50),GetSecondaryDisplay()); |
| EXPECT_EQ(root_windows[0], window->GetRootWindow()); |
| } |
| |
| TEST_F(ExtendedDesktopTest,KeyEventsOnLockScreen){ |
| UpdateDisplay("200x100,300x200"); |
| aura::Window::Windows root_windows=Shell::GetAllRootWindows(); |
| |
| // Create normal windows on both displays. |
| views::Widget* widget1=CreateTestWidget( |
| display::Screen::GetScreen()->GetPrimaryDisplay().bounds()); |
| widget1->Show(); |
| EXPECT_EQ(root_windows[0], widget1->GetNativeView()->GetRootWindow()); |
| views::Widget* widget2=CreateTestWidget(GetSecondaryDisplay().bounds()); |
| widget2->Show(); |
| EXPECT_EQ(root_windows[1], widget2->GetNativeView()->GetRootWindow()); |
| |
| // Create a LockScreen window. |
| views::Widget* lock_widget=CreateTestWidget( |
| display::Screen::GetScreen()->GetPrimaryDisplay().bounds()); |
| views::Textfield* textfield=new views::Textfield; |
| lock_widget->client_view()->AddChildViewRaw(textfield); |
| |
| Shell::GetContainer(Shell::GetPrimaryRootWindow(), |
| kShellWindowId_LockScreenContainer) |
| ->AddChild(lock_widget->GetNativeView()); |
| lock_widget->Show(); |
| textfield->RequestFocus(); |
| |
| aura::client::FocusClient* focus_client= |
| aura::client::GetFocusClient(root_windows[0]); |
| EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow()); |
| |
| // The lock window should get events on both root windows. |
| ui::test::EventGenerator* event_generator=GetEventGenerator(); |
| |
| event_generator->set_current_target(root_windows[0]); |
| event_generator->PressAndReleaseKey(ui::VKEY_A); |
| EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow()); |
| EXPECT_EQ("a", base::UTF16ToASCII(textfield->GetText())); |
| |
| event_generator->set_current_target(root_windows[1]); |
| event_generator->PressAndReleaseKey(ui::VKEY_B); |
| EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow()); |
| EXPECT_EQ("ab", base::UTF16ToASCII(textfield->GetText())); |
| |
| // Deleting 2nd display. The lock window still should get the events. |
| UpdateDisplay("200x100"); |
| event_generator->set_current_target(root_windows[0]); |
| event_generator->PressAndReleaseKey(ui::VKEY_C); |
| EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow()); |
| EXPECT_EQ("abc", base::UTF16ToASCII(textfield->GetText())); |
| |
| // Creating 2nd display again, and lock window still should get events |
| // on both root windows. |
| UpdateDisplay("200x100,300x200"); |
| root_windows=Shell::GetAllRootWindows(); |
| event_generator->set_current_target(root_windows[0]); |
| event_generator->PressAndReleaseKey(ui::VKEY_D); |
| EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow()); |
| EXPECT_EQ("abcd", base::UTF16ToASCII(textfield->GetText())); |
| |
| event_generator->set_current_target(root_windows[1]); |
| event_generator->PressAndReleaseKey(ui::VKEY_E); |
| EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow()); |
| EXPECT_EQ("abcde", base::UTF16ToASCII(textfield->GetText())); |
| } |
| |
| // Verifies that clicking in the primary display and dragging to the secondary |
| // display correctly sets the event location (window local) and root_location |
| // (in screen coordinates) for the mouse event. https://crrev.com/11691010 |
| TEST_F(ExtendedDesktopTest,PassiveGrab){ |
| // This test deals with input events but not visuals so don't throttle input |
| // on visuals. |
| aura::Env::GetInstance()->set_throttle_input_on_resize_for_testing(false); |
| EventLocationRecordingEventHandler event_handler; |
| Shell::Get()->AddPreTargetHandler(&event_handler); |
| |
| // Create large displays so the widget won't be moved after creation. |
| // https://crbug.com/890633 |
| UpdateDisplay("1000x900,1000x900"); |
| |
| views::Widget* widget=CreateTestWidget(gfx::Rect(50,50,200,200)); |
| widget->Show(); |
| ASSERT_EQ("50,50 200x200", widget->GetWindowBoundsInScreen().ToString()); |
| |
| // Move the mouse to the center of the window. |
| ui::test::EventGenerator* generator=GetEventGenerator(); |
| generator->MoveMouseTo(150,150); |
| |
| // Location is relative to the window. |
| EXPECT_EQ("100,100", event_handler.GetLocation()); |
| |
| // Root location is relative to the display. |
| EXPECT_EQ("150,150", event_handler.GetRootLocation()); |
| event_handler.Reset(); |
| |
| // Drag the mouse to the secondary display. Does not drag the window. |
| generator->PressLeftButton(); |
| generator->MoveMouseBy(1000,0); |
| |
| // Location is relative to the original window. |
| EXPECT_EQ("1100,100", event_handler.GetLocation()); |
| |
| // Root location is relative to the original display. |
| EXPECT_EQ("1150,150", event_handler.GetRootLocation()); |
| event_handler.Reset(); |
| |
| // End the drag. |
| generator->ReleaseLeftButton(); |
| EXPECT_EQ("-999,-999", event_handler.GetRootLocation()); |
| EXPECT_EQ("-999,-999", event_handler.GetLocation()); |
| event_handler.Reset(); |
| |
| // Move the mouse to the top-left of the secondary display. |
| generator->MoveMouseTo(1001,1); |
| |
| // Location is relative to the new display. |
| EXPECT_EQ("1,1", event_handler.GetLocation()); |
| |
| // Root location is relative to the new display. |
| EXPECT_EQ("1,1", event_handler.GetRootLocation()); |
| event_handler.Reset(); |
| |
| Shell::Get()->RemovePreTargetHandler(&event_handler); |
| } |
| |
| }// namespace ash |