blob: 2484f518698977e1ee80c7921b0b531fa8907696 [file]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/ozone/platform/x11/x11_window_ozone.h"
#include <memory>
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/devices/x11/touch_factory_x11.h"
#include "ui/events/event.h"
#include "ui/events/platform/x11/x11_event_source_libevent.h"
#include "ui/events/test/events_test_utils_x11.h"
#include "ui/ozone/platform/x11/x11_window_manager_ozone.h"
#include "ui/ozone/test/mock_platform_window_delegate.h"
#include "ui/platform_window/platform_window_delegate.h"
namespace ui {
namespace {
using ::testing::Eq;
using ::testing::_;
constexpr int kPointerDeviceId = 1;
ACTION_P(StoreWidget, widget_ptr) {
*widget_ptr = arg0;
}
ACTION_P(CloneEvent, event_ptr) {
*event_ptr = Event::Clone(*arg0);
}
} // namespace
class X11WindowOzoneTest : public testing::Test {
public:
X11WindowOzoneTest()
: task_env_(std::make_unique<base::test::ScopedTaskEnvironment>(
base::test::ScopedTaskEnvironment::MainThreadType::UI)) {}
~X11WindowOzoneTest() override = default;
void SetUp() override {
XDisplay* display = gfx::GetXDisplay();
event_source_ = std::make_unique<X11EventSourceLibevent>(display);
window_manager_ = std::make_unique<X11WindowManagerOzone>();
TouchFactory::GetInstance()->SetPointerDeviceForTest({kPointerDeviceId});
}
protected:
std::unique_ptr<PlatformWindow> CreatePlatformWindow(
MockPlatformWindowDelegate* delegate,
const gfx::Rect& bounds,
gfx::AcceleratedWidget* widget) {
EXPECT_CALL(*delegate, OnAcceleratedWidgetAvailable(_))
.WillOnce(StoreWidget(widget));
auto window = std::make_unique<X11WindowOzone>(window_manager_.get(),
delegate, bounds);
return std::move(window);
}
void DispatchXEvent(XEvent* event, gfx::AcceleratedWidget widget) {
DCHECK_EQ(GenericEvent, event->type);
XIDeviceEvent* device_event =
static_cast<XIDeviceEvent*>(event->xcookie.data);
device_event->event = widget;
event_source_->ProcessXEvent(event);
}
private:
std::unique_ptr<base::test::ScopedTaskEnvironment> task_env_;
std::unique_ptr<X11WindowManagerOzone> window_manager_;
std::unique_ptr<X11EventSourceLibevent> event_source_;
DISALLOW_COPY_AND_ASSIGN(X11WindowOzoneTest);
};
// This test ensures that events are handled by a right target(widget).
TEST_F(X11WindowOzoneTest, SendPlatformEventToRightTarget) {
MockPlatformWindowDelegate delegate;
gfx::AcceleratedWidget widget;
constexpr gfx::Rect bounds(30, 80, 800, 600);
auto window = CreatePlatformWindow(&delegate, bounds, &widget);
ScopedXI2Event xi_event;
xi_event.InitGenericButtonEvent(kPointerDeviceId, ET_MOUSE_PRESSED,
gfx::Point(218, 290), EF_NONE);
// First check events can be received by a target window.
std::unique_ptr<Event> event;
EXPECT_CALL(delegate, DispatchEvent(_)).WillOnce(CloneEvent(&event));
DispatchXEvent(xi_event, widget);
EXPECT_EQ(ET_MOUSE_PRESSED, event->type());
testing::Mock::VerifyAndClearExpectations(&delegate);
MockPlatformWindowDelegate delegate_2;
gfx::AcceleratedWidget widget_2;
gfx::Rect bounds_2(525, 155, 296, 407);
auto window_2 = CreatePlatformWindow(&delegate_2, bounds_2, &widget_2);
// Check event goes to right target without capture being set.
event.reset();
EXPECT_CALL(delegate, DispatchEvent(_)).Times(0);
EXPECT_CALL(delegate_2, DispatchEvent(_)).WillOnce(CloneEvent(&event));
DispatchXEvent(xi_event, widget_2);
EXPECT_EQ(ET_MOUSE_PRESSED, event->type());
EXPECT_CALL(delegate, OnClosed()).Times(1);
EXPECT_CALL(delegate_2, OnClosed()).Times(1);
}
// This test case ensures that events are consumed by a window with explicit
// capture, even though the event is sent to other window.
TEST_F(X11WindowOzoneTest, SendPlatformEventToCapturedWindow) {
MockPlatformWindowDelegate delegate;
gfx::AcceleratedWidget widget;
constexpr gfx::Rect bounds(30, 80, 800, 600);
EXPECT_CALL(delegate, OnClosed()).Times(1);
auto window = CreatePlatformWindow(&delegate, bounds, &widget);
MockPlatformWindowDelegate delegate_2;
gfx::AcceleratedWidget widget_2;
gfx::Rect bounds_2(525, 155, 296, 407);
EXPECT_CALL(delegate_2, OnClosed()).Times(1);
auto window_2 = CreatePlatformWindow(&delegate_2, bounds_2, &widget_2);
ScopedXI2Event xi_event;
xi_event.InitGenericButtonEvent(kPointerDeviceId, ET_MOUSE_PRESSED,
gfx::Point(218, 290), EF_NONE);
// Set capture to the second window, but send an event to another window
// target. The event must have its location converted and received by the
// captured window instead.
window_2->SetCapture();
std::unique_ptr<Event> event;
EXPECT_CALL(delegate, DispatchEvent(_)).Times(0);
EXPECT_CALL(delegate_2, DispatchEvent(_)).WillOnce(CloneEvent(&event));
DispatchXEvent(xi_event, widget);
EXPECT_EQ(ET_MOUSE_PRESSED, event->type());
EXPECT_EQ(gfx::Point(-277, 215), event->AsLocatedEvent()->location());
}
} // namespace ui