Commit 39c503de authored by Scott Violet's avatar Scott Violet Committed by Commit Bot

chromeos: wires up pointer event observers for ws2

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: default avatarMichael Wasserman <msw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#557797}
parent 5b3c55bc
......@@ -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",
......@@ -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",
]
......
// 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
// 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_
......@@ -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(
......@@ -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,
......
......@@ -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"
......@@ -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_; }
......@@ -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(
......@@ -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);
};
......
......@@ -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"
......@@ -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"
......@@ -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) {
......@@ -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(
......@@ -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(
......
......@@ -22,10 +22,14 @@ class Window;
}
namespace ui {
class Event;
namespace ws2 {
class ClientChangeTracker;
class ClientRoot;
class PointerWatcher;
class WindowService;
class WindowServiceClientBinding;
......@@ -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,
......@@ -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;
......@@ -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;
......@@ -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);
};
......
......@@ -15,6 +15,10 @@ WindowServiceClientTestHelper::WindowServiceClientTestHelper(
WindowServiceClientTestHelper::~WindowServiceClientTestHelper() = default;
mojom::WindowTree* WindowServiceClientTestHelper::window_tree() {
return static_cast<mojom::WindowTree*>(window_service_client_);
}
aura::Window* WindowServiceClientTestHelper::NewTopLevelWindow(
Id transport_window_id) {
base::flat_map<std::string, std::vector<uint8_t>> properties;
......@@ -34,6 +38,13 @@ void WindowServiceClientTestHelper::SetWindowBounds(aura::Window* window,
local_surface_id);
}
void WindowServiceClientTestHelper::SetEventTargetingPolicy(
aura::Window* window,
mojom::EventTargetingPolicy policy) {
window_service_client_->SetEventTargetingPolicy(
window_service_client_->TransportIdForWindow(window), policy);
}
void WindowServiceClientTestHelper::SetWindowProperty(
aura::Window* window,
const std::string& name,
......
......@@ -5,6 +5,8 @@
#ifndef SERVICES_UI_WS2_WINDOW_SERVICE_CLIENT_TEST_HELPER_H_
#define SERVICES_UI_WS2_WINDOW_SERVICE_CLIENT_TEST_HELPER_H_
#include <vector>
#include "base/macros.h"
#include "services/ui/ws2/ids.h"
......@@ -17,6 +19,13 @@ class Rect;
}
namespace ui {
namespace mojom {
class WindowTree;
enum class EventTargetingPolicy;
} // namespace mojom
namespace ws2 {
class WindowServiceClient;
......@@ -28,10 +37,14 @@ class WindowServiceClientTestHelper {
WindowServiceClient* window_service_client);
~WindowServiceClientTestHelper();
mojom::WindowTree* window_tree();
aura::Window* NewTopLevelWindow(Id transport_window_id);
void SetWindowBounds(aura::Window* window,
const gfx::Rect& bounds,
uint32_t change_id = 1);
void SetEventTargetingPolicy(aura::Window* window,
mojom::EventTargetingPolicy policy);
void SetWindowProperty(aura::Window* window,
const std::string& name,
const std::vector<uint8_t>& value,
......
......@@ -8,6 +8,7 @@
#include <stdint.h>
#include <memory>
#include <queue>
#include "base/test/scoped_task_environment.h"
#include "services/ui/public/cpp/property_type_converters.h"
......@@ -21,8 +22,10 @@
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/test/aura_test_helper.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
#include "ui/compositor/test/context_factories_for_test.h"
#include "ui/events/test/event_generator.h"
#include "ui/gl/test/gl_surface_test_support.h"
namespace ui {
......@@ -54,11 +57,16 @@ class WindowServiceTestHelper {
}
~WindowServiceTestHelper() {
window_service_client_.reset();
service_.reset();
aura_test_helper_.TearDown();
ui::TerminateContextFactoryForTests();
}
aura::Window* root() { return aura_test_helper_.root_window(); }
TestWindowServiceDelegate* delegate() { return &delegate_; }
TestWindowTreeClient* window_tree_client() { return &window_tree_client_; }
std::vector<Change>* changes() {
return window_tree_client_.tracker()->changes();
}
......@@ -173,6 +181,68 @@ TEST(WindowServiceClientTest, SetProperty) {
helper.changes()->clear();
}
TEST(WindowServiceClientTest, PointerWatcher) {
WindowServiceTestHelper helper;
TestWindowTreeClient* window_tree_client = helper.window_tree_client();
aura::Window* top_level = helper.helper_->NewTopLevelWindow(1);
ASSERT_TRUE(top_level);
helper.helper_->SetEventTargetingPolicy(top_level,
mojom::EventTargetingPolicy::NONE);
EXPECT_EQ(mojom::EventTargetingPolicy::NONE,
top_level->event_targeting_policy());
// Start the pointer watcher only for pointer down/up.
helper.helper_->window_tree()->StartPointerWatcher(false);
top_level->Show();
top_level->SetBounds(gfx::Rect(10, 10, 100, 100));
test::EventGenerator event_generator(helper.root());
event_generator.MoveMouseTo(50, 50);
ASSERT_TRUE(window_tree_client->observed_pointer_events().empty());
event_generator.MoveMouseTo(5, 6);
ASSERT_TRUE(window_tree_client->observed_pointer_events().empty());
event_generator.PressLeftButton();
{
ASSERT_EQ(1u, window_tree_client->observed_pointer_events().size());
auto event = std::move(window_tree_client->PopObservedPointerEvent().event);
ASSERT_TRUE(event);
EXPECT_EQ(ET_POINTER_DOWN, event->type());
EXPECT_EQ(gfx::Point(5, 6), event->AsLocatedEvent()->location());
}
event_generator.ReleaseLeftButton();
{
ASSERT_EQ(1u, window_tree_client->observed_pointer_events().size());
auto event = std::move(window_tree_client->PopObservedPointerEvent().event);
ASSERT_TRUE(event);
EXPECT_EQ(ET_POINTER_UP, event->type());
EXPECT_EQ(gfx::Point(5, 6), event->AsLocatedEvent()->location());
}
// Enable observing move events.
helper.helper_->window_tree()->StartPointerWatcher(true);
event_generator.MoveMouseTo(8, 9);
{
ASSERT_EQ(1u, window_tree_client->observed_pointer_events().size());
auto event = std::move(window_tree_client->PopObservedPointerEvent().event);
ASSERT_TRUE(event);
EXPECT_EQ(ET_POINTER_MOVED, event->type());
EXPECT_EQ(gfx::Point(8, 9), event->AsLocatedEvent()->location());
}
const int kTouchId = 11;
event_generator.MoveTouchId(gfx::Point(2, 3), kTouchId);
{
ASSERT_EQ(1u, window_tree_client->observed_pointer_events().size());
auto event = std::move(window_tree_client->PopObservedPointerEvent().event);
ASSERT_TRUE(event);
EXPECT_EQ(ET_POINTER_MOVED, event->type());
EXPECT_EQ(gfx::Point(2, 3), event->AsLocatedEvent()->location());
}
}
} // namespace
} // namespace ws2
} // namespace ui
......@@ -74,6 +74,7 @@ jumbo_component("aura") {
"window.h",
"window_delegate.h",
"window_event_dispatcher.h",
"window_event_dispatcher_observer.h",
"window_observer.h",
"window_occlusion_tracker.h",
"window_port.h",
......
......@@ -20,6 +20,7 @@
#include "ui/aura/mus/window_port_mus.h"
#include "ui/aura/mus/window_tree_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher_observer.h"
#include "ui/aura/window_port_for_shutdown.h"
#include "ui/events/event_target_iterator.h"
#include "ui/events/platform/platform_event_source.h"
......@@ -115,6 +116,16 @@ void Env::RemoveObserver(EnvObserver* observer) {
observers_.RemoveObserver(observer);
}
void Env::AddWindowEventDispatcherObserver(
WindowEventDispatcherObserver* observer) {
window_event_dispatcher_observers_.AddObserver(observer);
}
void Env::RemoveWindowEventDispatcherObserver(
WindowEventDispatcherObserver* observer) {
window_event_dispatcher_observers_.RemoveObserver(observer);
}
bool Env::IsMouseButtonDown() const {
return input_state_lookup_.get() ? input_state_lookup_->IsMouseButtonDown() :
mouse_button_flags_ != 0;
......
......@@ -48,6 +48,7 @@ class InputStateLookup;
class MouseLocationManager;
class MusMouseLocationUpdater;
class Window;
class WindowEventDispatcherObserver;
class WindowPort;
class WindowTreeClient;
class WindowTreeHost;
......@@ -83,6 +84,15 @@ class AURA_EXPORT Env : public ui::EventTarget,
void AddObserver(EnvObserver* observer);
void RemoveObserver(EnvObserver* observer);
void AddWindowEventDispatcherObserver(
WindowEventDispatcherObserver* observer);
void RemoveWindowEventDispatcherObserver(
WindowEventDispatcherObserver* observer);
base::ObserverList<WindowEventDispatcherObserver>&
window_event_dispatcher_observers() {
return window_event_dispatcher_observers_;
}
EnvInputStateController* env_controller() const {
return env_controller_.get();
}
......@@ -202,6 +212,12 @@ class AURA_EXPORT Env : public ui::EventTarget,
base::ObserverList<EnvObserver> observers_;
// Code wanting to observe WindowEventDispatcher typically wants to observe
// all WindowEventDispatchers. This is made easier by having Env own all the
// observers.
base::ObserverList<WindowEventDispatcherObserver>
window_event_dispatcher_observers_;
std::unique_ptr<EnvInputStateController> env_controller_;
int mouse_button_flags_;
// Location of last mouse event, in screen coordinates.
......
......@@ -22,6 +22,7 @@
#include "ui/aura/mus/mus_mouse_location_updater.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/aura/window_event_dispatcher_observer.h"
#include "ui/aura/window_targeter.h"
#include "ui/aura/window_tracker.h"
#include "ui/aura/window_tree_host.h"
......@@ -77,6 +78,23 @@ void ConvertEventLocationToTarget(ui::EventTarget* event_target,
} // namespace
WindowEventDispatcher::ObserverNotifier::ObserverNotifier(
WindowEventDispatcher* dispatcher,
const ui::Event& event)
: dispatcher_(dispatcher) {
for (WindowEventDispatcherObserver& observer :
Env::GetInstance()->window_event_dispatcher_observers()) {
observer.OnWindowEventDispatcherStartedProcessing(dispatcher, event);
}
}
WindowEventDispatcher::ObserverNotifier::~ObserverNotifier() {
for (WindowEventDispatcherObserver& observer :
Env::GetInstance()->window_event_dispatcher_observers()) {
observer.OnWindowEventDispatcherFinishedProcessingEvent(dispatcher_);
}
}
////////////////////////////////////////////////////////////////////////////////
// WindowEventDispatcher, public:
......@@ -536,11 +554,14 @@ void WindowEventDispatcher::OnEventProcessingStarted(ui::Event* event) {
if (mus_mouse_location_updater_)
mus_mouse_location_updater_->OnEventProcessingStarted(*event);
observer_notifiers_.push(std::make_unique<ObserverNotifier>(this, *event));
}
void WindowEventDispatcher::OnEventProcessingFinished(ui::Event* event) {
if (mus_mouse_location_updater_)
mus_mouse_location_updater_->OnEventProcessingFinished();
observer_notifiers_.pop();
}
////////////////////////////////////////////////////////////////////////////////
......
......@@ -6,6 +6,7 @@
#define UI_AURA_WINDOW_EVENT_DISPATCHER_H_
#include <memory>
#include <queue>
#include <vector>
#include "base/callback.h"
......@@ -29,6 +30,7 @@
#include "ui/gfx/native_widget_types.h"
namespace ui {
class Event;
class GestureEvent;
class GestureRecognizer;
class MouseEvent;
......@@ -58,6 +60,8 @@ class AURA_EXPORT WindowEventDispatcher : public ui::EventProcessor,
explicit WindowEventDispatcher(WindowTreeHost* host);
~WindowEventDispatcher() override;
WindowTreeHost* host() { return host_; }
Window* mouse_pressed_handler() { return mouse_pressed_handler_; }
Window* mouse_moved_handler() { return mouse_moved_handler_; }
Window* touchpad_pinch_handler() { return touchpad_pinch_handler_; }
......@@ -136,6 +140,21 @@ class AURA_EXPORT WindowEventDispatcher : public ui::EventProcessor,
friend class Window;
friend class TestScreen;
// Used to call WindowEventDispatcherObserver when event processing starts
// (from the constructor) and finishes (from the destructor). Notification is
// handled by this object to ensure notification happens if the associated
// WindowEventDispatcher is destroyed during processing of the event.
class ObserverNotifier {
public:
ObserverNotifier(WindowEventDispatcher* dispatcher, const ui::Event& event);
~ObserverNotifier();
private:
WindowEventDispatcher* dispatcher_;
DISALLOW_COPY_AND_ASSIGN(ObserverNotifier);
};
// The parameter for OnWindowHidden() to specify why window is hidden.
enum WindowHiddenReason {
WINDOW_DESTROYED, // Window is destroyed.
......@@ -301,6 +320,10 @@ class AURA_EXPORT WindowEventDispatcher : public ui::EventProcessor,
// pointer moves are released and there is no held move event.
base::OnceClosure did_dispatch_held_move_event_callback_;
// See ObserverNotifier for details. This is a queue to handle the case of
// nested event dispatch.
std::queue<std::unique_ptr<ObserverNotifier>> observer_notifiers_;
// Used to schedule reposting an event.
base::WeakPtrFactory<WindowEventDispatcher> repost_event_factory_;
......
// 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 UI_AURA_WINDOW_EVENT_DISPATCHER_OBSERVER_H_
#define UI_AURA_WINDOW_EVENT_DISPATCHER_OBSERVER_H_
#include "ui/aura/aura_export.h"
namespace ui {
class Event;
}
namespace aura {
class WindowEventDispatcher;
// WindowEventDispatcherObservers are added to Env and observe *all*
// WindowEventDispatchers.
class AURA_EXPORT WindowEventDispatcherObserver {
public:
// Called when WindowEventDispatcher starts processing an event.
//
// NOTE: this function is called *after* the location has been transformed
// (assuming the event is a located event). In other words, the coordinates
// are DIPs when this is called.
virtual void OnWindowEventDispatcherStartedProcessing(
WindowEventDispatcher* dispatcher,
const ui::Event& event) {}
// Called when WindowEventDispatcher finishes processing an event.
virtual void OnWindowEventDispatcherFinishedProcessingEvent(
WindowEventDispatcher* dispatcher) {}
protected:
virtual ~WindowEventDispatcherObserver() {}
};
} // namespace aura
#endif // UI_AURA_WINDOW_EVENT_DISPATCHER_OBSERVER_H_
......@@ -89,8 +89,8 @@ class AURA_EXPORT WindowTargeter : public ui::EventTargeter {
protected:
// Same as FindTargetForEvent(), but used for positional events. The location
// etc. of |event| are in |root|'s coordinate system. When finding the target
// for the event, the targeter can mutate the |event| (e.g. change the
// etc. of |event| are in |window|'s coordinate system. When finding the
// target for the event, the targeter can mutate the |event| (e.g. change the
// coordinate to be in the returned target's coordinate system) so that it can
// be dispatched to the target without any further modification.
virtual Window* FindTargetForLocatedEvent(Window* window,
......
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