ws: Queue input events on delivery, not dispatch.
Queue additional events generated by EventRewriters, as needed.
Refactor EventQueue to operate later, closer to EventSink delivery.
Eliminate HostEventQueue and [Test]HostEventDispatcher.
Use Shell via WSDelegate for EventInjector's display -> host lookup.
Update tests and setup code; add a queue unit test for host destruction.
Move content_browsertests' aura::TestScreen ownership to WMTestHelper.
TODO: Remove WindowTreeHost::event_sink(), use GetEventSink().
Alternate WIP sticky keys DCHECK workaround: https://crrev.com/c/1371878
Bug: 913549
Test: No SingleProcessMash sticky keys DCHECK, no input regressions.
Change-Id: I61d67af94fad0ed8414a7945160a7c231dca47a1
Reviewed-on: https://chromium-review.googlesource.com/c/1372629
Commit-Queue: Michael Wasserman <msw@chromium.org>
Reviewed-by: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#616930}
diff --git a/ash/display/extended_mouse_warp_controller_unittest.cc b/ash/display/extended_mouse_warp_controller_unittest.cc
index f523765..d99f540 100644
--- a/ash/display/extended_mouse_warp_controller_unittest.cc
+++ b/ash/display/extended_mouse_warp_controller_unittest.cc
@@ -66,7 +66,7 @@
location_in_host_native, ui::EventTimeForNow(),
event_flag1, event_flag2);
ui::MouseEvent mouseev(&native_event);
- host->DispatchEventFromQueue(&mouseev);
+ host->DispatchEvent(&mouseev);
// The test relies on the last_mouse_location, which will be updated by
// a synthesized event posted asynchronusly. Wait until the synthesized
diff --git a/ash/host/ash_window_tree_host_platform.cc b/ash/host/ash_window_tree_host_platform.cc
index 7f237a7..de050d2 100644
--- a/ash/host/ash_window_tree_host_platform.cc
+++ b/ash/host/ash_window_tree_host_platform.cc
@@ -14,7 +14,7 @@
#include "ash/ws/window_service_owner.h"
#include "base/feature_list.h"
#include "base/trace_event/trace_event.h"
-#include "services/ws/host_event_queue.h"
+#include "services/ws/event_queue.h"
#include "services/ws/public/cpp/input_devices/input_device_controller_client.h"
#include "services/ws/public/mojom/window_manager.mojom.h"
#include "services/ws/window_service.h"
@@ -181,17 +181,11 @@
ConfineCursorToRootWindow();
}
-void AshWindowTreeHostPlatform::DispatchEvent(ui::Event* event) {
- host_event_queue_->DispatchOrQueueEvent(event);
-}
-
void AshWindowTreeHostPlatform::CommonInit() {
transformer_helper_.Init();
- host_event_queue_ = Shell::Get()
- ->window_service_owner()
- ->window_service()
- ->RegisterHostEventDispatcher(this, this);
+ event_queue_ =
+ Shell::Get()->window_service_owner()->window_service()->event_queue();
if (!base::FeatureList::IsEnabled(features::kMash))
return;
@@ -201,14 +195,6 @@
SetSharedInputMethod(input_method_.get());
}
-ui::EventDispatchDetails AshWindowTreeHostPlatform::DispatchEventFromQueue(
- ui::Event* event) {
- TRACE_EVENT0("input", "AshWindowTreeHostPlatform::DispatchEvent");
- if (event->IsLocatedEvent())
- TranslateLocatedEvent(static_cast<ui::LocatedEvent*>(event));
- return SendEventToSink(event);
-}
-
void AshWindowTreeHostPlatform::SetTapToClickPaused(bool state) {
ws::InputDeviceControllerClient* input_device_controller_client =
Shell::Get()->shell_delegate()->GetInputDeviceControllerClient();
@@ -226,6 +212,20 @@
return !target || !ws::WindowService::IsProxyWindow(target);
}
+void AshWindowTreeHostPlatform::DispatchEvent(ui::Event* event) {
+ TRACE_EVENT0("input", "AshWindowTreeHostPlatform::DispatchEvent");
+ if (event->IsLocatedEvent())
+ TranslateLocatedEvent(event->AsLocatedEvent());
+ return aura::WindowTreeHostPlatform::DispatchEvent(event);
+}
+
+ui::EventDispatchDetails AshWindowTreeHostPlatform::DeliverEventToSink(
+ ui::Event* event) {
+ // Queue the event if needed, or deliver it directly to the sink.
+ auto result = event_queue_->DeliverOrQueueEvent(this, event);
+ return result.value_or(ui::EventDispatchDetails());
+}
+
void AshWindowTreeHostPlatform::SetTextInputState(
ui::mojom::TextInputStatePtr state) {
ui::PlatformImeController* ime =
diff --git a/ash/host/ash_window_tree_host_platform.h b/ash/host/ash_window_tree_host_platform.h
index 32267ac1..09476d6 100644
--- a/ash/host/ash_window_tree_host_platform.h
+++ b/ash/host/ash_window_tree_host_platform.h
@@ -10,7 +10,6 @@
#include "ash/ash_export.h"
#include "ash/host/ash_window_tree_host.h"
#include "ash/host/transformer_helper.h"
-#include "services/ws/host_event_dispatcher.h"
#include "ui/aura/mus/input_method_mus_delegate.h"
#include "ui/aura/window_tree_host_platform.h"
@@ -19,7 +18,7 @@
}
namespace ws {
-class HostEventQueue;
+class EventQueue;
}
namespace ui {
@@ -32,8 +31,7 @@
class ASH_EXPORT AshWindowTreeHostPlatform
: public AshWindowTreeHost,
public aura::WindowTreeHostPlatform,
- public aura::InputMethodMusDelegate,
- public ws::HostEventDispatcher {
+ public aura::InputMethodMusDelegate {
public:
explicit AshWindowTreeHostPlatform(
ui::PlatformWindowInitProperties properties);
@@ -73,17 +71,15 @@
void SetBoundsInPixels(const gfx::Rect& bounds,
const viz::LocalSurfaceIdAllocation&
local_surface_id_allocation) override;
- void DispatchEvent(ui::Event* event) override;
bool ShouldSendKeyEventToIme() override;
+ void DispatchEvent(ui::Event* event) override;
+ ui::EventDispatchDetails DeliverEventToSink(ui::Event* event) override;
// aura::InputMethodMusDelegate:
void SetTextInputState(ui::mojom::TextInputStatePtr state) override;
void SetImeVisibility(bool visible,
ui::mojom::TextInputStatePtr state) override;
- // ws::HostEventDispatcher:
- ui::EventDispatchDetails DispatchEventFromQueue(ui::Event* event) override;
-
private:
// All constructors call into this.
void CommonInit();
@@ -102,7 +98,7 @@
// those connections are correctly established.
std::unique_ptr<aura::InputMethodMus> input_method_;
- std::unique_ptr<ws::HostEventQueue> host_event_queue_;
+ ws::EventQueue* event_queue_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(AshWindowTreeHostPlatform);
};
diff --git a/ash/ws/window_service_delegate_impl.cc b/ash/ws/window_service_delegate_impl.cc
index 90fe7fc..816600f 100644
--- a/ash/ws/window_service_delegate_impl.cc
+++ b/ash/ws/window_service_delegate_impl.cc
@@ -223,6 +223,11 @@
return Shell::Get();
}
+aura::Window* WindowServiceDelegateImpl::GetRootWindowForDisplayId(
+ int64_t display_id) {
+ return Shell::Get()->GetRootWindowForDisplayId(display_id);
+}
+
aura::Window* WindowServiceDelegateImpl::GetTopmostWindowAtPoint(
const gfx::Point& location_in_screen,
const std::set<aura::Window*>& ignore,
diff --git a/ash/ws/window_service_delegate_impl.h b/ash/ws/window_service_delegate_impl.h
index 5fc2fa4..da131644 100644
--- a/ash/ws/window_service_delegate_impl.h
+++ b/ash/ws/window_service_delegate_impl.h
@@ -43,6 +43,7 @@
void SetModalType(aura::Window* window, ui::ModalType type) override;
ui::SystemInputInjector* GetSystemInputInjector() override;
ui::EventTarget* GetGlobalEventTarget() override;
+ aura::Window* GetRootWindowForDisplayId(int64_t display_id) override;
aura::Window* GetTopmostWindowAtPoint(const gfx::Point& location_in_screen,
const std::set<aura::Window*>& ignores,
aura::Window** real_topmost) override;
diff --git a/content/shell/browser/shell.h b/content/shell/browser/shell.h
index 4faf60e..e014d4c 100644
--- a/content/shell/browser/shell.h
+++ b/content/shell/browser/shell.h
@@ -26,10 +26,6 @@
#elif defined(USE_AURA)
#if defined(OS_CHROMEOS)
-namespace display {
-class Screen;
-}
-
namespace wm {
class WMTestHelper;
}
@@ -293,7 +289,6 @@
#elif defined(USE_AURA)
#if defined(OS_CHROMEOS)
static wm::WMTestHelper* wm_test_helper_;
- static display::Screen* test_screen_;
#else
static wm::WMState* wm_state_;
#endif
diff --git a/content/shell/browser/shell_views.cc b/content/shell/browser/shell_views.cc
index c7f3ac3..ef4da07 100644
--- a/content/shell/browser/shell_views.cc
+++ b/content/shell/browser/shell_views.cc
@@ -20,7 +20,6 @@
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/resource/resource_bundle.h"
-#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/md_text_button.h"
@@ -35,7 +34,6 @@
#include "ui/views/widget/widget_delegate.h"
#if defined(OS_CHROMEOS)
-#include "ui/aura/test/test_screen.h"
#include "ui/wm/test/wm_test_helper.h"
#else // !defined(OS_CHROMEOS)
#include "ui/views/widget/desktop_aura/desktop_screen.h"
@@ -318,8 +316,6 @@
#if defined(OS_CHROMEOS)
// static
wm::WMTestHelper* Shell::wm_test_helper_ = nullptr;
-// static
-display::Screen* Shell::test_screen_ = nullptr;
#elif defined(USE_AURA)
// static
wm::WMState* Shell::wm_state_ = nullptr;
@@ -334,8 +330,6 @@
_setmode(_fileno(stderr), _O_BINARY);
#endif
#if defined(OS_CHROMEOS)
- test_screen_ = aura::TestScreen::Create(gfx::Size());
- display::Screen::SetScreenInstance(test_screen_);
ui::ContextFactory* ui_context_factory =
aura::Env::GetInstance()->mode() == aura::Env::Mode::LOCAL
? GetContextFactory()
@@ -355,9 +349,6 @@
#if defined(OS_CHROMEOS)
delete wm_test_helper_;
wm_test_helper_ = nullptr;
-
- delete test_screen_;
- test_screen_ = nullptr;
#endif
delete views_delegate_;
views_delegate_ = nullptr;
diff --git a/services/ws/BUILD.gn b/services/ws/BUILD.gn
index e37828e..83a649d 100644
--- a/services/ws/BUILD.gn
+++ b/services/ws/BUILD.gn
@@ -17,8 +17,7 @@
"//ash:ash_unittests",
]
public = [
- "host_event_dispatcher.h",
- "host_event_queue.h",
+ "event_queue.h",
"ids.h",
"window_delegate_impl.h",
"window_manager_interface.h",
@@ -46,10 +45,8 @@
"event_observer_helper.cc",
"event_observer_helper.h",
"event_queue.cc",
- "event_queue.h",
"focus_handler.cc",
"focus_handler.h",
- "host_event_queue.cc",
"injected_event_handler.cc",
"injected_event_handler.h",
"proxy_window.cc",
@@ -137,8 +134,6 @@
"proxy_window_test_helper.h",
"test_change_tracker.cc",
"test_change_tracker.h",
- "test_host_event_dispatcher.cc",
- "test_host_event_dispatcher.h",
"test_screen_provider_observer.cc",
"test_screen_provider_observer.h",
"test_window_service_delegate.cc",
diff --git a/services/ws/event_injector.cc b/services/ws/event_injector.cc
index 0693947..19e63bb 100644
--- a/services/ws/event_injector.cc
+++ b/services/ws/event_injector.cc
@@ -7,12 +7,10 @@
#include "base/bind.h"
#include "base/stl_util.h"
#include "services/ws/event_queue.h"
-#include "services/ws/host_event_queue.h"
#include "services/ws/injected_event_handler.h"
#include "services/ws/window_service.h"
+#include "services/ws/window_service_delegate.h"
#include "ui/aura/window_tree_host.h"
-#include "ui/display/display.h"
-#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/events/event_sink.h"
@@ -20,7 +18,7 @@
struct EventInjector::EventAndHost {
std::unique_ptr<ui::Event> event;
- aura::WindowTreeHost* window_tree_host = nullptr;
+ aura::WindowTreeHost* host = nullptr;
};
struct EventInjector::HandlerAndCallback {
@@ -30,9 +28,8 @@
};
struct EventInjector::QueuedEvent {
- int64_t display_id;
- // |callback| is the callback supplied by the client.
- EventInjector::InjectEventCallback callback;
+ base::WeakPtr<aura::WindowTreeHost> host; // May be destroyed while queued.
+ EventInjector::InjectEventCallback callback; // Supplied by the client.
std::unique_ptr<ui::Event> event;
};
@@ -65,21 +62,15 @@
NOTREACHED();
}
-aura::WindowTreeHost* EventInjector::GetWindowTreeHostForDisplayId(
- int64_t display_id) {
- HostEventQueue* host_event_queue =
- window_service_->event_queue()->GetHostEventQueueForDisplay(display_id);
- return host_event_queue ? host_event_queue->window_tree_host() : nullptr;
-}
-
EventInjector::EventAndHost EventInjector::DetermineEventAndHost(
int64_t display_id,
std::unique_ptr<ui::Event> event) {
EventAndHost event_and_host;
- aura::WindowTreeHost* window_tree_host =
- GetWindowTreeHostForDisplayId(display_id);
- if (!window_tree_host) {
- DVLOG(1) << "InjectEvent(): invalid display " << display_id;
+ aura::Window* window =
+ window_service_->delegate()->GetRootWindowForDisplayId(display_id);
+ event_and_host.host = window ? window->GetHost() : nullptr;
+ if (!event_and_host.host) {
+ DVLOG(1) << "InjectEvent(): invalid or destroyed display " << display_id;
return event_and_host;
}
@@ -96,7 +87,6 @@
// https://chromium.googlesource.com/chromium/src/+/ae087c53f5ce4557bfb0b92a13651342336fe18a/services/ws/event_injector.cc#22
}
- event_and_host.window_tree_host = window_tree_host;
event_and_host.event = std::move(event);
return event_and_host;
}
@@ -106,9 +96,7 @@
QueuedEvent queued_event = std::move(queued_events_.front());
queued_events_.pop_front();
- aura::WindowTreeHost* window_tree_host =
- GetWindowTreeHostForDisplayId(queued_event.display_id);
- if (!window_tree_host) {
+ if (!queued_event.host) {
std::move(queued_event.callback).Run(false);
return;
}
@@ -116,8 +104,8 @@
std::unique_ptr<HandlerAndCallback> handler_and_callback =
std::make_unique<HandlerAndCallback>();
handler_and_callback->callback = std::move(queued_event.callback);
- handler_and_callback->handler =
- std::make_unique<InjectedEventHandler>(window_service_, window_tree_host);
+ handler_and_callback->handler = std::make_unique<InjectedEventHandler>(
+ window_service_, queued_event.host.get());
InjectedEventHandler* handler = handler_and_callback->handler.get();
handlers_.push_back(std::move(handler_and_callback));
auto callback = base::BindOnce(&EventInjector::OnEventDispatched,
@@ -130,7 +118,7 @@
bool honor_rewriters) {
EventAndHost event_and_host =
DetermineEventAndHost(display_id, std::move(event));
- if (!event_and_host.window_tree_host)
+ if (!event_and_host.host || !event_and_host.event)
return;
// Reset the latency time. This way telemetry doesn't include the time from
@@ -143,9 +131,12 @@
ui::INPUT_EVENT_LATENCY_UI_COMPONENT, event_time, 1);
event_and_host.event->set_latency(latency_info);
- EventQueue::DispatchOrQueueEvent(window_service_,
- event_and_host.window_tree_host,
- event_and_host.event.get(), honor_rewriters);
+ // SendEventToSink send events through rewriters; DeliverEventToSink does not.
+ // The event may be queued before actually being delivered to the EventSink.
+ if (honor_rewriters)
+ event_and_host.host->SendEventToSink(event_and_host.event.get());
+ else
+ event_and_host.host->DeliverEventToSink(event_and_host.event.get());
}
void EventInjector::InjectEvent(int64_t display_id,
@@ -153,15 +144,15 @@
InjectEventCallback cb) {
EventAndHost event_and_host =
DetermineEventAndHost(display_id, std::move(event));
- if (!event_and_host.window_tree_host) {
+ if (!event_and_host.host || !event_and_host.event) {
std::move(cb).Run(false);
return;
}
QueuedEvent queued_event;
- queued_event.display_id = display_id;
- queued_event.callback = std::move(cb);
+ queued_event.host = event_and_host.host->GetWeakPtr();
queued_event.event = std::move(event_and_host.event);
+ queued_event.callback = std::move(cb);
queued_events_.push_back(std::move(queued_event));
// Both EventQueue and |this| are owned by WindowService, so Unretained() is
@@ -172,15 +163,13 @@
void EventInjector::InjectEventNoAck(int64_t display_id,
std::unique_ptr<ui::Event> event) {
- InjectEventNoAckImpl(display_id, std::move(event),
- /* honor_rewriters */ true);
+ InjectEventNoAckImpl(display_id, std::move(event), /*honor_rewriters*/ true);
}
void EventInjector::InjectEventNoAckNoRewriters(
int64_t display_id,
std::unique_ptr<ui::Event> event) {
- InjectEventNoAckImpl(display_id, std::move(event),
- /* honor_rewriters */ false);
+ InjectEventNoAckImpl(display_id, std::move(event), /*honor_rewriters*/ false);
}
} // namespace ws
diff --git a/services/ws/event_injector.h b/services/ws/event_injector.h
index 4a9edc8..a3abed0 100644
--- a/services/ws/event_injector.h
+++ b/services/ws/event_injector.h
@@ -42,12 +42,9 @@
void OnEventDispatched(InjectedEventHandler* handler);
- aura::WindowTreeHost* GetWindowTreeHostForDisplayId(int64_t display_id);
-
// Determines the target WindowTreeHost and provides an mapping on |event|
- // before dispatch. If the returned EventAndHost has a null
- // |window_tree_host| there was a problem in conversion and the event should
- // not be dispatched.
+ // before dispatch. If the returned EventAndHost has a null |host|, there was
+ // a problem in conversion and the event should not be dispatched.
EventAndHost DetermineEventAndHost(int64_t display_id,
std::unique_ptr<ui::Event> event);
diff --git a/services/ws/event_injector_unittest.cc b/services/ws/event_injector_unittest.cc
index 2d65def..e804ad2 100644
--- a/services/ws/event_injector_unittest.cc
+++ b/services/ws/event_injector_unittest.cc
@@ -7,6 +7,7 @@
#include <memory>
#include "services/ws/event_injector.h"
+#include "services/ws/window_delegate_impl.h"
#include "services/ws/window_service.h"
#include "services/ws/window_service_test_helper.h"
#include "services/ws/window_service_test_setup.h"
@@ -33,17 +34,15 @@
TEST(EventInjectorTest, NoAck) {
WindowServiceTestSetup test_setup;
test_setup.service()->OnStart();
- ui::EventSource* event_source =
- test_setup.aura_test_helper()->root_window()->GetHost()->GetEventSource();
+ auto* event_source = test_setup.root()->GetHost()->GetEventSource();
ui::test::TestEventRewriter test_event_rewriter;
event_source->AddEventRewriter(&test_event_rewriter);
- const int64_t display_id =
- display::Screen::GetScreen()->GetPrimaryDisplay().id();
EventInjector* event_injector =
WindowServiceTestHelper(test_setup.service()).event_injector();
mojom::EventInjector* mojom_event_injector =
static_cast<mojom::EventInjector*>(event_injector);
+ auto display_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
mojom_event_injector->InjectEventNoAck(display_id, CreateTestEvent());
EXPECT_EQ(1, test_event_rewriter.events_seen());
EXPECT_FALSE(event_injector->HasQueuedEvents());
diff --git a/services/ws/event_queue.cc b/services/ws/event_queue.cc
index 2dd345a2..f6b480c 100644
--- a/services/ws/event_queue.cc
+++ b/services/ws/event_queue.cc
@@ -4,9 +4,6 @@
#include "services/ws/event_queue.h"
-#include "base/stl_util.h"
-#include "services/ws/host_event_dispatcher.h"
-#include "services/ws/host_event_queue.h"
#include "services/ws/window_service.h"
#include "services/ws/window_tree.h"
#include "ui/aura/window.h"
@@ -32,10 +29,8 @@
} // namespace
struct EventQueue::QueuedEvent {
- HostEventQueue* host = nullptr;
+ base::WeakPtr<aura::WindowTreeHost> host; // May be destroyed while queued.
std::unique_ptr<ui::Event> event;
- bool honor_rewriters = false;
-
base::OnceClosure callback;
};
@@ -47,39 +42,14 @@
window_service_->RemoveObserver(this);
}
-std::unique_ptr<HostEventQueue> EventQueue::RegisterHostEventDispatcher(
- aura::WindowTreeHost* window_tree_host,
- HostEventDispatcher* dispatcher) {
- return std::make_unique<HostEventQueue>(weak_factory_.GetWeakPtr(),
- window_tree_host, dispatcher);
-}
+base::Optional<ui::EventDispatchDetails> EventQueue::DeliverOrQueueEvent(
+ aura::WindowTreeHost* host,
+ ui::Event* event) {
+ if (!ShouldQueueEvent(host, *event))
+ return host->GetEventSink()->OnEventFromSource(event);
-// static
-base::Optional<ui::EventDispatchDetails> EventQueue::DispatchOrQueueEvent(
- WindowService* service,
- aura::WindowTreeHost* window_tree_host,
- ui::Event* event,
- bool honor_rewriters) {
- DCHECK(window_tree_host);
- HostEventQueue* host_event_queue =
- service->event_queue()->GetHostEventQueueForDisplay(
- window_tree_host->GetDisplayId());
- DCHECK(host_event_queue);
- return host_event_queue->DispatchOrQueueEvent(event, honor_rewriters);
-}
-
-bool EventQueue::ShouldQueueEvent(HostEventQueue* host_queue,
- const ui::Event& event) {
- if (!in_flight_event_ || !IsQueableEvent(event))
- return false;
- aura::WindowTargeter* targeter =
- host_queue->window_tree_host()->window()->targeter();
- if (!targeter)
- targeter = host_queue->window_tree_host()->dispatcher()->event_targeter();
- DCHECK(targeter);
- aura::Window* target =
- targeter->FindTargetForKeyEvent(host_queue->window_tree_host()->window());
- return target && WindowService::IsProxyWindow(target);
+ QueueEvent(host, *event);
+ return base::nullopt;
}
void EventQueue::NotifyWhenReadyToDispatch(base::OnceClosure closure) {
@@ -92,40 +62,24 @@
}
}
-HostEventQueue* EventQueue::GetHostEventQueueForDisplay(int64_t display_id) {
- for (HostEventQueue* host_queue : host_event_queues_) {
- if (host_queue->window_tree_host()->GetDisplayId() == display_id)
- return host_queue;
- }
- return nullptr;
+bool EventQueue::ShouldQueueEvent(aura::WindowTreeHost* host,
+ const ui::Event& event) {
+ if (!in_flight_event_ || !IsQueableEvent(event))
+ return false;
+ aura::WindowTargeter* targeter = host->window()->targeter();
+ if (!targeter)
+ targeter = host->dispatcher()->event_targeter();
+ DCHECK(targeter);
+ aura::Window* target = targeter->FindTargetForKeyEvent(host->window());
+ return target && WindowService::IsProxyWindow(target);
}
-void EventQueue::OnClientTookTooLongToAckEvent() {
- DVLOG(1) << "Client took too long to respond to event";
- DCHECK(in_flight_event_);
- OnClientAckedEvent(in_flight_event_->client_id, in_flight_event_->event_id);
-}
-
-void EventQueue::OnHostEventQueueCreated(HostEventQueue* host) {
- host_event_queues_.insert(host);
-}
-
-void EventQueue::OnHostEventQueueDestroyed(HostEventQueue* host) {
- base::EraseIf(queued_events_,
- [&host](const std::unique_ptr<QueuedEvent>& event) {
- return event->host == host;
- });
- host_event_queues_.erase(host);
-}
-
-void EventQueue::QueueEvent(HostEventQueue* host,
- const ui::Event& event,
- bool honor_rewriters) {
+void EventQueue::QueueEvent(aura::WindowTreeHost* host,
+ const ui::Event& event) {
DCHECK(ShouldQueueEvent(host, event));
std::unique_ptr<QueuedEvent> queued_event = std::make_unique<QueuedEvent>();
- queued_event->host = host;
+ queued_event->host = host->GetWeakPtr();
queued_event->event = ui::Event::Clone(event);
- queued_event->honor_rewriters = honor_rewriters;
queued_events_.push_back(std::move(queued_event));
}
@@ -135,14 +89,21 @@
std::move(*queued_events_.begin());
queued_events_.pop_front();
if (queued_event->callback) {
+ DCHECK(!queued_event->event) << "Running callback and ignoring event";
std::move(queued_event->callback).Run();
- } else {
- queued_event->host->DispatchEventDontQueue(queued_event->event.get(),
- queued_event->honor_rewriters);
+ } else if (queued_event->host) {
+ ignore_result(queued_event->host->GetEventSink()->OnEventFromSource(
+ queued_event->event.get()));
}
}
}
+void EventQueue::OnClientTookTooLongToAckEvent() {
+ DVLOG(1) << "Client took too long to respond to event";
+ DCHECK(in_flight_event_);
+ OnClientAckedEvent(in_flight_event_->client_id, in_flight_event_->event_id);
+}
+
void EventQueue::OnWillSendEventToClient(ClientSpecificId client_id,
uint32_t event_id,
const ui::Event& event) {
diff --git a/services/ws/event_queue.h b/services/ws/event_queue.h
index 0f2d4ff..0fe3972 100644
--- a/services/ws/event_queue.h
+++ b/services/ws/event_queue.h
@@ -8,7 +8,6 @@
#include <stdint.h>
#include <memory>
-#include <set>
#include "base/callback_forward.h"
#include "base/component_export.h"
@@ -31,51 +30,30 @@
namespace ws {
-class HostEventDispatcher;
-class HostEventQueue;
class WindowService;
-// EventQueue handles the actual queuing, waiting and dispatching of events.
-// HostEventQueues calls into this. EventQueue tracks the dispatch by way of
-// being a WindowServiceObserver. EventQueue also supports adding a callback
-// that is notified when the queue is empty.
+// EventQueue handles queueing, waiting, and delivering events to event sinks.
+// EventQueue tracks the dispatch by way of being a WindowServiceObserver.
+// EventQueue also supports queueing callbacks run in order with queued events.
class COMPONENT_EXPORT(WINDOW_SERVICE) EventQueue
: public WindowServiceObserver {
public:
explicit EventQueue(WindowService* service);
~EventQueue() override;
- // Creates a new HostEventQueue.
- std::unique_ptr<HostEventQueue> RegisterHostEventDispatcher(
- aura::WindowTreeHost* window_tree_host,
- HostEventDispatcher* dispatcher);
-
- // Convenience to locate the HostEventDispatcher for |window_tree_host|
- // and call DispatchOrQueueEvent() on it with |event|. If |honor_rewriters|
- // is true, the event is passed through EventRewriters first. Events received
- // from the platform go through EventRewriters, so generally
- // |honor_rewriters| should be true, remote injection may need to circumvent
- // that though. If the event was not queued, the return value contains the
- // result of the event processing.
- static base::Optional<ui::EventDispatchDetails> DispatchOrQueueEvent(
- WindowService* service,
- aura::WindowTreeHost* window_tree_host,
- ui::Event* event,
- bool honor_rewriters);
-
- // Returns true if |event| should be queued at this time.
- bool ShouldQueueEvent(HostEventQueue* host, const ui::Event& event);
+ // Queue the event if needed, or deliver it directly to the host's event sink.
+ // Call WindowTreeHost::SendEventToSink instead, if the event should be passed
+ // through the host's EventRewriters; that calls through here after rewriting.
+ base::Optional<ui::EventDispatchDetails> DeliverOrQueueEvent(
+ aura::WindowTreeHost* host,
+ ui::Event* event);
// Notifies |closure| when this EventQueue is ready to dispatch an event,
// which may be immediately.
void NotifyWhenReadyToDispatch(base::OnceClosure closure);
- // Returns the HostEventQueue associated with the specified display.
- HostEventQueue* GetHostEventQueueForDisplay(int64_t display_id);
-
private:
friend class EventQueueTestHelper;
- friend class HostEventQueue;
struct QueuedEvent;
@@ -85,19 +63,16 @@
uint32_t event_id = 0u;
};
+ // Returns true if |event| should be queued at this time for the given |host|.
+ bool ShouldQueueEvent(aura::WindowTreeHost* host, const ui::Event& event);
+
+ // Adds |event| to |queued_events_| for delivery to |host|.
+ void QueueEvent(aura::WindowTreeHost* host, const ui::Event& event);
+
// Called by |ack_timer_| if the client does not respond to the event in a
// timely manner.
void OnClientTookTooLongToAckEvent();
- // Called when a HostEventQueue is created/deleted.
- void OnHostEventQueueCreated(HostEventQueue* host);
- void OnHostEventQueueDestroyed(HostEventQueue* host);
-
- // Adds |event| to |queued_events_|.
- void QueueEvent(HostEventQueue* host,
- const ui::Event& event,
- bool honor_rewriters);
-
// Processes QueuedEvents until |queued_events_| is empty, or there is an
// event sent to a client.
void DispatchNextQueuedEvent();
@@ -117,9 +92,6 @@
// Set when an event has been sent to a client.
base::Optional<InFlightEvent> in_flight_event_;
- // Set of HostEventQueues.
- std::set<HostEventQueue*> host_event_queues_;
-
base::OneShotTimer ack_timer_;
// Because of destruction order HostEventQueues may outlive this.
diff --git a/services/ws/event_queue_unittest.cc b/services/ws/event_queue_unittest.cc
index 64c07f0..6aa22c8 100644
--- a/services/ws/event_queue_unittest.cc
+++ b/services/ws/event_queue_unittest.cc
@@ -64,8 +64,8 @@
EXPECT_EQ(CHANGE_TYPE_INPUT_EVENT, (*setup.changes())[0].type);
setup.changes()->clear();
- // Generator another key event. As still waiting for a response from the
- // client this event should be queued.
+ // Generate another key event. As the client has not yet responded to the
+ // first event, this event should be queued.
event_generator.PressKey(ui::VKEY_B, ui::EF_NONE);
EXPECT_TRUE(event_queue_test_helper.HasInFlightEvent());
EXPECT_TRUE(setup.changes()->empty());
@@ -145,5 +145,44 @@
EXPECT_TRUE(was_dispatch_closure_run);
}
+TEST(EventQueueTest, HostDestroyedWhileEventQueued) {
+ WindowServiceTestSetup setup;
+ setup.set_ack_events_immediately(false);
+
+ // Events are only queued if they target a window with a remote client.
+ aura::Window* top_level =
+ setup.window_tree_test_helper()->NewTopLevelWindow();
+ ASSERT_TRUE(top_level);
+ top_level->Show();
+ top_level->Focus();
+ EXPECT_TRUE(top_level->HasFocus());
+
+ // Generate a single key event.
+ setup.changes()->clear();
+ EventQueueTestHelper event_queue_test_helper(setup.service()->event_queue());
+ ui::test::EventGenerator event_generator(setup.root());
+ event_generator.PressKey(ui::VKEY_A, ui::EF_NONE);
+ EXPECT_TRUE(event_queue_test_helper.HasInFlightEvent());
+ ASSERT_EQ(1u, setup.changes()->size());
+ EXPECT_EQ(CHANGE_TYPE_INPUT_EVENT, (*setup.changes())[0].type);
+ setup.changes()->clear();
+
+ // Generate another key event. As the client has not yet responded to the
+ // first event, this event should be queued.
+ event_generator.PressKey(ui::VKEY_B, ui::EF_NONE);
+ EXPECT_TRUE(event_queue_test_helper.HasInFlightEvent());
+ EXPECT_TRUE(setup.changes()->empty());
+
+ // Destroy the window and its host.
+ setup.window_tree_test_helper()->DeleteWindow(top_level);
+ setup.changes()->clear();
+
+ // Ack the first event, the second event should be safely ignored.
+ event_queue_test_helper.AckInFlightEvent();
+ EXPECT_FALSE(event_queue_test_helper.HasInFlightEvent());
+ auto iter = FirstChangeOfType(*setup.changes(), CHANGE_TYPE_INPUT_EVENT);
+ EXPECT_EQ(iter, setup.changes()->end());
+}
+
} // namespace
} // namespace ws
diff --git a/services/ws/host_event_dispatcher.h b/services/ws/host_event_dispatcher.h
deleted file mode 100644
index f5e9622..0000000
--- a/services/ws/host_event_dispatcher.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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_WS_HOST_EVENT_DISPATCHER_H_
-#define SERVICES_WS_HOST_EVENT_DISPATCHER_H_
-
-#include "base/component_export.h"
-#include "base/macros.h"
-
-namespace ui {
-class Event;
-struct EventDispatchDetails;
-}
-
-namespace ws {
-
-// Used to dispatch events. See HostEventQueue for details.
-class COMPONENT_EXPORT(WINDOW_SERVICE) HostEventDispatcher {
- public:
- // NOTE: as with other event dispatch related functions, the *caller* owns
- // |event|, but HostEventDispatcher may modify |event| as necessary (but not
- // delete it).
- virtual ui::EventDispatchDetails DispatchEventFromQueue(ui::Event* event) = 0;
-
- protected:
- virtual ~HostEventDispatcher() = default;
-};
-
-} // namespace ws
-
-#endif // SERVICES_WS_HOST_EVENT_DISPATCHER_H_
diff --git a/services/ws/host_event_queue.cc b/services/ws/host_event_queue.cc
deleted file mode 100644
index fc7e5afa..0000000
--- a/services/ws/host_event_queue.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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/ws/host_event_queue.h"
-
-#include "services/ws/event_queue.h"
-#include "services/ws/host_event_dispatcher.h"
-#include "ui/aura/window_tree_host.h"
-#include "ui/events/event_sink.h"
-
-namespace ws {
-
-HostEventQueue::HostEventQueue(base::WeakPtr<EventQueue> event_queue,
- aura::WindowTreeHost* window_tree_host,
- HostEventDispatcher* host_event_dispatcher)
- : event_queue_(event_queue),
- window_tree_host_(window_tree_host),
- host_event_dispatcher_(host_event_dispatcher) {
- event_queue_->OnHostEventQueueCreated(this);
-}
-
-HostEventQueue::~HostEventQueue() {
- if (event_queue_)
- event_queue_->OnHostEventQueueDestroyed(this);
-}
-
-base::Optional<ui::EventDispatchDetails> HostEventQueue::DispatchOrQueueEvent(
- ui::Event* event,
- bool honor_rewriters) {
- if (event_queue_ && event_queue_->ShouldQueueEvent(this, *event)) {
- event_queue_->QueueEvent(this, *event, honor_rewriters);
- return base::nullopt;
- }
- return DispatchEventDontQueue(event, honor_rewriters);
-}
-
-ui::EventDispatchDetails HostEventQueue::DispatchEventDontQueue(
- ui::Event* event,
- bool honor_rewriters) {
- if (honor_rewriters)
- return host_event_dispatcher_->DispatchEventFromQueue(event);
- return window_tree_host_->event_sink()->OnEventFromSource(event);
-}
-
-} // namespace ws
diff --git a/services/ws/host_event_queue.h b/services/ws/host_event_queue.h
deleted file mode 100644
index 98d367e..0000000
--- a/services/ws/host_event_queue.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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_WS_HOST_EVENT_QUEUE_H_
-#define SERVICES_WS_HOST_EVENT_QUEUE_H_
-
-#include "base/component_export.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
-
-namespace aura {
-class WindowTreeHost;
-}
-
-namespace ui {
-class Event;
-struct EventDispatchDetails;
-}
-
-namespace ws {
-
-class EventQueue;
-class HostEventDispatcher;
-
-// HostEventQueue is associated with a single WindowTreeHost and used to queue
-// events (if necessary), before the WindowTreeHost does processing.
-// HostEventQueue is created by way of
-// WindowService::RegisterHostEventDispatcher(). The expectation is
-// WindowTreeHost calls to HostEventQueue::DispatchOrQueueEvent() on every
-// event. When necessary, HostEventQueue calls back to HostEventDispatcher to
-// handle the actual dispatch.
-class COMPONENT_EXPORT(WINDOW_SERVICE) HostEventQueue {
- public:
- HostEventQueue(base::WeakPtr<EventQueue> event_queue,
- aura::WindowTreeHost* window_tree_host,
- HostEventDispatcher* host_event_dispatcher);
- ~HostEventQueue();
-
- // If necessary, queues the event. If the event need not be queued,
- // HostEventDispatcher::DispatchEventFromQueue() is called synchronously. If
- // the event was not queued, the return value contains the result of the
- // event processing.
- base::Optional<ui::EventDispatchDetails> DispatchOrQueueEvent(
- ui::Event* event,
- bool honor_rewriters = true);
-
- aura::WindowTreeHost* window_tree_host() { return window_tree_host_; }
-
- HostEventDispatcher* host_event_dispatcher() {
- return host_event_dispatcher_;
- }
-
- private:
- friend class EventQueue;
-
- // Dispatches an event directly, circumventing any queuing. This is private as
- // it's only useful internally.
- ui::EventDispatchDetails DispatchEventDontQueue(ui::Event* event,
- bool honor_rewriters);
-
- // Because of shutdown ordering, HostEventQueue may be deleted *after*
- // EventQueue.
- base::WeakPtr<EventQueue> event_queue_;
- aura::WindowTreeHost* window_tree_host_;
- HostEventDispatcher* host_event_dispatcher_;
-
- DISALLOW_COPY_AND_ASSIGN(HostEventQueue);
-};
-
-} // namespace ws
-
-#endif // SERVICES_WS_HOST_EVENT_QUEUE_H_
diff --git a/services/ws/injected_event_handler.cc b/services/ws/injected_event_handler.cc
index caa047a..7bf38646 100644
--- a/services/ws/injected_event_handler.cc
+++ b/services/ws/injected_event_handler.cc
@@ -5,7 +5,6 @@
#include "services/ws/injected_event_handler.h"
#include "base/memory/ptr_util.h"
-#include "services/ws/event_queue.h"
#include "services/ws/window_service.h"
#include "services/ws/window_service_delegate.h"
#include "ui/aura/env.h"
@@ -57,16 +56,14 @@
auto this_ref = weak_factory_.GetWeakPtr();
pre_target_register_ = std::make_unique<ScopedPreTargetRegister>(
window_service_->delegate()->GetGlobalEventTarget(), this);
- auto result = EventQueue::DispatchOrQueueEvent(window_service_,
- window_tree_host_, event.get(),
- /* honors_rewriters */ true);
+ auto result = window_tree_host_->SendEventToSink(event.get());
if (!this_ref)
return;
// |pre_target_register_| needs to be a member to ensure it's destroyed
// if |this| is destroyed.
pre_target_register_.reset();
- if (result && result->event_discarded) {
+ if (result.event_discarded) {
DCHECK(!event_id_);
NotifyCallback();
}
diff --git a/services/ws/injected_event_handler_unittest.cc b/services/ws/injected_event_handler_unittest.cc
index fd47e41..16d0feb 100644
--- a/services/ws/injected_event_handler_unittest.cc
+++ b/services/ws/injected_event_handler_unittest.cc
@@ -9,11 +9,9 @@
#include "base/bind.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/test/test_connector_factory.h"
-#include "services/ws/host_event_queue.h"
#include "services/ws/public/cpp/host/gpu_interface_provider.h"
#include "services/ws/public/mojom/constants.mojom.h"
#include "services/ws/public/mojom/window_tree.mojom.h"
-#include "services/ws/test_host_event_dispatcher.h"
#include "services/ws/window_service.h"
#include "services/ws/window_service_test_setup.h"
#include "services/ws/window_tree.h"
@@ -83,11 +81,6 @@
aura::WindowTreeHost::Create(
ui::PlatformWindowInitProperties{gfx::Rect(20, 30, 100, 50)});
second_host->InitHost();
- auto host_event_dispatcher =
- std::make_unique<TestHostEventDispatcher>(second_host.get());
- auto host_event_queue = test_setup.service()->RegisterHostEventDispatcher(
- second_host.get(), host_event_dispatcher.get());
-
second_host->window()->Show();
// Create a top-level in |second_host|.
diff --git a/services/ws/test_host_event_dispatcher.cc b/services/ws/test_host_event_dispatcher.cc
deleted file mode 100644
index 828896e..0000000
--- a/services/ws/test_host_event_dispatcher.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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/ws/test_host_event_dispatcher.h"
-
-#include "ui/aura/window_tree_host.h"
-#include "ui/events/event_sink.h"
-#include "ui/events/test/events_test_utils.h"
-
-namespace ws {
-
-TestHostEventDispatcher::TestHostEventDispatcher(
- aura::WindowTreeHost* window_tree_host)
- : window_tree_host_(window_tree_host) {
- DCHECK(window_tree_host_);
-}
-
-TestHostEventDispatcher::~TestHostEventDispatcher() = default;
-
-ui::EventDispatchDetails TestHostEventDispatcher::DispatchEventFromQueue(
- ui::Event* event) {
- return ui::EventSourceTestApi(window_tree_host_).SendEventToSink(event);
-}
-
-} // namespace ws
diff --git a/services/ws/test_host_event_dispatcher.h b/services/ws/test_host_event_dispatcher.h
deleted file mode 100644
index 688defa..0000000
--- a/services/ws/test_host_event_dispatcher.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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_WS_TEST_HOST_EVENT_DISPATCHER_H_
-#define SERVICES_WS_TEST_HOST_EVENT_DISPATCHER_H_
-
-#include "base/component_export.h"
-#include "base/macros.h"
-#include "services/ws/host_event_dispatcher.h"
-
-namespace aura {
-class WindowTreeHost;
-}
-
-namespace ws {
-
-class TestHostEventDispatcher : public HostEventDispatcher {
- public:
- explicit TestHostEventDispatcher(aura::WindowTreeHost* window_tree_host);
- ~TestHostEventDispatcher() override;
-
- // HostEventDispatcher:
- ui::EventDispatchDetails DispatchEventFromQueue(ui::Event* event) override;
-
- private:
- aura::WindowTreeHost* window_tree_host_;
-
- DISALLOW_COPY_AND_ASSIGN(TestHostEventDispatcher);
-};
-
-} // namespace ws
-
-#endif // SERVICES_WS_TEST_HOST_EVENT_DISPATCHER_H_
diff --git a/services/ws/test_window_service_delegate.cc b/services/ws/test_window_service_delegate.cc
index 132c575..2b1e394 100644
--- a/services/ws/test_window_service_delegate.cc
+++ b/services/ws/test_window_service_delegate.cc
@@ -6,6 +6,7 @@
#include "ui/aura/mus/property_converter.h"
#include "ui/aura/window.h"
+#include "ui/display/screen.h"
namespace ws {
@@ -75,6 +76,13 @@
return top_level_parent_->GetRootWindow();
}
+aura::Window* TestWindowServiceDelegate::GetRootWindowForDisplayId(
+ int64_t display_id) {
+ if (display::Screen::GetScreen()->GetAllDisplays().size() > 1)
+ NOTIMPLEMENTED_LOG_ONCE() << "Add test support for multiple displays.";
+ return top_level_parent_->GetRootWindow();
+}
+
aura::Window* TestWindowServiceDelegate::GetTopmostWindowAtPoint(
const gfx::Point& location_in_screen,
const std::set<aura::Window*>& ignore,
diff --git a/services/ws/test_window_service_delegate.h b/services/ws/test_window_service_delegate.h
index 8c7da54..8e1e0bd6 100644
--- a/services/ws/test_window_service_delegate.h
+++ b/services/ws/test_window_service_delegate.h
@@ -68,6 +68,7 @@
DragDropCompletedCallback callback) override;
void CancelDragLoop(aura::Window* window) override;
ui::EventTarget* GetGlobalEventTarget() override;
+ aura::Window* GetRootWindowForDisplayId(int64_t display_id) override;
aura::Window* GetTopmostWindowAtPoint(const gfx::Point& location_in_screen,
const std::set<aura::Window*>& ignore,
aura::Window** real_topmost) override;
diff --git a/services/ws/test_ws/test_window_service.cc b/services/ws/test_ws/test_window_service.cc
index 5fb0551..ffe5a19 100644
--- a/services/ws/test_ws/test_window_service.cc
+++ b/services/ws/test_ws/test_window_service.cc
@@ -10,10 +10,7 @@
#include "base/bind_helpers.h"
#include "mojo/public/cpp/bindings/map.h"
#include "services/service_manager/public/cpp/connector.h"
-#include "services/ws/host_event_dispatcher.h"
-#include "services/ws/host_event_queue.h"
#include "services/ws/public/mojom/constants.mojom.h"
-#include "services/ws/test_host_event_dispatcher.h"
#include "services/ws/test_ws/test_gpu_interface_provider.h"
#include "services/ws/window_service.h"
#include "ui/aura/client/aura_constants.h"
@@ -21,6 +18,7 @@
#include "ui/aura/mus/property_utils.h"
#include "ui/aura/window_tracker.h"
#include "ui/compositor/test/context_factories_for_test.h"
+#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/events/event_sink.h"
#include "ui/gl/test/gl_surface_test_support.h"
@@ -141,6 +139,12 @@
return aura_test_helper_->root_window();
}
+aura::Window* TestWindowService::GetRootWindowForDisplayId(int64_t display_id) {
+ if (display::Screen::GetScreen()->GetAllDisplays().size() > 1)
+ NOTIMPLEMENTED_LOG_ONCE() << "Add test support for multiple displays.";
+ return aura_test_helper_->root_window();
+}
+
void TestWindowService::OnStart() {
CHECK(!started_);
started_ = true;
@@ -186,10 +190,6 @@
this, std::move(gpu_interface_provider_),
aura_test_helper_->focus_client(), /*decrement_client_ids=*/false,
aura_test_helper_->GetEnv());
- test_host_event_dispatcher_ =
- std::make_unique<TestHostEventDispatcher>(aura_test_helper_->host());
- host_event_queue_ = window_service_->RegisterHostEventDispatcher(
- aura_test_helper_->host(), test_host_event_dispatcher_.get());
window_service_->BindServiceRequest(std::move(request));
pid_receiver->SetPID(base::GetCurrentProcId());
}
diff --git a/services/ws/test_ws/test_window_service.h b/services/ws/test_ws/test_window_service.h
index 7279ee4..e500031 100644
--- a/services/ws/test_ws/test_window_service.h
+++ b/services/ws/test_ws/test_window_service.h
@@ -34,8 +34,6 @@
namespace ws {
-class HostEventQueue;
-class TestHostEventDispatcher;
class WindowService;
namespace test {
@@ -79,6 +77,7 @@
DragDropCompletedCallback callback) override;
void CancelDragLoop(aura::Window* window) override;
ui::EventTarget* GetGlobalEventTarget() override;
+ aura::Window* GetRootWindowForDisplayId(int64_t display_id) override;
// service_manager::Service:
void OnStart() override;
@@ -144,10 +143,6 @@
// is used in service_unittests where ui features is not used there.
bool is_in_process_ = false;
- std::unique_ptr<TestHostEventDispatcher> test_host_event_dispatcher_;
-
- std::unique_ptr<HostEventQueue> host_event_queue_;
-
std::unique_ptr<VisibilitySynchronizer> visibility_synchronizer_;
DISALLOW_COPY_AND_ASSIGN(TestWindowService);
diff --git a/services/ws/window_service.cc b/services/ws/window_service.cc
index b667a8a47..33f4cef 100644
--- a/services/ws/window_service.cc
+++ b/services/ws/window_service.cc
@@ -14,7 +14,6 @@
#include "services/ws/embedding.h"
#include "services/ws/event_injector.h"
#include "services/ws/event_queue.h"
-#include "services/ws/host_event_queue.h"
#include "services/ws/proxy_window.h"
#include "services/ws/public/cpp/host/gpu_interface_provider.h"
#include "services/ws/public/mojom/window_manager.mojom.h"
@@ -250,13 +249,6 @@
return proxy_window->GetIdForDebugging();
}
-std::unique_ptr<HostEventQueue> WindowService::RegisterHostEventDispatcher(
- aura::WindowTreeHost* window_tree_host,
- HostEventDispatcher* dispatcher) {
- return event_queue_->RegisterHostEventDispatcher(window_tree_host,
- dispatcher);
-}
-
void WindowService::OnStart() {
test_config_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseTestConfig);
diff --git a/services/ws/window_service.h b/services/ws/window_service.h
index 212f4bc..e51e55a 100644
--- a/services/ws/window_service.h
+++ b/services/ws/window_service.h
@@ -34,7 +34,6 @@
namespace aura {
class Env;
class Window;
-class WindowTreeHost;
namespace client {
class FocusClient;
}
@@ -61,8 +60,6 @@
class EventInjector;
class EventQueue;
class GpuInterfaceProvider;
-class HostEventDispatcher;
-class HostEventQueue;
class RemotingEventInjector;
class ScreenProvider;
class ProxyWindow;
@@ -173,12 +170,6 @@
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics);
- // Registers the HostEventDispatcher for a WindowTreeHost and returns the
- // HostEventQueue that |window_tree_host| should use to dispatch events.
- std::unique_ptr<HostEventQueue> RegisterHostEventDispatcher(
- aura::WindowTreeHost* window_tree_host,
- HostEventDispatcher* dispatcher);
-
// Returns an id useful for debugging. See ProxyWindow::GetIdForDebugging()
// for details.
std::string GetIdForDebugging(aura::Window* window);
diff --git a/services/ws/window_service_delegate.h b/services/ws/window_service_delegate.h
index 6938de8..5d59e8c 100644
--- a/services/ws/window_service_delegate.h
+++ b/services/ws/window_service_delegate.h
@@ -121,6 +121,8 @@
// Returns the EventTarget which can process all of the events on the system.
virtual ui::EventTarget* GetGlobalEventTarget() = 0;
+ virtual aura::Window* GetRootWindowForDisplayId(int64_t display_id) = 0;
+
// Returns the topmost visible window at the location in screen coordinate,
// excluding |ignore|. |real_topmost| is updated to the topmost visible window
// at the location without excluding |ignore|.
diff --git a/services/ws/window_service_test_setup.cc b/services/ws/window_service_test_setup.cc
index da5bdc6c..9f8cb7c 100644
--- a/services/ws/window_service_test_setup.cc
+++ b/services/ws/window_service_test_setup.cc
@@ -7,9 +7,7 @@
#include "services/ws/embedding.h"
#include "services/ws/event_queue.h"
#include "services/ws/event_queue_test_helper.h"
-#include "services/ws/host_event_queue.h"
#include "services/ws/public/cpp/host/gpu_interface_provider.h"
-#include "services/ws/test_host_event_dispatcher.h"
#include "services/ws/window_service.h"
#include "services/ws/window_tree.h"
#include "services/ws/window_tree_binding.h"
@@ -39,80 +37,55 @@
DISALLOW_COPY_AND_ASSIGN(TestFocusRules);
};
-// EventTargeterWs sole purpose is to make OnEventFromSource() forward events
-// to the appropriate HostEventQueue. This is normally done by a WindowTreeHost
-// subclass, but because tests create a platform specific WindowTreeHost
-// implementation, that isn't possible.
-class EventTargeterWs : public ui::EventTarget,
- public ui::EventTargeter,
- public ui::EventSource,
- public ui::EventSink {
+// An EventSource that mimics AshWindowTreeHostPlatform's EventQueue usage.
+class EventSourceWithQueue : public ui::EventSource {
public:
- EventTargeterWs(WindowServiceTestSetup* test_setup,
- HostEventQueue* host_event_queue)
- : test_setup_(test_setup), host_event_queue_(host_event_queue) {}
-
- ~EventTargeterWs() override = default;
-
- // ui::EventTargeter:
- ui::EventTarget* FindTargetForEvent(ui::EventTarget* root,
- ui::Event* event) override {
- return this;
- }
- ui::EventTarget* FindNextBestTarget(ui::EventTarget* previous_target,
- ui::Event* event) override {
- return this;
- }
-
- // ui::EventTarget:
- bool CanAcceptEvent(const ui::Event& event) override { return true; }
- ui::EventTarget* GetParentTarget() override { return nullptr; }
- std::unique_ptr<ui::EventTargetIterator> GetChildIterator() const override {
- return nullptr;
- }
- ui::EventTargeter* GetEventTargeter() override { return this; }
+ explicit EventSourceWithQueue(WindowServiceTestSetup* test_setup,
+ aura::Window* root)
+ : test_setup_(test_setup), root_(root) {}
+ ~EventSourceWithQueue() override = default;
// ui::EventSource:
- ui::EventSink* GetEventSink() override { return this; }
-
- // ui::EventSink:
- ui::EventDispatchDetails OnEventFromSource(ui::Event* event) override {
- host_event_queue_->DispatchOrQueueEvent(event);
- WindowService* window_service = test_setup_->service();
+ ui::EventSink* GetEventSink() override {
+ return root_->GetHost()->GetEventSink();
+ }
+ ui::EventDispatchDetails DeliverEventToSink(ui::Event* event) override {
+ auto* queue = test_setup_->service()->event_queue();
+ // Queue the event if needed, or deliver it directly to the sink.
+ auto result = queue->DeliverOrQueueEvent(root_->GetHost(), event);
if (test_setup_->ack_events_immediately() &&
- EventQueueTestHelper(window_service->event_queue())
- .HasInFlightEvent()) {
- EventQueueTestHelper(window_service->event_queue()).AckInFlightEvent();
+ EventQueueTestHelper(queue).HasInFlightEvent()) {
+ EventQueueTestHelper(queue).AckInFlightEvent();
}
- return ui::EventDispatchDetails();
+
+ return result.value_or(ui::EventDispatchDetails());
}
private:
WindowServiceTestSetup* test_setup_;
- HostEventQueue* host_event_queue_;
+ aura::Window* root_;
- DISALLOW_COPY_AND_ASSIGN(EventTargeterWs);
+ DISALLOW_COPY_AND_ASSIGN(EventSourceWithQueue);
};
// EventGeneratorDelegate implementation for mus.
class EventGeneratorDelegateWs : public aura::test::EventGeneratorDelegateAura {
public:
- EventGeneratorDelegateWs(WindowServiceTestSetup* test_setup,
- HostEventQueue* host_event_queue)
- : event_targeter_(test_setup, host_event_queue) {}
+ explicit EventGeneratorDelegateWs(WindowServiceTestSetup* test_setup,
+ aura::Window* root)
+ : root_(root), event_source_(test_setup, root) {}
~EventGeneratorDelegateWs() override = default;
// EventGeneratorDelegateAura:
ui::EventTarget* GetTargetAt(const gfx::Point& location) override {
- return &event_targeter_;
+ return root_;
}
ui::EventSource* GetEventSource(ui::EventTarget* target) override {
- return target == &event_targeter_
- ? &event_targeter_
- : EventGeneratorDelegateAura::GetEventSource(target);
+ return target == root_ ? &event_source_
+ : EventGeneratorDelegateAura::GetEventSource(target);
}
gfx::Point CenterOfTarget(const ui::EventTarget* target) const override {
- if (target != &event_targeter_)
+ if (target != root_)
return EventGeneratorDelegateAura::CenterOfTarget(target);
return display::Screen::GetScreen()
->GetPrimaryDisplay()
@@ -121,22 +94,23 @@
}
void ConvertPointFromTarget(const ui::EventTarget* target,
gfx::Point* point) const override {
- if (target != &event_targeter_)
+ if (target != root_)
EventGeneratorDelegateAura::ConvertPointFromTarget(target, point);
}
void ConvertPointToTarget(const ui::EventTarget* target,
gfx::Point* point) const override {
- if (target != &event_targeter_)
+ if (target != root_)
EventGeneratorDelegateAura::ConvertPointToTarget(target, point);
}
void ConvertPointFromHost(const ui::EventTarget* hosted_target,
gfx::Point* point) const override {
- if (hosted_target != &event_targeter_)
+ if (hosted_target != root_)
EventGeneratorDelegateAura::ConvertPointFromHost(hosted_target, point);
}
private:
- EventTargeterWs event_targeter_;
+ aura::Window* root_;
+ EventSourceWithQueue event_source_;
DISALLOW_COPY_AND_ASSIGN(EventGeneratorDelegateWs);
};
@@ -148,10 +122,7 @@
aura::Window* window) {
DCHECK(root_window);
DCHECK(root_window->GetHost());
- return std::make_unique<EventGeneratorDelegateWs>(
- test_setup,
- test_setup->service()->event_queue()->GetHostEventQueueForDisplay(
- root_window->GetHost()->GetDisplayId()));
+ return std::make_unique<EventGeneratorDelegateWs>(test_setup, root_window);
}
} // namespace
@@ -175,10 +146,6 @@
aura::client::SetFocusClient(root(), focus_controller());
wm::SetActivationClient(root(), focus_controller());
delegate_.set_top_level_parent(aura_test_helper_.root_window());
- host_event_dispatcher_ =
- std::make_unique<TestHostEventDispatcher>(aura_test_helper_.host());
- host_event_queue_ = service_->RegisterHostEventDispatcher(
- aura_test_helper_.host(), host_event_dispatcher_.get());
window_tree_ = service_->CreateWindowTree(&window_tree_client_);
window_tree_->InitFromFactory();
diff --git a/services/ws/window_service_test_setup.h b/services/ws/window_service_test_setup.h
index d2ba022..a20fbe3 100644
--- a/services/ws/window_service_test_setup.h
+++ b/services/ws/window_service_test_setup.h
@@ -22,8 +22,6 @@
namespace ws {
-class HostEventQueue;
-class TestHostEventDispatcher;
class WindowService;
class WindowTree;
class WindowTreeTestHelper;
@@ -64,8 +62,6 @@
aura::test::AuraTestHelper* aura_test_helper() { return &aura_test_helper_; }
- HostEventQueue* host_event_queue() { return host_event_queue_.get(); }
-
private:
base::test::ScopedTaskEnvironment task_environment_{
base::test::ScopedTaskEnvironment::MainThreadType::UI};
@@ -74,8 +70,6 @@
std::unique_ptr<wm::ScopedCaptureClient> scoped_capture_client_;
TestWindowServiceDelegate delegate_;
std::unique_ptr<WindowService> service_;
- std::unique_ptr<TestHostEventDispatcher> host_event_dispatcher_;
- std::unique_ptr<HostEventQueue> host_event_queue_;
TestWindowTreeClient window_tree_client_;
std::unique_ptr<WindowTree> window_tree_;
std::unique_ptr<WindowTreeTestHelper> window_tree_test_helper_;
diff --git a/testing/buildbot/filters/chromeos.single_process_mash.interactive_ui_tests.filter b/testing/buildbot/filters/chromeos.single_process_mash.interactive_ui_tests.filter
index 79f23c6c..197df33 100644
--- a/testing/buildbot/filters/chromeos.single_process_mash.interactive_ui_tests.filter
+++ b/testing/buildbot/filters/chromeos.single_process_mash.interactive_ui_tests.filter
@@ -8,9 +8,5 @@
# ChromeOS.
-BrowserKeyEventsTest.AccessKeys
-# crbug.com/913549
--StickyKeysBrowserTest.OpenTrayMenu
--StickyKeysBrowserTest.SearchLeftOmnibox
-
# This test is flaky. https://crbug.com/897879
-ExtensionApiTest.DisplayModeWindowIsInFullscreen
diff --git a/ui/aura/window_tree_host.cc b/ui/aura/window_tree_host.cc
index 89ed4c6..8a18313 100644
--- a/ui/aura/window_tree_host.cc
+++ b/ui/aura/window_tree_host.cc
@@ -139,6 +139,10 @@
return dispatcher_.get();
}
+base::WeakPtr<WindowTreeHost> WindowTreeHost::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
gfx::Transform WindowTreeHost::GetRootTransform() const {
gfx::Transform transform;
transform.Scale(device_scale_factor_, device_scale_factor_);
@@ -274,6 +278,10 @@
return dispatch_details;
}
+ui::EventSink* WindowTreeHost::GetEventSink() {
+ return dispatcher_.get();
+}
+
int64_t WindowTreeHost::GetDisplayId() {
return display::Screen::GetScreen()->GetDisplayNearestWindow(window()).id();
}
@@ -495,10 +503,6 @@
capture_window->ReleaseCapture();
}
-ui::EventSink* WindowTreeHost::GetEventSink() {
- return dispatcher_.get();
-}
-
void WindowTreeHost::OnDisplayMetricsChanged(const display::Display& display,
uint32_t metrics) {
if (metrics & DisplayObserver::DISPLAY_METRIC_COLOR_SPACE) {
diff --git a/ui/aura/window_tree_host.h b/ui/aura/window_tree_host.h
index e89644f9..6db3f3b13 100644
--- a/ui/aura/window_tree_host.h
+++ b/ui/aura/window_tree_host.h
@@ -85,6 +85,7 @@
Window* window() { return window_; }
const Window* window() const { return window_; }
+ // TODO(msw): Remove this, callers should use GetEventSink().
ui::EventSink* event_sink();
WindowEventDispatcher* dispatcher() {
@@ -95,6 +96,8 @@
ui::Compositor* compositor() { return compositor_.get(); }
+ base::WeakPtr<WindowTreeHost> GetWeakPtr();
+
// Gets/Sets the root window's transform.
virtual gfx::Transform GetRootTransform() const;
virtual void SetRootTransform(const gfx::Transform& transform);
@@ -177,6 +180,9 @@
ui::KeyEvent* event,
base::OnceCallback<void(bool)> ack_callback) final;
+ // Overridden from ui::EventSource:
+ ui::EventSink* GetEventSink() override;
+
// Returns the id of the display. Default implementation queries Screen.
virtual int64_t GetDisplayId();
@@ -298,9 +304,6 @@
// Hides the WindowTreeHost.
virtual void HideImpl() = 0;
- // Overridden from ui::EventSource:
- ui::EventSink* GetEventSink() override;
-
// display::DisplayObserver implementation.
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t metrics) override;
diff --git a/ui/events/event_source.cc b/ui/events/event_source.cc
index 323e8b4..85a6f40 100644
--- a/ui/events/event_source.cc
+++ b/ui/events/event_source.cc
@@ -43,6 +43,12 @@
return SendEventToSinkFromRewriter(event, nullptr);
}
+EventDispatchDetails EventSource::DeliverEventToSink(Event* event) {
+ EventSink* sink = GetEventSink();
+ CHECK(sink);
+ return sink->OnEventFromSource(event);
+}
+
EventDispatchDetails EventSource::SendEventToSinkFromRewriter(
Event* event,
const EventRewriter* rewriter) {
@@ -102,10 +108,4 @@
return EventDispatchDetails();
}
-EventDispatchDetails EventSource::DeliverEventToSink(Event* event) {
- EventSink* sink = GetEventSink();
- CHECK(sink);
- return sink->OnEventFromSource(event);
-}
-
} // namespace ui
diff --git a/ui/events/event_source.h b/ui/events/event_source.h
index d5b9b1c..ad84e60 100644
--- a/ui/events/event_source.h
+++ b/ui/events/event_source.h
@@ -33,10 +33,14 @@
void AddEventRewriter(EventRewriter* rewriter);
void RemoveEventRewriter(EventRewriter* rewriter);
- protected:
// Sends the event through all rewriters and onto the source's EventSink.
EventDispatchDetails SendEventToSink(Event* event);
+ // Send the event to the sink after rewriting; subclass overrides may queue
+ // events before delivery, i.e. for the WindowService.
+ virtual EventDispatchDetails DeliverEventToSink(Event* event);
+
+ protected:
// Sends the event through the rewriters and onto the source's EventSink.
// If |rewriter| is valid, |event| is only sent to the subsequent rewriters.
// This is used for asynchronous reposting of events processed by |rewriter|.
@@ -48,8 +52,6 @@
friend class EventRewriter;
friend class EventSourceTestApi;
- EventDispatchDetails DeliverEventToSink(Event* event);
-
typedef std::vector<EventRewriter*> EventRewriterList;
EventRewriterList rewriter_list_;
diff --git a/ui/wm/test/wm_test_helper.cc b/ui/wm/test/wm_test_helper.cc
index 24996bd..b62bdb6 100644
--- a/ui/wm/test/wm_test_helper.cc
+++ b/ui/wm/test/wm_test_helper.cc
@@ -22,6 +22,7 @@
#include "ui/aura/mus/window_tree_host_mus_init_params.h"
#include "ui/aura/test/mus/window_tree_client_test_api.h"
#include "ui/aura/test/test_focus_client.h"
+#include "ui/aura/test/test_screen.h"
#include "ui/aura/window.h"
#include "ui/base/ui_base_features.h"
#include "ui/platform_window/platform_window_init_properties.h"
@@ -63,6 +64,9 @@
run_loop.Run();
}
host_->window()->RemovePreTargetHandler(root_window_event_filter_.get());
+
+ if (display::Screen::GetScreen() == test_screen_.get())
+ display::Screen::SetScreenInstance(nullptr);
}
aura::Window* WMTestHelper::GetDefaultParent(aura::Window* window,
@@ -72,6 +76,11 @@
void WMTestHelper::InitLocalHost(const gfx::Size& default_window_size) {
wm_state_ = std::make_unique<WMState>();
+
+ // Install a screen, like TestWindowService's AuraTestHelper for InitMusHost.
+ test_screen_ = base::WrapUnique(aura::TestScreen::Create(gfx::Size()));
+ display::Screen::SetScreenInstance(test_screen_.get());
+
host_ = aura::WindowTreeHost::Create(
ui::PlatformWindowInitProperties{gfx::Rect(default_window_size)});
host_->InitHost();
diff --git a/ui/wm/test/wm_test_helper.h b/ui/wm/test/wm_test_helper.h
index 390953d..3ce5ac0 100644
--- a/ui/wm/test/wm_test_helper.h
+++ b/ui/wm/test/wm_test_helper.h
@@ -17,6 +17,7 @@
namespace aura {
class PropertyConverter;
+class TestScreen;
class Window;
class WindowTreeClient;
class WindowTreeHost;
@@ -86,6 +87,7 @@
int64_t display_id_for_new_windows) override;
std::unique_ptr<WMState> wm_state_;
+ std::unique_ptr<aura::TestScreen> test_screen_;
std::unique_ptr<ws::InputDeviceClient> input_device_client_;
std::unique_ptr<aura::PropertyConverter> property_converter_;
std::unique_ptr<aura::WindowTreeClient> window_tree_client_;