Commit ba5b7706 authored by Elliot Glaysher's avatar Elliot Glaysher Committed by Commit Bot

Make mus-chromeos work as a remoting destination.

mus-chromeos can work as a remoting accessor, but before this patch,
didn't process input events correctly. You can now chromote into a
mus-ash environment.

Bug: 769308
Change-Id: I92ccd3d5e6cda9e873be59d711acdc83a2864772
Reviewed-on: https://chromium-review.googlesource.com/827940Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Elliot Glaysher <erg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#524516}
parent 6c3982b4
...@@ -40,6 +40,11 @@ void RemoteEventDispatcherImpl::DispatchEvent(int64_t display_id, ...@@ -40,6 +40,11 @@ void RemoteEventDispatcherImpl::DispatchEvent(int64_t display_id,
cb.Run(false); cb.Run(false);
return; return;
} }
// If this is a mouse pointer event, then we have to also update the
// location of the cursor on the screen.
if (event->IsMousePointerEvent())
display->platform_display()->MoveCursorTo(located_event->location());
} }
ignore_result(static_cast<PlatformDisplayDelegate*>(display) ignore_result(static_cast<PlatformDisplayDelegate*>(display)
->GetEventSink() ->GetEventSink()
......
...@@ -363,6 +363,7 @@ test("aura_unittests") { ...@@ -363,6 +363,7 @@ test("aura_unittests") {
"mus/input_method_mus_unittest.cc", "mus/input_method_mus_unittest.cc",
"mus/os_exchange_data_provider_mus_unittest.cc", "mus/os_exchange_data_provider_mus_unittest.cc",
"mus/property_converter_unittest.cc", "mus/property_converter_unittest.cc",
"mus/system_input_injector_mus_unittest.cc",
"mus/user_activity_forwarder_unittest.cc", "mus/user_activity_forwarder_unittest.cc",
"mus/window_port_mus_unittest.cc", "mus/window_port_mus_unittest.cc",
"mus/window_tree_client_unittest.cc", "mus/window_tree_client_unittest.cc",
......
...@@ -4,12 +4,14 @@ ...@@ -4,12 +4,14 @@
#include "ui/aura/mus/system_input_injector_mus.h" #include "ui/aura/mus/system_input_injector_mus.h"
#include "ui/aura/env.h"
#include "ui/aura/mus/window_manager_delegate.h" #include "ui/aura/mus/window_manager_delegate.h"
#include "ui/display/display.h" #include "ui/display/display.h"
#include "ui/display/screen.h" #include "ui/display/screen.h"
#include "ui/events/base_event_utils.h" #include "ui/events/base_event_utils.h"
#include "ui/events/event.h" #include "ui/events/event.h"
#include "ui/events/keycodes/keyboard_code_conversion.h" #include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/gfx/geometry/point_conversions.h"
namespace aura { namespace aura {
...@@ -49,19 +51,62 @@ SystemInputInjectorMus::SystemInputInjectorMus(WindowManagerClient* client) ...@@ -49,19 +51,62 @@ SystemInputInjectorMus::SystemInputInjectorMus(WindowManagerClient* client)
SystemInputInjectorMus::~SystemInputInjectorMus() {} SystemInputInjectorMus::~SystemInputInjectorMus() {}
void SystemInputInjectorMus::MoveCursorTo(const gfx::PointF& location) { void SystemInputInjectorMus::MoveCursorTo(const gfx::PointF& location) {
// TODO(erg): This appears to never be receiving the events from the remote ui::MouseEvent event(
// side of the connection. I think this is because it doesn't send mouse ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(),
// events before the first paint. modifiers_.GetModifierFlags(),
NOTIMPLEMENTED(); /* changed_button_flags */ 0,
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE));
event.set_location_f(location);
event.set_root_location_f(location);
InjectEventAt(ui::PointerEvent(event), gfx::ToRoundedPoint(location));
} }
void SystemInputInjectorMus::InjectMouseButton(ui::EventFlags button, void SystemInputInjectorMus::InjectMouseButton(ui::EventFlags button,
bool down) { bool down) {
NOTIMPLEMENTED(); gfx::Point location = aura::Env::GetInstance()->last_mouse_location();
int modifier = ui::MODIFIER_NONE;
switch (button) {
case ui::EF_LEFT_MOUSE_BUTTON:
modifier = ui::MODIFIER_LEFT_MOUSE_BUTTON;
break;
case ui::EF_RIGHT_MOUSE_BUTTON:
modifier = ui::MODIFIER_RIGHT_MOUSE_BUTTON;
break;
case ui::EF_MIDDLE_MOUSE_BUTTON:
modifier = ui::MODIFIER_MIDDLE_MOUSE_BUTTON;
default:
LOG(WARNING) << "Invalid flag: " << button << " for the button parameter";
return;
}
int flag = modifiers_.GetEventFlagFromModifier(modifier);
bool was_down = modifiers_.GetModifierFlags() & flag;
modifiers_.UpdateModifier(modifier, down);
down = modifiers_.GetModifierFlags() & flag;
// Suppress nested clicks. EventModifiers counts presses, we only
// dispatch an event on 0-1 (first press) and 1-0 (last release) transitions.
if (down == was_down)
return;
ui::MouseEvent event(
down ? ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED, location, location,
ui::EventTimeForNow(), modifiers_.GetModifierFlags() | flag,
/* changed_button_flags */ flag,
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE));
InjectEventAt(ui::PointerEvent(event), location);
} }
void SystemInputInjectorMus::InjectMouseWheel(int delta_x, int delta_y) { void SystemInputInjectorMus::InjectMouseWheel(int delta_x, int delta_y) {
NOTIMPLEMENTED(); gfx::Point location = aura::Env::GetInstance()->last_mouse_location();
ui::MouseWheelEvent event(gfx::Vector2d(delta_x, delta_y), location, location,
ui::EventTimeForNow(),
modifiers_.GetModifierFlags(),
/* changed_button_flags */ 0);
InjectEventAt(ui::PointerEvent(event), location);
} }
void SystemInputInjectorMus::InjectKeyEvent(ui::DomCode dom_code, void SystemInputInjectorMus::InjectKeyEvent(ui::DomCode dom_code,
...@@ -77,22 +122,24 @@ void SystemInputInjectorMus::InjectKeyEvent(ui::DomCode dom_code, ...@@ -77,22 +122,24 @@ void SystemInputInjectorMus::InjectKeyEvent(ui::DomCode dom_code,
ui::KeyEvent e(down ? ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED, key_code, ui::KeyEvent e(down ? ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED, key_code,
dom_code, modifiers_.GetModifierFlags()); dom_code, modifiers_.GetModifierFlags());
// Even when we're dispatching a key event, we need to have a valid display InjectEventAt(e, display::Screen::GetScreen()->GetCursorScreenPoint());
// for event targeting, so grab the display of where the cursor currently is. }
void SystemInputInjectorMus::InjectEventAt(const ui::Event& event,
const gfx::Point& location) {
display::Screen* screen = display::Screen::GetScreen(); display::Screen* screen = display::Screen::GetScreen();
display::Display display = display::Display display = screen->GetDisplayNearestPoint(location);
screen->GetDisplayNearestPoint(screen->GetCursorScreenPoint()); client_->InjectEvent(event, display.id());
client_->InjectEvent(e, display.id());
} }
void SystemInputInjectorMus::UpdateModifier(unsigned int modifier, bool down) { void SystemInputInjectorMus::UpdateModifier(unsigned int modifier, bool down) {
if (modifier == ui::MODIFIER_NONE) if (modifier == ui::MODIFIER_NONE)
return; return;
if (modifier == ui::MODIFIER_CAPS_LOCK) // KeyboardEvdev performs a transformation here from MODIFIER_CAPS_LOCK to
modifiers_.UpdateModifier(ui::MODIFIER_MOD3, down); // MODIFIER_MOD3. That was needed to work around X11, we actually want to
else // ship this state across the wire without modification.
modifiers_.UpdateModifier(modifier, down); modifiers_.UpdateModifier(modifier, down);
} }
} // namespace aura } // namespace aura
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef UI_AURA_MUS_SYSTEM_INPUT_INJECTOR_MUS_H_ #ifndef UI_AURA_MUS_SYSTEM_INPUT_INJECTOR_MUS_H_
#define UI_AURA_MUS_SYSTEM_INPUT_INJECTOR_MUS_H_ #define UI_AURA_MUS_SYSTEM_INPUT_INJECTOR_MUS_H_
#include "ui/aura/aura_export.h"
#include "ui/events/event_modifiers.h" #include "ui/events/event_modifiers.h"
#include "ui/events/system_input_injector.h" #include "ui/events/system_input_injector.h"
...@@ -12,7 +13,7 @@ namespace aura { ...@@ -12,7 +13,7 @@ namespace aura {
class WindowManagerClient; class WindowManagerClient;
class SystemInputInjectorMus : public ui::SystemInputInjector { class AURA_EXPORT SystemInputInjectorMus : public ui::SystemInputInjector {
public: public:
explicit SystemInputInjectorMus(WindowManagerClient* client); explicit SystemInputInjectorMus(WindowManagerClient* client);
~SystemInputInjectorMus() override; ~SystemInputInjectorMus() override;
...@@ -26,6 +27,9 @@ class SystemInputInjectorMus : public ui::SystemInputInjector { ...@@ -26,6 +27,9 @@ class SystemInputInjectorMus : public ui::SystemInputInjector {
bool suppress_auto_repeat) override; bool suppress_auto_repeat) override;
private: private:
// Forwards |event| to the display at |location|.
void InjectEventAt(const ui::Event& event, const gfx::Point& location);
// Updates |modifiers_| based on an incoming event. // Updates |modifiers_| based on an incoming event.
void UpdateModifier(unsigned int modifier, bool down); void UpdateModifier(unsigned int modifier, bool down);
......
// 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/aura/mus/system_input_injector_mus.h"
#include <vector>
#include "ui/aura/mus/window_manager_delegate.h"
#include "ui/aura/mus/window_tree_host_mus_init_params.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/events/event.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/keyboard_codes.h"
namespace aura {
class TestDispaterchWindowManagerClient : public aura::WindowManagerClient {
public:
const std::vector<std::unique_ptr<ui::Event>>& events() const {
return events_;
}
// This is the one method in this interface that we're using to grab data.
void InjectEvent(const ui::Event& event, int64_t display_id) override {
events_.push_back(ui::Event::Clone(event));
}
// The rest of these interfaces aren't relevant to testing
// SystemInputInjectorMus and are left empty.
void SetFrameDecorationValues(
ui::mojom::FrameDecorationValuesPtr values) override {}
void SetNonClientCursor(Window* window,
const ui::CursorData& non_client_cursor) override {}
void AddAccelerators(std::vector<ui::mojom::WmAcceleratorPtr> accelerators,
const base::Callback<void(bool)>& callback) override {}
void RemoveAccelerator(uint32_t id) override {}
void AddActivationParent(Window* window) override {}
void RemoveActivationParent(Window* window) override {}
void SetExtendedHitRegionForChildren(Window* window,
const gfx::Insets& mouse_area,
const gfx::Insets& touch_area) override {
}
void LockCursor() override {}
void UnlockCursor() override {}
void SetCursorVisible(bool visible) override {}
void SetCursorSize(ui::CursorSize cursor_size) override {}
void SetGlobalOverrideCursor(base::Optional<ui::CursorData> cursor) override {
}
void SetCursorTouchVisible(bool enabled) override {}
void SetKeyEventsThatDontHideCursor(
std::vector<ui::mojom::EventMatcherPtr> cursor_key_list) override {}
void RequestClose(Window* window) override {}
void SetBlockingContainers(
const std::vector<BlockingContainers>& all_blocking_containers) override {
}
bool WaitForInitialDisplays() override { return false; }
WindowTreeHostMusInitParams CreateInitParamsForNewDisplay() override {
return WindowTreeHostMusInitParams();
}
void SetDisplayConfiguration(
const std::vector<display::Display>& displays,
std::vector<ui::mojom::WmViewportMetricsPtr> viewport_metrics,
int64_t primary_display_id,
const std::vector<display::Display>& mirrors) override {}
void AddDisplayReusingWindowTreeHost(
WindowTreeHostMus* window_tree_host,
const display::Display& display,
ui::mojom::WmViewportMetricsPtr viewport_metrics) override {}
void SwapDisplayRoots(WindowTreeHostMus* window_tree_host1,
WindowTreeHostMus* window_tree_host2) override {}
private:
std::vector<std::unique_ptr<ui::Event>> events_;
};
class SystemInputInjectorMusTest : public test::AuraTestBase {
protected:
const std::vector<std::unique_ptr<ui::Event>>& events() const {
return window_manager_client_.events();
}
SystemInputInjectorMus* injector() { return input_injector_.get(); }
void SetUp() override {
test::AuraTestBase::SetUp();
input_injector_ =
std::make_unique<SystemInputInjectorMus>(&window_manager_client_);
}
void TearDown() override {
input_injector_.reset();
test::AuraTestBase::TearDown();
}
private:
TestDispaterchWindowManagerClient window_manager_client_;
std::unique_ptr<SystemInputInjectorMus> input_injector_;
};
TEST_F(SystemInputInjectorMusTest, MouseMove) {
injector()->MoveCursorTo(gfx::PointF(40, 45));
ASSERT_EQ(1u, events().size());
ASSERT_EQ(ui::ET_POINTER_MOVED, events()[0]->type());
EXPECT_EQ(gfx::Point(40, 45), events()[0]->AsPointerEvent()->location());
}
TEST_F(SystemInputInjectorMusTest, ModifierKeys) {
injector()->InjectKeyEvent(ui::DomCode::CONTROL_LEFT, true, true);
injector()->InjectKeyEvent(ui::DomCode::US_T, true, true);
ASSERT_EQ(2u, events().size());
ASSERT_EQ(ui::ET_KEY_PRESSED, events()[1]->type());
// Verify that we have the right modifier on the event.
EXPECT_TRUE(events()[1]->IsControlDown());
EXPECT_EQ(ui::VKEY_T, events()[1]->AsKeyEvent()->key_code());
}
TEST_F(SystemInputInjectorMusTest, MouseButton) {
injector()->InjectKeyEvent(ui::DomCode::CONTROL_LEFT, true, true);
injector()->InjectMouseButton(ui::EF_LEFT_MOUSE_BUTTON, true);
// Verify that this is a ctrl+click.
ASSERT_EQ(2u, events().size());
ASSERT_EQ(ui::ET_POINTER_DOWN, events()[1]->type());
EXPECT_TRUE(events()[1]->IsControlDown());
EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events()[1]->flags());
}
TEST_F(SystemInputInjectorMusTest, MouseWheel) {
injector()->InjectMouseWheel(0, 20);
ASSERT_EQ(1u, events().size());
ASSERT_EQ(ui::ET_POINTER_WHEEL_CHANGED, events()[0]->type());
EXPECT_EQ(gfx::Vector2d(0, 20),
events()[0]->AsPointerEvent()->pointer_details().offset);
}
} // namespace aura
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