Skip to content

Commit

Permalink
chromeos: wires up pointer event observers for ws2
Browse files Browse the repository at this point in the history
When a client is notified of events it's told if the event matches a
pointer observer. If the event does match a pointer observer, a single
event is sent to the client. This implies I need a post event
processing hook to determine if the client was notified already and
not send if appropriate. This is why I added
WindowEventDispatcherObserver as a way to deal with this. I'll be more
obvious in a following patch.

BUG=837692
TEST=covered by test

Change-Id: Ifb3e332466b3e6a6ee09c625020d6dbf9ed1a54e
Reviewed-on: https://chromium-review.googlesource.com/1054413
Commit-Queue: Scott Violet <sky@chromium.org>
Reviewed-by: Michael Wasserman <msw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#557797}
  • Loading branch information
Scott Violet authored and Commit Bot committed May 11, 2018
1 parent 5b3c55b commit 39c503d
Show file tree
Hide file tree
Showing 17 changed files with 427 additions and 15 deletions.
3 changes: 3 additions & 0 deletions services/ui/ws2/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ component("lib") {
"client_root.h",
"client_window.cc",
"client_window.h",
"pointer_watcher.cc",
"pointer_watcher.h",
"screen_provider.cc",
"screen_provider.h",
"window_host_frame_sink_client.cc",
Expand Down Expand Up @@ -127,6 +129,7 @@ source_set("tests") {
"//third_party/mesa:osmesa",
"//ui/aura:test_support",
"//ui/compositor:test_support",
"//ui/events:test_support",
"//ui/gl:test_support",
]

Expand Down
66 changes: 66 additions & 0 deletions services/ui/ws2/pointer_watcher.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2018 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 "services/ui/ws2/pointer_watcher.h"

#include "services/ui/ws2/window_service_client.h"
#include "ui/aura/env.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"

namespace ui {
namespace ws2 {

PointerWatcher::PointerWatcher(WindowServiceClient* client) : client_(client) {
aura::Env::GetInstance()->AddWindowEventDispatcherObserver(this);
}

PointerWatcher::~PointerWatcher() {
aura::Env::GetInstance()->RemoveWindowEventDispatcherObserver(this);
}

bool PointerWatcher::ShouldSendEventToClient(const ui::Event& event) const {
switch (event.type()) {
case ui::ET_MOUSE_PRESSED:
case ui::ET_MOUSE_RELEASED:
case ui::ET_TOUCH_PRESSED:
case ui::ET_TOUCH_RELEASED:
return true;

case ui::ET_MOUSE_MOVED:
case ui::ET_TOUCH_MOVED:
case ui::ET_MOUSEWHEEL:
return types_to_watch_ == TypesToWatch::kUpDownMoveWheel;

default:
break;
}
return false;
}

void PointerWatcher::OnWindowEventDispatcherStartedProcessing(
aura::WindowEventDispatcher* dispatcher,
const ui::Event& event) {
if (!ShouldSendEventToClient(event))
return;

// TODO(sky): this needs to interact with actual event sending so that we
// only send pointer events if an event wasn't also sent to the client.
// Part of https://crbug.com/837692
std::unique_ptr<ui::Event> event_to_send;
// Client code expects to get PointerEvents.
if (event.IsMouseEvent())
event_to_send = std::make_unique<ui::PointerEvent>(*event.AsMouseEvent());
else if (event.IsTouchEvent())
event_to_send = std::make_unique<ui::PointerEvent>(*event.AsTouchEvent());
else
NOTREACHED();
client_->SendPointerWatcherEventToClient(dispatcher->host()->GetDisplayId(),
std::move(event_to_send));
}

} // namespace ws2
} // namespace ui
58 changes: 58 additions & 0 deletions services/ui/ws2/pointer_watcher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2018 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.

#ifndef SERVICES_UI_WS2_POINTER_WATCHER_H_
#define SERVICES_UI_WS2_POINTER_WATCHER_H_

#include "base/macros.h"
#include "ui/aura/window_event_dispatcher_observer.h"

namespace ui {
namespace ws2 {

class WindowServiceClient;

// PointerWatcher is used when a client has requested to observe pointer events
// that the client would not normally receive. PointerWatcher observes events
// by way of aura::WindowEventDispatcherObserver and forwards them to the
// client.
//
// This class provides the server implementation of
// ui::mojom::WindowTree::StartPointerWatcher(), see it for more information.
class PointerWatcher : public aura::WindowEventDispatcherObserver {
public:
enum class TypesToWatch {
// Pointer up/down events.
kUpDown,

// Pointer up, down, move (including drag) and wheel events.
kUpDownMoveWheel,
};

explicit PointerWatcher(WindowServiceClient* client);
~PointerWatcher() override;

void set_types_to_watch(TypesToWatch types) { types_to_watch_ = types; }

private:
// Returns true if |event| matches the types the PointerWatcher has been
// configured to monitor.
bool ShouldSendEventToClient(const ui::Event& event) const;

// aura::WindowEventDispatcherObserver:
void OnWindowEventDispatcherStartedProcessing(
aura::WindowEventDispatcher* dispatcher,
const ui::Event& event) override;

TypesToWatch types_to_watch_ = TypesToWatch::kUpDown;

WindowServiceClient* client_;

DISALLOW_COPY_AND_ASSIGN(PointerWatcher);
};

} // namespace ws2
} // namespace ui

#endif // SERVICES_UI_WS2_POINTER_WATCHER_H_
30 changes: 27 additions & 3 deletions services/ui/ws2/test_window_tree_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,29 @@
namespace ui {
namespace ws2 {

TestWindowTreeClient::ObservedPointerEvent::ObservedPointerEvent() = default;

TestWindowTreeClient::ObservedPointerEvent::ObservedPointerEvent(
ObservedPointerEvent&& other) = default;

TestWindowTreeClient::ObservedPointerEvent::~ObservedPointerEvent() = default;

TestWindowTreeClient::TestWindowTreeClient() {
tracker_.set_delegate(this);
}

TestWindowTreeClient::~TestWindowTreeClient() = default;

TestWindowTreeClient::ObservedPointerEvent
TestWindowTreeClient::PopObservedPointerEvent() {
if (observed_pointer_events_.empty())
return ObservedPointerEvent();

ObservedPointerEvent event = std::move(observed_pointer_events_.front());
observed_pointer_events_.pop();
return event;
}

void TestWindowTreeClient::OnChangeAdded() {}

void TestWindowTreeClient::OnEmbed(
Expand Down Expand Up @@ -145,9 +162,16 @@ void TestWindowTreeClient::OnWindowInputEvent(
tree_->OnWindowInputEventAck(event_id, mojom::EventResult::HANDLED);
}

void TestWindowTreeClient::OnPointerEventObserved(std::unique_ptr<ui::Event>,
Id window_id,
int64_t display_id) {}
void TestWindowTreeClient::OnPointerEventObserved(
std::unique_ptr<ui::Event> event,
Id window_id,
int64_t display_id) {
ObservedPointerEvent observed_pointer_event;
observed_pointer_event.window_id = window_id;
observed_pointer_event.display_id = display_id;
observed_pointer_event.event = std::move(event);
observed_pointer_events_.push(std::move(observed_pointer_event));
}

void TestWindowTreeClient::OnWindowSharedPropertyChanged(
Id window,
Expand Down
28 changes: 27 additions & 1 deletion services/ui/ws2/test_window_tree_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
#ifndef SERVICES_UI_WS2_TEST_WINDOW_TREE_CLIENT_H_
#define SERVICES_UI_WS2_TEST_WINDOW_TREE_CLIENT_H_

#include <stdint.h>

#include <queue>

#include "base/component_export.h"
#include "base/macros.h"
#include "services/ui/public/interfaces/window_tree.mojom.h"
Expand All @@ -17,9 +21,30 @@ namespace ws2 {
class TestWindowTreeClient : public mojom::WindowTreeClient,
public TestChangeTracker::Delegate {
public:
// An ObservedPointerEvent is created for each call to
// OnPointerEventObserved()
struct ObservedPointerEvent {
ObservedPointerEvent();
ObservedPointerEvent(ObservedPointerEvent&& other);
~ObservedPointerEvent();

std::unique_ptr<ui::Event> event;
Id window_id = 0;
int64_t display_id = 0;
};

TestWindowTreeClient();
~TestWindowTreeClient() override;

std::queue<ObservedPointerEvent>& observed_pointer_events() {
return observed_pointer_events_;
}

// Returns the oldest ObservedPointerEvent that was received by way of
// OnPointerEventObserved(). If no pointer events have been observed, |event|
// in the returned object is null.
ObservedPointerEvent PopObservedPointerEvent();

mojom::WindowTree* tree() { return tree_.get(); }
TestChangeTracker* tracker() { return &tracker_; }
Id root_window_id() const { return root_window_id_; }
Expand Down Expand Up @@ -95,7 +120,7 @@ class TestWindowTreeClient : public mojom::WindowTreeClient,
const gfx::PointF& event_location_in_screen_pixel_layout,
std::unique_ptr<ui::Event> event,
bool matches_pointer_watcher) override;
void OnPointerEventObserved(std::unique_ptr<ui::Event>,
void OnPointerEventObserved(std::unique_ptr<ui::Event> event,
Id window_id,
int64_t display_id) override;
void OnWindowSharedPropertyChanged(
Expand Down Expand Up @@ -138,6 +163,7 @@ class TestWindowTreeClient : public mojom::WindowTreeClient,
mojom::WindowTreePtr tree_;
Id root_window_id_ = 0;
bool track_root_bounds_changes_ = false;
std::queue<ObservedPointerEvent> observed_pointer_events_;

DISALLOW_COPY_AND_ASSIGN(TestWindowTreeClient);
};
Expand Down
24 changes: 20 additions & 4 deletions services/ui/ws2/window_service_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "services/ui/ws2/client_change_tracker.h"
#include "services/ui/ws2/client_root.h"
#include "services/ui/ws2/client_window.h"
#include "services/ui/ws2/pointer_watcher.h"
#include "services/ui/ws2/window_service.h"
#include "services/ui/ws2/window_service_client_binding.h"
#include "services/ui/ws2/window_service_delegate.h"
Expand All @@ -21,6 +22,7 @@
#include "ui/aura/mus/property_converter.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
#include "ui/aura/window_tree_host.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_type.h"
#include "ui/display/display.h"
Expand Down Expand Up @@ -74,6 +76,13 @@ WindowServiceClient::~WindowServiceClient() {
}
}

void WindowServiceClient::SendPointerWatcherEventToClient(
int64_t display_id,
std::unique_ptr<ui::Event> event) {
window_tree_client_->OnPointerEventObserved(std::move(event),
kInvalidTransportId, display_id);
}

ClientRoot* WindowServiceClient::CreateClientRoot(
aura::Window* window,
mojom::WindowTreePtr window_tree) {
Expand Down Expand Up @@ -724,11 +733,15 @@ void WindowServiceClient::ReleaseCapture(uint32_t change_id, Id window_id) {
}

void WindowServiceClient::StartPointerWatcher(bool want_moves) {
NOTIMPLEMENTED();
if (!pointer_watcher_)
pointer_watcher_ = std::make_unique<PointerWatcher>(this);
pointer_watcher_->set_types_to_watch(
want_moves ? PointerWatcher::TypesToWatch::kUpDownMoveWheel
: PointerWatcher::TypesToWatch::kUpDown);
}

void WindowServiceClient::StopPointerWatcher() {
NOTIMPLEMENTED();
pointer_watcher_.reset();
}

void WindowServiceClient::SetWindowBounds(
Expand Down Expand Up @@ -926,9 +939,12 @@ void WindowServiceClient::SetImeVisibility(
}

void WindowServiceClient::SetEventTargetingPolicy(
Id window_id,
Id transport_window_id,
::ui::mojom::EventTargetingPolicy policy) {
NOTIMPLEMENTED();
aura::Window* window =
GetWindowByClientId(MakeClientWindowId(transport_window_id));
if (IsClientCreatedWindow(window) || IsClientRootWindow(window))
window->SetEventTargetingPolicy(policy);
}

void WindowServiceClient::OnWindowInputEventAck(
Expand Down
22 changes: 17 additions & 5 deletions services/ui/ws2/window_service_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@ class Window;
}

namespace ui {

class Event;

namespace ws2 {

class ClientChangeTracker;
class ClientRoot;
class PointerWatcher;
class WindowService;
class WindowServiceClientBinding;

Expand All @@ -52,7 +56,7 @@ class WindowServiceClientBinding;
// WindowServiceClientBinding).
class COMPONENT_EXPORT(WINDOW_SERVICE) WindowServiceClient
: public mojom::WindowTree,
aura::WindowObserver {
public aura::WindowObserver {
public:
WindowServiceClient(WindowService* window_service,
ClientSpecificId client_id,
Expand All @@ -64,6 +68,11 @@ class COMPONENT_EXPORT(WINDOW_SERVICE) WindowServiceClient
void InitForEmbed(aura::Window* root, mojom::WindowTreePtr window_tree_ptr);
void InitFromFactory();

// Notifies the client that an event matching a pointer watcher has been
// received.
void SendPointerWatcherEventToClient(int64_t display_id,
std::unique_ptr<Event> event);

private:
friend class ClientRoot;
friend class WindowServiceClientTestHelper;
Expand Down Expand Up @@ -282,11 +291,10 @@ class COMPONENT_EXPORT(WINDOW_SERVICE) WindowServiceClient
void SetImeVisibility(Id window_id,
bool visible,
::ui::mojom::TextInputStatePtr state) override;
void SetEventTargetingPolicy(
Id window_id,
::ui::mojom::EventTargetingPolicy policy) override;
void SetEventTargetingPolicy(Id transport_window_id,
ui::mojom::EventTargetingPolicy policy) override;
void OnWindowInputEventAck(uint32_t event_id,
::ui::mojom::EventResult result) override;
mojom::EventResult result) override;
void DeactivateWindow(Id window_id) override;
void StackAbove(uint32_t change_id, Id above_id, Id below_id) override;
void StackAtTop(uint32_t change_id, Id window_id) override;
Expand Down Expand Up @@ -355,6 +363,10 @@ class COMPONENT_EXPORT(WINDOW_SERVICE) WindowServiceClient
// Used to track the active change from the client.
std::unique_ptr<ClientChangeTracker> property_change_tracker_;

// If non-null the client has requested pointer events the client would not
// normally get.
std::unique_ptr<PointerWatcher> pointer_watcher_;

DISALLOW_COPY_AND_ASSIGN(WindowServiceClient);
};

Expand Down
Loading

0 comments on commit 39c503d

Please sign in to comment.