1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
|
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include "ui/aura/env.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/events/event.h"
#include "ui/events/test/event_generator.h"
#include "ui/views/test/native_widget_factory.h"
#include "ui/views/test/widget_test.h"
#include "ui/views/view.h"
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
#include "ui/views/widget/desktop_aura/desktop_screen_position_client.h"
#include "ui/views/widget/root_view.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/capture_controller.h"
// NOTE: these tests do native capture, so they have to be in
// interactive_ui_tests.
namespace views {
using DesktopCaptureControllerTest = test::DesktopWidgetTestInteractive;
// This class provides functionality to verify whether the View instance
// received the gesture event.
class DesktopViewInputTest : public View {
METADATA_HEADER(DesktopViewInputTest, View)
public:
DesktopViewInputTest() = default;
DesktopViewInputTest(const DesktopViewInputTest&) = delete;
DesktopViewInputTest& operator=(const DesktopViewInputTest&) = delete;
void OnGestureEvent(ui::GestureEvent* event) override {
received_gesture_event_ = true;
return View::OnGestureEvent(event);
}
// Resets state maintained by this class.
void Reset() { received_gesture_event_ = false; }
bool received_gesture_event() const { return received_gesture_event_; }
private:
bool received_gesture_event_ = false;
};
BEGIN_METADATA(DesktopViewInputTest)
END_METADATA
std::unique_ptr<views::Widget> CreateWidget() {
auto widget = std::make_unique<views::Widget>();
views::Widget::InitParams params(
views::Widget::InitParams::CLIENT_OWNS_WIDGET,
views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
params.accept_events = true;
params.native_widget = new DesktopNativeWidgetAura(widget.get());
params.bounds = gfx::Rect(0, 0, 200, 100);
widget->Init(std::move(params));
widget->Show();
return widget;
}
// Verifies mouse handlers are reset when a window gains capture. Specifically
// creates two widgets, does a mouse press in one, sets capture in the other and
// verifies state is reset in the first.
TEST_F(DesktopCaptureControllerTest, ResetMouseHandlers) {
std::unique_ptr<Widget> w1(CreateWidget());
std::unique_ptr<Widget> w2(CreateWidget());
ui::test::EventGenerator generator1(w1->GetNativeView()->GetRootWindow());
generator1.MoveMouseToCenterOf(w1->GetNativeView());
generator1.PressLeftButton();
EXPECT_FALSE(w1->HasCapture());
aura::WindowEventDispatcher* w1_dispatcher =
w1->GetNativeView()->GetHost()->dispatcher();
EXPECT_TRUE(w1_dispatcher->mouse_pressed_handler() != nullptr);
EXPECT_TRUE(w1_dispatcher->mouse_moved_handler() != nullptr);
w2->SetCapture(w2->GetRootView());
EXPECT_TRUE(w2->HasCapture());
EXPECT_TRUE(w1_dispatcher->mouse_pressed_handler() == nullptr);
EXPECT_TRUE(w1_dispatcher->mouse_moved_handler() == nullptr);
w2->ReleaseCapture();
RunPendingMessages();
}
// Tests aura::Window capture and whether gesture events are sent to the window
// which has capture.
// The test case creates two visible widgets and sets capture to the underlying
// aura::Windows one by one. It then sends a gesture event and validates whether
// the window which had capture receives the gesture.
// TODO(sky): move this test, it should be part of ScopedCaptureClient tests.
TEST_F(DesktopCaptureControllerTest, CaptureWindowInputEventTest) {
std::unique_ptr<aura::client::ScreenPositionClient> desktop_position_client1;
std::unique_ptr<aura::client::ScreenPositionClient> desktop_position_client2;
auto widget1 = std::make_unique<Widget>();
Widget::InitParams params = CreateParams(
Widget::InitParams::CLIENT_OWNS_WIDGET, Widget::InitParams::TYPE_POPUP);
std::unique_ptr<wm::ScopedCaptureClient> scoped_capture_client(
new wm::ScopedCaptureClient(params.context->GetRootWindow()));
aura::client::CaptureClient* capture_client = wm::CaptureController::Get();
params.bounds = gfx::Rect(50, 50, 650, 650);
params.native_widget = test::CreatePlatformNativeWidgetImpl(
widget1.get(), test::kStubCapture, nullptr);
desktop_position_client1 = std::make_unique<DesktopScreenPositionClient>(
params.context->GetRootWindow());
widget1->Init(std::move(params));
internal::RootView* root1 =
static_cast<internal::RootView*>(widget1->GetRootView());
aura::client::SetScreenPositionClient(
widget1->GetNativeView()->GetRootWindow(),
desktop_position_client1.get());
DesktopViewInputTest* v1 = new DesktopViewInputTest();
v1->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
root1->AddChildViewRaw(v1);
widget1->Show();
auto widget2 = std::make_unique<Widget>();
params = CreateParams(Widget::InitParams::CLIENT_OWNS_WIDGET,
Widget::InitParams::TYPE_POPUP);
params.bounds = gfx::Rect(50, 50, 650, 650);
params.native_widget = test::CreatePlatformNativeWidgetImpl(
widget2.get(), test::kStubCapture, nullptr);
desktop_position_client2 = std::make_unique<DesktopScreenPositionClient>(
params.context->GetRootWindow());
widget2->Init(std::move(params));
internal::RootView* root2 =
static_cast<internal::RootView*>(widget2->GetRootView());
aura::client::SetScreenPositionClient(
widget2->GetNativeView()->GetRootWindow(),
desktop_position_client2.get());
ui::EventDispatchDetails details;
DesktopViewInputTest* v2 = new DesktopViewInputTest();
v2->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
root2->AddChildViewRaw(v2);
widget2->Show();
EXPECT_FALSE(widget1->GetNativeView()->HasCapture());
EXPECT_FALSE(widget2->GetNativeView()->HasCapture());
EXPECT_EQ(nullptr, capture_client->GetCaptureWindow());
widget1->GetNativeView()->SetCapture();
EXPECT_TRUE(widget1->GetNativeView()->HasCapture());
EXPECT_FALSE(widget2->GetNativeView()->HasCapture());
EXPECT_EQ(capture_client->GetCaptureWindow(), widget1->GetNativeView());
ui::GestureEvent g1(
80, 80, 0, base::TimeTicks(),
ui::GestureEventDetails(ui::EventType::kGestureLongPress));
details = root1->OnEventFromSource(&g1);
EXPECT_FALSE(details.dispatcher_destroyed);
EXPECT_FALSE(details.target_destroyed);
EXPECT_TRUE(v1->received_gesture_event());
EXPECT_FALSE(v2->received_gesture_event());
v1->Reset();
v2->Reset();
widget2->GetNativeView()->SetCapture();
EXPECT_FALSE(widget1->GetNativeView()->HasCapture());
EXPECT_TRUE(widget2->GetNativeView()->HasCapture());
EXPECT_EQ(capture_client->GetCaptureWindow(), widget2->GetNativeView());
details = root2->OnEventFromSource(&g1);
EXPECT_FALSE(details.dispatcher_destroyed);
EXPECT_FALSE(details.target_destroyed);
EXPECT_TRUE(v2->received_gesture_event());
EXPECT_FALSE(v1->received_gesture_event());
widget1->CloseNow();
widget2->CloseNow();
RunPendingMessages();
}
} // namespace views
|