| Index: ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
|
| diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
|
| index aec6aa2968b23f500743fe3dbd11964aa150aca3..8fc6b74ad219fd7fbb08b2b43b7ec938e09b9f9e 100644
|
| --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
|
| +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
|
| @@ -8,23 +8,30 @@
|
| #include <X11/Xlib.h>
|
|
|
| // Get rid of X11 macros which conflict with gtest.
|
| +// It is necessary to include this header before the rest so that Bool can be
|
| +// undefined.
|
| +#include "ui/events/test/events_test_utils_x11.h"
|
| #undef Bool
|
| #undef None
|
|
|
| +#include "base/command_line.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/run_loop.h"
|
| #include "ui/aura/window.h"
|
| #include "ui/aura/window_tree_host.h"
|
| #include "ui/base/hit_test.h"
|
| #include "ui/base/x/x11_util.h"
|
| +#include "ui/events/devices/x11/touch_factory_x11.h"
|
| #include "ui/events/platform/x11/x11_event_source.h"
|
| #include "ui/gfx/geometry/point.h"
|
| #include "ui/gfx/geometry/rect.h"
|
| #include "ui/gfx/path.h"
|
| +#include "ui/gfx/switches.h"
|
| #include "ui/gfx/x/x11_atom_cache.h"
|
| #include "ui/views/test/views_test_base.h"
|
| #include "ui/views/test/x11_property_change_waiter.h"
|
| #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
|
| +#include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
|
| #include "ui/views/widget/widget_delegate.h"
|
| #include "ui/views/window/non_client_view.h"
|
|
|
| @@ -32,6 +39,8 @@ namespace views {
|
|
|
| namespace {
|
|
|
| +const int kPointerDeviceId = 1;
|
| +
|
| // Blocks till the window state hint, |hint|, is set or unset.
|
| class WMStateWaiter : public X11PropertyChangeWaiter {
|
| public:
|
| @@ -454,4 +463,137 @@ TEST_F(DesktopWindowTreeHostX11Test, ToggleMinimizePropogateToContentWindow) {
|
| EXPECT_TRUE(widget.GetNativeWindow()->IsVisible());
|
| }
|
|
|
| +class MouseEventRecorder : public ui::EventHandler {
|
| + public:
|
| + MouseEventRecorder() {}
|
| + ~MouseEventRecorder() override {}
|
| +
|
| + void Reset() { mouse_events_.clear(); }
|
| +
|
| + const std::vector<ui::MouseEvent>& mouse_events() const {
|
| + return mouse_events_;
|
| + }
|
| +
|
| + private:
|
| + // ui::EventHandler:
|
| + void OnMouseEvent(ui::MouseEvent* mouse) override {
|
| + mouse_events_.push_back(*mouse);
|
| + }
|
| +
|
| + std::vector<ui::MouseEvent> mouse_events_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(MouseEventRecorder);
|
| +};
|
| +
|
| +// A custom event-source that can be used to directly dispatch synthetic X11
|
| +// events.
|
| +class CustomX11EventSource : public ui::X11EventSource {
|
| + public:
|
| + CustomX11EventSource() : X11EventSource(gfx::GetXDisplay()) {}
|
| + ~CustomX11EventSource() override {}
|
| +
|
| + void DispatchSingleEvent(XEvent* xevent) {
|
| + PlatformEventSource::DispatchEvent(xevent);
|
| + }
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(CustomX11EventSource);
|
| +};
|
| +
|
| +class DesktopWindowTreeHostX11HighDPITest
|
| + : public DesktopWindowTreeHostX11Test {
|
| + public:
|
| + DesktopWindowTreeHostX11HighDPITest() {}
|
| + ~DesktopWindowTreeHostX11HighDPITest() override {}
|
| +
|
| + void DispatchSingleEventToWidget(XEvent* event, Widget* widget) {
|
| + DCHECK_EQ(GenericEvent, event->type);
|
| + XIDeviceEvent* device_event =
|
| + static_cast<XIDeviceEvent*>(event->xcookie.data);
|
| + device_event->event =
|
| + widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget();
|
| + event_source_.DispatchSingleEvent(event);
|
| + }
|
| +
|
| + void PretendCapture(views::Widget* capture_widget) {
|
| + DesktopWindowTreeHostX11* capture_host = nullptr;
|
| + if (capture_widget) {
|
| + capture_host = static_cast<DesktopWindowTreeHostX11*>(
|
| + capture_widget->GetNativeWindow()->GetHost());
|
| + }
|
| + DesktopWindowTreeHostX11::g_current_capture = capture_host;
|
| + if (capture_widget)
|
| + capture_widget->GetNativeWindow()->SetCapture();
|
| + }
|
| +
|
| + private:
|
| + void SetUp() override {
|
| + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
| + command_line->AppendSwitchASCII(switches::kForceDeviceScaleFactor, "2");
|
| + std::vector<unsigned int> pointer_devices;
|
| + pointer_devices.push_back(kPointerDeviceId);
|
| + ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(pointer_devices);
|
| +
|
| + DesktopWindowTreeHostX11Test::SetUp();
|
| + }
|
| +
|
| + CustomX11EventSource event_source_;
|
| + DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostX11HighDPITest);
|
| +};
|
| +
|
| +TEST_F(DesktopWindowTreeHostX11HighDPITest, LocatedEventDispatchWithCapture) {
|
| + Widget first;
|
| + Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
|
| + params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
|
| + params.native_widget = new DesktopNativeWidgetAura(&first);
|
| + params.bounds = gfx::Rect(0, 0, 50, 50);
|
| + first.Init(params);
|
| + first.Show();
|
| +
|
| + Widget second;
|
| + params = CreateParams(Widget::InitParams::TYPE_WINDOW);
|
| + params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
|
| + params.native_widget = new DesktopNativeWidgetAura(&second);
|
| + params.bounds = gfx::Rect(50, 50, 50, 50);
|
| + second.Init(params);
|
| + second.Show();
|
| +
|
| + ui::X11EventSource::GetInstance()->DispatchXEvents();
|
| +
|
| + MouseEventRecorder first_recorder, second_recorder;
|
| + first.GetNativeWindow()->AddPreTargetHandler(&first_recorder);
|
| + second.GetNativeWindow()->AddPreTargetHandler(&second_recorder);
|
| +
|
| + // Dispatch an event on |first|. Verify it gets the event.
|
| + ui::ScopedXI2Event event;
|
| + event.InitGenericButtonEvent(kPointerDeviceId, ui::ET_MOUSEWHEEL,
|
| + gfx::Point(50, 50), ui::EF_NONE);
|
| + DispatchSingleEventToWidget(event, &first);
|
| + ASSERT_EQ(1u, first_recorder.mouse_events().size());
|
| + EXPECT_EQ(ui::ET_MOUSEWHEEL, first_recorder.mouse_events()[0].type());
|
| + EXPECT_EQ(gfx::Point(25, 25).ToString(),
|
| + first_recorder.mouse_events()[0].location().ToString());
|
| + ASSERT_EQ(0u, second_recorder.mouse_events().size());
|
| +
|
| + first_recorder.Reset();
|
| + second_recorder.Reset();
|
| +
|
| + // Set a capture on |second|, and dispatch the same event to |first|. This
|
| + // event should reach |second| instead.
|
| + PretendCapture(&second);
|
| + event.InitGenericButtonEvent(kPointerDeviceId, ui::ET_MOUSEWHEEL,
|
| + gfx::Point(50, 50), ui::EF_NONE);
|
| + DispatchSingleEventToWidget(event, &first);
|
| +
|
| + ASSERT_EQ(0u, first_recorder.mouse_events().size());
|
| + ASSERT_EQ(1u, second_recorder.mouse_events().size());
|
| + EXPECT_EQ(ui::ET_MOUSEWHEEL, second_recorder.mouse_events()[0].type());
|
| + EXPECT_EQ(gfx::Point(-25, -25).ToString(),
|
| + second_recorder.mouse_events()[0].location().ToString());
|
| +
|
| + PretendCapture(nullptr);
|
| + first.GetNativeWindow()->RemovePreTargetHandler(&first_recorder);
|
| + second.GetNativeWindow()->RemovePreTargetHandler(&second_recorder);
|
| +}
|
| +
|
| } // namespace views
|
|
|