summaryrefslogtreecommitdiff
path: root/chromium/ui/aura
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-12-10 16:19:40 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-12-10 16:01:50 +0000
commit51f6c2793adab2d864b3d2b360000ef8db1d3e92 (patch)
tree835b3b4446b012c75e80177cef9fbe6972cc7dbe /chromium/ui/aura
parent6036726eb981b6c4b42047513b9d3f4ac865daac (diff)
downloadqtwebengine-chromium-51f6c2793adab2d864b3d2b360000ef8db1d3e92.tar.gz
BASELINE: Update Chromium to 71.0.3578.93
Change-Id: I6a32086c33670e1b033f8b10e6bf1fd4da1d105d Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/ui/aura')
-rw-r--r--chromium/ui/aura/BUILD.gn5
-rw-r--r--chromium/ui/aura/client/aura_constants.cc6
-rw-r--r--chromium/ui/aura/client/aura_constants.h14
-rw-r--r--chromium/ui/aura/env.cc28
-rw-r--r--chromium/ui/aura/env.h7
-rw-r--r--chromium/ui/aura/event_injector.cc21
-rw-r--r--chromium/ui/aura/gestures/gesture_recognizer_unittest.cc3
-rw-r--r--chromium/ui/aura/hit_test_data_provider_aura_unittest.cc23
-rw-r--r--chromium/ui/aura/local/window_port_local.cc15
-rw-r--r--chromium/ui/aura/mus/client_surface_embedder.cc14
-rw-r--r--chromium/ui/aura/mus/client_surface_embedder.h5
-rw-r--r--chromium/ui/aura/mus/embed_root.cc1
-rw-r--r--chromium/ui/aura/mus/gesture_synchronizer.cc55
-rw-r--r--chromium/ui/aura/mus/gesture_synchronizer.h45
-rw-r--r--chromium/ui/aura/mus/gesture_synchronizer_unittest.cc90
-rw-r--r--chromium/ui/aura/mus/input_method_mus.cc45
-rw-r--r--chromium/ui/aura/mus/input_method_mus.h9
-rw-r--r--chromium/ui/aura/mus/input_method_mus_unittest.cc94
-rw-r--r--chromium/ui/aura/mus/mus_mouse_location_updater.cc24
-rw-r--r--chromium/ui/aura/mus/mus_types.h10
-rw-r--r--chromium/ui/aura/mus/os_exchange_data_provider_mus.cc3
-rw-r--r--chromium/ui/aura/mus/property_converter.cc109
-rw-r--r--chromium/ui/aura/mus/property_converter.h20
-rw-r--r--chromium/ui/aura/mus/property_converter_unittest.cc91
-rw-r--r--chromium/ui/aura/mus/text_input_client_impl.cc5
-rw-r--r--chromium/ui/aura/mus/window_mus.h2
-rw-r--r--chromium/ui/aura/mus/window_port_mus.cc163
-rw-r--r--chromium/ui/aura/mus/window_port_mus.h28
-rw-r--r--chromium/ui/aura/mus/window_port_mus_unittest.cc62
-rw-r--r--chromium/ui/aura/mus/window_tree_client.cc192
-rw-r--r--chromium/ui/aura/mus/window_tree_client.h41
-rw-r--r--chromium/ui/aura/mus/window_tree_client_unittest.cc213
-rw-r--r--chromium/ui/aura/mus/window_tree_host_mus.cc4
-rw-r--r--chromium/ui/aura/mus/window_tree_host_mus.h3
-rw-r--r--chromium/ui/aura/mus/window_tree_host_mus_delegate.h5
-rw-r--r--chromium/ui/aura/mus/window_tree_host_mus_unittest.cc26
-rw-r--r--chromium/ui/aura/screen_ozone.h2
-rw-r--r--chromium/ui/aura/test/ui_controls_factory_ozone.cc64
-rw-r--r--chromium/ui/aura/window.cc67
-rw-r--r--chromium/ui/aura/window.h15
-rw-r--r--chromium/ui/aura/window_delegate.h8
-rw-r--r--chromium/ui/aura/window_event_dispatcher.cc16
-rw-r--r--chromium/ui/aura/window_event_dispatcher.h2
-rw-r--r--chromium/ui/aura/window_event_dispatcher_unittest.cc93
-rw-r--r--chromium/ui/aura/window_occlusion_tracker.cc59
-rw-r--r--chromium/ui/aura/window_occlusion_tracker.h35
-rw-r--r--chromium/ui/aura/window_occlusion_tracker_unittest.cc35
-rw-r--r--chromium/ui/aura/window_port.cc2
-rw-r--r--chromium/ui/aura/window_port.h24
-rw-r--r--chromium/ui/aura/window_port_for_shutdown.cc3
-rw-r--r--chromium/ui/aura/window_targeter.cc57
-rw-r--r--chromium/ui/aura/window_targeter.h22
-rw-r--r--chromium/ui/aura/window_targeter_unittest.cc31
-rw-r--r--chromium/ui/aura/window_tree_host.cc13
-rw-r--r--chromium/ui/aura/window_tree_host.h19
-rw-r--r--chromium/ui/aura/window_tree_host_platform.cc23
-rw-r--r--chromium/ui/aura/window_tree_host_platform.h3
-rw-r--r--chromium/ui/aura/window_tree_host_unittest.cc41
-rw-r--r--chromium/ui/aura/window_unittest.cc6
59 files changed, 1433 insertions, 688 deletions
diff --git a/chromium/ui/aura/BUILD.gn b/chromium/ui/aura/BUILD.gn
index c97d5dda9cf..cba785ad544 100644
--- a/chromium/ui/aura/BUILD.gn
+++ b/chromium/ui/aura/BUILD.gn
@@ -47,6 +47,7 @@ jumbo_component("aura") {
"mus/focus_synchronizer.h",
"mus/focus_synchronizer_delegate.h",
"mus/focus_synchronizer_observer.h",
+ "mus/gesture_synchronizer.h",
"mus/in_flight_change.h",
"mus/input_method_mus.h",
"mus/input_method_mus_delegate.h",
@@ -118,6 +119,7 @@ jumbo_component("aura") {
"mus/drag_drop_controller_mus.cc",
"mus/embed_root.cc",
"mus/focus_synchronizer.cc",
+ "mus/gesture_synchronizer.cc",
"mus/in_flight_change.cc",
"mus/input_method_mus.cc",
"mus/mus_context_factory.cc",
@@ -250,6 +252,8 @@ jumbo_static_library("test_support") {
"test/mus/test_window_tree_client_delegate.h",
"test/mus/test_window_tree_client_setup.cc",
"test/mus/test_window_tree_client_setup.h",
+ "test/mus/window_port_mus_test_helper.cc",
+ "test/mus/window_port_mus_test_helper.h",
"test/mus/window_tree_client_private.cc",
"test/mus/window_tree_client_private.h",
"test/test_cursor_client.cc",
@@ -370,6 +374,7 @@ test("aura_unittests") {
"mouse_location_manager_unittest.cc",
"mus/drag_drop_controller_mus_unittest.cc",
"mus/focus_synchronizer_unittest.cc",
+ "mus/gesture_synchronizer_unittest.cc",
"mus/input_method_mus_unittest.cc",
"mus/os_exchange_data_provider_mus_unittest.cc",
"mus/property_converter_unittest.cc",
diff --git a/chromium/ui/aura/client/aura_constants.cc b/chromium/ui/aura/client/aura_constants.cc
index c0b3bf9c200..1ed7c6e50d9 100644
--- a/chromium/ui/aura/client/aura_constants.cc
+++ b/chromium/ui/aura/client/aura_constants.cc
@@ -24,8 +24,6 @@ DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AURA_EXPORT, void*)
DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AURA_EXPORT, SkColor)
DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AURA_EXPORT, int32_t)
DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AURA_EXPORT, int64_t)
-DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AURA_EXPORT,
- aura::client::WindowEmbedType)
DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AURA_EXPORT, aura::client::FocusClient*)
DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AURA_EXPORT, aura::Window*)
@@ -54,9 +52,6 @@ DEFINE_UI_CLASS_PROPERTY_KEY(Window*, kHostWindowKey, nullptr);
DEFINE_UI_CLASS_PROPERTY_KEY(bool, kImmersiveFullscreenKey, false);
DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::Size, kMinimumSize, nullptr);
DEFINE_UI_CLASS_PROPERTY_KEY(bool, kMirroringEnabledKey, false);
-DEFINE_UI_CLASS_PROPERTY_KEY(WindowEmbedType,
- kEmbedType,
- WindowEmbedType::NONE);
DEFINE_UI_CLASS_PROPERTY_KEY(Window*, kChildModalParentKey, nullptr);
DEFINE_UI_CLASS_PROPERTY_KEY(ui::ModalType, kModalKey, ui::MODAL_TYPE_NONE);
DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(std::string, kNameKey, nullptr);
@@ -68,6 +63,7 @@ DEFINE_UI_CLASS_PROPERTY_KEY(
DEFINE_UI_CLASS_PROPERTY_KEY(int32_t,
kResizeBehaviorKey,
ws::mojom::kResizeBehaviorCanResize);
+DEFINE_UI_CLASS_PROPERTY_KEY(int, kResizeHandleInset, 0);
DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::Rect, kRestoreBoundsKey, nullptr);
DEFINE_UI_CLASS_PROPERTY_KEY(
ui::WindowShowState, kShowStateKey, ui::SHOW_STATE_DEFAULT);
diff --git a/chromium/ui/aura/client/aura_constants.h b/chromium/ui/aura/client/aura_constants.h
index a184412827a..65dc33a5477 100644
--- a/chromium/ui/aura/client/aura_constants.h
+++ b/chromium/ui/aura/client/aura_constants.h
@@ -23,11 +23,6 @@ namespace aura {
namespace client {
class FocusClient;
-enum class WindowEmbedType {
- NONE,
- EMBED_IN_OWNER,
-};
-
// Alphabetical sort.
// A property key to store whether accessibility focus falls back to widget or
@@ -124,6 +119,12 @@ AURA_EXPORT extern const WindowProperty<ui::WindowShowState>* const
// ws::mojom::kResizeBehavior values.
AURA_EXPORT extern const WindowProperty<int32_t>* const kResizeBehaviorKey;
+// Reserves a number of dip around the window (i.e. inset from its exterior
+// border) for event routing back to the top level window. This is used for
+// routing events to toplevel window resize handles. It should only be respected
+// for restored windows (maximized and fullscreen can't be drag-resized).
+AURA_EXPORT extern const WindowProperty<int>* const kResizeHandleInset;
+
// A property key to store the restore bounds in screen coordinates for a
// window.
AURA_EXPORT extern const WindowProperty<gfx::Rect*>* const kRestoreBoundsKey;
@@ -149,9 +150,6 @@ AURA_EXPORT extern const WindowProperty<int>* const kTopViewInset;
// A property key to store the window icon, typically 16x16 for title bars.
AURA_EXPORT extern const WindowProperty<gfx::ImageSkia*>* const kWindowIconKey;
-// Indicates the type of embedding within the given window.
-AURA_EXPORT extern const WindowProperty<WindowEmbedType>* const kEmbedType;
-
// The corner radius of a window in DIPs. Currently only used for shadows.
// Default is -1, meaning "unspecified". 0 Ensures corners are square.
AURA_EXPORT extern const WindowProperty<int>* const kWindowCornerRadiusKey;
diff --git a/chromium/ui/aura/env.cc b/chromium/ui/aura/env.cc
index 07ff6f5bf18..bbd91404c0f 100644
--- a/chromium/ui/aura/env.cc
+++ b/chromium/ui/aura/env.cc
@@ -6,6 +6,7 @@
#include "base/command_line.h"
#include "base/lazy_instance.h"
+#include "base/memory/ptr_util.h"
#include "services/ws/public/mojom/window_tree.mojom.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/env_input_state_controller.h"
@@ -20,6 +21,7 @@
#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_occlusion_tracker.h"
#include "ui/aura/window_port_for_shutdown.h"
#include "ui/base/ui_base_features.h"
#include "ui/events/event_target_iterator.h"
@@ -113,19 +115,8 @@ std::unique_ptr<WindowPort> Env::CreateWindowPort(Window* window) {
return std::make_unique<WindowPortForShutdown>();
DCHECK(window_tree_client_);
- WindowMusType window_mus_type;
- switch (window->GetProperty(aura::client::kEmbedType)) {
- case aura::client::WindowEmbedType::NONE:
- window_mus_type = WindowMusType::LOCAL;
- break;
- case aura::client::WindowEmbedType::EMBED_IN_OWNER:
- window_mus_type = WindowMusType::EMBED_IN_OWNER;
- break;
- default:
- NOTREACHED();
- }
- // Use LOCAL as all other cases are created by WindowTreeClient explicitly.
- return std::make_unique<WindowPortMus>(window_tree_client_, window_mus_type);
+ return std::make_unique<WindowPortMus>(window_tree_client_,
+ WindowMusType::LOCAL);
}
void Env::AddObserver(EnvObserver* observer) {
@@ -196,6 +187,17 @@ void Env::ScheduleEmbed(
window_tree_client_->ScheduleEmbed(std::move(client), std::move(callback));
}
+WindowOcclusionTracker* Env::GetWindowOcclusionTracker() {
+ // TODO(https://crbug.com/867150): DCHECK to ensure LOCAL aura after mus
+ // code path is wired up.
+ if (!window_occlusion_tracker_) {
+ // Use base::WrapUnique + new because of the constructor is private.
+ window_occlusion_tracker_ = base::WrapUnique(new WindowOcclusionTracker());
+ }
+
+ return window_occlusion_tracker_.get();
+}
+
////////////////////////////////////////////////////////////////////////////////
// Env, private:
diff --git a/chromium/ui/aura/env.h b/chromium/ui/aura/env.h
index f8fb629389f..3738281bedd 100644
--- a/chromium/ui/aura/env.h
+++ b/chromium/ui/aura/env.h
@@ -59,6 +59,7 @@ class MouseLocationManager;
class MusMouseLocationUpdater;
class Window;
class WindowEventDispatcherObserver;
+class WindowOcclusionTracker;
class WindowPort;
class WindowTreeClient;
class WindowTreeHost;
@@ -191,6 +192,9 @@ class AURA_EXPORT Env : public ui::EventTarget,
mojo::InterfacePtr<ws::mojom::WindowTreeClient> client,
base::OnceCallback<void(const base::UnguessableToken&)> callback);
+ // Get WindowOcclusionTracker instance. Create it if it is not yet created.
+ WindowOcclusionTracker* GetWindowOcclusionTracker();
+
private:
friend class test::EnvTestHelper;
friend class test::EnvWindowTreeClientSetter;
@@ -285,6 +289,9 @@ class AURA_EXPORT Env : public ui::EventTarget,
// Only created if CreateMouseLocationManager() was called.
std::unique_ptr<MouseLocationManager> mouse_location_manager_;
+ // Lazily created for LOCAL aura.
+ std::unique_ptr<WindowOcclusionTracker> window_occlusion_tracker_;
+
DISALLOW_COPY_AND_ASSIGN(Env);
};
diff --git a/chromium/ui/aura/event_injector.cc b/chromium/ui/aura/event_injector.cc
index fd2a7423c05..f67d1fe5721 100644
--- a/chromium/ui/aura/event_injector.cc
+++ b/chromium/ui/aura/event_injector.cc
@@ -13,24 +13,6 @@
#include "ui/events/event.h"
#include "ui/events/event_sink.h"
-namespace {
-std::unique_ptr<ui::Event> MapEvent(const ui::Event& event) {
- if (event.IsScrollEvent()) {
- return std::make_unique<ui::PointerEvent>(
- ui::MouseWheelEvent(*event.AsScrollEvent()));
- }
-
- if (event.IsMouseEvent())
- return std::make_unique<ui::PointerEvent>(*event.AsMouseEvent());
-
- if (event.IsTouchEvent())
- return std::make_unique<ui::PointerEvent>(*event.AsTouchEvent());
-
- return ui::Event::Clone(event);
-}
-
-} // namespace
-
namespace aura {
EventInjector::EventInjector() {}
@@ -60,7 +42,8 @@ ui::EventDispatchDetails EventInjector::Inject(WindowTreeHost* host,
env->window_tree_client_->connector()->BindInterface(
ws::mojom::kServiceName, &event_injector_);
}
- event_injector_->InjectEventNoAck(host->GetDisplayId(), MapEvent(*event));
+ event_injector_->InjectEventNoAck(host->GetDisplayId(),
+ ui::Event::Clone(*event));
return ui::EventDispatchDetails();
}
diff --git a/chromium/ui/aura/gestures/gesture_recognizer_unittest.cc b/chromium/ui/aura/gestures/gesture_recognizer_unittest.cc
index 86b08db290d..ee72e003826 100644
--- a/chromium/ui/aura/gestures/gesture_recognizer_unittest.cc
+++ b/chromium/ui/aura/gestures/gesture_recognizer_unittest.cc
@@ -4705,8 +4705,7 @@ TEST_F(GestureRecognizerTest, TransferEventsToRoutesAckCorrectly) {
// Transfer event sequence from previous window to the new window.
aura::Env::GetInstance()->gesture_recognizer()->TransferEventsTo(
- window_1.get(), window_2.get(),
- ui::GestureRecognizer::ShouldCancelTouches::DontCancel);
+ window_1.get(), window_2.get(), ui::TransferTouchesBehavior::kDontCancel);
delegate_1->Reset();
delegate_1->ReceivedAck();
diff --git a/chromium/ui/aura/hit_test_data_provider_aura_unittest.cc b/chromium/ui/aura/hit_test_data_provider_aura_unittest.cc
index b120625ed1a..79f73481cad 100644
--- a/chromium/ui/aura/hit_test_data_provider_aura_unittest.cc
+++ b/chromium/ui/aura/hit_test_data_provider_aura_unittest.cc
@@ -8,6 +8,7 @@
#include "components/viz/common/hit_test/hit_test_region_list.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/test/aura_test_base.h"
+#include "ui/aura/test/mus/window_port_mus_test_helper.h"
#include "ui/aura/window.h"
#include "ui/aura/window_targeter.h"
#include "ui/gfx/geometry/rect.h"
@@ -28,15 +29,15 @@ namespace {
// | ---------- |
// | hit hit |
// ----------------------
-class TestHoleWindowTargeter : public aura::WindowTargeter {
+class TestHoleWindowTargeter : public WindowTargeter {
public:
TestHoleWindowTargeter() = default;
~TestHoleWindowTargeter() override {}
private:
- // aura::WindowTargeter:
- std::unique_ptr<aura::WindowTargeter::HitTestRects> GetExtraHitTestShapeRects(
- aura::Window* target) const override {
+ // WindowTargeter:
+ std::unique_ptr<WindowTargeter::HitTestRects> GetExtraHitTestShapeRects(
+ Window* target) const override {
gfx::Rect bounds = target->bounds();
int x0 = 0;
int x1 = bounds.width() / 3;
@@ -46,7 +47,7 @@ class TestHoleWindowTargeter : public aura::WindowTargeter {
int y1 = bounds.height() / 3;
int y2 = bounds.height() - bounds.height() / 3;
int y3 = bounds.height();
- auto shape_rects = std::make_unique<aura::WindowTargeter::HitTestRects>();
+ auto shape_rects = std::make_unique<WindowTargeter::HitTestRects>();
shape_rects->emplace_back(x0, y0, bounds.width(), y1 - y0);
shape_rects->emplace_back(x0, y1, x1 - x0, y2 - y1);
shape_rects->emplace_back(x2, y1, x3 - x2, y2 - y1);
@@ -73,23 +74,17 @@ class HitTestDataProviderAuraTest : public test::AuraTestBaseMus {
test::AuraTestBaseMus::SetUp();
root_ = std::make_unique<Window>(nullptr);
- root_->SetProperty(aura::client::kEmbedType,
- aura::client::WindowEmbedType::EMBED_IN_OWNER);
root_->Init(ui::LAYER_NOT_DRAWN);
root_->SetEventTargeter(std::make_unique<WindowTargeter>());
root_->SetBounds(gfx::Rect(0, 0, 300, 200));
root_->Show();
window2_ = new Window(nullptr);
- window2_->SetProperty(aura::client::kEmbedType,
- aura::client::WindowEmbedType::EMBED_IN_OWNER);
window2_->Init(ui::LAYER_TEXTURED);
window2_->SetBounds(gfx::Rect(20, 30, 40, 60));
window2_->Show();
window3_ = new Window(nullptr);
- window3_->SetProperty(aura::client::kEmbedType,
- aura::client::WindowEmbedType::EMBED_IN_OWNER);
window3_->Init(ui::LAYER_TEXTURED);
window3_->SetEventTargeter(std::make_unique<WindowTargeter>());
window3_->SetBounds(gfx::Rect(50, 60, 100, 40));
@@ -175,10 +170,14 @@ TEST_F(HitTestDataProviderAuraTest, Stacking) {
TEST_F(HitTestDataProviderAuraTest, CustomTargeter) {
constexpr int kMouseInset = -5;
constexpr int kTouchInset = -10;
- auto targeter = std::make_unique<aura::WindowTargeter>();
+ auto targeter = std::make_unique<WindowTargeter>();
targeter->SetInsets(gfx::Insets(kMouseInset), gfx::Insets(kTouchInset));
window3()->SetEventTargeter(std::move(targeter));
+ targeter = std::make_unique<WindowTargeter>();
+ targeter->SetInsets(gfx::Insets(kMouseInset), gfx::Insets(kTouchInset));
+ window4()->SetEventTargeter(std::move(targeter));
+
window2()->SetEmbedFrameSinkId(viz::FrameSinkId(1, 2));
const base::Optional<viz::HitTestRegionList> hit_test_data =
hit_test_data_provider()->GetHitTestData(compositor_frame_);
diff --git a/chromium/ui/aura/local/window_port_local.cc b/chromium/ui/aura/local/window_port_local.cc
index 56c7db037cc..454a3dea5b2 100644
--- a/chromium/ui/aura/local/window_port_local.cc
+++ b/chromium/ui/aura/local/window_port_local.cc
@@ -9,6 +9,7 @@
#include "components/viz/client/local_surface_id_provider.h"
#include "components/viz/common/features.h"
#include "components/viz/host/host_frame_sink_manager.h"
+#include "services/ws/public/mojom/window_tree_constants.mojom.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/env.h"
#include "ui/aura/hit_test_data_provider_aura.h"
@@ -19,7 +20,9 @@
#include "ui/display/screen.h"
namespace aura {
+
namespace {
+static const char* kExo = "Exo";
class ScopedCursorHider {
public:
@@ -63,7 +66,9 @@ class ScopedCursorHider {
} // namespace
WindowPortLocal::WindowPortLocal(Window* window)
- : window_(window), weak_factory_(this) {}
+ : WindowPort(WindowPort::Type::kLocal),
+ window_(window),
+ weak_factory_(this) {}
WindowPortLocal::~WindowPortLocal() {
if (frame_sink_id_.is_valid()) {
@@ -156,10 +161,16 @@ WindowPortLocal::CreateLayerTreeFrameSink() {
params.pipes.compositor_frame_sink_info = std::move(sink_info);
params.pipes.client_request = std::move(client_request);
params.enable_surface_synchronization = true;
+ params.client_name = kExo;
if (features::IsVizHitTestingDrawQuadEnabled()) {
+ bool root_accepts_events =
+ (window_->event_targeting_policy() ==
+ ws::mojom::EventTargetingPolicy::TARGET_ONLY) ||
+ (window_->event_targeting_policy() ==
+ ws::mojom::EventTargetingPolicy::TARGET_AND_DESCENDANTS);
params.hit_test_data_provider =
std::make_unique<viz::HitTestDataProviderDrawQuad>(
- true /* should_ask_for_child_region */);
+ true /* should_ask_for_child_region */, root_accepts_events);
} else {
params.hit_test_data_provider =
std::make_unique<HitTestDataProviderAura>(window_);
diff --git a/chromium/ui/aura/mus/client_surface_embedder.cc b/chromium/ui/aura/mus/client_surface_embedder.cc
index 21913636c50..340eef15b1f 100644
--- a/chromium/ui/aura/mus/client_surface_embedder.cc
+++ b/chromium/ui/aura/mus/client_surface_embedder.cc
@@ -43,6 +43,10 @@ void ClientSurfaceEmbedder::SetPrimarySurfaceId(
false /* stretch_content_to_fill_bounds */);
}
+bool ClientSurfaceEmbedder::HasPrimarySurfaceId() const {
+ return surface_layer_owner_->layer()->GetPrimarySurfaceId() != nullptr;
+}
+
void ClientSurfaceEmbedder::SetFallbackSurfaceInfo(
const viz::SurfaceInfo& surface_info) {
fallback_surface_info_ = surface_info;
@@ -50,6 +54,16 @@ void ClientSurfaceEmbedder::SetFallbackSurfaceInfo(
UpdateSizeAndGutters();
}
+void ClientSurfaceEmbedder::SetClientAreaInsets(
+ const gfx::Insets& client_area_insets) {
+ if (client_area_insets_ == client_area_insets)
+ return;
+
+ client_area_insets_ = client_area_insets;
+ if (inject_gutter_)
+ UpdateSizeAndGutters();
+}
+
void ClientSurfaceEmbedder::UpdateSizeAndGutters() {
surface_layer_owner_->layer()->SetBounds(gfx::Rect(window_->bounds().size()));
if (!inject_gutter_)
diff --git a/chromium/ui/aura/mus/client_surface_embedder.h b/chromium/ui/aura/mus/client_surface_embedder.h
index cec86d00c37..bcf1ce1bace 100644
--- a/chromium/ui/aura/mus/client_surface_embedder.h
+++ b/chromium/ui/aura/mus/client_surface_embedder.h
@@ -37,10 +37,15 @@ class AURA_EXPORT ClientSurfaceEmbedder {
// on the provided |surface_id|.
void SetPrimarySurfaceId(const viz::SurfaceId& surface_id);
+ bool HasPrimarySurfaceId() const;
+
// Sets the fallback SurfaceInfo of the surface layer. The clip layer is not
// updated.
void SetFallbackSurfaceInfo(const viz::SurfaceInfo& surface_info);
+ void SetClientAreaInsets(const gfx::Insets& client_area_insets);
+ const gfx::Insets& client_area_insets() const { return client_area_insets_; }
+
// Update the surface layer size and the right and bottom gutter layers for
// the current window size.
void UpdateSizeAndGutters();
diff --git a/chromium/ui/aura/mus/embed_root.cc b/chromium/ui/aura/mus/embed_root.cc
index 372988eaa30..32fa6b55747 100644
--- a/chromium/ui/aura/mus/embed_root.cc
+++ b/chromium/ui/aura/mus/embed_root.cc
@@ -123,6 +123,7 @@ void EmbedRoot::OnEmbed(std::unique_ptr<WindowTreeHost> window_tree_host) {
focus_client_ =
std::make_unique<EmbeddedFocusClient>(window_tree_host->window());
window_tree_host_ = std::move(window_tree_host);
+ window_tree_host_->Show();
delegate_->OnEmbed(window());
}
diff --git a/chromium/ui/aura/mus/gesture_synchronizer.cc b/chromium/ui/aura/mus/gesture_synchronizer.cc
new file mode 100644
index 00000000000..ce216f54f35
--- /dev/null
+++ b/chromium/ui/aura/mus/gesture_synchronizer.cc
@@ -0,0 +1,55 @@
+// 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 "ui/aura/mus/gesture_synchronizer.h"
+
+#include "services/ws/public/mojom/window_tree.mojom.h"
+#include "ui/aura/env.h"
+#include "ui/aura/mus/window_mus.h"
+#include "ui/aura/window.h"
+#include "ui/events/gestures/gesture_recognizer.h"
+
+namespace aura {
+
+GestureSynchronizer::GestureSynchronizer(ws::mojom::WindowTree* window_tree)
+ : window_tree_(window_tree) {
+ Env::GetInstance()->gesture_recognizer()->AddObserver(this);
+}
+
+GestureSynchronizer::~GestureSynchronizer() {
+ Env::GetInstance()->gesture_recognizer()->RemoveObserver(this);
+}
+
+void GestureSynchronizer::OnActiveTouchesCanceledExcept(
+ ui::GestureConsumer* not_cancelled) {
+ ws::Id not_cancelled_window_id = kInvalidServerId;
+ if (not_cancelled) {
+ WindowMus* not_cancelled_window =
+ WindowMus::Get(static_cast<Window*>(not_cancelled));
+ not_cancelled_window_id = not_cancelled_window->server_id();
+ }
+ window_tree_->CancelActiveTouchesExcept(not_cancelled_window_id);
+}
+
+void GestureSynchronizer::OnEventsTransferred(
+ ui::GestureConsumer* current_consumer,
+ ui::GestureConsumer* new_consumer,
+ ui::TransferTouchesBehavior transfer_touches_behavior) {
+ WindowMus* current_window =
+ WindowMus::Get(static_cast<Window*>(current_consumer));
+ WindowMus* new_window = WindowMus::Get(static_cast<Window*>(new_consumer));
+ DCHECK(current_window);
+ DCHECK(new_window);
+ window_tree_->TransferGestureEventsTo(
+ current_window->server_id(), new_window->server_id(),
+ transfer_touches_behavior == ui::TransferTouchesBehavior::kCancel);
+}
+
+void GestureSynchronizer::OnActiveTouchesCanceled(
+ ui::GestureConsumer* consumer) {
+ WindowMus* window = WindowMus::Get(static_cast<Window*>(consumer));
+ window_tree_->CancelActiveTouches(window->server_id());
+}
+
+} // namespace aura
diff --git a/chromium/ui/aura/mus/gesture_synchronizer.h b/chromium/ui/aura/mus/gesture_synchronizer.h
new file mode 100644
index 00000000000..66ab563d33f
--- /dev/null
+++ b/chromium/ui/aura/mus/gesture_synchronizer.h
@@ -0,0 +1,45 @@
+// 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_MUS_GESTURE_SYNCHRONIZER_H_
+#define UI_AURA_MUS_GESTURE_SYNCHRONIZER_H_
+
+#include "base/macros.h"
+#include "ui/events/gestures/gesture_recognizer_observer.h"
+
+namespace ws {
+namespace mojom {
+
+class WindowTree;
+
+} // namespace mojom
+} // namespace ws
+
+namespace aura {
+
+// GestureSynchronizer is responsible for keeping GestureRecognizer's state
+// synchronized between aura and the mus server.
+class GestureSynchronizer : public ui::GestureRecognizerObserver {
+ public:
+ explicit GestureSynchronizer(ws::mojom::WindowTree* window_tree);
+ ~GestureSynchronizer() override;
+
+ private:
+ // ui::GestureRecognizerObserver:
+ void OnActiveTouchesCanceledExcept(
+ ui::GestureConsumer* not_cancelled) override;
+ void OnEventsTransferred(
+ ui::GestureConsumer* current_consumer,
+ ui::GestureConsumer* new_consumer,
+ ui::TransferTouchesBehavior transfer_touches_behavior) override;
+ void OnActiveTouchesCanceled(ui::GestureConsumer* consumer) override;
+
+ ws::mojom::WindowTree* window_tree_;
+
+ DISALLOW_COPY_AND_ASSIGN(GestureSynchronizer);
+};
+
+} // namespace aura
+
+#endif // UI_AURA_MUS_GESTURE_SYNCHRONIZER_H_
diff --git a/chromium/ui/aura/mus/gesture_synchronizer_unittest.cc b/chromium/ui/aura/mus/gesture_synchronizer_unittest.cc
new file mode 100644
index 00000000000..cd1e7e0dee8
--- /dev/null
+++ b/chromium/ui/aura/mus/gesture_synchronizer_unittest.cc
@@ -0,0 +1,90 @@
+// 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 "ui/aura/mus/gesture_synchronizer.h"
+
+#include <memory>
+
+#include "ui/aura/env.h"
+#include "ui/aura/mus/window_mus.h"
+#include "ui/aura/mus/window_tree_host_mus.h"
+#include "ui/aura/mus/window_tree_host_mus_init_params.h"
+#include "ui/aura/test/aura_mus_test_base.h"
+#include "ui/aura/test/mus/test_window_tree.h"
+
+namespace aura {
+
+class GestureSynchronizerTest : public test::AuraMusClientTestBase {
+ public:
+ GestureSynchronizerTest() = default;
+ ~GestureSynchronizerTest() override = default;
+
+ void SetUp() override {
+ test::AuraMusClientTestBase::SetUp();
+
+ window_tree_host_ = std::make_unique<WindowTreeHostMus>(
+ CreateInitParamsForTopLevel(window_tree_client_impl()));
+ window_tree_host_->InitHost();
+ window_tree_host_->Show();
+ }
+
+ protected:
+ ui::GestureRecognizer* gesture_recognizer() {
+ return Env::GetInstance()->gesture_recognizer();
+ }
+
+ std::unique_ptr<Window> NewWindow() {
+ auto window = std::make_unique<Window>(nullptr);
+ window->Init(ui::LAYER_NOT_DRAWN);
+ window_tree_host_->window()->AddChild(window.get());
+ window->Show();
+ return window;
+ }
+
+ private:
+ std::unique_ptr<WindowTreeHostMus> window_tree_host_;
+
+ DISALLOW_COPY_AND_ASSIGN(GestureSynchronizerTest);
+};
+
+TEST_F(GestureSynchronizerTest, CancelActiveTouchesExcept) {
+ std::unique_ptr<Window> window = NewWindow();
+ gesture_recognizer()->CancelActiveTouchesExcept(window.get());
+ EXPECT_EQ(window_tree()->last_not_cancelled_window_id(),
+ WindowMus::Get(window.get())->server_id());
+}
+
+TEST_F(GestureSynchronizerTest, CancelActiveTouchesExceptForNullptr) {
+ gesture_recognizer()->CancelActiveTouchesExcept(nullptr);
+ EXPECT_EQ(window_tree()->last_not_cancelled_window_id(), kInvalidServerId);
+}
+
+TEST_F(GestureSynchronizerTest, CancelActiveTouches) {
+ std::unique_ptr<Window> window = NewWindow();
+ gesture_recognizer()->CancelActiveTouches(window.get());
+ EXPECT_EQ(window_tree()->last_cancelled_window_id(),
+ WindowMus::Get(window.get())->server_id());
+}
+
+TEST_F(GestureSynchronizerTest, TransferGestureEventsTo) {
+ std::unique_ptr<Window> window1 = NewWindow();
+ std::unique_ptr<Window> window2 = NewWindow();
+ gesture_recognizer()->TransferEventsTo(window1.get(), window2.get(),
+ ui::TransferTouchesBehavior::kCancel);
+ EXPECT_EQ(window_tree()->last_transfer_current(),
+ WindowMus::Get(window1.get())->server_id());
+ EXPECT_EQ(window_tree()->last_transfer_new(),
+ WindowMus::Get(window2.get())->server_id());
+ EXPECT_TRUE(window_tree()->last_transfer_should_cancel());
+
+ gesture_recognizer()->TransferEventsTo(
+ window2.get(), window1.get(), ui::TransferTouchesBehavior::kDontCancel);
+ EXPECT_EQ(window_tree()->last_transfer_current(),
+ WindowMus::Get(window2.get())->server_id());
+ EXPECT_EQ(window_tree()->last_transfer_new(),
+ WindowMus::Get(window1.get())->server_id());
+ EXPECT_FALSE(window_tree()->last_transfer_should_cancel());
+}
+
+} // namespace aura
diff --git a/chromium/ui/aura/mus/input_method_mus.cc b/chromium/ui/aura/mus/input_method_mus.cc
index f840416fe0f..cf1328a6e05 100644
--- a/chromium/ui/aura/mus/input_method_mus.cc
+++ b/chromium/ui/aura/mus/input_method_mus.cc
@@ -19,6 +19,21 @@
using ws::mojom::EventResult;
namespace aura {
+namespace {
+
+void CallEventResultCallback(InputMethodMus::EventResultCallback ack_callback,
+ bool handled) {
+ // |ack_callback| can be null if the standard form of DispatchKeyEvent() is
+ // called instead of the version which provides a callback. In mus+ash we
+ // use the version with callback, but some unittests use the standard form.
+ if (!ack_callback)
+ return;
+
+ std::move(ack_callback)
+ .Run(handled ? EventResult::HANDLED : EventResult::UNHANDLED);
+}
+
+} // namespace
////////////////////////////////////////////////////////////////////////////////
// InputMethodMus, public:
@@ -34,7 +49,7 @@ InputMethodMus::~InputMethodMus() {
// Mus won't dispatch the next key event until the existing one is acked. We
// may have KeyEvents sent to IME and awaiting the result, we need to ack
// them otherwise mus won't process the next event until it times out.
- AckPendingCallbacksUnhandled();
+ AckPendingCallbacks();
}
void InputMethodMus::Init(service_manager::Connector* connector) {
@@ -50,13 +65,9 @@ ui::EventDispatchDetails InputMethodMus::DispatchKeyEvent(
// If no text input client, do nothing.
if (!GetTextInputClient()) {
- ui::EventDispatchDetails dispatch_details = DispatchKeyEventPostIME(event);
- if (ack_callback) {
- std::move(ack_callback)
- .Run(event->handled() ? EventResult::HANDLED
- : EventResult::UNHANDLED);
- }
- return dispatch_details;
+ return DispatchKeyEventPostIME(
+ event,
+ base::BindOnce(&CallEventResultCallback, std::move(ack_callback)));
}
return SendKeyEventToInputMethod(*event, std::move(ack_callback));
@@ -136,7 +147,8 @@ ui::EventDispatchDetails InputMethodMus::SendKeyEventToInputMethod(
// This code path is hit in tests that don't connect to the server.
DCHECK(!ack_callback);
std::unique_ptr<ui::Event> event_clone = ui::Event::Clone(event);
- return DispatchKeyEventPostIME(event_clone->AsKeyEvent());
+ return DispatchKeyEventPostIME(event_clone->AsKeyEvent(),
+ base::NullCallback());
}
// IME driver will notify us whether it handled the event or not by calling
@@ -160,7 +172,7 @@ void InputMethodMus::OnDidChangeFocusedClient(
// We are about to close the pipe with pending callbacks. Closing the pipe
// results in none of the callbacks being run. We have to run the callbacks
// else mus won't process the next event immediately.
- AckPendingCallbacksUnhandled();
+ AckPendingCallbacks();
if (!focused) {
input_method_ = nullptr;
@@ -200,10 +212,10 @@ void InputMethodMus::UpdateTextInputType() {
}
}
-void InputMethodMus::AckPendingCallbacksUnhandled() {
+void InputMethodMus::AckPendingCallbacks() {
for (auto& callback : pending_callbacks_) {
if (callback)
- std::move(callback).Run(EventResult::UNHANDLED);
+ std::move(callback).Run(EventResult::HANDLED);
}
pending_callbacks_.clear();
}
@@ -216,14 +228,7 @@ void InputMethodMus::ProcessKeyEventCallback(
DCHECK(!pending_callbacks_.empty());
EventResultCallback ack_callback = std::move(pending_callbacks_.front());
pending_callbacks_.pop_front();
-
- // |ack_callback| can be null if the standard form of DispatchKeyEvent() is
- // called instead of the version which provides a callback. In mus+ash we
- // use the version with callback, but some unittests use the standard form.
- if (ack_callback) {
- std::move(ack_callback)
- .Run(handled ? EventResult::HANDLED : EventResult::UNHANDLED);
- }
+ CallEventResultCallback(std::move(ack_callback), handled);
}
} // namespace aura
diff --git a/chromium/ui/aura/mus/input_method_mus.h b/chromium/ui/aura/mus/input_method_mus.h
index d47ed317001..d54bf4357cc 100644
--- a/chromium/ui/aura/mus/input_method_mus.h
+++ b/chromium/ui/aura/mus/input_method_mus.h
@@ -64,10 +64,13 @@ class AURA_EXPORT InputMethodMus : public ui::InputMethodBase {
void UpdateTextInputType();
- // Runs all pending callbacks with UNHANDLED. This is called during shutdown,
+ // Runs all pending callbacks with HANDLED. This is called during shutdown,
// or any time |input_method_ptr_| is reset to ensure we don't leave mus
- // waiting for an ack.
- void AckPendingCallbacksUnhandled();
+ // waiting for an ack. We ack HANDLED because the input method can be reset
+ // due to focus changes in response to shortcuts (e.g. Ctrl-T opening a tab)
+ // and we don't want the window manager to try to process the accelerators.
+ // https://crbug.com/874098
+ void AckPendingCallbacks();
// Called when the server responds to our request to process an event.
void ProcessKeyEventCallback(
diff --git a/chromium/ui/aura/mus/input_method_mus_unittest.cc b/chromium/ui/aura/mus/input_method_mus_unittest.cc
index eaa79232a93..b70f26395ba 100644
--- a/chromium/ui/aura/mus/input_method_mus_unittest.cc
+++ b/chromium/ui/aura/mus/input_method_mus_unittest.cc
@@ -21,12 +21,22 @@ class TestInputMethodDelegate : public ui::internal::InputMethodDelegate {
TestInputMethodDelegate() {}
~TestInputMethodDelegate() override {}
+ bool was_dispatch_key_event_post_ime_called() const {
+ return was_dispatch_key_event_post_ime_called_;
+ }
+
// ui::internal::InputMethodDelegate:
- ui::EventDispatchDetails DispatchKeyEventPostIME(ui::KeyEvent* key) override {
+ ui::EventDispatchDetails DispatchKeyEventPostIME(
+ ui::KeyEvent* key,
+ base::OnceCallback<void(bool)> ack_callback) override {
+ was_dispatch_key_event_post_ime_called_ = true;
+ CallDispatchKeyEventPostIMEAck(key, std::move(ack_callback));
return ui::EventDispatchDetails();
}
private:
+ bool was_dispatch_key_event_post_ime_called_ = false;
+
DISALLOW_COPY_AND_ASSIGN(TestInputMethodDelegate);
};
@@ -94,23 +104,28 @@ using InputMethodMusTest = test::AuraTestBaseMus;
namespace {
// Used in closure supplied to processing the event.
-void RunFunctionWithEventResult(bool* was_run, ws::mojom::EventResult result) {
+void RunFunctionWithEventResult(bool* was_run,
+ ws::mojom::EventResult* result_out,
+ ws::mojom::EventResult result) {
*was_run = true;
+ *result_out = result;
}
} // namespace
TEST_F(InputMethodMusTest, PendingCallbackRunFromDestruction) {
bool was_event_result_callback_run = false;
- // Create an InputMethodMus and foward an event to it.
+ ws::mojom::EventResult event_result = ws::mojom::EventResult::UNHANDLED;
+ // Create an InputMethodMus and forward an event to it.
{
TestInputMethodDelegate input_method_delegate;
InputMethodMus input_method_mus(&input_method_delegate, nullptr);
TestInputMethod test_input_method;
InputMethodMusTestApi::SetInputMethod(&input_method_mus,
&test_input_method);
- EventResultCallback callback = base::BindOnce(
- &RunFunctionWithEventResult, &was_event_result_callback_run);
+ EventResultCallback callback =
+ base::BindOnce(&RunFunctionWithEventResult,
+ &was_event_result_callback_run, &event_result);
ui::EventDispatchDetails details =
InputMethodMusTestApi::CallSendKeyEventToInputMethod(
@@ -136,14 +151,16 @@ TEST_F(InputMethodMusTest, PendingCallbackRunFromDestruction) {
TEST_F(InputMethodMusTest, PendingCallbackRunFromOnDidChangeFocusedClient) {
bool was_event_result_callback_run = false;
+ ws::mojom::EventResult event_result = ws::mojom::EventResult::UNHANDLED;
ui::DummyTextInputClient test_input_client;
- // Create an InputMethodMus and foward an event to it.
+ // Create an InputMethodMus and forward an event to it.
TestInputMethodDelegate input_method_delegate;
InputMethodMus input_method_mus(&input_method_delegate, nullptr);
TestInputMethod test_input_method;
InputMethodMusTestApi::SetInputMethod(&input_method_mus, &test_input_method);
- EventResultCallback callback = base::BindOnce(&RunFunctionWithEventResult,
- &was_event_result_callback_run);
+ EventResultCallback callback =
+ base::BindOnce(&RunFunctionWithEventResult,
+ &was_event_result_callback_run, &event_result);
ui::EventDispatchDetails details =
InputMethodMusTestApi::CallSendKeyEventToInputMethod(
&input_method_mus,
@@ -159,18 +176,21 @@ TEST_F(InputMethodMusTest, PendingCallbackRunFromOnDidChangeFocusedClient) {
&input_method_mus, nullptr, &test_input_client);
// Changing the focused client should trigger running the callback.
EXPECT_TRUE(was_event_result_callback_run);
+ EXPECT_EQ(ws::mojom::EventResult::HANDLED, event_result);
}
TEST_F(InputMethodMusTest,
PendingCallbackRunFromOnDidChangeFocusedClientToNull) {
bool was_event_result_callback_run = false;
- // Create an InputMethodMus and foward an event to it.
+ ws::mojom::EventResult event_result = ws::mojom::EventResult::UNHANDLED;
+ // Create an InputMethodMus and forward an event to it.
TestInputMethodDelegate input_method_delegate;
InputMethodMus input_method_mus(&input_method_delegate, nullptr);
TestInputMethod test_input_method;
InputMethodMusTestApi::SetInputMethod(&input_method_mus, &test_input_method);
- EventResultCallback callback = base::BindOnce(&RunFunctionWithEventResult,
- &was_event_result_callback_run);
+ EventResultCallback callback =
+ base::BindOnce(&RunFunctionWithEventResult,
+ &was_event_result_callback_run, &event_result);
ui::EventDispatchDetails details =
InputMethodMusTestApi::CallSendKeyEventToInputMethod(
&input_method_mus,
@@ -186,6 +206,7 @@ TEST_F(InputMethodMusTest,
nullptr, nullptr);
// Changing the focused client should trigger running the callback.
EXPECT_TRUE(was_event_result_callback_run);
+ EXPECT_EQ(ws::mojom::EventResult::HANDLED, event_result);
}
// See description of ChangeTextInputTypeWhileProcessingCallback for details.
@@ -205,9 +226,12 @@ class TestInputMethodDelegate2 : public ui::internal::InputMethodDelegate {
}
// ui::internal::InputMethodDelegate:
- ui::EventDispatchDetails DispatchKeyEventPostIME(ui::KeyEvent* key) override {
+ ui::EventDispatchDetails DispatchKeyEventPostIME(
+ ui::KeyEvent* key,
+ base::OnceCallback<void(bool)> ack_callback) override {
was_dispatch_key_event_post_ime_called_ = true;
input_method_mus_->SetFocusedTextInputClient(text_input_client_);
+ CallDispatchKeyEventPostIMEAck(key, std::move(ack_callback));
return ui::EventDispatchDetails();
}
@@ -224,16 +248,18 @@ class TestInputMethodDelegate2 : public ui::internal::InputMethodDelegate {
// scenario and the callback is correctly called.
TEST_F(InputMethodMusTest, ChangeTextInputTypeWhileProcessingCallback) {
bool was_event_result_callback_run = false;
+ ws::mojom::EventResult event_result = ws::mojom::EventResult::UNHANDLED;
ui::DummyTextInputClient test_input_client;
- // Create an InputMethodMus and foward an event to it.
+ // Create an InputMethodMus and forward an event to it.
TestInputMethodDelegate2 input_method_delegate;
InputMethodMus input_method_mus(&input_method_delegate, nullptr);
input_method_delegate.SetInputMethodAndClient(&input_method_mus,
&test_input_client);
TestInputMethod test_input_method;
InputMethodMusTestApi::SetInputMethod(&input_method_mus, &test_input_method);
- EventResultCallback callback = base::BindOnce(&RunFunctionWithEventResult,
- &was_event_result_callback_run);
+ EventResultCallback callback =
+ base::BindOnce(&RunFunctionWithEventResult,
+ &was_event_result_callback_run, &event_result);
const ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0);
ui::EventDispatchDetails details =
InputMethodMusTestApi::CallSendKeyEventToInputMethod(
@@ -243,10 +269,13 @@ TEST_F(InputMethodMusTest, ChangeTextInputTypeWhileProcessingCallback) {
ASSERT_EQ(1u, test_input_method.process_key_event_callbacks()->size());
// Callback should not have been run yet.
EXPECT_FALSE(was_event_result_callback_run);
- std::move((*test_input_method.process_key_event_callbacks())[0]).Run(false);
+ const bool handled = true;
+ std::move((*test_input_method.process_key_event_callbacks())[0]).Run(handled);
// Callback should have been run.
EXPECT_TRUE(was_event_result_callback_run);
+ EXPECT_EQ(ws::mojom::EventResult::HANDLED, event_result);
+ EXPECT_FALSE(input_method_delegate.was_dispatch_key_event_post_ime_called());
}
// Calling OnTextInputTypeChanged from unfocused client should
@@ -317,4 +346,37 @@ TEST_F(InputMethodMusTest, ShowVirtualKeyboardIfEnabled) {
EXPECT_TRUE(test_input_method.was_show_virtual_keyboard_if_enabled_called());
}
+TEST_F(InputMethodMusTest, AckUnhandledCallsDispatchKeyEventPostUnhandled) {
+ bool was_event_result_callback_run = false;
+ ws::mojom::EventResult event_result = ws::mojom::EventResult::UNHANDLED;
+ // Create an InputMethodMus and forward an event to it.
+ TestInputMethodDelegate input_method_delegate;
+ InputMethodMus input_method_mus(&input_method_delegate, nullptr);
+ TestInputMethod test_input_method;
+ InputMethodMusTestApi::SetInputMethod(&input_method_mus, &test_input_method);
+ EventResultCallback callback =
+ base::BindOnce(&RunFunctionWithEventResult,
+ &was_event_result_callback_run, &event_result);
+ const ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0);
+ ignore_result(InputMethodMusTestApi::CallSendKeyEventToInputMethod(
+ &input_method_mus, key_event, std::move(callback)));
+ // The event should have been queued.
+ ASSERT_EQ(1u, test_input_method.process_key_event_callbacks()->size());
+ // Callback should not have been run yet.
+ EXPECT_FALSE(was_event_result_callback_run);
+ const bool handled = false;
+ std::move((*test_input_method.process_key_event_callbacks())[0]).Run(handled);
+ test_input_method.process_key_event_callbacks()->clear();
+
+ // Callback should have been run.
+ EXPECT_TRUE(was_event_result_callback_run);
+ EXPECT_EQ(ws::mojom::EventResult::UNHANDLED, event_result);
+
+ // DispatchKeyEventPostIME() should not have beeen called. In production
+ // the following calls result:
+ // InputMethodChromeOS -> RemoteTextInputClient -> TextInputClientImpl ->
+ // InputMethodMus's delegate.
+ EXPECT_FALSE(input_method_delegate.was_dispatch_key_event_post_ime_called());
+}
+
} // namespace aura
diff --git a/chromium/ui/aura/mus/mus_mouse_location_updater.cc b/chromium/ui/aura/mus/mus_mouse_location_updater.cc
index 32aa588cb61..ce61eab444f 100644
--- a/chromium/ui/aura/mus/mus_mouse_location_updater.cc
+++ b/chromium/ui/aura/mus/mus_mouse_location_updater.cc
@@ -38,27 +38,17 @@ MusMouseLocationUpdater::~MusMouseLocationUpdater() {
}
void MusMouseLocationUpdater::OnEventProcessingStarted(const ui::Event& event) {
- if (!IsMouseEventWithLocation(event) ||
- Env::GetInstance()->always_use_last_mouse_location_) {
+ Env* env = Env::GetInstance();
+ if (!IsMouseEventWithLocation(event) || env->always_use_last_mouse_location_)
return;
- }
is_processing_trigger_event_ = true;
- gfx::Point location_in_screen = event.AsMouseEvent()->root_location();
// event.target() may not exist in some tests.
- if (event.target()) {
- aura::Window* root_window =
- static_cast<aura::Window*>(event.target())->GetRootWindow();
- auto* screen_position_client =
- aura::client::GetScreenPositionClient(root_window);
- // screen_position_client may not exist in tests.
- if (screen_position_client) {
- screen_position_client->ConvertPointToScreen(root_window,
- &location_in_screen);
- }
- }
- Env::GetInstance()->SetLastMouseLocation(location_in_screen);
- Env::GetInstance()->get_last_mouse_location_from_mus_ = false;
+ const gfx::Point screen_location =
+ event.target() ? event.target()->GetScreenLocation(*event.AsMouseEvent())
+ : event.AsMouseEvent()->root_location();
+ env->SetLastMouseLocation(screen_location);
+ env->get_last_mouse_location_from_mus_ = false;
}
void MusMouseLocationUpdater::OnEventProcessingFinished() {
diff --git a/chromium/ui/aura/mus/mus_types.h b/chromium/ui/aura/mus/mus_types.h
index 4f406261d73..3a58e55eeb9 100644
--- a/chromium/ui/aura/mus/mus_types.h
+++ b/chromium/ui/aura/mus/mus_types.h
@@ -20,17 +20,9 @@ enum class WindowMusType {
// The window is an embed root in the embedded client. That is, the client
// received this window by way of another client calling Embed(). In other
// words, this is the embedded side of an embedding.
- // NOTE: in the client that called Embed() the window type is LOCAL (or
- // EMBED_IN_OWNER).
- // TODO(sky): ensure when Embed() is called type is always set to
- // EMBED_IN_OWNER, and if the embedding is removed it goes back to LOCAL.
- // https://crbug.com/834487
+ // NOTE: in the client that called Embed() the window type is LOCAL.
EMBED,
- // Embed() was called on the window by the local client. In other words, this
- // is the embedder side of an embedding.
- EMBED_IN_OWNER,
-
// The window was created by requesting a top level
// (WindowTree::NewTopLevel()).
TOP_LEVEL,
diff --git a/chromium/ui/aura/mus/os_exchange_data_provider_mus.cc b/chromium/ui/aura/mus/os_exchange_data_provider_mus.cc
index 9e41787ea96..f8e327cd09b 100644
--- a/chromium/ui/aura/mus/os_exchange_data_provider_mus.cc
+++ b/chromium/ui/aura/mus/os_exchange_data_provider_mus.cc
@@ -113,8 +113,7 @@ void OSExchangeDataProviderMus::SetFilename(const base::FilePath& path) {
void OSExchangeDataProviderMus::SetFilenames(
const std::vector<ui::FileInfo>& file_names) {
std::vector<std::string> paths;
- for (std::vector<ui::FileInfo>::const_iterator it = file_names.begin();
- it != file_names.end(); ++it) {
+ for (auto it = file_names.begin(); it != file_names.end(); ++it) {
std::string url_spec = net::FilePathToFileURL(it->path).spec();
if (!url_spec.empty())
paths.push_back(url_spec);
diff --git a/chromium/ui/aura/mus/property_converter.cc b/chromium/ui/aura/mus/property_converter.cc
index 51cd00e1d81..0d0e345318e 100644
--- a/chromium/ui/aura/mus/property_converter.cc
+++ b/chromium/ui/aura/mus/property_converter.cc
@@ -4,6 +4,7 @@
#include "ui/aura/mus/property_converter.h"
+#include "base/time/time.h"
#include "base/unguessable_token.h"
#include "mojo/public/cpp/bindings/type_converter.h"
#include "services/ws/public/cpp/property_type_converters.h"
@@ -108,10 +109,58 @@ PropertyConverter::PropertyConverter() {
client::kAnimationsDisabledKey,
ws::mojom::WindowManager::kAnimationsDisabled_Property,
CreateAcceptAnyValueCallback());
+ RegisterWindowPtrProperty(
+ client::kChildModalParentKey,
+ ws::mojom::WindowManager::kChildModalParent_Property);
}
PropertyConverter::~PropertyConverter() {}
+const void* PropertyConverter::GetPropertyKeyFromTransportName(
+ const std::string& transport_name) {
+ for (const auto& primitive_property : primitive_properties_) {
+ if (primitive_property.second.transport_name == transport_name)
+ return primitive_property.first;
+ }
+
+ for (const auto& image_property : image_properties_) {
+ if (image_property.second == transport_name)
+ return image_property.first->name;
+ }
+
+ for (const auto& rect_property : rect_properties_) {
+ if (rect_property.second == transport_name)
+ return rect_property.first->name;
+ }
+
+ for (const auto& size_property : size_properties_) {
+ if (size_property.second == transport_name)
+ return size_property.first->name;
+ }
+
+ for (const auto& string_property : string_properties_) {
+ if (string_property.second == transport_name)
+ return string_property.first->name;
+ }
+
+ for (const auto& string16_property : string16_properties_) {
+ if (string16_property.second == transport_name)
+ return string16_property.first->name;
+ }
+
+ for (const auto& unguessable_token_property : unguessable_token_properties_) {
+ if (unguessable_token_property.second == transport_name)
+ return unguessable_token_property.first->name;
+ }
+
+ for (const auto& window_ptr_property : window_ptr_properties_) {
+ if (window_ptr_property.second == transport_name)
+ return window_ptr_property.first->name;
+ }
+
+ return nullptr;
+}
+
bool PropertyConverter::IsTransportNameRegistered(
const std::string& name) const {
return transport_names_.count(name) > 0;
@@ -131,7 +180,7 @@ bool PropertyConverter::ConvertPropertyForTransport(
const gfx::ImageSkia* value = window->GetProperty(image_key);
if (value) {
// TODO(crbug.com/667566): Support additional scales or gfx::Image[Skia].
- SkBitmap bitmap = value->GetRepresentation(1.f).sk_bitmap();
+ SkBitmap bitmap = value->GetRepresentation(1.f).GetBitmap();
*transport_value = std::make_unique<std::vector<uint8_t>>(
mojo::ConvertTo<std::vector<uint8_t>>(bitmap));
} else {
@@ -171,6 +220,14 @@ bool PropertyConverter::ConvertPropertyForTransport(
return true;
}
+ // window_ptr_properties_ aren't processed here since Window* values aren't
+ // transferrable. A post processing step in WindowTree and WindowTreeClient
+ // takes care of the conversion.
+ if (IsWindowPtrPropertyRegistered(
+ static_cast<const WindowProperty<Window*>*>(key))) {
+ return true;
+ }
+
// Handle primitive property types generically.
DCHECK_GT(primitive_properties_.count(key), 0u);
PrimitiveType default_value = primitive_properties_[key].default_value;
@@ -210,6 +267,10 @@ std::string PropertyConverter::GetTransportNameForPropertyKey(const void* key) {
if (unguessable_token_properties_.count(unguessable_token_key) > 0)
return unguessable_token_properties_[unguessable_token_key];
+ auto* window_ptr_key = static_cast<const WindowProperty<Window*>*>(key);
+ if (window_ptr_properties_.count(window_ptr_key) > 0)
+ return window_ptr_properties_[window_ptr_key];
+
return std::string();
}
@@ -307,6 +368,20 @@ void PropertyConverter::SetPropertyFromTransportValue(
}
}
+ // window_ptr_properties_ aren't processed here since Window* values aren't
+ // transferrable. A post processing step in WindowTree and WindowTreeClient
+ // takes care of the conversion.
+ for (const auto& window_ptr_property : window_ptr_properties_) {
+ if (window_ptr_property.second == transport_name) {
+ LOG(ERROR) << transport_name << " is a registered window property but "
+ << "should not be processed here.";
+ return;
+ }
+ }
+
+ // WARNING: Adding a new map, be sure and update
+ // GetPropertyKeyFromTransportName() as well.
+
DVLOG(2) << "Unknown mus property name: " << transport_name;
}
@@ -379,6 +454,15 @@ void PropertyConverter::RegisterString16Property(
transport_names_.insert(transport_name);
}
+void PropertyConverter::RegisterTimeDeltaProperty(
+ const WindowProperty<base::TimeDelta>* property,
+ const char* transport_name) {
+ // TimeDelta is internally handled (by class_property) as a primitive
+ // value (int64_t) . See ClassPropertyCaster<base::TimeDelta> for details.
+ RegisterPrimitiveProperty(property, transport_name,
+ CreateAcceptAnyValueCallback());
+}
+
void PropertyConverter::RegisterUnguessableTokenProperty(
const WindowProperty<base::UnguessableToken*>* property,
const char* transport_name) {
@@ -388,6 +472,29 @@ void PropertyConverter::RegisterUnguessableTokenProperty(
transport_names_.insert(transport_name);
}
+void PropertyConverter::RegisterWindowPtrProperty(
+ const WindowProperty<Window*>* property,
+ const char* transport_name) {
+ DCHECK(!IsTransportNameRegistered(transport_name))
+ << "Property already registered: " << transport_name;
+ window_ptr_properties_[property] = transport_name;
+ transport_names_.insert(transport_name);
+}
+
+const WindowProperty<Window*>* PropertyConverter::GetWindowPtrProperty(
+ const std::string& transport_name) const {
+ for (const auto& iter : window_ptr_properties_) {
+ if (transport_name == iter.second)
+ return iter.first;
+ }
+ return nullptr;
+}
+
+bool PropertyConverter::IsWindowPtrPropertyRegistered(
+ const WindowProperty<Window*>* property) const {
+ return window_ptr_properties_.find(property) != window_ptr_properties_.end();
+}
+
base::flat_map<std::string, std::vector<uint8_t>>
PropertyConverter::GetTransportProperties(Window* window) {
base::flat_map<std::string, std::vector<uint8_t>> properties;
diff --git a/chromium/ui/aura/mus/property_converter.h b/chromium/ui/aura/mus/property_converter.h
index 8d13b2021cd..82650db1321 100644
--- a/chromium/ui/aura/mus/property_converter.h
+++ b/chromium/ui/aura/mus/property_converter.h
@@ -18,6 +18,7 @@
#include "ui/aura/window.h"
namespace base {
+class TimeDelta;
class UnguessableToken;
}
@@ -45,6 +46,10 @@ class AURA_EXPORT PropertyConverter {
// accept any value.
static base::RepeatingCallback<bool(int64_t)> CreateAcceptAnyValueCallback();
+ // Returns the key for the window property registered against the specified
+ // transport name.
+ const void* GetPropertyKeyFromTransportName(const std::string& name);
+
// Returns true if RegisterProperty() has been called with the specified
// transport name.
bool IsTransportNameRegistered(const std::string& name) const;
@@ -111,9 +116,23 @@ class AURA_EXPORT PropertyConverter {
const char* transport_name);
void RegisterString16Property(const WindowProperty<base::string16*>* property,
const char* transport_name);
+ void RegisterTimeDeltaProperty(
+ const WindowProperty<base::TimeDelta>* property,
+ const char* transport_name);
void RegisterUnguessableTokenProperty(
const WindowProperty<base::UnguessableToken*>* property,
const char* transport_name);
+ void RegisterWindowPtrProperty(const WindowProperty<Window*>* property,
+ const char* transport_name);
+
+ // Returns the window property key of Window* value which is registered with
+ // the transport_name. If the name is not registered or registered with a
+ // different type, returns nullptr.
+ const WindowProperty<Window*>* GetWindowPtrProperty(
+ const std::string& transport_name) const;
+
+ bool IsWindowPtrPropertyRegistered(
+ const WindowProperty<Window*>* property) const;
// Get a flat map of the window's registered properties, to use for transport.
base::flat_map<std::string, std::vector<uint8_t>> GetTransportProperties(
@@ -151,6 +170,7 @@ class AURA_EXPORT PropertyConverter {
string16_properties_;
std::map<const WindowProperty<base::UnguessableToken*>*, const char*>
unguessable_token_properties_;
+ std::map<const WindowProperty<Window*>*, const char*> window_ptr_properties_;
// Set of transport names supplied to RegisterProperty().
std::set<std::string> transport_names_;
diff --git a/chromium/ui/aura/mus/property_converter_unittest.cc b/chromium/ui/aura/mus/property_converter_unittest.cc
index 50838071d5f..2d0382cf08f 100644
--- a/chromium/ui/aura/mus/property_converter_unittest.cc
+++ b/chromium/ui/aura/mus/property_converter_unittest.cc
@@ -43,6 +43,10 @@ DEFINE_UI_CLASS_PROPERTY_KEY(int16_t, kTestPropertyKey7, 1);
DEFINE_UI_CLASS_PROPERTY_KEY(int32_t, kTestPropertyKey8, -1);
DEFINE_UI_CLASS_PROPERTY_KEY(int64_t, kTestPropertyKey9, 777);
+DEFINE_UI_CLASS_PROPERTY_KEY(base::TimeDelta,
+ kTestTimeDeltaKey,
+ base::TimeDelta());
+
DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::ImageSkia,
kTestImageSkiaPropertyKey,
nullptr);
@@ -53,6 +57,9 @@ DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(
DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(base::string16, kTestString16PropertyKey,
nullptr);
+DEFINE_UI_CLASS_PROPERTY_KEY(Window*, kTestWindowPtrPropertyKey, nullptr);
+DEFINE_UI_CLASS_PROPERTY_KEY(Window*, kTestWindowPtrUnregisteredKey, nullptr);
+
const char kTestPropertyServerKey0[] = "test-property-server0";
const char kTestPropertyServerKey1[] = "test-property-server1";
const char kTestPropertyServerKey2[] = "test-property-server2";
@@ -69,6 +76,10 @@ const char kTestRectPropertyServerKey[] = "test-rect-property-server";
const char kTestSizePropertyServerKey[] = "test-size-property-server";
const char kTestStringPropertyServerKey[] = "test-string-property-server";
const char kTestString16PropertyServerKey[] = "test-string16-property-server";
+const char kTestTimeDeltaPropertyServerKey[] =
+ "test-time-delta-property-server";
+const char kTestWindowPtrPropertyServerKey[] =
+ "test-window-ptr-property-server";
// Test registration, naming and value conversion for primitive property types.
template <typename T>
@@ -369,4 +380,84 @@ TEST_F(PropertyConverterTest, String16Property) {
EXPECT_EQ(value_2, *window->GetProperty(kTestString16PropertyKey));
}
+TEST_F(PropertyConverterTest, TimeDeltaProperty) {
+ PropertyConverter property_converter;
+ property_converter.RegisterTimeDeltaProperty(kTestTimeDeltaKey,
+ kTestTimeDeltaPropertyServerKey);
+ EXPECT_EQ(
+ kTestTimeDeltaPropertyServerKey,
+ property_converter.GetTransportNameForPropertyKey(kTestTimeDeltaKey));
+ EXPECT_TRUE(property_converter.IsTransportNameRegistered(
+ kTestTimeDeltaPropertyServerKey));
+
+ std::unique_ptr<Window> window(CreateNormalWindow(1, root_window(), nullptr));
+ const base::TimeDelta time_delta =
+ base::TimeDelta::FromMilliseconds(123456789);
+ window->SetProperty(kTestTimeDeltaKey, time_delta);
+
+ std::string transport_name_out;
+ std::unique_ptr<std::vector<uint8_t>> transport_value_out;
+ EXPECT_TRUE(property_converter.ConvertPropertyForTransport(
+ window.get(), kTestTimeDeltaKey, &transport_name_out,
+ &transport_value_out));
+ EXPECT_EQ(kTestTimeDeltaPropertyServerKey, transport_name_out);
+ const int64_t storage_value_1 = time_delta.InMicroseconds();
+ std::vector<uint8_t> transport_value =
+ mojo::ConvertTo<std::vector<uint8_t>>(storage_value_1);
+ EXPECT_EQ(transport_value, *transport_value_out.get());
+
+ int64_t decoded_value_1 = 0;
+ EXPECT_TRUE(property_converter.GetPropertyValueFromTransportValue(
+ kTestTimeDeltaPropertyServerKey, *transport_value_out, &decoded_value_1));
+ EXPECT_EQ(time_delta.InMicroseconds(), decoded_value_1);
+
+ window->SetProperty(kTestTimeDeltaKey, base::TimeDelta());
+ property_converter.SetPropertyFromTransportValue(
+ window.get(), kTestTimeDeltaPropertyServerKey, &transport_value);
+ EXPECT_EQ(time_delta, window->GetProperty(kTestTimeDeltaKey));
+}
+
+TEST_F(PropertyConverterTest, WindowPtrProperty) {
+ PropertyConverter property_converter;
+ property_converter.RegisterString16Property(kTestString16PropertyKey,
+ kTestString16PropertyServerKey);
+ property_converter.RegisterWindowPtrProperty(kTestWindowPtrPropertyKey,
+ kTestWindowPtrPropertyServerKey);
+ EXPECT_EQ(kTestWindowPtrPropertyServerKey,
+ property_converter.GetTransportNameForPropertyKey(
+ kTestWindowPtrPropertyKey));
+ EXPECT_TRUE(property_converter.IsTransportNameRegistered(
+ kTestWindowPtrPropertyServerKey));
+
+ EXPECT_TRUE(property_converter.IsWindowPtrPropertyRegistered(
+ kTestWindowPtrPropertyKey));
+ EXPECT_EQ(kTestWindowPtrPropertyKey, property_converter.GetWindowPtrProperty(
+ kTestWindowPtrPropertyServerKey));
+ EXPECT_FALSE(property_converter.IsWindowPtrPropertyRegistered(
+ kTestWindowPtrUnregisteredKey));
+ EXPECT_FALSE(
+ property_converter.GetWindowPtrProperty(kTestString16PropertyServerKey));
+
+ std::unique_ptr<Window> window1(
+ CreateNormalWindow(1, root_window(), nullptr));
+ std::unique_ptr<Window> window2(
+ CreateNormalWindow(2, root_window(), nullptr));
+ window1->SetProperty(kTestWindowPtrPropertyKey, window2.get());
+
+ std::string transport_name_out;
+ std::unique_ptr<std::vector<uint8_t>> transport_value_out;
+ EXPECT_TRUE(property_converter.ConvertPropertyForTransport(
+ window1.get(), kTestWindowPtrPropertyKey, &transport_name_out,
+ &transport_value_out));
+ EXPECT_EQ(kTestWindowPtrPropertyServerKey, transport_name_out);
+ EXPECT_FALSE(transport_value_out);
+
+ window1->ClearProperty(kTestWindowPtrPropertyKey);
+ std::vector<uint8_t> transport_value = mojo::ConvertTo<std::vector<uint8_t>>(
+ reinterpret_cast<uint64_t>(window2.get()));
+ property_converter.SetPropertyFromTransportValue(
+ window1.get(), kTestWindowPtrPropertyServerKey, &transport_value);
+ EXPECT_FALSE(window1->GetProperty(kTestWindowPtrPropertyKey));
+}
+
} // namespace aura
diff --git a/chromium/ui/aura/mus/text_input_client_impl.cc b/chromium/ui/aura/mus/text_input_client_impl.cc
index 0ce8eb10c23..29121c53a7e 100644
--- a/chromium/ui/aura/mus/text_input_client_impl.cc
+++ b/chromium/ui/aura/mus/text_input_client_impl.cc
@@ -52,9 +52,8 @@ void TextInputClientImpl::DispatchKeyEventPostIME(
std::unique_ptr<ui::Event> event,
DispatchKeyEventPostIMECallback callback) {
if (delegate_) {
- delegate_->DispatchKeyEventPostIME(event->AsKeyEvent());
- if (callback && !callback.is_null())
- std::move(callback).Run(event->stopped_propagation());
+ delegate_->DispatchKeyEventPostIME(event->AsKeyEvent(),
+ std::move(callback));
}
}
diff --git a/chromium/ui/aura/mus/window_mus.h b/chromium/ui/aura/mus/window_mus.h
index bac124e8b37..3ee4b65d25a 100644
--- a/chromium/ui/aura/mus/window_mus.h
+++ b/chromium/ui/aura/mus/window_mus.h
@@ -28,7 +28,6 @@ enum class OrderDirection;
namespace viz {
class FrameSinkId;
class LocalSurfaceId;
-class SurfaceInfo;
}
namespace aura {
@@ -95,7 +94,6 @@ class AURA_EXPORT WindowMus {
const viz::FrameSinkId& frame_sink_id) = 0;
virtual const viz::LocalSurfaceId& GetOrAllocateLocalSurfaceId(
const gfx::Size& new_size) = 0;
- virtual void SetFallbackSurfaceInfo(const viz::SurfaceInfo& surface_info) = 0;
// The window was deleted on the server side. DestroyFromServer() should
// result in deleting |this|.
virtual void DestroyFromServer() = 0;
diff --git a/chromium/ui/aura/mus/window_port_mus.cc b/chromium/ui/aura/mus/window_port_mus.cc
index 9db986531be..2eb6ad5647c 100644
--- a/chromium/ui/aura/mus/window_port_mus.cc
+++ b/chromium/ui/aura/mus/window_port_mus.cc
@@ -4,13 +4,15 @@
#include "ui/aura/mus/window_port_mus.h"
+#include "base/auto_reset.h"
#include "cc/mojo_embedder/async_layer_tree_frame_sink.h"
+#include "components/viz/client/hit_test_data_provider_draw_quad.h"
#include "components/viz/client/local_surface_id_provider.h"
#include "components/viz/host/host_frame_sink_manager.h"
+#include "services/ws/public/mojom/window_tree_constants.mojom.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/transient_window_client.h"
#include "ui/aura/env.h"
-#include "ui/aura/hit_test_data_provider_aura.h"
#include "ui/aura/mus/client_surface_embedder.h"
#include "ui/aura/mus/property_converter.h"
#include "ui/aura/mus/window_tree_client.h"
@@ -27,6 +29,10 @@
namespace aura {
+namespace {
+static const char* kMus = "Mus";
+} // namespace
+
WindowPortMus::WindowMusChangeDataImpl::WindowMusChangeDataImpl() = default;
WindowPortMus::WindowMusChangeDataImpl::~WindowMusChangeDataImpl() = default;
@@ -38,7 +44,8 @@ WindowMus* WindowMus::Get(Window* window) {
WindowPortMus::WindowPortMus(WindowTreeClient* client,
WindowMusType window_mus_type)
- : WindowMus(window_mus_type),
+ : WindowPort(WindowPort::Type::kMus),
+ WindowMus(window_mus_type),
window_tree_client_(client),
weak_ptr_factory_(this) {}
@@ -56,7 +63,10 @@ WindowPortMus::~WindowPortMus() {
// static
WindowPortMus* WindowPortMus::Get(Window* window) {
- return static_cast<WindowPortMus*>(WindowPort::Get(window));
+ WindowPort* port = WindowPort::Get(window);
+ return port && port->type() == WindowPort::Type::kMus
+ ? static_cast<WindowPortMus*>(port)
+ : nullptr;
}
void WindowPortMus::SetTextInputState(ui::mojom::TextInputStatePtr state) {
@@ -85,23 +95,36 @@ void WindowPortMus::SetCanAcceptDrops(bool can_accept_drops) {
window_tree_client_->SetCanAcceptDrops(this, can_accept_drops);
}
-void WindowPortMus::SetHitTestMask(const base::Optional<gfx::Rect>& mask) {
- window_tree_client_->SetHitTestMask(this, mask);
+void WindowPortMus::SetHitTestInsets(const gfx::Insets& mouse,
+ const gfx::Insets& touch) {
+ window_tree_client_->SetHitTestInsets(this, mouse, touch);
}
void WindowPortMus::Embed(ws::mojom::WindowTreeClientPtr client,
uint32_t flags,
ws::mojom::WindowTree::EmbedCallback callback) {
- window_tree_client_->Embed(window_, std::move(client), flags,
- std::move(callback));
+ if (!PrepareForEmbed()) {
+ std::move(callback).Run(false);
+ return;
+ }
+ window_tree_client_->tree_->Embed(
+ server_id(), std::move(client), flags,
+ base::BindOnce(&WindowPortMus::OnEmbedAck, weak_ptr_factory_.GetWeakPtr(),
+ std::move(callback)));
}
void WindowPortMus::EmbedUsingToken(
const base::UnguessableToken& token,
uint32_t flags,
ws::mojom::WindowTree::EmbedCallback callback) {
- window_tree_client_->EmbedUsingToken(window_, token, flags,
- std::move(callback));
+ if (!PrepareForEmbed()) {
+ std::move(callback).Run(false);
+ return;
+ }
+ window_tree_client_->tree_->EmbedUsingToken(
+ server_id(), token, flags,
+ base::BindOnce(&WindowPortMus::OnEmbedAck, weak_ptr_factory_.GetWeakPtr(),
+ std::move(callback)));
}
std::unique_ptr<cc::mojo_embedder::AsyncLayerTreeFrameSink>
@@ -119,11 +142,18 @@ WindowPortMus::RequestLayerTreeFrameSink(
params.gpu_memory_buffer_manager = gpu_memory_buffer_manager;
params.pipes.compositor_frame_sink_info = std::move(sink_info);
params.pipes.client_request = std::move(client_request);
+ bool root_accepts_events =
+ (window_->event_targeting_policy() ==
+ ws::mojom::EventTargetingPolicy::TARGET_ONLY) ||
+ (window_->event_targeting_policy() ==
+ ws::mojom::EventTargetingPolicy::TARGET_AND_DESCENDANTS);
params.hit_test_data_provider =
- std::make_unique<HitTestDataProviderAura>(window_);
+ std::make_unique<viz::HitTestDataProviderDrawQuad>(
+ true /* should_ask_for_child_region */, root_accepts_events);
params.local_surface_id_provider =
std::make_unique<viz::DefaultLocalSurfaceIdProvider>();
params.enable_surface_synchronization = true;
+ params.client_name = kMus;
auto layer_tree_frame_sink =
std::make_unique<cc::mojo_embedder::AsyncLayerTreeFrameSink>(
@@ -213,6 +243,43 @@ WindowPortMus::ServerChanges::iterator WindowPortMus::FindChangeByTypeAndData(
return iter;
}
+bool WindowPortMus::PrepareForEmbed() {
+ // Window::Init() must be called before Embed() (otherwise the server hasn't
+ // been told about the window).
+ DCHECK(window_->layer());
+
+ // The window server removes all children before embedding. In other words,
+ // it's generally an error to Embed() with existing children. So, fail early.
+ if (!window_->children().empty())
+ return false;
+
+ // Can only embed in windows created by this client.
+ if (window_mus_type() != WindowMusType::LOCAL)
+ return false;
+
+ // Don't allow an embed when one exists. This could be handled, if the
+ // callback was converted to OnChangeCompleted(). To attempt to handle it
+ // without routing the callback over the WindowTreeClient pipe would result
+ // in problemcs because of ordering. The ordering problem is because there is
+ // the Embed() request, the callback, and OnEmbeddedAppDisconnected() (which
+ // originates from the server side).
+ if (has_embedding_)
+ return false;
+
+ has_embedding_ = true;
+ return true;
+}
+
+// static
+void WindowPortMus::OnEmbedAck(
+ base::WeakPtr<WindowPortMus> window,
+ ws::mojom::WindowTree::EmbedCallback real_callback,
+ bool result) {
+ if (window && !result)
+ window->has_embedding_ = false;
+ std::move(real_callback).Run(window && result);
+}
+
PropertyConverter* WindowPortMus::GetPropertyConverter() {
return window_tree_client_->delegate_->GetPropertyConverter();
}
@@ -305,9 +372,12 @@ void WindowPortMus::SetPropertyFromServer(
void WindowPortMus::SetFrameSinkIdFromServer(
const viz::FrameSinkId& frame_sink_id) {
- DCHECK(window_mus_type() == WindowMusType::EMBED_IN_OWNER);
- window_->SetEmbedFrameSinkId(frame_sink_id);
- UpdatePrimarySurfaceId();
+ embed_frame_sink_id_ = frame_sink_id;
+ window_->SetEmbedFrameSinkId(embed_frame_sink_id_);
+ // We may not have allocated a LocalSurfaceId. Call OnWindowMusBoundsChanged()
+ // to trigger updating the LocalSurfaceId *and* notifying the server.
+ window_tree_client_->OnWindowMusBoundsChanged(this, window_->bounds(),
+ window_->bounds());
}
const viz::LocalSurfaceId& WindowPortMus::GetOrAllocateLocalSurfaceId(
@@ -331,25 +401,6 @@ const viz::LocalSurfaceId& WindowPortMus::GetOrAllocateLocalSurfaceId(
return local_surface_id_;
}
-void WindowPortMus::SetFallbackSurfaceInfo(
- const viz::SurfaceInfo& surface_info) {
- if (!window_->IsEmbeddingClient()) {
- // |primary_surface_id_| shold not be valid, since we didn't know the
- // |window_->frame_sink_id()|.
- DCHECK(!primary_surface_id_.is_valid());
- window_->SetEmbedFrameSinkId(surface_info.id().frame_sink_id());
- UpdatePrimarySurfaceId();
- }
-
- // The frame sink id should never be changed.
- DCHECK_EQ(surface_info.id().frame_sink_id(), window_->GetFrameSinkId());
-
- fallback_surface_info_ = surface_info;
- UpdateClientSurfaceEmbedder();
- if (window_->delegate())
- window_->delegate()->OnFirstSurfaceActivation(fallback_surface_info_);
-}
-
void WindowPortMus::DestroyFromServer() {
std::unique_ptr<ScopedServerChange> remove_from_parent_change;
if (window_->parent()) {
@@ -408,6 +459,8 @@ WindowPortMus::ChangeSource WindowPortMus::OnTransientChildRemoved(
void WindowPortMus::AllocateLocalSurfaceId() {
local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
UpdatePrimarySurfaceId();
+ if (local_layer_tree_frame_sink_)
+ local_layer_tree_frame_sink_->SetLocalSurfaceId(local_surface_id_);
}
bool WindowPortMus::IsLocalSurfaceIdAllocationSuppressed() const {
@@ -426,6 +479,12 @@ void WindowPortMus::UpdateLocalSurfaceIdFromEmbeddedClient(
embedded_client_local_surface_id);
local_surface_id_ =
parent_local_surface_id_allocator_.GetCurrentLocalSurfaceId();
+ UpdatePrimarySurfaceId();
+
+ // OnWindowMusBoundsChanged() triggers notifying the server of the new
+ // LocalSurfaceId.
+ window_tree_client_->OnWindowMusBoundsChanged(this, window_->bounds(),
+ window_->bounds());
}
const viz::LocalSurfaceId& WindowPortMus::GetLocalSurfaceId() {
@@ -459,6 +518,7 @@ void WindowPortMus::PrepareForDestroy() {
}
void WindowPortMus::NotifyEmbeddedAppDisconnected() {
+ has_embedding_ = false;
for (WindowObserver& observer : *GetObservers(window_))
observer.OnEmbeddedAppDisconnected(window_);
}
@@ -575,20 +635,18 @@ WindowPortMus::CreateLayerTreeFrameSink() {
DCHECK_EQ(window_mus_type(), WindowMusType::LOCAL);
DCHECK(!local_layer_tree_frame_sink_);
- std::unique_ptr<cc::LayerTreeFrameSink> frame_sink;
auto client_layer_tree_frame_sink = RequestLayerTreeFrameSink(
- nullptr,
- aura::Env::GetInstance()->context_factory()->GetGpuMemoryBufferManager());
+ nullptr, window_->env()->context_factory()->GetGpuMemoryBufferManager());
local_layer_tree_frame_sink_ = client_layer_tree_frame_sink->GetWeakPtr();
- frame_sink = std::move(client_layer_tree_frame_sink);
- window_->SetEmbedFrameSinkId(GenerateFrameSinkIdFromServerId());
+ embed_frame_sink_id_ = GenerateFrameSinkIdFromServerId();
+ window_->SetEmbedFrameSinkId(embed_frame_sink_id_);
gfx::Size size_in_pixel =
gfx::ConvertSizeToPixel(GetDeviceScaleFactor(), window_->bounds().size());
// Make sure |local_surface_id_| and |last_surface_size_in_pixels_| are
// correct for the new created |local_layer_tree_frame_sink_|.
GetOrAllocateLocalSurfaceId(size_in_pixel);
- return frame_sink;
+ return client_layer_tree_frame_sink;
}
void WindowPortMus::OnEventTargetingPolicyChanged() {
@@ -599,25 +657,30 @@ bool WindowPortMus::ShouldRestackTransientChildren() {
return should_restack_transient_children_;
}
+void WindowPortMus::RegisterFrameSinkId(const viz::FrameSinkId& frame_sink_id) {
+ if (frame_sink_id == embed_frame_sink_id_)
+ return;
+
+ window_tree_client_->RegisterFrameSinkId(this, frame_sink_id);
+}
+
+void WindowPortMus::UnregisterFrameSinkId(
+ const viz::FrameSinkId& frame_sink_id) {
+ if (frame_sink_id == embed_frame_sink_id_)
+ return;
+
+ window_tree_client_->UnregisterFrameSinkId(this);
+}
+
void WindowPortMus::UpdatePrimarySurfaceId() {
- if (window_mus_type() != WindowMusType::EMBED_IN_OWNER &&
- window_mus_type() != WindowMusType::LOCAL) {
+ if (window_mus_type() != WindowMusType::LOCAL)
return;
- }
if (!window_->IsEmbeddingClient() || !local_surface_id_.is_valid())
return;
primary_surface_id_ =
viz::SurfaceId(window_->GetFrameSinkId(), local_surface_id_);
- UpdateClientSurfaceEmbedder();
-}
-
-void WindowPortMus::UpdateClientSurfaceEmbedder() {
- if (window_mus_type() != WindowMusType::EMBED_IN_OWNER &&
- window_mus_type() != WindowMusType::LOCAL) {
- return;
- }
if (!client_surface_embedder_) {
client_surface_embedder_ = std::make_unique<ClientSurfaceEmbedder>(
@@ -625,7 +688,7 @@ void WindowPortMus::UpdateClientSurfaceEmbedder() {
}
client_surface_embedder_->SetPrimarySurfaceId(primary_surface_id_);
- client_surface_embedder_->SetFallbackSurfaceInfo(fallback_surface_info_);
+ client_surface_embedder_->UpdateSizeAndGutters();
}
} // namespace aura
diff --git a/chromium/ui/aura/mus/window_port_mus.h b/chromium/ui/aura/mus/window_port_mus.h
index e6ec469c098..428b05a2732 100644
--- a/chromium/ui/aura/mus/window_port_mus.h
+++ b/chromium/ui/aura/mus/window_port_mus.h
@@ -45,7 +45,6 @@ namespace aura {
class ClientSurfaceEmbedder;
class PropertyConverter;
class Window;
-class WindowPortMusTest;
class WindowTreeClient;
class WindowTreeClientPrivate;
class WindowTreeHostMus;
@@ -87,7 +86,7 @@ class AURA_EXPORT WindowPortMus : public WindowPort, public WindowMus {
void SetCanAcceptDrops(bool can_accept_drops);
// See description in mojom for details on this.
- void SetHitTestMask(const base::Optional<gfx::Rect>& mask);
+ void SetHitTestInsets(const gfx::Insets& mouse, const gfx::Insets& touch);
// Embeds a new client in this Window. See WindowTreeClient::Embed() for
// details on arguments.
@@ -106,7 +105,7 @@ class AURA_EXPORT WindowPortMus : public WindowPort, public WindowMus {
viz::FrameSinkId GenerateFrameSinkIdFromServerId() const;
private:
- friend class WindowPortMusTest;
+ friend class WindowPortMusTestHelper;
friend class WindowTreeClient;
friend class WindowTreeClientPrivate;
friend class WindowTreeHostMus;
@@ -116,7 +115,7 @@ class AURA_EXPORT WindowPortMus : public WindowPort, public WindowMus {
// Changes to the underlying Window originating from the server must be done
// in such a way that the same change is not applied back to the server. To
- // accomplish this every changes from the server is associated with at least
+ // accomplish this every change from the server is associated with at least
// one ServerChange. If the underlying Window ends up calling back to this
// class and the change is expected then the change is ignored and not sent to
// the server. For example, here's the flow when the server changes the
@@ -221,6 +220,16 @@ class AURA_EXPORT WindowPortMus : public WindowPort, public WindowMus {
ServerChanges::iterator FindChangeByTypeAndData(const ServerChangeType type,
const ServerChangeData& data);
+ // Called to setup state necessary for an embedding. Returns false if an
+ // embedding is not allowed in this window.
+ bool PrepareForEmbed();
+
+ // Called from OnEmbed() with the result of the embedding. |real_callback| is
+ // the callback supplied to the embed call.
+ static void OnEmbedAck(base::WeakPtr<WindowPortMus> window,
+ ws::mojom::WindowTree::EmbedCallback real_callback,
+ bool result);
+
PropertyConverter* GetPropertyConverter();
// WindowMus:
@@ -245,7 +254,6 @@ class AURA_EXPORT WindowPortMus : public WindowPort, public WindowMus {
const gfx::Size& surface_size_in_pixels) override;
void UpdateLocalSurfaceIdFromEmbeddedClient(
const viz::LocalSurfaceId& embedded_client_local_surface_id) override;
- void SetFallbackSurfaceInfo(const viz::SurfaceInfo& surface_info) override;
void DestroyFromServer() override;
void AddTransientChildFromServer(WindowMus* child) override;
void RemoveTransientChildFromServer(WindowMus* child) override;
@@ -285,9 +293,10 @@ class AURA_EXPORT WindowPortMus : public WindowPort, public WindowMus {
const viz::LocalSurfaceId& GetLocalSurfaceId() override;
void OnEventTargetingPolicyChanged() override;
bool ShouldRestackTransientChildren() override;
+ void RegisterFrameSinkId(const viz::FrameSinkId& frame_sink_id) override;
+ void UnregisterFrameSinkId(const viz::FrameSinkId& frame_sink_id) override;
void UpdatePrimarySurfaceId();
- void UpdateClientSurfaceEmbedder();
WindowTreeClient* window_tree_client_;
@@ -300,7 +309,6 @@ class AURA_EXPORT WindowPortMus : public WindowPort, public WindowMus {
ServerChanges server_changes_;
viz::SurfaceId primary_surface_id_;
- viz::SurfaceInfo fallback_surface_info_;
viz::LocalSurfaceId local_surface_id_;
// TODO(sad, fsamuel): For 'mash' mode, where the embedder is responsible for
@@ -311,9 +319,15 @@ class AURA_EXPORT WindowPortMus : public WindowPort, public WindowMus {
ui::CursorData cursor_;
+ // Set if this class calls SetEmbedFrameSinkId() on the associated window.
+ viz::FrameSinkId embed_frame_sink_id_;
+
// See description in single place that changes the value for details.
bool should_restack_transient_children_ = true;
+ // True if this window has an embedding.
+ bool has_embedding_ = false;
+
// When a frame sink is created
// for a local aura::Window, we need keep a weak ptr of it, so we can update
// the local surface id when necessary.
diff --git a/chromium/ui/aura/mus/window_port_mus_unittest.cc b/chromium/ui/aura/mus/window_port_mus_unittest.cc
index 0e05b5886d5..fe616b2dc28 100644
--- a/chromium/ui/aura/mus/window_port_mus_unittest.cc
+++ b/chromium/ui/aura/mus/window_port_mus_unittest.cc
@@ -7,26 +7,16 @@
#include "cc/mojo_embedder/async_layer_tree_frame_sink.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/mus/client_surface_embedder.h"
+#include "ui/aura/test/aura_mus_test_base.h"
#include "ui/aura/test/aura_test_base.h"
+#include "ui/aura/test/mus/test_window_tree.h"
+#include "ui/aura/test/mus/window_port_mus_test_helper.h"
#include "ui/aura/window.h"
#include "ui/base/ui_base_features.h"
namespace aura {
-class WindowPortMusTest : public test::AuraTestBase {
- public:
- WindowPortMusTest() { EnableMusWithTestWindowTree(); }
-
- ~WindowPortMusTest() override = default;
-
- base::WeakPtr<cc::LayerTreeFrameSink> GetFrameSinkFor(Window* window) {
- auto* window_mus = WindowPortMus::Get(window);
- return window_mus->local_layer_tree_frame_sink_;
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(WindowPortMusTest);
-};
+using WindowPortMusTest = test::AuraMusClientTestBase;
// TODO(sadrul): https://crbug.com/842361.
TEST_F(WindowPortMusTest,
@@ -45,7 +35,7 @@ TEST_F(WindowPortMusTest,
window.CreateLayerTreeFrameSink());
EXPECT_TRUE(frame_sink.get());
- auto mus_frame_sink = GetFrameSinkFor(&window);
+ auto mus_frame_sink = WindowPortMusTestHelper(&window).GetFrameSink();
ASSERT_TRUE(mus_frame_sink);
auto frame_sink_local_surface_id =
static_cast<cc::mojo_embedder::AsyncLayerTreeFrameSink*>(
@@ -71,4 +61,46 @@ TEST_F(WindowPortMusTest, ClientSurfaceEmbedderUpdatesLayer) {
EXPECT_EQ(local_surface_id, primary_surface_id.local_surface_id());
}
+TEST_F(WindowPortMusTest,
+ UpdateLocalSurfaceIdFromEmbeddedClientUpdateClientSurfaceEmbedder) {
+ Window window(nullptr);
+ window.Init(ui::LAYER_NOT_DRAWN);
+ window.set_owned_by_parent(false);
+ window.SetBounds(gfx::Rect(300, 300));
+ // Simulate an embedding.
+ window.SetEmbedFrameSinkId(viz::FrameSinkId(0, 1));
+ root_window()->AddChild(&window);
+
+ // AckAllChanges() so that can verify a bounds change happens from
+ // UpdateLocalSurfaceIdFromEmbeddedClient().
+ window_tree()->AckAllChanges();
+
+ // Update the LocalSurfaceId.
+ viz::LocalSurfaceId current_id = window.GetSurfaceId().local_surface_id();
+ ASSERT_TRUE(current_id.is_valid());
+ viz::ParentLocalSurfaceIdAllocator* parent_allocator =
+ WindowPortMusTestHelper(&window).GetParentLocalSurfaceIdAllocator();
+ parent_allocator->Reset(current_id);
+ viz::LocalSurfaceId updated_id = parent_allocator->GenerateId();
+ ASSERT_TRUE(updated_id.is_valid());
+ EXPECT_NE(updated_id, current_id);
+ window.UpdateLocalSurfaceIdFromEmbeddedClient(updated_id);
+
+ // Updating the LocalSurfaceId should propagate to the ClientSurfaceEmbedder.
+ auto* window_mus = WindowPortMus::Get(&window);
+ ASSERT_TRUE(window_mus);
+ ASSERT_TRUE(window_mus->client_surface_embedder());
+ EXPECT_EQ(updated_id, window_mus->client_surface_embedder()
+ ->GetPrimarySurfaceIdForTesting()
+ .local_surface_id());
+
+ // The server is notified of a bounds change, so that it sees the new
+ // LocalSurfaceId.
+ ASSERT_EQ(1u,
+ window_tree()->GetChangeCountForType(WindowTreeChangeType::BOUNDS));
+ ASSERT_TRUE(window_tree()->last_local_surface_id());
+ EXPECT_EQ(window_mus->server_id(), window_tree()->window_id());
+ EXPECT_EQ(updated_id, *(window_tree()->last_local_surface_id()));
+}
+
} // namespace aura
diff --git a/chromium/ui/aura/mus/window_tree_client.cc b/chromium/ui/aura/mus/window_tree_client.cc
index 517bd131eaf..f28829be913 100644
--- a/chromium/ui/aura/mus/window_tree_client.cc
+++ b/chromium/ui/aura/mus/window_tree_client.cc
@@ -38,6 +38,7 @@
#include "ui/aura/mus/embed_root.h"
#include "ui/aura/mus/embed_root_delegate.h"
#include "ui/aura/mus/focus_synchronizer.h"
+#include "ui/aura/mus/gesture_synchronizer.h"
#include "ui/aura/mus/in_flight_change.h"
#include "ui/aura/mus/input_method_mus.h"
#include "ui/aura/mus/mus_context_factory.h"
@@ -121,32 +122,7 @@ WindowTreeHostMus* GetWindowTreeHostMus(WindowMus* window) {
}
bool IsInternalProperty(const void* key) {
- return key == client::kModalKey || key == client::kChildModalParentKey;
-}
-
-// Create and return a MouseEvent or TouchEvent from |event| if |event| is a
-// PointerEvent, otherwise return the copy of |event|.
-std::unique_ptr<ui::Event> MapEvent(const ui::Event& event) {
- if (event.IsPointerEvent()) {
- const ui::PointerEvent& pointer_event = *event.AsPointerEvent();
- // Use a switch statement in case more pointer types are added.
- switch (pointer_event.pointer_details().pointer_type) {
- case ui::EventPointerType::POINTER_TYPE_MOUSE:
- if (event.type() == ui::ET_POINTER_WHEEL_CHANGED)
- return std::make_unique<ui::MouseWheelEvent>(pointer_event);
- return std::make_unique<ui::MouseEvent>(pointer_event);
- case ui::EventPointerType::POINTER_TYPE_TOUCH:
- case ui::EventPointerType::POINTER_TYPE_PEN:
- return std::make_unique<ui::TouchEvent>(pointer_event);
- case ui::EventPointerType::POINTER_TYPE_ERASER:
- NOTIMPLEMENTED();
- break;
- case ui::EventPointerType::POINTER_TYPE_UNKNOWN:
- NOTREACHED();
- break;
- }
- }
- return ui::Event::Clone(event);
+ return key == client::kModalKey;
}
} // namespace
@@ -273,31 +249,26 @@ void WindowTreeClient::SetImeVisibility(WindowMus* window,
tree_->SetImeVisibility(window->server_id(), visible, std::move(state));
}
-void WindowTreeClient::SetHitTestMask(
- WindowMus* window,
- const base::Optional<gfx::Rect>& mask_rect) {
+void WindowTreeClient::SetHitTestInsets(WindowMus* window,
+ const gfx::Insets& mouse,
+ const gfx::Insets& touch) {
DCHECK(tree_);
- tree_->SetHitTestMask(window->server_id(), mask_rect);
+ tree_->SetHitTestInsets(window->server_id(), mouse, touch);
}
-void WindowTreeClient::Embed(Window* window,
- ws::mojom::WindowTreeClientPtr client,
- uint32_t flags,
- ws::mojom::WindowTree::EmbedCallback callback) {
- DCHECK(tree_);
- // Window::Init() must be called before Embed() (otherwise the server hasn't
- // been told about the window).
- DCHECK(window->layer());
- if (!window->children().empty()) {
- // The window server removes all children before embedding. In other words,
- // it's generally an error to Embed() with existing children. So, fail
- // early.
- std::move(callback).Run(false);
- return;
- }
+void WindowTreeClient::RegisterFrameSinkId(
+ WindowMus* window,
+ const viz::FrameSinkId& frame_sink_id) {
+ tree_->AttachFrameSinkId(window->server_id(), frame_sink_id);
+
+ // Call OnWindowMusBoundsChanged() to force allocation of a LocalSurfaceId as
+ // well as notifying the server of the LocalSurfaceId.
+ const gfx::Rect bounds = window->GetWindow()->bounds();
+ OnWindowMusBoundsChanged(window, bounds, bounds);
+}
- tree_->Embed(WindowMus::Get(window)->server_id(), std::move(client), flags,
- std::move(callback));
+void WindowTreeClient::UnregisterFrameSinkId(WindowMus* window) {
+ tree_->UnattachFrameSinkId(window->server_id());
}
void WindowTreeClient::ScheduleEmbed(
@@ -306,27 +277,6 @@ void WindowTreeClient::ScheduleEmbed(
tree_->ScheduleEmbed(std::move(client), std::move(callback));
}
-void WindowTreeClient::EmbedUsingToken(
- Window* window,
- const base::UnguessableToken& token,
- uint32_t flags,
- ws::mojom::WindowTree::EmbedCallback callback) {
- DCHECK(tree_);
- // Window::Init() must be called before Embed() (otherwise the server hasn't
- // been told about the window).
- DCHECK(window->layer());
- if (!window->children().empty()) {
- // The window server removes all children before embedding. In other words,
- // it's generally an error to Embed() with existing children. So, fail
- // early.
- std::move(callback).Run(false);
- return;
- }
-
- tree_->EmbedUsingToken(WindowMus::Get(window)->server_id(), token, flags,
- std::move(callback));
-}
-
void WindowTreeClient::AttachCompositorFrameSink(
ws::Id window_id,
viz::mojom::CompositorFrameSinkRequest compositor_frame_sink,
@@ -413,7 +363,9 @@ WindowMus* WindowTreeClient::GetWindowByServerId(ws::Id id) {
bool WindowTreeClient::IsWindowKnown(aura::Window* window) {
WindowMus* window_mus = WindowMus::Get(window);
- return windows_.count(window_mus->server_id()) > 0;
+ // NOTE: this function explicitly checks for a null WindowMus as it may be
+ // called from global observers that may see other types.
+ return window_mus && windows_.count(window_mus->server_id()) > 0;
}
InFlightChange* WindowTreeClient::GetOldestInFlightChangeMatching(
@@ -584,6 +536,7 @@ void WindowTreeClient::WindowTreeConnectionEstablished(
drag_drop_controller_ = std::make_unique<DragDropControllerMus>(this, tree_);
capture_synchronizer_ = std::make_unique<CaptureSynchronizer>(this, tree_);
focus_synchronizer_ = std::make_unique<FocusSynchronizer>(this, tree_);
+ gesture_synchronizer_ = std::make_unique<GestureSynchronizer>(tree_);
}
void WindowTreeClient::OnConnectionLost() {
@@ -601,18 +554,6 @@ bool WindowTreeClient::HandleInternalPropertyChanged(WindowMus* window,
window->GetWindow()->GetProperty(client::kModalKey));
return true;
}
- if (key == client::kChildModalParentKey) {
- const uint32_t change_id =
- ScheduleInFlightChange(std::make_unique<CrashInFlightChange>(
- window, ChangeType::CHILD_MODAL_PARENT));
- Window* child_modal_parent =
- window->GetWindow()->GetProperty(client::kChildModalParentKey);
- tree_->SetChildModalParent(
- change_id, window->server_id(),
- child_modal_parent ? WindowMus::Get(child_modal_parent)->server_id()
- : kInvalidServerId);
- return true;
- }
return false;
}
@@ -736,16 +677,17 @@ void WindowTreeClient::ScheduleInFlightBoundsChange(
ScheduleInFlightChange(std::make_unique<InFlightBoundsChange>(
this, window, old_bounds, window->GetLocalSurfaceId()));
base::Optional<viz::LocalSurfaceId> local_surface_id;
- if (window->window_mus_type() == WindowMusType::EMBED_IN_OWNER ||
+ if (window->GetWindow()->IsEmbeddingClient() ||
window->HasLocalLayerTreeFrameSink()) {
// Do not use ConvertRectToPixel, enclosing rects cause problems.
const gfx::Size size = gfx::ScaleToCeiledSize(
new_bounds.size(), window->GetDeviceScaleFactor());
local_surface_id = window->GetOrAllocateLocalSurfaceId(size);
// |window_tree_host| may be null if this is called during creation of
- // the window associated with the WindowTreeHostMus.
+ // the window associated with the WindowTreeHostMus, or if there is an
+ // embedding.
WindowTreeHost* window_tree_host = window->GetWindow()->GetHost();
- if (window_tree_host)
+ if (window_tree_host && window_tree_host->window() == window->GetWindow())
window_tree_host->compositor()->OnChildResizing();
}
tree_->SetWindowBounds(change_id, window->server_id(), new_bounds,
@@ -904,13 +846,24 @@ void WindowTreeClient::OnWindowMusPropertyChanged(
WindowPortPropertyDataMus* data_mus =
static_cast<WindowPortPropertyDataMus*>(data.get());
+ PropertyConverter* property_converter = delegate_->GetPropertyConverter();
std::string transport_name;
std::unique_ptr<std::vector<uint8_t>> transport_value;
- if (!delegate_->GetPropertyConverter()->ConvertPropertyForTransport(
+ if (!property_converter->ConvertPropertyForTransport(
window->GetWindow(), key, &transport_name, &transport_value)) {
return;
}
DCHECK_EQ(transport_name, data_mus->transport_name);
+ const auto* window_ptr_key = static_cast<const WindowProperty<Window*>*>(key);
+ if (property_converter->IsWindowPtrPropertyRegistered(window_ptr_key)) {
+ DCHECK(!transport_value);
+ Window* value = window->GetWindow()->GetProperty(window_ptr_key);
+ WindowMus* window_mus = WindowMus::Get(value);
+ if (window_mus) {
+ transport_value = std::make_unique<std::vector<uint8_t>>(
+ mojo::ConvertTo<std::vector<uint8_t>>(window_mus->server_id()));
+ }
+ }
base::Optional<std::vector<uint8_t>> transport_value_mojo;
if (transport_value)
@@ -1273,6 +1226,14 @@ void WindowTreeClient::OnWindowOpacityChanged(ws::Id window_id,
window->SetOpacityFromServer(new_opacity);
}
+void WindowTreeClient::OnWindowDisplayChanged(ws::Id window_id,
+ int64_t display_id) {
+ WindowMus* window = GetWindowByServerId(window_id);
+ if (!window)
+ return;
+ GetWindowTreeHostMus(window->GetWindow())->set_display_id(display_id);
+}
+
void WindowTreeClient::OnWindowParentDrawnStateChanged(ws::Id window_id,
bool drawn) {
// TODO: route to WindowTreeHost.
@@ -1311,10 +1272,22 @@ void WindowTreeClient::OnWindowInputEvent(uint32_t event_id,
DCHECK(event);
WindowMus* window = GetWindowByServerId(window_id); // May be null.
+ DCHECK(!event->IsPointerEvent());
+
if (matches_pointer_watcher && has_pointer_watcher_) {
- DCHECK(event->IsPointerEvent());
- std::unique_ptr<ui::Event> event_in_dip(ui::Event::Clone(*event));
- NotifyPointerEventObserved(event_in_dip->AsPointerEvent(), display_id,
+ // TODO(sky): remove this once PointerWatcher doesn't need PointerEvent.
+ // https://crbug.com/865781
+ std::unique_ptr<ui::Event> pointer_event;
+ if (event->IsMouseEvent()) {
+ pointer_event =
+ std::make_unique<ui::PointerEvent>(*event->AsMouseEvent());
+ } else if (event->IsTouchEvent()) {
+ pointer_event =
+ std::make_unique<ui::PointerEvent>(*event->AsTouchEvent());
+ } else {
+ NOTREACHED();
+ }
+ NotifyPointerEventObserved(pointer_event->AsPointerEvent(), display_id,
window);
}
@@ -1323,13 +1296,10 @@ void WindowTreeClient::OnWindowInputEvent(uint32_t event_id,
if (!window || !window->GetWindow()->GetHost()) {
EnvInputStateController* env_controller =
Env::GetInstance()->env_controller();
- std::unique_ptr<ui::Event> mapped_event = MapEvent(*event.get());
- if (mapped_event->IsMouseEvent()) {
- env_controller->UpdateStateForMouseEvent(nullptr,
- *mapped_event->AsMouseEvent());
- } else if (mapped_event->IsTouchEvent()) {
- env_controller->UpdateStateForTouchEvent(*mapped_event->AsTouchEvent());
- }
+ if (event->IsMouseEvent())
+ env_controller->UpdateStateForMouseEvent(nullptr, *event->AsMouseEvent());
+ else if (event->IsTouchEvent())
+ env_controller->UpdateStateForTouchEvent(*event->AsTouchEvent());
tree_->OnWindowInputEventAck(event_id, ws::mojom::EventResult::UNHANDLED);
return;
}
@@ -1343,10 +1313,6 @@ void WindowTreeClient::OnWindowInputEvent(uint32_t event_id,
}
}
- // TODO(moshayedi): crbug.com/617222. No need to convert to ui::MouseEvent or
- // ui::TouchEvent once we have proper support for pointer events.
- std::unique_ptr<ui::Event> mapped_event = MapEvent(*event.get());
- ui::Event* event_to_dispatch = mapped_event.get();
// |ack_handler| may use |event_to_dispatch| from its destructor, so it needs
// to be destroyed after |event_to_dispatch| is destroyed.
EventAckHandler ack_handler(CreateEventResultCallback(event_id));
@@ -1354,12 +1320,12 @@ void WindowTreeClient::OnWindowInputEvent(uint32_t event_id,
if (!event->IsKeyEvent()) {
// Set |window| as the target, except for key events. Key events go to the
// focused window, which may have changed by the time we process the event.
- ui::Event::DispatcherApi(event_to_dispatch).set_target(window->GetWindow());
+ ui::Event::DispatcherApi(event.get()).set_target(window->GetWindow());
}
- GetWindowTreeHostMus(window)->SendEventToSink(event_to_dispatch);
+ GetWindowTreeHostMus(window)->SendEventToSink(event.get());
- ack_handler.set_handled(event_to_dispatch->handled());
+ ack_handler.set_handled(event->handled());
}
void WindowTreeClient::OnPointerEventObserved(std::unique_ptr<ui::Event> event,
@@ -1397,21 +1363,6 @@ void WindowTreeClient::OnWindowCursorChanged(ws::Id window_id,
window->SetCursorFromServer(cursor);
}
-void WindowTreeClient::OnWindowSurfaceChanged(
- ws::Id window_id,
- const viz::SurfaceInfo& surface_info) {
- WindowMus* window = GetWindowByServerId(window_id);
- if (!window)
- return;
-
- // If the parent is informed of a child's surface then that surface ID is
- // guaranteed to be available in the display compositor so we set it as the
- // fallback. If surface synchronization is enabled, the primary SurfaceInfo
- // is created by the embedder, and the LocalSurfaceId is allocated by the
- // embedder.
- window->SetFallbackSurfaceInfo(surface_info);
-}
-
void WindowTreeClient::OnDragDropStart(
const base::flat_map<std::string, std::vector<uint8_t>>& mime_data) {
drag_drop_controller_->OnDragDropStart(mojo::FlatMapToMap(mime_data));
@@ -1605,13 +1556,6 @@ void WindowTreeClient::OnWindowTreeHostStackAtTop(
tree_->StackAtTop(change_id, window->server_id());
}
-void WindowTreeClient::OnWindowTreeHostPerformWmAction(
- WindowTreeHostMus* window_tree_host,
- const std::string& action) {
- WindowMus* window = WindowMus::Get(window_tree_host->window());
- tree_->PerformWmAction(window->server_id(), action);
-}
-
void WindowTreeClient::OnWindowTreeHostPerformWindowMove(
WindowTreeHostMus* window_tree_host,
ws::mojom::MoveLoopSource source,
diff --git a/chromium/ui/aura/mus/window_tree_client.h b/chromium/ui/aura/mus/window_tree_client.h
index f4d0931ed3e..9183c781309 100644
--- a/chromium/ui/aura/mus/window_tree_client.h
+++ b/chromium/ui/aura/mus/window_tree_client.h
@@ -61,6 +61,7 @@ class DragDropControllerMus;
class EmbedRoot;
class EmbedRootDelegate;
class FocusSynchronizer;
+class GestureSynchronizer;
class InFlightBoundsChange;
class InFlightChange;
class InFlightFocusChange;
@@ -136,20 +137,14 @@ class AURA_EXPORT WindowTreeClient
void SetImeVisibility(WindowMus* window,
bool visible,
ui::mojom::TextInputStatePtr state);
- void SetHitTestMask(WindowMus* window, const base::Optional<gfx::Rect>& rect);
-
- // Embeds a new client in |window|. |flags| is a bitmask of the values defined
- // by kEmbedFlag*; 0 gives default behavior. |callback| is called to indicate
- // whether the embedding succeeded or failed and may be called immediately if
- // the embedding is known to fail.
- void Embed(Window* window,
- ws::mojom::WindowTreeClientPtr client,
- uint32_t flags,
- ws::mojom::WindowTree::EmbedCallback callback);
- void EmbedUsingToken(Window* window,
- const base::UnguessableToken& token,
- uint32_t flags,
- ws::mojom::WindowTree::EmbedCallback callback);
+ void SetHitTestInsets(WindowMus* window,
+ const gfx::Insets& mouse,
+ const gfx::Insets& touch);
+
+ // See WindowPort for details on these.
+ void RegisterFrameSinkId(WindowMus* window,
+ const viz::FrameSinkId& child_frame_sink_id);
+ void UnregisterFrameSinkId(WindowMus* window);
// Schedules an embed of a client. See
// ws::mojom::WindowTreeClient::ScheduleEmbed() for details.
@@ -177,6 +172,17 @@ class AURA_EXPORT WindowTreeClient
ws::mojom::MoveLoopSource source,
aura::Window* initial_target);
+ // See mojom for details.
+ template <typename Interface>
+ mojo::AssociatedInterfacePtr<Interface> BindWindowManagerInterface() {
+ ws::mojom::WindowManagerAssociatedPtr interface_ptr;
+ tree_->BindWindowManagerInterface(Interface::Name_,
+ mojo::MakeRequest(&interface_ptr));
+ return mojo::AssociatedInterfacePtr<Interface>(
+ mojo::AssociatedInterfacePtrInfo<Interface>(
+ interface_ptr.PassInterface().PassHandle(), Interface::Version_));
+ }
+
// Returns true if the specified window was created by this client.
bool WasCreatedByThisClient(const WindowMus* window) const;
@@ -403,6 +409,7 @@ class AURA_EXPORT WindowTreeClient
void OnWindowOpacityChanged(ws::Id window_id,
float old_opacity,
float new_opacity) override;
+ void OnWindowDisplayChanged(ws::Id window_id, int64_t display_id) override;
void OnWindowParentDrawnStateChanged(ws::Id window_id, bool drawn) override;
void OnWindowSharedPropertyChanged(
ws::Id window_id,
@@ -418,8 +425,6 @@ class AURA_EXPORT WindowTreeClient
int64_t display_id) override;
void OnWindowFocused(ws::Id focused_window_id) override;
void OnWindowCursorChanged(ws::Id window_id, ui::CursorData cursor) override;
- void OnWindowSurfaceChanged(ws::Id window_id,
- const viz::SurfaceInfo& surface_info) override;
void OnDragDropStart(const base::flat_map<std::string, std::vector<uint8_t>>&
mime_data) override;
void OnDragEnter(ws::Id window_id,
@@ -469,8 +474,6 @@ class AURA_EXPORT WindowTreeClient
void OnWindowTreeHostStackAbove(WindowTreeHostMus* window_tree_host,
Window* window) override;
void OnWindowTreeHostStackAtTop(WindowTreeHostMus* window_tree_host) override;
- void OnWindowTreeHostPerformWmAction(WindowTreeHostMus* window_tree_host,
- const std::string& action) override;
void OnWindowTreeHostPerformWindowMove(
WindowTreeHostMus* window_tree_host,
ws::mojom::MoveLoopSource mus_source,
@@ -526,6 +529,8 @@ class AURA_EXPORT WindowTreeClient
std::unique_ptr<FocusSynchronizer> focus_synchronizer_;
+ std::unique_ptr<GestureSynchronizer> gesture_synchronizer_;
+
mojo::Binding<ws::mojom::WindowTreeClient> binding_;
ws::mojom::WindowTreePtr tree_ptr_;
// Typically this is the value contained in |tree_ptr_|, but tests may
diff --git a/chromium/ui/aura/mus/window_tree_client_unittest.cc b/chromium/ui/aura/mus/window_tree_client_unittest.cc
index e8c841cb632..2ca4cce0c21 100644
--- a/chromium/ui/aura/mus/window_tree_client_unittest.cc
+++ b/chromium/ui/aura/mus/window_tree_client_unittest.cc
@@ -39,6 +39,7 @@
#include "ui/aura/mus/window_tree_host_mus_init_params.h"
#include "ui/aura/test/aura_mus_test_base.h"
#include "ui/aura/test/mus/test_window_tree.h"
+#include "ui/aura/test/mus/window_port_mus_test_helper.h"
#include "ui/aura/test/mus/window_tree_client_private.h"
#include "ui/aura/test/test_screen.h"
#include "ui/aura/test/test_window_delegate.h"
@@ -68,10 +69,12 @@ namespace {
DEFINE_UI_CLASS_PROPERTY_KEY(uint8_t, kTestPropertyKey1, 0);
DEFINE_UI_CLASS_PROPERTY_KEY(uint16_t, kTestPropertyKey2, 0);
DEFINE_UI_CLASS_PROPERTY_KEY(bool, kTestPropertyKey3, false);
+DEFINE_UI_CLASS_PROPERTY_KEY(Window*, kTestPropertyKey4, nullptr);
const char kTestPropertyServerKey1[] = "test-property-server1";
const char kTestPropertyServerKey2[] = "test-property-server2";
const char kTestPropertyServerKey3[] = "test-property-server3";
+const char kTestPropertyServerKey4[] = "test-property-server4";
ws::Id server_id(Window* window) {
return window ? WindowMus::Get(window)->server_id() : 0;
@@ -113,6 +116,8 @@ void RegisterTestProperties(PropertyConverter* converter) {
converter->RegisterPrimitiveProperty(
kTestPropertyKey3, kTestPropertyServerKey3,
PropertyConverter::CreateAcceptAnyValueCallback());
+ converter->RegisterWindowPtrProperty(kTestPropertyKey4,
+ kTestPropertyServerKey4);
}
// Convert a primitive aura property value to a mus transport value.
@@ -269,11 +274,8 @@ TEST_F(WindowTreeClientTest, SetBoundsFailed) {
// reverted if the server replied that the change failed.
TEST_F(WindowTreeClientTest, SetBoundsFailedLocalSurfaceId) {
Window window(nullptr);
- // TOP_LEVEL_IN_WM and EMBED_IN_OWNER windows allocate viz::LocalSurfaceIds
- // when their sizes change.
- window.SetProperty(aura::client::kEmbedType,
- aura::client::WindowEmbedType::EMBED_IN_OWNER);
window.Init(ui::LAYER_NOT_DRAWN);
+ WindowPortMusTestHelper(&window).SimulateEmbedding();
const gfx::Rect original_bounds(window.bounds());
const gfx::Rect new_bounds(gfx::Rect(0, 0, 100, 100));
@@ -295,111 +297,29 @@ INSTANTIATE_TEST_CASE_P(/* no prefix */,
WindowTreeClientTestSurfaceSync,
::testing::Bool());
-namespace {
-
-class FirstSurfaceActivationWindowDelegate : public test::TestWindowDelegate {
- public:
- FirstSurfaceActivationWindowDelegate() = default;
- ~FirstSurfaceActivationWindowDelegate() override = default;
-
- const viz::SurfaceInfo& last_surface_info() const {
- return last_surface_info_;
- }
-
- void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override {
- last_surface_info_ = surface_info;
- }
-
- private:
- viz::SurfaceInfo last_surface_info_;
-
- DISALLOW_COPY_AND_ASSIGN(FirstSurfaceActivationWindowDelegate);
-};
-
-} // namespace
-
-// Verifies that a ClientSurfaceEmbedder is created for a window once it has
-// a bounds, and a valid FrameSinkId.
-TEST_P(WindowTreeClientTestSurfaceSync, ClientSurfaceEmbedderOnValidEmbedding) {
- FirstSurfaceActivationWindowDelegate delegate;
- Window window(&delegate);
- // EMBED_IN_OWNER windows allocate viz::LocalSurfaceIds when their sizes
- // change.
- window.SetProperty(aura::client::kEmbedType,
- aura::client::WindowEmbedType::EMBED_IN_OWNER);
+// Verifies that windows with an embedding create a ClientSurfaceEmbedder.
+TEST_P(WindowTreeClientTestSurfaceSync, ClientSurfaceEmbedderCreated) {
+ Window window(nullptr);
window.Init(ui::LAYER_NOT_DRAWN);
+ WindowPortMusTestHelper(&window).SimulateEmbedding();
// The window will allocate a viz::LocalSurfaceId once it has a bounds.
- WindowMus* window_mus = WindowMus::Get(&window);
- ASSERT_NE(nullptr, window_mus);
- EXPECT_FALSE(window_mus->GetLocalSurfaceId().is_valid());
- gfx::Rect new_bounds(gfx::Rect(0, 0, 100, 100));
- ASSERT_NE(new_bounds, window.bounds());
- window.SetBounds(new_bounds);
- EXPECT_EQ(new_bounds, window.bounds());
- EXPECT_TRUE(window_mus->GetLocalSurfaceId().is_valid());
-
- // An ClientSurfaceEmbedder isn't created UNTIL the window has a bounds and
- // a valid FrameSinkId.
WindowPortMus* window_port_mus = WindowPortMus::Get(&window);
ASSERT_NE(nullptr, window_port_mus);
+ EXPECT_FALSE(WindowMus::Get(&window)->GetLocalSurfaceId().is_valid());
+ // A ClientSurfaceEmbedder is only created once there is bounds and a
+ // FrameSinkId.
EXPECT_EQ(nullptr, window_port_mus->client_surface_embedder());
-
- // Now that the window has a valid FrameSinkId, it can embed the client in a
- // CompositorFrame.
- window_tree_client()->OnFrameSinkIdAllocated(server_id(&window),
- viz::FrameSinkId(1, 1));
- ClientSurfaceEmbedder* client_surface_embedder =
- window_port_mus->client_surface_embedder();
- ASSERT_NE(nullptr, client_surface_embedder);
- EXPECT_FALSE(delegate.last_surface_info().is_valid());
-
- // When a SurfaceInfo arrives from the window server, we use it as the
- // fallback SurfaceInfo. Here we issue the primary SurfaceId back to the
- // client lib. This should cause the gutter to go away, eliminating overdraw.
- window_tree_client()->OnWindowSurfaceChanged(
- server_id(&window),
- viz::SurfaceInfo(window_port_mus->PrimarySurfaceIdForTesting(), 1.0f,
- gfx::Size(100, 100)));
- EXPECT_TRUE(delegate.last_surface_info().is_valid());
- EXPECT_EQ(delegate.last_surface_info().id(),
- window_port_mus->PrimarySurfaceIdForTesting());
-}
-
-// Verifies that EMBED_IN_OWNER windows do not gutter.
-TEST_P(WindowTreeClientTestSurfaceSync, NoEmbedInOwnerGutter) {
- FirstSurfaceActivationWindowDelegate delegate;
- Window window(&delegate);
- // TOP_LEVEL_IN_WM and EMBED_IN_OWNER windows allocate viz::LocalSurfaceIds
- // when their sizes change.
- window.SetProperty(aura::client::kEmbedType,
- aura::client::WindowEmbedType::EMBED_IN_OWNER);
- window.Init(ui::LAYER_NOT_DRAWN);
-
- // The window will allocate a viz::LocalSurfaceId once it has a bounds.
- WindowMus* window_mus = WindowMus::Get(&window);
- ASSERT_NE(nullptr, window_mus);
- EXPECT_FALSE(window_mus->GetLocalSurfaceId().is_valid());
gfx::Rect new_bounds(gfx::Rect(0, 0, 100, 100));
ASSERT_NE(new_bounds, window.bounds());
window.SetBounds(new_bounds);
EXPECT_EQ(new_bounds, window.bounds());
- EXPECT_TRUE(window_mus->GetLocalSurfaceId().is_valid());
+ EXPECT_TRUE(WindowMus::Get(&window)->GetLocalSurfaceId().is_valid());
- // An ClientSurfaceEmbedder isn't created UNTIL the window has a bounds and
- // a valid FrameSinkId.
- WindowPortMus* window_port_mus = WindowPortMus::Get(&window);
- ASSERT_NE(nullptr, window_port_mus);
- EXPECT_EQ(nullptr, window_port_mus->client_surface_embedder());
-
- // Now that the window has a valid FrameSinkId, it can embed the client in a
- // CompositorFrame.
- window_tree_client()->OnFrameSinkIdAllocated(server_id(&window),
- viz::FrameSinkId(1, 1));
+ // Once the bounds have been set, the ClientSurfaceEmbedder should be created.
ClientSurfaceEmbedder* client_surface_embedder =
window_port_mus->client_surface_embedder();
ASSERT_NE(nullptr, client_surface_embedder);
- EXPECT_FALSE(delegate.last_surface_info().is_valid());
EXPECT_EQ(nullptr, client_surface_embedder->BottomGutterForTesting());
EXPECT_EQ(nullptr, client_surface_embedder->RightGutterForTesting());
@@ -410,11 +330,8 @@ TEST_P(WindowTreeClientTestSurfaceSync, NoEmbedInOwnerGutter) {
TEST_P(WindowTreeClientTestSurfaceSync, SetBoundsLocalSurfaceIdChanges) {
ASSERT_EQ(base::nullopt, window_tree()->last_local_surface_id());
Window window(nullptr);
- // TOP_LEVEL_IN_WM and EMBED_IN_OWNER windows allocate viz::LocalSurfaceIds
- // when their sizes change.
- window.SetProperty(aura::client::kEmbedType,
- aura::client::WindowEmbedType::EMBED_IN_OWNER);
window.Init(ui::LAYER_NOT_DRAWN);
+ WindowPortMusTestHelper(&window).SimulateEmbedding();
// Resize the window and verify that we've allocated a viz::LocalSurfaceId.
const gfx::Rect new_bounds(0, 0, 100, 100);
@@ -800,6 +717,26 @@ TEST_F(WindowTreeClientTest, SetStringProperty) {
EXPECT_EQ(example, *root_window()->GetProperty(client::kNameKey));
}
+TEST_F(WindowTreeClientTest, SetWindowPointerProperty) {
+ PropertyConverter* property_converter = GetPropertyConverter();
+ RegisterTestProperties(property_converter);
+
+ Window window(nullptr);
+ window.Init(ui::LAYER_NOT_DRAWN);
+ window.Show();
+ root_window()->SetProperty(kTestPropertyKey4, &window);
+ base::Optional<std::vector<uint8_t>> value =
+ window_tree()->GetLastPropertyValue();
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(WindowMus::Get(&window)->server_id(),
+ mojo::ConvertTo<ws::Id>(*value));
+ window_tree()->AckAllChanges();
+
+ root_window()->ClearProperty(kTestPropertyKey4);
+ value = window_tree()->GetLastPropertyValue();
+ EXPECT_FALSE(value.has_value());
+}
+
// Verifies visible is reverted if the server replied that the change failed.
TEST_F(WindowTreeClientTest, SetVisibleFailed) {
const bool original_visible = root_window()->TargetVisibility();
@@ -1010,13 +947,13 @@ TEST_F(WindowTreeClientTest, InputEventPointerEvent) {
const gfx::Point event_location(2, 3);
const uint32_t event_id = 1;
window_delegate.set_event_id(event_id);
- ui::PointerEvent pointer_event(
- ui::ET_POINTER_MOVED, event_location, gfx::Point(), ui::EF_NONE, 0,
- ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, 0),
- base::TimeTicks());
+ ui::MouseEvent mouse_event(
+ ui::ET_MOUSE_MOVED, event_location, event_location, ui::EventTimeForNow(),
+ ui::EF_NONE, ui::EF_NONE,
+ ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, 0));
window_tree_client()->OnWindowInputEvent(event_id, server_id(&child),
window_tree_host.display_id(),
- ui::Event::Clone(pointer_event), 0);
+ ui::Event::Clone(mouse_event), 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
EXPECT_EQ(ws::mojom::EventResult::HANDLED,
window_tree()->GetEventResult(event_id));
@@ -1046,13 +983,13 @@ TEST_F(WindowTreeClientTest, InputEventPen) {
const gfx::Point event_location(2, 3);
const uint32_t event_id = 1;
window_delegate.set_event_id(event_id);
- ui::PointerEvent pointer_event(
- ui::ET_POINTER_DOWN, event_location, gfx::Point(), ui::EF_NONE, 0,
- ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_PEN, 0),
- ui::EventTimeForNow());
+ ui::MouseEvent mouse_event(
+ ui::ET_MOUSE_PRESSED, event_location, event_location,
+ ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE,
+ ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_PEN, 0));
window_tree_client()->OnWindowInputEvent(event_id, server_id(&child),
window_tree_host.display_id(),
- ui::Event::Clone(pointer_event), 0);
+ ui::Event::Clone(mouse_event), 0);
// Pen event was handled.
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
@@ -1346,14 +1283,13 @@ TEST_F(WindowTreeClientTest, InputMouseEventNoWindow) {
const gfx::Point event_location(2, 3);
uint32_t event_id = 1;
window_delegate.set_event_id(event_id);
- ui::PointerEvent pointer_event_down(
- ui::ET_POINTER_DOWN, event_location, event_location,
- ui::EF_LEFT_MOUSE_BUTTON, 0,
- ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, 0),
- ui::EventTimeForNow());
+ ui::MouseEvent mouse_event_down(
+ ui::ET_MOUSE_PRESSED, event_location, event_location,
+ ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0,
+ ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, 0));
window_tree_client()->OnWindowInputEvent(
event_id, server_id(&child), window_tree_host.display_id(),
- ui::Event::Clone(pointer_event_down), 0);
+ ui::Event::Clone(mouse_event_down), 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
EXPECT_EQ(ws::mojom::EventResult::HANDLED,
window_tree()->GetEventResult(event_id));
@@ -1366,14 +1302,13 @@ TEST_F(WindowTreeClientTest, InputMouseEventNoWindow) {
const gfx::Point event_location1(4, 5);
event_id = 2;
window_delegate.set_event_id(event_id);
- ui::PointerEvent pointer_event_up(
- ui::ET_POINTER_UP, event_location1, event_location,
- ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON,
- ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, 0),
- ui::EventTimeForNow());
- window_tree_client()->OnWindowInputEvent(
- event_id, kInvalidServerId, window_tree_host.display_id(),
- ui::Event::Clone(pointer_event_up), 0);
+ ui::MouseEvent mouse_event_up(
+ ui::ET_MOUSE_RELEASED, event_location1, event_location,
+ ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON,
+ ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, 0));
+ window_tree_client()->OnWindowInputEvent(event_id, kInvalidServerId,
+ window_tree_host.display_id(),
+ ui::Event::Clone(mouse_event_up), 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
// WindowTreeClient::OnWindowInputEvent cannot find a target window with
// kInvalidServerId but should use the event to update event states kept in
@@ -1410,13 +1345,12 @@ TEST_F(WindowTreeClientTest, InputTouchEventNoWindow) {
const gfx::Point event_location(2, 3);
uint32_t event_id = 1;
window_delegate.set_event_id(event_id);
- ui::PointerEvent pointer_event_down(
- ui::ET_POINTER_DOWN, event_location, gfx::Point(), 0, 0,
- ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0),
- ui::EventTimeForNow());
+ ui::TouchEvent touch_event_down(
+ ui::ET_TOUCH_PRESSED, event_location, ui::EventTimeForNow(),
+ ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
window_tree_client()->OnWindowInputEvent(
event_id, server_id(&child), window_tree_host.display_id(),
- ui::Event::Clone(pointer_event_down), 0);
+ ui::Event::Clone(touch_event_down), 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
EXPECT_EQ(ws::mojom::EventResult::HANDLED,
window_tree()->GetEventResult(event_id));
@@ -1426,13 +1360,12 @@ TEST_F(WindowTreeClientTest, InputTouchEventNoWindow) {
event_id = 2;
window_delegate.set_event_id(event_id);
- ui::PointerEvent pointer_event_up(
- ui::ET_POINTER_UP, event_location, gfx::Point(), 0, 0,
- ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0),
- ui::EventTimeForNow());
- window_tree_client()->OnWindowInputEvent(
- event_id, kInvalidServerId, window_tree_host.display_id(),
- ui::Event::Clone(pointer_event_up), 0);
+ ui::TouchEvent touch_event_up(
+ ui::ET_TOUCH_RELEASED, event_location, ui::EventTimeForNow(),
+ ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
+ window_tree_client()->OnWindowInputEvent(event_id, kInvalidServerId,
+ window_tree_host.display_id(),
+ ui::Event::Clone(touch_event_up), 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
// WindowTreeClient::OnWindowInputEvent cannot find a target window with
// kInvalidServerId but should use the event to update event states kept in
@@ -1543,12 +1476,12 @@ TEST_F(WindowTreeClientPointerObserverTest,
window_tree_client_impl()->StartPointerWatcher(false /* want_moves */);
// Simulate the server dispatching an event that also matched the observer.
- std::unique_ptr<ui::PointerEvent> pointer_event_down(new ui::PointerEvent(
- ui::ET_POINTER_DOWN, gfx::Point(), gfx::Point(), ui::EF_CONTROL_DOWN, 0,
+ ui::TouchEvent touch_event_down(
+ ui::ET_TOUCH_PRESSED, gfx::Point(), ui::EventTimeForNow(),
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1),
- base::TimeTicks::Now()));
- window_tree_client()->OnWindowInputEvent(1, server_id(top_level), 0,
- std::move(pointer_event_down), true);
+ ui::EF_CONTROL_DOWN);
+ window_tree_client()->OnWindowInputEvent(
+ 1, server_id(top_level), 0, ui::Event::Clone(touch_event_down), true);
// Delegate sensed the event.
const ui::Event* last_event = last_event_observed();
diff --git a/chromium/ui/aura/mus/window_tree_host_mus.cc b/chromium/ui/aura/mus/window_tree_host_mus.cc
index 4714427d756..47ff9645626 100644
--- a/chromium/ui/aura/mus/window_tree_host_mus.cc
+++ b/chromium/ui/aura/mus/window_tree_host_mus.cc
@@ -146,10 +146,6 @@ void WindowTreeHostMus::StackAtTop() {
delegate_->OnWindowTreeHostStackAtTop(this);
}
-void WindowTreeHostMus::PerformWmAction(const std::string& action) {
- delegate_->OnWindowTreeHostPerformWmAction(this, action);
-}
-
void WindowTreeHostMus::PerformWindowMove(
ws::mojom::MoveLoopSource mus_source,
const gfx::Point& cursor_location,
diff --git a/chromium/ui/aura/mus/window_tree_host_mus.h b/chromium/ui/aura/mus/window_tree_host_mus.h
index c023265a716..eaafd008187 100644
--- a/chromium/ui/aura/mus/window_tree_host_mus.h
+++ b/chromium/ui/aura/mus/window_tree_host_mus.h
@@ -68,9 +68,6 @@ class AURA_EXPORT WindowTreeHostMus : public WindowTreeHostPlatform,
// windows which we might not own.
void StackAtTop();
- // Requests that the window manager perform |action| on the window.
- void PerformWmAction(const std::string& action);
-
// Tells the window manager to take control of moving the window. Returns
// true if the move wasn't canceled.
void PerformWindowMove(ws::mojom::MoveLoopSource mus_source,
diff --git a/chromium/ui/aura/mus/window_tree_host_mus_delegate.h b/chromium/ui/aura/mus/window_tree_host_mus_delegate.h
index 636d7018f35..0c17643cca5 100644
--- a/chromium/ui/aura/mus/window_tree_host_mus_delegate.h
+++ b/chromium/ui/aura/mus/window_tree_host_mus_delegate.h
@@ -54,11 +54,6 @@ class AURA_EXPORT WindowTreeHostMusDelegate {
virtual void OnWindowTreeHostStackAtTop(
WindowTreeHostMus* window_tree_host) = 0;
- // Called to signal to the window manager to take an action.
- virtual void OnWindowTreeHostPerformWmAction(
- WindowTreeHostMus* window_tree_host,
- const std::string& action) = 0;
-
// Called to start a move loop, where the window manager will take over
// moving a window during a drag.
virtual void OnWindowTreeHostPerformWindowMove(
diff --git a/chromium/ui/aura/mus/window_tree_host_mus_unittest.cc b/chromium/ui/aura/mus/window_tree_host_mus_unittest.cc
index 39a7302ed1d..90c5bc823a2 100644
--- a/chromium/ui/aura/mus/window_tree_host_mus_unittest.cc
+++ b/chromium/ui/aura/mus/window_tree_host_mus_unittest.cc
@@ -23,30 +23,4 @@ TEST_F(WindowTreeHostMusTest, UpdateClientArea) {
EXPECT_EQ(new_insets, window_tree()->last_client_area());
}
-TEST_F(WindowTreeHostMusTest, SetHitTestMask) {
- std::unique_ptr<WindowTreeHostMus> window_tree_host_mus =
- std::make_unique<WindowTreeHostMus>(
- CreateInitParamsForTopLevel(window_tree_client_impl()));
-
- EXPECT_FALSE(window_tree()->last_hit_test_mask().has_value());
- gfx::Rect mask(10, 10, 10, 10);
- WindowPortMus::Get(window_tree_host_mus->window())->SetHitTestMask(mask);
- ASSERT_TRUE(window_tree()->last_hit_test_mask().has_value());
- EXPECT_EQ(mask, window_tree()->last_hit_test_mask());
-
- WindowPortMus::Get(window_tree_host_mus->window())
- ->SetHitTestMask(base::nullopt);
- ASSERT_FALSE(window_tree()->last_hit_test_mask().has_value());
-}
-
-TEST_F(WindowTreeHostMusTest, PerformWmAction) {
- std::unique_ptr<WindowTreeHostMus> window_tree_host_mus =
- std::make_unique<WindowTreeHostMus>(
- CreateInitParamsForTopLevel(window_tree_client_impl()));
-
- const std::string test_action("test-action");
- window_tree_host_mus->PerformWmAction(test_action);
- EXPECT_EQ(test_action, window_tree()->last_wm_action());
-}
-
} // namespace aura
diff --git a/chromium/ui/aura/screen_ozone.h b/chromium/ui/aura/screen_ozone.h
index 132ea591702..7c26999f515 100644
--- a/chromium/ui/aura/screen_ozone.h
+++ b/chromium/ui/aura/screen_ozone.h
@@ -5,6 +5,8 @@
#ifndef UI_AURA_SCREEN_OZONE_H_
#define UI_AURA_SCREEN_OZONE_H_
+#include <memory>
+
#include "base/macros.h"
#include "ui/aura/aura_export.h"
#include "ui/display/screen.h"
diff --git a/chromium/ui/aura/test/ui_controls_factory_ozone.cc b/chromium/ui/aura/test/ui_controls_factory_ozone.cc
index 8538cfb0893..24ef109d467 100644
--- a/chromium/ui/aura/test/ui_controls_factory_ozone.cc
+++ b/chromium/ui/aura/test/ui_controls_factory_ozone.cc
@@ -6,12 +6,12 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/ws/public/mojom/constants.mojom.h"
#include "services/ws/public/mojom/event_injector.mojom.h"
-#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/env.h"
#include "ui/aura/mus/window_tree_client.h"
#include "ui/aura/test/aura_test_utils.h"
@@ -19,6 +19,8 @@
#include "ui/aura/test/ui_controls_factory_aura.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/test/ui_controls_aura.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
#include "ui/events/event_utils.h"
#include "ui/events/test/events_test_utils.h"
@@ -122,16 +124,19 @@ class UIControlsOzone : public ui_controls::UIControlsAura {
bool SendMouseMoveNotifyWhenDone(long screen_x,
long screen_y,
base::OnceClosure closure) override {
- gfx::Point root_location(screen_x, screen_y);
- aura::client::ScreenPositionClient* screen_position_client =
- aura::client::GetScreenPositionClient(host_->window());
- if (screen_position_client) {
- screen_position_client->ConvertPointFromScreen(host_->window(),
- &root_location);
+ // The location needs to be in display's coordinate.
+ gfx::Point display_location(screen_x, screen_y);
+ display::Display display;
+ if (!display::Screen::GetScreen()->GetDisplayWithDisplayId(
+ host_->GetDisplayId(), &display)) {
+ LOG(ERROR) << "Failed to see the display for " << host_->GetDisplayId();
+ return false;
}
+ display_location -= display.bounds().OffsetFromOrigin();
- gfx::Point host_location = root_location;
+ gfx::Point host_location = display_location;
host_->ConvertDIPToPixels(&host_location);
+ last_mouse_location_ = host_location;
ui::EventType event_type;
@@ -155,16 +160,24 @@ class UIControlsOzone : public ui_controls::UIControlsAura {
int button_state,
base::OnceClosure closure,
int accelerator_state) override {
- gfx::Point root_location = host_->window()->env()->last_mouse_location();
- aura::client::ScreenPositionClient* screen_position_client =
- aura::client::GetScreenPositionClient(host_->window());
- if (screen_position_client) {
- screen_position_client->ConvertPointFromScreen(host_->window(),
- &root_location);
- }
+ gfx::Point host_location;
+ if (last_mouse_location_.has_value()) {
+ host_location = last_mouse_location_.value();
+ } else {
+ // The location needs to be in display's coordinate.
+ gfx::Point display_location =
+ host_->window()->env()->last_mouse_location();
+ display::Display display;
+ if (!display::Screen::GetScreen()->GetDisplayWithDisplayId(
+ host_->GetDisplayId(), &display)) {
+ LOG(ERROR) << "Failed to see the display for " << host_->GetDisplayId();
+ return false;
+ }
+ display_location -= display.bounds().OffsetFromOrigin();
- gfx::Point host_location = root_location;
- host_->ConvertDIPToPixels(&host_location);
+ host_location = display_location;
+ host_->ConvertDIPToPixels(&host_location);
+ }
int changed_button_flag = 0;
@@ -219,18 +232,8 @@ class UIControlsOzone : public ui_controls::UIControlsAura {
private:
void SendEventToSink(ui::Event* event, base::OnceClosure closure) {
if (host_->window()->env()->mode() == aura::Env::Mode::MUS) {
- std::unique_ptr<ui::Event> event_to_send;
- if (event->IsMouseEvent()) {
- // WindowService expects MouseEvents as PointerEvents.
- // See http://crbug.com/617222.
- event_to_send =
- std::make_unique<ui::PointerEvent>(*event->AsMouseEvent());
- } else {
- event_to_send = ui::Event::Clone(*event);
- }
-
GetEventInjector()->InjectEvent(
- host_->GetDisplayId(), std::move(event_to_send),
+ host_->GetDisplayId(), ui::Event::Clone(*event),
base::BindOnce(&OnWindowServiceProcessedEvent, std::move(closure)));
return;
}
@@ -311,6 +314,11 @@ class UIControlsOzone : public ui_controls::UIControlsAura {
WindowTreeHost* host_;
ws::mojom::EventInjectorPtr event_injector_;
+ // The mouse location for the last SendMouseEventsNotifyWhenDone call. This is
+ // used rather than Env::last_mouse_location() as Env::last_mouse_location()
+ // is updated asynchronously with mus.
+ base::Optional<gfx::Point> last_mouse_location_;
+
// Mask of the mouse buttons currently down. This is static as it needs to
// track the state globally for all displays. A UIControlsOzone instance is
// created for each display host.
diff --git a/chromium/ui/aura/window.cc b/chromium/ui/aura/window.cc
index 3ebec72c8db..18829840094 100644
--- a/chromium/ui/aura/window.cc
+++ b/chromium/ui/aura/window.cc
@@ -92,7 +92,7 @@ Window::Window(WindowDelegate* delegate,
}
Window::~Window() {
- WindowOcclusionTracker::ScopedPauseOcclusionTracking pause_occlusion_tracking;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking(env_);
if (layer()->owner() == this)
layer()->CompleteAllAnimations();
@@ -160,7 +160,7 @@ Window::~Window() {
}
void Window::Init(ui::LayerType layer_type) {
- WindowOcclusionTracker::ScopedPauseOcclusionTracking pause_occlusion_tracking;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking(env_);
if (!port_owner_) {
port_owner_ = env_->CreateWindowPort(this);
@@ -285,7 +285,7 @@ gfx::Rect Window::GetBoundsInScreen() const {
}
void Window::SetTransform(const gfx::Transform& transform) {
- WindowOcclusionTracker::ScopedPauseOcclusionTracking pause_occlusion_tracking;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking(env_);
for (WindowObserver& observer : observers_)
observer.OnWindowTargetTransformChanging(this, transform);
layer()->SetTransform(transform);
@@ -308,7 +308,11 @@ void Window::SetLayoutManager(LayoutManager* layout_manager) {
std::unique_ptr<WindowTargeter> Window::SetEventTargeter(
std::unique_ptr<WindowTargeter> targeter) {
std::unique_ptr<WindowTargeter> old_targeter = std::move(targeter_);
+ if (old_targeter)
+ old_targeter->OnInstalled(nullptr);
targeter_ = std::move(targeter);
+ if (targeter_)
+ targeter_->OnInstalled(this);
return old_targeter;
}
@@ -369,7 +373,7 @@ void Window::StackChildBelow(Window* child, Window* target) {
}
void Window::AddChild(Window* child) {
- WindowOcclusionTracker::ScopedPauseOcclusionTracking pause_occlusion_tracking;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking(env_);
DCHECK(layer()) << "Parent has not been Init()ed yet.";
DCHECK(child->layer()) << "Child has not been Init()ed yt.";
@@ -411,7 +415,7 @@ void Window::AddChild(Window* child) {
}
void Window::RemoveChild(Window* child) {
- WindowOcclusionTracker::ScopedPauseOcclusionTracking pause_occlusion_tracking;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking(env_);
WindowObserver::HierarchyChangeParams params;
params.target = child;
@@ -547,6 +551,20 @@ bool Window::HasObserver(const WindowObserver* observer) const {
}
void Window::SetEventTargetingPolicy(ws::mojom::EventTargetingPolicy policy) {
+#if DCHECK_IS_ON()
+ const bool old_window_accepts_events =
+ (event_targeting_policy_ ==
+ ws::mojom::EventTargetingPolicy::TARGET_ONLY) ||
+ (event_targeting_policy_ ==
+ ws::mojom::EventTargetingPolicy::TARGET_AND_DESCENDANTS);
+ const bool new_window_accepts_events =
+ (policy == ws::mojom::EventTargetingPolicy::TARGET_ONLY) ||
+ (policy == ws::mojom::EventTargetingPolicy::TARGET_AND_DESCENDANTS);
+ if (new_window_accepts_events != old_window_accepts_events) {
+ DCHECK(!created_layer_tree_frame_sink_);
+ }
+#endif
+
if (event_targeting_policy_ == policy)
return;
@@ -833,7 +851,7 @@ void Window::SetVisible(bool visible) {
if (visible == layer()->GetTargetVisibility())
return; // No change.
- WindowOcclusionTracker::ScopedPauseOcclusionTracking pause_occlusion_tracking;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking(env_);
for (WindowObserver& observer : observers_)
observer.OnWindowVisibilityChanging(this, visible);
@@ -886,7 +904,7 @@ void Window::RemoveChildImpl(Window* child, Window* new_parent) {
if (child->OwnsLayer())
layer()->Remove(child->layer());
child->parent_ = NULL;
- Windows::iterator i = std::find(children_.begin(), children_.end(), child);
+ auto i = std::find(children_.begin(), children_.end(), child);
DCHECK(i != children_.end());
children_.erase(i);
child->OnParentChanged();
@@ -908,7 +926,7 @@ void Window::StackChildRelativeTo(Window* child,
DCHECK_EQ(this, child->parent());
DCHECK_EQ(this, target->parent());
- WindowOcclusionTracker::ScopedPauseOcclusionTracking pause_occlusion_tracking;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking(env_);
client::WindowStackingClient* stacking_client =
client::GetWindowStackingClient();
@@ -1074,9 +1092,7 @@ bool Window::CleanupGestureState() {
bool state_modified = false;
state_modified |= env_->gesture_recognizer()->CancelActiveTouches(this);
state_modified |= env_->gesture_recognizer()->CleanupStateForConsumer(this);
- for (Window::Windows::iterator iter = children_.begin();
- iter != children_.end();
- ++iter) {
+ for (auto iter = children_.begin(); iter != children_.end(); ++iter) {
state_modified |= (*iter)->CleanupGestureState();
}
return state_modified;
@@ -1087,6 +1103,7 @@ std::unique_ptr<cc::LayerTreeFrameSink> Window::CreateLayerTreeFrameSink() {
DCHECK(frame_sink_id_.is_valid());
DCHECK(embeds_external_client_);
DCHECK(GetLocalSurfaceId().is_valid());
+ created_layer_tree_frame_sink_ = true;
return sink;
}
@@ -1133,6 +1150,8 @@ const viz::FrameSinkId& Window::GetFrameSinkId() const {
}
void Window::SetEmbedFrameSinkId(const viz::FrameSinkId& frame_sink_id) {
+ UnregisterFrameSinkId();
+
DCHECK(frame_sink_id.is_valid());
frame_sink_id_ = frame_sink_id;
embeds_external_client_ = true;
@@ -1143,6 +1162,10 @@ bool Window::IsEmbeddingClient() const {
return embeds_external_client_;
}
+void Window::TrackOcclusionState() {
+ env_->GetWindowOcclusionTracker()->Track(this);
+}
+
bool Window::RequiresDoubleTapGestureEvents() const {
return delegate_ && delegate_->RequiresDoubleTapGestureEvents();
}
@@ -1160,7 +1183,7 @@ void Window::OnPaintLayer(const ui::PaintContext& context) {
void Window::OnLayerBoundsChanged(const gfx::Rect& old_bounds,
ui::PropertyChangeReason reason) {
- WindowOcclusionTracker::ScopedPauseOcclusionTracking pause_occlusion_tracking;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking(env_);
bounds_ = layer()->bounds();
@@ -1177,13 +1200,13 @@ void Window::OnLayerBoundsChanged(const gfx::Rect& old_bounds,
}
void Window::OnLayerOpacityChanged(ui::PropertyChangeReason reason) {
- WindowOcclusionTracker::ScopedPauseOcclusionTracking pause_occlusion_tracking;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking(env_);
for (WindowObserver& observer : observers_)
observer.OnWindowOpacitySet(this, reason);
}
void Window::OnLayerAlphaShapeChanged() {
- WindowOcclusionTracker::ScopedPauseOcclusionTracking pause_occlusion_tracking;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking(env_);
for (WindowObserver& observer : observers_)
observer.OnWindowAlphaShapeSet(this);
}
@@ -1191,7 +1214,7 @@ void Window::OnLayerAlphaShapeChanged() {
void Window::OnLayerTransformed(const gfx::Transform& old_transform,
ui::PropertyChangeReason reason) {
port_->OnDidChangeTransform(old_transform, layer()->transform());
- WindowOcclusionTracker::ScopedPauseOcclusionTracking pause_occlusion_tracking;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking(env_);
for (WindowObserver& observer : observers_)
observer.OnWindowTransformed(this, reason);
}
@@ -1246,8 +1269,18 @@ void Window::ConvertEventToTarget(ui::EventTarget* target,
static_cast<Window*>(target));
}
+gfx::PointF Window::GetScreenLocationF(const ui::LocatedEvent& event) const {
+ DCHECK_EQ(this, event.target());
+ gfx::PointF screen_location(event.root_location_f());
+ const Window* root = GetRootWindow();
+ auto* screen_position_client = aura::client::GetScreenPositionClient(root);
+ if (screen_position_client)
+ screen_position_client->ConvertPointToScreen(root, &screen_location);
+ return screen_location;
+}
+
std::unique_ptr<ui::Layer> Window::RecreateLayer() {
- WindowOcclusionTracker::ScopedPauseOcclusionTracking pause_occlusion_tracking;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking(env_);
ui::LayerAnimator* const animator = layer()->GetAnimator();
const bool was_animating_opacity =
@@ -1307,6 +1340,7 @@ void Window::RegisterFrameSinkId() {
if (auto* compositor = layer()->GetCompositor()) {
compositor->AddChildFrameSink(frame_sink_id_);
registered_frame_sink_id_ = true;
+ port_->RegisterFrameSinkId(frame_sink_id_);
}
}
@@ -1314,6 +1348,7 @@ void Window::UnregisterFrameSinkId() {
if (!registered_frame_sink_id_)
return;
registered_frame_sink_id_ = false;
+ port_->UnregisterFrameSinkId(frame_sink_id_);
if (auto* compositor = layer()->GetCompositor())
compositor->RemoveChildFrameSink(frame_sink_id_);
}
diff --git a/chromium/ui/aura/window.h b/chromium/ui/aura/window.h
index 18a6a3601e6..6175dcd10ba 100644
--- a/chromium/ui/aura/window.h
+++ b/chromium/ui/aura/window.h
@@ -95,8 +95,8 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
STACK_BELOW
};
enum class OcclusionState {
- // The window's occlusion state isn't tracked
- // (WindowOcclusionTracker::Track) or hasn't been computed yet.
+ // The window's occlusion state isn't tracked (Window::TrackOcclusionState)
+ // or hasn't been computed yet.
UNKNOWN,
// The window or one of its descendants IsVisible() [1] and:
// - Its bounds aren't completely covered by fully opaque windows [2], or,
@@ -194,9 +194,9 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
// whether Show() without a Hide() has been invoked.
bool TargetVisibility() const { return visible_; }
// Returns the occlusion state of this window. Is UNKNOWN if the occlusion
- // state of this window isn't tracked (WindowOcclusionTracker::Track) or
+ // state of this window isn't tracked (Window::TrackOcclusionState) or
// hasn't been computed yet. Is stale if called within the scope of a
- // WindowOcclusionTracker::ScopedPauseOcclusionTracking.
+ // WindowOcclusionTracker::ScopedPause.
OcclusionState occlusion_state() const { return occlusion_state_; }
// Returns the window's bounds in root window's coordinates.
@@ -221,6 +221,7 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
std::unique_ptr<WindowTargeter> SetEventTargeter(
std::unique_ptr<WindowTargeter> targeter);
WindowTargeter* targeter() { return targeter_.get(); }
+ const WindowTargeter* targeter() const { return targeter_.get(); }
// Changes the bounds of the window. If present, the window's parent's
// LayoutManager may adjust the bounds.
@@ -430,6 +431,9 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
// Returns whether this window is embedding another client.
bool IsEmbeddingClient() const;
+ // Starts occlusion state tracking.
+ void TrackOcclusionState();
+
Env* env() { return env_; }
const Env* env() const { return env_; }
@@ -558,6 +562,7 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
ui::EventTargeter* GetEventTargeter() override;
void ConvertEventToTarget(ui::EventTarget* target,
ui::LocatedEvent* event) override;
+ gfx::PointF GetScreenLocationF(const ui::LocatedEvent& event) const override;
// Updates the layer name based on the window's name and id.
void UpdateLayerName();
@@ -572,6 +577,8 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
bool registered_frame_sink_id_ = false;
bool disable_frame_sink_id_registration_ = false;
+ bool created_layer_tree_frame_sink_ = false;
+
// Window owns its corresponding WindowPort, but the ref is held as a raw
// pointer in |port_| so that it can still be accessed during destruction.
// This is important as deleting the WindowPort may result in trying to lookup
diff --git a/chromium/ui/aura/window_delegate.h b/chromium/ui/aura/window_delegate.h
index fae8ea9c7ee..7911cb92df7 100644
--- a/chromium/ui/aura/window_delegate.h
+++ b/chromium/ui/aura/window_delegate.h
@@ -24,10 +24,6 @@ namespace ui {
class PaintContext;
}
-namespace viz {
-class SurfaceInfo;
-}
-
namespace aura {
// Delegate interface for aura::Window.
@@ -106,10 +102,6 @@ class AURA_EXPORT WindowDelegate : public ui::EventHandler {
// above returns true.
virtual void GetHitTestMask(gfx::Path* mask) const = 0;
- // Called when a child submits a CompositorFrame to a surface with the given
- // |surface_info| for the first time.
- virtual void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) {}
-
// Returns whether the window wants to receive and handle double tap gesture
// events. Defaults to false.
virtual bool RequiresDoubleTapGestureEvents() const;
diff --git a/chromium/ui/aura/window_event_dispatcher.cc b/chromium/ui/aura/window_event_dispatcher.cc
index b5ce6203d1a..f6ea825d7e2 100644
--- a/chromium/ui/aura/window_event_dispatcher.cc
+++ b/chromium/ui/aura/window_event_dispatcher.cc
@@ -836,15 +836,19 @@ ui::EventDispatchDetails WindowEventDispatcher::DispatchHeldEvents() {
}
if (held_move_event_) {
+ // |held_move_event_| should be cleared here. Some event handler can
+ // create its own run loop on an event (e.g. WindowMove loop for
+ // tab-dragging), which means the other move events need to be processed
+ // before this OnEventFromSource() finishes. See also b/119260190.
+ std::unique_ptr<ui::LocatedEvent> event = std::move(held_move_event_);
+
// If a mouse move has been synthesized, the target location is suspect,
// so drop the held mouse event.
- if (held_move_event_->IsTouchEvent() ||
- (held_move_event_->IsMouseEvent() && !synthesize_mouse_move_)) {
- dispatching_held_event_ = held_move_event_.get();
- dispatch_details = OnEventFromSource(held_move_event_.get());
+ if (event->IsTouchEvent() ||
+ (event->IsMouseEvent() && !synthesize_mouse_move_)) {
+ dispatching_held_event_ = event.get();
+ dispatch_details = OnEventFromSource(event.get());
}
- if (!dispatch_details.dispatcher_destroyed)
- held_move_event_.reset();
}
if (!dispatch_details.dispatcher_destroyed) {
diff --git a/chromium/ui/aura/window_event_dispatcher.h b/chromium/ui/aura/window_event_dispatcher.h
index 5a9e099cf7a..c66b2a1d2a7 100644
--- a/chromium/ui/aura/window_event_dispatcher.h
+++ b/chromium/ui/aura/window_event_dispatcher.h
@@ -64,6 +64,8 @@ class AURA_EXPORT WindowEventDispatcher : public ui::EventProcessor,
WindowEventDispatcher(WindowTreeHost* host, bool are_events_in_pixels);
~WindowEventDispatcher() override;
+ bool are_events_in_pixels() const { return are_events_in_pixels_; }
+
// Stops dispatching/synthesizing mouse events.
void Shutdown();
diff --git a/chromium/ui/aura/window_event_dispatcher_unittest.cc b/chromium/ui/aura/window_event_dispatcher_unittest.cc
index 27deae028d1..fc0967392b9 100644
--- a/chromium/ui/aura/window_event_dispatcher_unittest.cc
+++ b/chromium/ui/aura/window_event_dispatcher_unittest.cc
@@ -14,6 +14,7 @@
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
+#include "base/test/bind_test_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
@@ -1010,9 +1011,6 @@ class HoldPointerOnScrollHandler : public ui::test::TestEventHandler {
// Tests that touch-move events don't contribute to an in-progress scroll
// gesture if touch-move events are being held by the dispatcher.
TEST_P(WindowEventDispatcherTest, TouchMovesHeldOnScroll) {
- // TODO(sky): fails with mus. https://crbug.com/866502
- if (GetParam() == Env::Mode::MUS)
- return;
EventFilterRecorder recorder;
root_window()->AddPreTargetHandler(&recorder);
test::TestWindowDelegate delegate;
@@ -2179,6 +2177,77 @@ TEST_P(WindowEventDispatcherTest, CaptureWindowDestroyed) {
EXPECT_EQ(NULL, capture_window_tracker.capture_window());
}
+namespace {
+
+class RunLoopHandler : public ui::EventHandler {
+ public:
+ explicit RunLoopHandler(aura::Window* target)
+ : run_loop_(base::RunLoop::Type::kNestableTasksAllowed), target_(target) {
+ target_->AddPreTargetHandler(this);
+ }
+ ~RunLoopHandler() override { target_->RemovePreTargetHandler(this); }
+ int num_scroll_updates() const { return num_scroll_updates_; }
+
+ private:
+ // ui::EventHandler:
+ void OnGestureEvent(ui::GestureEvent* event) override {
+ if (event->type() != ui::ET_GESTURE_SCROLL_UPDATE)
+ return;
+ num_scroll_updates_++;
+ if (running_) {
+ run_loop_.QuitWhenIdle();
+ } else {
+ running_ = true;
+ run_loop_.Run();
+ }
+ }
+
+ base::RunLoop run_loop_;
+ bool running_ = false;
+ int num_scroll_updates_ = 0;
+
+ aura::Window* target_;
+
+ DISALLOW_COPY_AND_ASSIGN(RunLoopHandler);
+};
+
+} // namespace
+
+TEST_P(WindowEventDispatcherTest, HeldTouchMoveWithRunLoop) {
+ RunLoopHandler handler(root_window());
+
+ host()->dispatcher()->HoldPointerMoves();
+
+ gfx::Point point = root_window()->GetBoundsInScreen().CenterPoint();
+ ui::TouchEvent ev0(ui::ET_TOUCH_PRESSED, point, ui::EventTimeForNow(),
+ ui::PointerDetails());
+ DispatchEventUsingWindowDispatcher(&ev0);
+
+ point.Offset(10, 10);
+ ui::TouchEvent ev1(ui::ET_TOUCH_MOVED, point, ui::EventTimeForNow(),
+ ui::PointerDetails());
+ DispatchEventUsingWindowDispatcher(&ev1);
+ // The move event is held, so SCROLL_UPDATE does not happen yet.
+ EXPECT_EQ(0, handler.num_scroll_updates());
+
+ // ReleasePointerMoves() will post DispatchHeldEvent() asynchronously.
+ host()->dispatcher()->ReleasePointerMoves();
+ point.Offset(10, 10);
+ // Schedule another move event which should cause another SCROLL_UPDATE and
+ // quit the run_loop within the handler.
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindLambdaForTesting([&]() {
+ ui::TouchEvent ev2(ui::ET_TOUCH_MOVED, point, base::TimeTicks::Now(),
+ ui::PointerDetails());
+ DispatchEventUsingWindowDispatcher(&ev2);
+ }));
+ // Wait for both DispatchHeldEvent() and dispatch of |ev2|.
+ base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
+
+ // Makes sure that the run_loop ran and then ended.
+ EXPECT_EQ(2, handler.num_scroll_updates());
+}
+
class ExitMessageLoopOnMousePress : public ui::test::TestEventHandler {
public:
ExitMessageLoopOnMousePress() {}
@@ -2282,7 +2351,9 @@ class WindowEventDispatcherTestInHighDPI : public WindowEventDispatcherTest {
};
TEST_P(WindowEventDispatcherTestInHighDPI, EventLocationTransform) {
- // TODO(sky): fails with mus. https://crbug.com/866502
+ // This test is only applicable to LOCAL mode as it's setting a device scale
+ // factor and expecting events to be transformed while routing the event
+ // directly through host(). In MUS mode the window-service does the scaling.
if (GetParam() == Env::Mode::MUS)
return;
@@ -2322,9 +2393,12 @@ TEST_P(WindowEventDispatcherTestInHighDPI, EventLocationTransform) {
}
TEST_P(WindowEventDispatcherTestInHighDPI, TouchMovesHeldOnScroll) {
- // TODO(sky): fails with mus. https://crbug.com/866502
+ // This test is only applicable to LOCAL mode as it's setting a device scale
+ // factor and expecting events to be transformed while routing the event
+ // directly through host(). In MUS mode the window-service does the scaling.
if (GetParam() == Env::Mode::MUS)
return;
+
EventFilterRecorder recorder;
root_window()->AddPreTargetHandler(&recorder);
test::TestWindowDelegate delegate;
@@ -2394,9 +2468,12 @@ class TriggerNestedLoopOnRightMousePress : public ui::test::TestEventHandler {
// correctly.
TEST_P(WindowEventDispatcherTestInHighDPI,
EventsTransformedInRepostedEventTriggeredNestedLoop) {
- // TODO(sky): fails with mus. https://crbug.com/866502
+ // This test is only applicable to LOCAL mode as it's setting a device scale
+ // factor and expecting events to be transformed while routing the event
+ // directly through host(). In MUS mode the window-service does the scaling.
if (GetParam() == Env::Mode::MUS)
return;
+
std::unique_ptr<Window> window(CreateNormalWindow(1, root_window(), NULL));
// Make sure the window is visible.
RunAllPendingInMessageLoop();
@@ -2851,7 +2928,9 @@ TEST_P(WindowEventDispatcherTest, TouchMovesMarkedWhenCausingScroll) {
// cursor's position in root coordinates has changed (e.g. when the displays's
// scale factor changed). Test that hover effects are properly updated.
TEST_P(WindowEventDispatcherTest, OnCursorMovedToRootLocationUpdatesHover) {
- // TODO(sky): fails with mus. https://crbug.com/866502
+ // This test is only applicable to LOCAL mode as it's setting a device scale
+ // factor and expecting events to be transformed while routing the event
+ // directly through host(). In MUS mode the window-service does the scaling.
if (GetParam() == Env::Mode::MUS)
return;
diff --git a/chromium/ui/aura/window_occlusion_tracker.cc b/chromium/ui/aura/window_occlusion_tracker.cc
index 89f7a5b412f..16a1d228990 100644
--- a/chromium/ui/aura/window_occlusion_tracker.cc
+++ b/chromium/ui/aura/window_occlusion_tracker.cc
@@ -9,6 +9,7 @@
#include "base/stl_util.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkRegion.h"
+#include "ui/aura/env.h"
#include "ui/aura/window_tracker.h"
#include "ui/gfx/geometry/safe_integer_conversions.h"
#include "ui/gfx/transform.h"
@@ -32,10 +33,6 @@ constexpr ui::LayerAnimationElement::AnimatableProperties
// RenderWidgetHostViewAura. https://crbug.com/827268
constexpr int kMaxRecomputeOcclusion = 3;
-WindowOcclusionTracker* g_tracker = nullptr;
-
-int g_num_pause_occlusion_tracking = 0;
-
bool WindowOrParentHasShape(Window* window) {
if (window->layer()->alpha_shape())
return true;
@@ -112,46 +109,36 @@ bool OcclusionStatesMatch(
} // namespace
-WindowOcclusionTracker::ScopedPauseOcclusionTracking::
- ScopedPauseOcclusionTracking() {
- ++g_num_pause_occlusion_tracking;
+WindowOcclusionTracker::ScopedPause::ScopedPause(Env* env)
+ : tracker_(env->GetWindowOcclusionTracker()) {
+ ++tracker_->num_pause_occlusion_tracking_;
}
-WindowOcclusionTracker::ScopedPauseOcclusionTracking::
- ~ScopedPauseOcclusionTracking() {
- --g_num_pause_occlusion_tracking;
- DCHECK_GE(g_num_pause_occlusion_tracking, 0);
- if (g_tracker)
- g_tracker->MaybeComputeOcclusion();
+WindowOcclusionTracker::ScopedPause::~ScopedPause() {
+ --tracker_->num_pause_occlusion_tracking_;
+ DCHECK_GE(tracker_->num_pause_occlusion_tracking_, 0);
+ tracker_->MaybeComputeOcclusion();
}
void WindowOcclusionTracker::Track(Window* window) {
DCHECK(window);
DCHECK(window != window->GetRootWindow());
- if (!g_tracker)
- g_tracker = new WindowOcclusionTracker();
-
- auto insert_result = g_tracker->tracked_windows_.insert(
- {window, Window::OcclusionState::UNKNOWN});
+ auto insert_result =
+ tracked_windows_.insert({window, Window::OcclusionState::UNKNOWN});
DCHECK(insert_result.second);
- if (!window->HasObserver(g_tracker))
- window->AddObserver(g_tracker);
+ if (!window_observer_.IsObserving(window))
+ window_observer_.Add(window);
if (window->GetRootWindow())
- g_tracker->TrackedWindowAddedToRoot(window);
+ TrackedWindowAddedToRoot(window);
}
WindowOcclusionTracker::WindowOcclusionTracker() = default;
WindowOcclusionTracker::~WindowOcclusionTracker() = default;
-WindowOcclusionTracker* WindowOcclusionTracker::GetInstance() {
- DCHECK(g_tracker);
- return g_tracker;
-}
-
void WindowOcclusionTracker::MaybeComputeOcclusion() {
- if (g_num_pause_occlusion_tracking ||
+ if (num_pause_occlusion_tracking_ ||
num_times_occlusion_recomputed_in_current_step_ != 0) {
return;
}
@@ -459,9 +446,10 @@ void WindowOcclusionTracker::TrackedWindowRemovedFromRoot(Window* window) {
void WindowOcclusionTracker::RemoveObserverFromWindowAndDescendants(
Window* window) {
if (WindowIsTracked(window)) {
- DCHECK(window->HasObserver(this));
+ DCHECK(window_observer_.IsObserving(window));
} else {
- window->RemoveObserver(this);
+ if (window_observer_.IsObserving(window))
+ window_observer_.Remove(window);
window->layer()->GetAnimator()->RemoveObserver(this);
animated_windows_.erase(window);
}
@@ -470,10 +458,12 @@ void WindowOcclusionTracker::RemoveObserverFromWindowAndDescendants(
}
void WindowOcclusionTracker::AddObserverToWindowAndDescendants(Window* window) {
- if (WindowIsTracked(window))
- DCHECK(window->HasObserver(this));
- else
- window->AddObserver(this);
+ if (WindowIsTracked(window)) {
+ DCHECK(window_observer_.IsObserving(window));
+ } else {
+ DCHECK(!window_observer_.IsObserving(window));
+ window_observer_.Add(window);
+ }
for (Window* child_window : window->children())
AddObserverToWindowAndDescendants(child_window);
}
@@ -498,7 +488,7 @@ void WindowOcclusionTracker::OnWindowHierarchyChanged(
Window* const window = params.target;
Window* const root_window = window->GetRootWindow();
if (root_window && base::ContainsKey(root_windows_, root_window) &&
- !window->HasObserver(this)) {
+ !window_observer_.IsObserving(window)) {
AddObserverToWindowAndDescendants(window);
}
}
@@ -582,6 +572,7 @@ void WindowOcclusionTracker::OnWindowStackingChanged(Window* window) {
void WindowOcclusionTracker::OnWindowDestroyed(Window* window) {
DCHECK(!window->GetRootWindow() || (window == window->GetRootWindow()));
tracked_windows_.erase(window);
+ window_observer_.Remove(window);
// Animations should be completed or aborted before a window is destroyed.
DCHECK(!window->layer()->GetAnimator()->IsAnimatingOnePropertyOf(
kSkipWindowWhenPropertiesAnimated));
diff --git a/chromium/ui/aura/window_occlusion_tracker.h b/chromium/ui/aura/window_occlusion_tracker.h
index 2e6d557b31b..2b546a5a8b6 100644
--- a/chromium/ui/aura/window_occlusion_tracker.h
+++ b/chromium/ui/aura/window_occlusion_tracker.h
@@ -5,9 +5,12 @@
#ifndef UI_AURA_WINDOW_OCCLUSION_TRACKER_H_
#define UI_AURA_WINDOW_OCCLUSION_TRACKER_H_
+#include <memory>
+
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/macros.h"
+#include "base/scoped_observer.h"
#include "ui/aura/aura_export.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
@@ -26,10 +29,12 @@ namespace test {
class WindowOcclusionTrackerTestApi;
}
+class Env;
+
// Notifies tracked Windows when their occlusion state change.
//
// To start tracking the occlusion state of a Window, call
-// WindowOcclusionTracker::Track().
+// aura::Window::TrackOcclusionState()
//
// A Window is occluded if its bounds and transform are not animated and one of
// these conditions is true:
@@ -43,22 +48,25 @@ class AURA_EXPORT WindowOcclusionTracker : public ui::LayerAnimationObserver,
public:
// Prevents window occlusion state computations within its scope. If an event
// that could cause window occlusion states to change occurs within the scope
- // of a ScopedPauseOcclusionTracking, window occlusion state computations are
- // delayed until all ScopedPauseOcclusionTracking objects have been destroyed.
- class AURA_EXPORT ScopedPauseOcclusionTracking {
+ // of a ScopedPause, window occlusion state computations are delayed until all
+ // ScopedPause objects have been destroyed.
+ class AURA_EXPORT ScopedPause {
public:
- ScopedPauseOcclusionTracking();
- ~ScopedPauseOcclusionTracking();
+ explicit ScopedPause(Env* env);
+ ~ScopedPause();
private:
- DISALLOW_COPY_AND_ASSIGN(ScopedPauseOcclusionTracking);
+ WindowOcclusionTracker* const tracker_;
+ DISALLOW_COPY_AND_ASSIGN(ScopedPause);
};
// Start tracking the occlusion state of |window|.
- static void Track(Window* window);
+ void Track(Window* window);
private:
friend class test::WindowOcclusionTrackerTestApi;
+ friend class Env;
+ friend std::unique_ptr<WindowOcclusionTracker>::deleter_type;
struct RootWindowState {
// Number of Windows whose occlusion state is tracked under this root
@@ -72,11 +80,8 @@ class AURA_EXPORT WindowOcclusionTracker : public ui::LayerAnimationObserver,
WindowOcclusionTracker();
~WindowOcclusionTracker() override;
- static WindowOcclusionTracker* GetInstance();
-
// Recomputes the occlusion state of tracked windows under roots marked as
- // dirty in |root_windows_| if there are no active
- // ScopedPauseOcclusionTracking instance.
+ // dirty in |root_windows_| if there are no active ScopedPause instance.
void MaybeComputeOcclusion();
// Recomputes the occlusion state of |window| and its descendants.
@@ -211,6 +216,12 @@ class AURA_EXPORT WindowOcclusionTracker : public ui::LayerAnimationObserver,
// recomputed occlusion states. Always 0 when not in MaybeComputeOcclusion().
int num_times_occlusion_recomputed_in_current_step_ = 0;
+ // Counter of the current occlusion tracking pause.
+ int num_pause_occlusion_tracking_ = 0;
+
+ // Tracks the observed windows.
+ ScopedObserver<Window, WindowObserver> window_observer_{this};
+
DISALLOW_COPY_AND_ASSIGN(WindowOcclusionTracker);
};
diff --git a/chromium/ui/aura/window_occlusion_tracker_unittest.cc b/chromium/ui/aura/window_occlusion_tracker_unittest.cc
index 27caa0959a2..ee9247f9d99 100644
--- a/chromium/ui/aura/window_occlusion_tracker_unittest.cc
+++ b/chromium/ui/aura/window_occlusion_tracker_unittest.cc
@@ -76,7 +76,7 @@ class WindowOcclusionTrackerTest : public test::AuraTestBase {
window->Show();
parent = parent ? parent : root_window();
parent->AddChild(window);
- WindowOcclusionTracker::Track(window);
+ window->TrackOcclusionState();
return window;
}
@@ -958,9 +958,8 @@ TEST_F(WindowOcclusionTrackerTest, ResizeChildFromObserver) {
}
// Verify that the bounds of windows are changed multiple times within the scope
-// of a ScopedPauseOcclusionTracking, occlusion states are updated once at the
-// end of the scope.
-TEST_F(WindowOcclusionTrackerTest, ScopedPauseOcclusionTracking) {
+// of a ScopedPause, occlusion states are updated once at the end of the scope.
+TEST_F(WindowOcclusionTrackerTest, ScopedPause) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
@@ -977,8 +976,8 @@ TEST_F(WindowOcclusionTrackerTest, ScopedPauseOcclusionTracking) {
// Change bounds multiple times. At the end of the scope, expect window a to
// be occluded.
{
- WindowOcclusionTracker::ScopedPauseOcclusionTracking
- pause_occlusion_tracking;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking(
+ root_window()->env());
window_b->SetBounds(window_a->bounds());
window_a->SetBounds(gfx::Rect(0, 10, 5, 5));
window_b->SetBounds(window_a->bounds());
@@ -988,8 +987,8 @@ TEST_F(WindowOcclusionTrackerTest, ScopedPauseOcclusionTracking) {
EXPECT_FALSE(delegate_a->is_expecting_call());
}
-// Same as the previous test, but with nested ScopedPauseOcclusionTracking.
-TEST_F(WindowOcclusionTrackerTest, NestedScopedPauseOcclusionTracking) {
+// Same as the previous test, but with nested ScopedPause.
+TEST_F(WindowOcclusionTrackerTest, NestedScopedPause) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
@@ -1006,22 +1005,22 @@ TEST_F(WindowOcclusionTrackerTest, NestedScopedPauseOcclusionTracking) {
// Change bounds multiple times. At the end of the scope, expect window a to
// be occluded.
{
- WindowOcclusionTracker::ScopedPauseOcclusionTracking
- pause_occlusion_tracking_a;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking_a(
+ root_window()->env());
{
- WindowOcclusionTracker::ScopedPauseOcclusionTracking
- pause_occlusion_tracking_b;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking_b(
+ root_window()->env());
window_b->SetBounds(window_a->bounds());
}
{
- WindowOcclusionTracker::ScopedPauseOcclusionTracking
- pause_occlusion_tracking_c;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking_c(
+ root_window()->env());
window_a->SetBounds(gfx::Rect(0, 10, 5, 5));
}
{
- WindowOcclusionTracker::ScopedPauseOcclusionTracking
- pause_occlusion_tracking_d;
+ WindowOcclusionTracker::ScopedPause pause_occlusion_tracking_d(
+ root_window()->env());
window_b->SetBounds(window_a->bounds());
}
@@ -1451,7 +1450,7 @@ class WindowDelegateChangingWindowVisibility : public MockWindowDelegate {
// Verify that if a window changes its visibility every time it is notified that
// its occlusion state changed, a DCHECK occurs.
TEST_F(WindowOcclusionTrackerTest, OcclusionStatesDontBecomeStable) {
- test::WindowOcclusionTrackerTestApi test_api;
+ test::WindowOcclusionTrackerTestApi test_api(root_window()->env());
// Create 2 superposed tracked windows.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
@@ -1651,7 +1650,7 @@ class WindowDelegateAddingAndHidingChild : public MockWindowDelegate {
// to be recomputed.
TEST_F(WindowOcclusionTrackerTest,
HideWindowWithHiddenParentOnOcclusionChange) {
- test::WindowOcclusionTrackerTestApi test_api;
+ test::WindowOcclusionTrackerTestApi test_api(root_window()->env());
auto* delegate_a = new WindowDelegateAddingAndHidingChild(this);
delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
diff --git a/chromium/ui/aura/window_port.cc b/chromium/ui/aura/window_port.cc
index a710f70587b..2c3b71651ba 100644
--- a/chromium/ui/aura/window_port.cc
+++ b/chromium/ui/aura/window_port.cc
@@ -8,6 +8,8 @@
namespace aura {
+WindowPort::WindowPort(Type type) : type_(type) {}
+
// static
WindowPort* WindowPort::Get(Window* window) {
return window ? window->port_ : nullptr;
diff --git a/chromium/ui/aura/window_port.h b/chromium/ui/aura/window_port.h
index 99f07292d6f..8e058542b48 100644
--- a/chromium/ui/aura/window_port.h
+++ b/chromium/ui/aura/window_port.h
@@ -40,8 +40,22 @@ class WindowObserver;
// Env::CreateWindowPort() is used to create the WindowPort.
class AURA_EXPORT WindowPort {
public:
+ // Corresponds to the concrete implementation of this interface.
+ enum class Type {
+ // WindowPortLocal.
+ kLocal,
+
+ // WindowPortMus.
+ kMus,
+
+ // WindowPortForShutdown.
+ kShutdown,
+ };
+
virtual ~WindowPort() {}
+ Type type() const { return type_; }
+
// Called from Window::Init().
virtual void OnPreInit(Window* window) = 0;
@@ -116,13 +130,23 @@ class AURA_EXPORT WindowPort {
// See description of function with same name in transient_window_client.
virtual bool ShouldRestackTransientChildren() = 0;
+ // Called to register/unregister an embedded FramesSinkId. This is only called
+ // if SetEmbedFrameSinkId() is called on the associated Window.
+ virtual void RegisterFrameSinkId(const viz::FrameSinkId& frame_sink_id) {}
+ virtual void UnregisterFrameSinkId(const viz::FrameSinkId& frame_sink_id) {}
+
protected:
+ explicit WindowPort(Type type);
+
// Returns the WindowPort associated with a Window.
static WindowPort* Get(Window* window);
// Returns the ObserverList of a Window.
static base::ObserverList<WindowObserver, true>::Unchecked* GetObservers(
Window* window);
+
+ private:
+ const Type type_;
};
} // namespace aura
diff --git a/chromium/ui/aura/window_port_for_shutdown.cc b/chromium/ui/aura/window_port_for_shutdown.cc
index 998764cceed..a30583c51cd 100644
--- a/chromium/ui/aura/window_port_for_shutdown.cc
+++ b/chromium/ui/aura/window_port_for_shutdown.cc
@@ -9,7 +9,8 @@
namespace aura {
-WindowPortForShutdown::WindowPortForShutdown() {}
+WindowPortForShutdown::WindowPortForShutdown()
+ : WindowPort(WindowPort::Type::kShutdown) {}
WindowPortForShutdown::~WindowPortForShutdown() {}
diff --git a/chromium/ui/aura/window_targeter.cc b/chromium/ui/aura/window_targeter.cc
index 9555a1d7373..19a77c27a51 100644
--- a/chromium/ui/aura/window_targeter.cc
+++ b/chromium/ui/aura/window_targeter.cc
@@ -10,6 +10,8 @@
#include "ui/aura/client/focus_client.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/env.h"
+#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_delegate.h"
#include "ui/aura/window_event_dispatcher.h"
@@ -20,6 +22,14 @@
#include "ui/events/event_target_iterator.h"
namespace aura {
+namespace {
+
+bool AreInsetsEmptyOrPositive(const gfx::Insets& insets) {
+ return insets.left() >= 0 && insets.right() >= 0 && insets.top() >= 0 &&
+ insets.bottom() >= 0;
+}
+
+} // namespace
WindowTargeter::WindowTargeter() {}
WindowTargeter::~WindowTargeter() {}
@@ -60,11 +70,9 @@ void WindowTargeter::SetInsets(const gfx::Insets& mouse_extend,
if (mouse_extend_ == mouse_extend && touch_extend_ == touch_extend)
return;
- const gfx::Insets last_mouse_extend_ = mouse_extend_;
- const gfx::Insets last_touch_extend_ = touch_extend_;
mouse_extend_ = mouse_extend;
touch_extend_ = touch_extend;
- OnSetInsets(last_mouse_extend_, last_touch_extend_);
+ UpdateMusIfNecessary();
}
Window* WindowTargeter::GetPriorityTargetInRootWindow(
@@ -125,10 +133,12 @@ Window* WindowTargeter::FindTargetInRootWindow(Window* root_window,
if (consumer)
return static_cast<Window*>(consumer);
+#if defined(OS_CHROMEOS)
// If the initial touch is outside the window's display, target the root.
// This is used for bezel gesture events (eg. swiping in from screen edge).
display::Display display =
display::Screen::GetScreen()->GetDisplayNearestWindow(root_window);
+ // The window target may be null, so use the root's ScreenPositionClient.
gfx::Point screen_location = event.root_location();
if (client::GetScreenPositionClient(root_window)) {
client::GetScreenPositionClient(root_window)
@@ -136,6 +146,12 @@ Window* WindowTargeter::FindTargetInRootWindow(Window* root_window,
}
if (!display.bounds().Contains(screen_location))
return root_window;
+#else
+ // If the initial touch is outside the root window, target the root.
+ // TODO: this code is likely not necessarily and will be removed.
+ if (!root_window->bounds().Contains(event.location()))
+ return root_window;
+#endif
}
return nullptr;
@@ -189,6 +205,11 @@ ui::EventTarget* WindowTargeter::FindNextBestTarget(
return nullptr;
}
+void WindowTargeter::OnInstalled(Window* window) {
+ window_ = window;
+ UpdateMusIfNecessary();
+}
+
Window* WindowTargeter::FindTargetForLocatedEvent(Window* window,
ui::LocatedEvent* event) {
if (!window->parent()) {
@@ -278,12 +299,34 @@ bool WindowTargeter::EventLocationInsideBounds(
return false;
}
-bool WindowTargeter::ShouldUseExtendedBounds(const aura::Window* window) const {
- return true;
+bool WindowTargeter::ShouldUseExtendedBounds(const aura::Window* w) const {
+ // window() is null when this is used as the default targeter (by
+ // WindowEventDispatcher). Insets should never be set in this case, so the
+ // return should not matter.
+ if (!window()) {
+ DCHECK(mouse_extend_.IsEmpty());
+ DCHECK(touch_extend_.IsEmpty());
+ return false;
+ }
+
+ // Insets should only apply to the window. Subclasses may enforce other
+ // policies.
+ return window() == w;
}
-void WindowTargeter::OnSetInsets(const gfx::Insets& last_mouse_extend,
- const gfx::Insets& last_touch_extend) {}
+// TODO: this function should go away once https://crbug.com/879308 is fixed.
+void WindowTargeter::UpdateMusIfNecessary() {
+ if (!window_ || window_->env()->mode() != Env::Mode::MUS)
+ return;
+
+ // Negative insets are used solely to extend the hit-test region of child
+ // windows, which is not needed by code using MUS (negative insets are only
+ // used in the server).
+ if (AreInsetsEmptyOrPositive(mouse_extend_) &&
+ AreInsetsEmptyOrPositive(touch_extend_)) {
+ WindowPortMus::Get(window_)->SetHitTestInsets(mouse_extend_, touch_extend_);
+ }
+}
Window* WindowTargeter::FindTargetForKeyEvent(Window* window,
const ui::KeyEvent& key) {
diff --git a/chromium/ui/aura/window_targeter.h b/chromium/ui/aura/window_targeter.h
index 5f38c4828f8..3d251b8a37e 100644
--- a/chromium/ui/aura/window_targeter.h
+++ b/chromium/ui/aura/window_targeter.h
@@ -88,6 +88,12 @@ class AURA_EXPORT WindowTargeter : public ui::EventTargeter {
ui::Event* event) override;
protected:
+ aura::Window* window() { return window_; }
+ const aura::Window* window() const { return window_; }
+
+ // This is called by Window when the targeter is set on a window.
+ virtual void OnInstalled(Window* window);
+
// Same as FindTargetForEvent(), but used for positional events. The location
// 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
@@ -114,22 +120,26 @@ class AURA_EXPORT WindowTargeter : public ui::EventTargeter {
// Returns true if the hit testing (GetHitTestRects()) should use the
// extended bounds.
- virtual bool ShouldUseExtendedBounds(const aura::Window* window) const;
-
- // Called after the hit-test area has been extended with SetInsets(). The
- // supplied insets are the values before the call to SetInsets().
- virtual void OnSetInsets(const gfx::Insets& last_mouse_extend,
- const gfx::Insets& last_touch_extend);
+ virtual bool ShouldUseExtendedBounds(const aura::Window* w) const;
const gfx::Insets& mouse_extend() const { return mouse_extend_; }
const gfx::Insets& touch_extend() const { return touch_extend_; }
private:
+ // To call OnInstalled().
+ friend class Window;
+
+ void UpdateMusIfNecessary();
+
Window* FindTargetForKeyEvent(Window* root_window, const ui::KeyEvent& event);
Window* FindTargetForNonKeyEvent(Window* root_window, ui::Event* event);
Window* FindTargetForLocatedEventRecursively(Window* root_window,
ui::LocatedEvent* event);
+ // The Window this WindowTargeter is installed on. Null if not attached to a
+ // Window.
+ aura::Window* window_ = nullptr;
+
gfx::Insets mouse_extend_;
gfx::Insets touch_extend_;
diff --git a/chromium/ui/aura/window_targeter_unittest.cc b/chromium/ui/aura/window_targeter_unittest.cc
index daeb8529d05..1085c08c32c 100644
--- a/chromium/ui/aura/window_targeter_unittest.cc
+++ b/chromium/ui/aura/window_targeter_unittest.cc
@@ -8,7 +8,9 @@
#include "base/macros.h"
#include "ui/aura/scoped_window_targeter.h"
+#include "ui/aura/test/aura_mus_test_base.h"
#include "ui/aura/test/aura_test_base.h"
+#include "ui/aura/test/mus/test_window_tree.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
#include "ui/display/display.h"
@@ -332,4 +334,33 @@ INSTANTIATE_TEST_CASE_P(/* no prefix */,
WindowTargeterTest,
::testing::Values(Env::Mode::LOCAL, Env::Mode::MUS));
+using WindowTargeterMus = aura::test::AuraMusClientTestBase;
+
+TEST_F(WindowTargeterMus, SetInsets) {
+ aura::Window window(nullptr);
+ window.Init(ui::LAYER_NOT_DRAWN);
+ std::unique_ptr<WindowTargeter> window_targeter_ptr =
+ std::make_unique<WindowTargeter>();
+ WindowTargeter* window_targeter = window_targeter_ptr.get();
+ window.SetEventTargeter(std::move(window_targeter_ptr));
+ const gfx::Insets insets1(1, 2, 3, 4);
+ const gfx::Insets insets2(11, 12, 13, 14);
+ window_targeter->SetInsets(insets1, insets2);
+ EXPECT_EQ(insets1, window_tree()->last_mouse_hit_test_insets());
+ EXPECT_EQ(insets2, window_tree()->last_touch_hit_test_insets());
+}
+
+TEST_F(WindowTargeterMus, SetInsetsBeforeInstall) {
+ aura::Window window(nullptr);
+ window.Init(ui::LAYER_NOT_DRAWN);
+ std::unique_ptr<WindowTargeter> window_targeter =
+ std::make_unique<WindowTargeter>();
+ const gfx::Insets insets1(1, 2, 3, 4);
+ const gfx::Insets insets2(11, 12, 13, 14);
+ window_targeter->SetInsets(insets1, insets2);
+ window.SetEventTargeter(std::move(window_targeter));
+ EXPECT_EQ(insets1, window_tree()->last_mouse_hit_test_insets());
+ EXPECT_EQ(insets2, window_tree()->last_touch_hit_test_insets());
+}
+
} // namespace aura
diff --git a/chromium/ui/aura/window_tree_host.cc b/chromium/ui/aura/window_tree_host.cc
index 4c3ea6cb9d1..eb205785534 100644
--- a/chromium/ui/aura/window_tree_host.cc
+++ b/chromium/ui/aura/window_tree_host.cc
@@ -243,7 +243,8 @@ void WindowTreeHost::SetSharedInputMethod(ui::InputMethod* input_method) {
}
ui::EventDispatchDetails WindowTreeHost::DispatchKeyEventPostIME(
- ui::KeyEvent* event) {
+ ui::KeyEvent* event,
+ base::OnceCallback<void(bool)> ack_callback) {
// If dispatch to IME is already disabled we shouldn't reach here.
DCHECK(!dispatcher_->should_skip_ime());
dispatcher_->set_skip_ime(true);
@@ -252,6 +253,7 @@ ui::EventDispatchDetails WindowTreeHost::DispatchKeyEventPostIME(
event_sink()->OnEventFromSource(event);
if (!dispatch_details.dispatcher_destroyed)
dispatcher_->set_skip_ime(false);
+ CallDispatchKeyEventPostIMEAck(event, std::move(ack_callback));
return dispatch_details;
}
@@ -300,6 +302,11 @@ WindowTreeHost::WindowTreeHost(std::unique_ptr<Window> window)
display::Screen::GetScreen()->AddObserver(this);
}
+void WindowTreeHost::IntializeDeviceScaleFactor(float device_scale_factor) {
+ DCHECK(!compositor_->root_layer()) << "Only call this before InitHost()";
+ device_scale_factor_ = device_scale_factor;
+}
+
void WindowTreeHost::DestroyCompositor() {
if (compositor_) {
compositor_->RemoveObserver(this);
@@ -442,10 +449,6 @@ ui::EventSink* WindowTreeHost::GetEventSink() {
return dispatcher_.get();
}
-void WindowTreeHost::OnDisplayAdded(const display::Display& new_display) {}
-
-void WindowTreeHost::OnDisplayRemoved(const display::Display& old_display) {}
-
void WindowTreeHost::OnDisplayMetricsChanged(const display::Display& display,
uint32_t metrics) {
if (metrics & DisplayObserver::DISPLAY_METRIC_COLOR_SPACE) {
diff --git a/chromium/ui/aura/window_tree_host.h b/chromium/ui/aura/window_tree_host.h
index d600ca4869e..8eec7d205ea 100644
--- a/chromium/ui/aura/window_tree_host.h
+++ b/chromium/ui/aura/window_tree_host.h
@@ -45,12 +45,13 @@ struct PlatformWindowInitProperties;
}
namespace aura {
-class ScopedKeyboardHook;
namespace test {
class WindowTreeHostTestApi;
}
+class Env;
+class ScopedKeyboardHook;
class WindowEventDispatcher;
class WindowTreeHostObserver;
@@ -64,9 +65,11 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate,
public:
~WindowTreeHost() override;
- // Creates a new WindowTreeHost with the specified |properties|.
+ // Creates a new WindowTreeHost with the specified |properties| and an
+ // optional |env|. If |env| is null, the default Env::GetInstance() is used.
static std::unique_ptr<WindowTreeHost> Create(
- ui::PlatformWindowInitProperties properties);
+ ui::PlatformWindowInitProperties properties,
+ Env* env = nullptr);
// Returns the WindowTreeHost for the specified accelerated widget, or NULL
// if there is none associated.
@@ -168,7 +171,9 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate,
void SetSharedInputMethod(ui::InputMethod* input_method);
// Overridden from ui::internal::InputMethodDelegate:
- ui::EventDispatchDetails DispatchKeyEventPostIME(ui::KeyEvent* event) final;
+ ui::EventDispatchDetails DispatchKeyEventPostIME(
+ ui::KeyEvent* event,
+ base::OnceCallback<void(bool)> ack_callback) final;
// Returns the id of the display. Default implementation queries Screen.
virtual int64_t GetDisplayId();
@@ -224,6 +229,10 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate,
explicit WindowTreeHost(std::unique_ptr<Window> window = nullptr);
+ // Set the cached display device scale factor. This should only be called
+ // during subclass initialization, when the value is needed before InitHost().
+ void IntializeDeviceScaleFactor(float device_scale_factor);
+
void DestroyCompositor();
void DestroyDispatcher();
@@ -273,8 +282,6 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate,
ui::EventSink* GetEventSink() override;
// display::DisplayObserver implementation.
- void OnDisplayAdded(const display::Display& new_display) override;
- void OnDisplayRemoved(const display::Display& old_display) override;
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t metrics) override;
diff --git a/chromium/ui/aura/window_tree_host_platform.cc b/chromium/ui/aura/window_tree_host_platform.cc
index 76865a51750..c16bbb1477a 100644
--- a/chromium/ui/aura/window_tree_host_platform.cc
+++ b/chromium/ui/aura/window_tree_host_platform.cc
@@ -10,6 +10,7 @@
#include "base/run_loop.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
+#include "ui/aura/client/cursor_client.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
@@ -42,11 +43,12 @@ namespace aura {
// static
std::unique_ptr<WindowTreeHost> WindowTreeHost::Create(
- ui::PlatformWindowInitProperties properties) {
+ ui::PlatformWindowInitProperties properties,
+ Env* env) {
return std::make_unique<WindowTreeHostPlatform>(
std::move(properties),
std::make_unique<aura::Window>(nullptr, client::WINDOW_TYPE_UNKNOWN,
- Env::GetInstance()));
+ env ? env : Env::GetInstance()));
}
WindowTreeHostPlatform::WindowTreeHostPlatform(
@@ -215,8 +217,23 @@ void WindowTreeHostPlatform::OnDamageRect(const gfx::Rect& damage_rect) {
void WindowTreeHostPlatform::DispatchEvent(ui::Event* event) {
TRACE_EVENT0("input", "WindowTreeHostPlatform::DispatchEvent");
ui::EventDispatchDetails details = SendEventToSink(event);
- if (details.dispatcher_destroyed)
+ if (details.dispatcher_destroyed) {
event->SetHandled();
+ return;
+ }
+
+ // Reset the cursor on ET_MOUSE_EXITED, so that when the mouse re-enters the
+ // window, the cursor is updated correctly.
+ if (event->type() == ui::ET_MOUSE_EXITED) {
+ client::CursorClient* cursor_client = client::GetCursorClient(window());
+ if (cursor_client) {
+ // The cursor-change needs to happen through the CursorClient so that
+ // other external states are updated correctly, instead of just changing
+ // |current_cursor_| here.
+ cursor_client->SetCursor(ui::CursorType::kNone);
+ DCHECK_EQ(ui::CursorType::kNone, current_cursor_.native_type());
+ }
+ }
}
void WindowTreeHostPlatform::OnCloseRequest() {
diff --git a/chromium/ui/aura/window_tree_host_platform.h b/chromium/ui/aura/window_tree_host_platform.h
index 5ea1727398f..91fde9bcf2a 100644
--- a/chromium/ui/aura/window_tree_host_platform.h
+++ b/chromium/ui/aura/window_tree_host_platform.h
@@ -84,6 +84,9 @@ class AURA_EXPORT WindowTreeHostPlatform : public WindowTreeHost,
bool IsKeyLocked(ui::DomCode dom_code) override;
base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;
+ // This function is only for test purpose.
+ gfx::NativeCursor* GetCursorNative() { return &current_cursor_; }
+
private:
gfx::AcceleratedWidget widget_;
std::unique_ptr<ui::PlatformWindow> platform_window_;
diff --git a/chromium/ui/aura/window_tree_host_unittest.cc b/chromium/ui/aura/window_tree_host_unittest.cc
index 8207d3ba42d..6d40482c6d6 100644
--- a/chromium/ui/aura/window_tree_host_unittest.cc
+++ b/chromium/ui/aura/window_tree_host_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "ui/aura/test/aura_test_base.h"
+#include "ui/aura/test/test_cursor_client.h"
#include "ui/aura/test/test_screen.h"
#include "ui/aura/test/window_event_dispatcher_test_api.h"
#include "ui/aura/window.h"
@@ -10,6 +11,7 @@
#include "ui/base/ime/input_method.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/test/draw_waiter_for_test.h"
+#include "ui/events/base_event_utils.h"
#include "ui/events/event_rewriter.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/platform_window/stub/stub_window.h"
@@ -141,12 +143,51 @@ class TestWindowTreeHost : public WindowTreeHostPlatform {
CreateCompositor();
}
+ ui::CursorType GetCursorType() { return GetCursorNative()->native_type(); }
+ void DispatchEventForTest(ui::Event* event) { DispatchEvent(event); }
+
private:
DISALLOW_COPY_AND_ASSIGN(TestWindowTreeHost);
};
+class TestCursorClient : public test::TestCursorClient {
+ public:
+ explicit TestCursorClient(aura::Window* root_window)
+ : test::TestCursorClient(root_window) {
+ window_ = root_window;
+ }
+ ~TestCursorClient() override {}
+
+ // Overridden from test::TestCursorClient:
+ void SetCursor(gfx::NativeCursor cursor) override {
+ WindowTreeHost* host = window_->GetHost();
+ if (host)
+ host->SetCursor(cursor);
+ }
+
+ private:
+ aura::Window* window_;
+ DISALLOW_COPY_AND_ASSIGN(TestCursorClient);
+};
+
TEST_F(WindowTreeHostTest, LostCaptureDuringTearDown) {
TestWindowTreeHost host;
}
+// Tests if the cursor type is reset after ET_MOUSE_EXITED event.
+TEST_F(WindowTreeHostTest, ResetCursorOnExit) {
+ TestWindowTreeHost host;
+ aura::TestCursorClient cursor_client(host.window());
+
+ // Set the cursor with the specific type to check if it's reset after
+ // ET_MOUSE_EXITED event.
+ host.SetCursorNative(ui::CursorType::kCross);
+
+ ui::MouseEvent exit_event(ui::ET_MOUSE_EXITED, gfx::Point(), gfx::Point(),
+ ui::EventTimeForNow(), 0, 0);
+
+ host.DispatchEventForTest(&exit_event);
+ EXPECT_EQ(host.GetCursorType(), ui::CursorType::kNone);
+}
+
} // namespace aura
diff --git a/chromium/ui/aura/window_unittest.cc b/chromium/ui/aura/window_unittest.cc
index a61fc13a4de..7edb1e5aced 100644
--- a/chromium/ui/aura/window_unittest.cc
+++ b/chromium/ui/aura/window_unittest.cc
@@ -1638,9 +1638,13 @@ TEST_P(WindowTest, Transform) {
}
TEST_P(WindowTest, TransformGesture) {
- // TODO(sky): fails with mus. https://crbug.com/866502
+ // This test is only applicable to LOCAL mode as it's setting a transform on
+ // host() and expecting events to be transformed while routing the event
+ // directly through host(). In MUS mode the window-service does the
+ // transformation.
if (GetParam() == Env::Mode::MUS)
return;
+
gfx::Size size = host()->GetBoundsInPixels().size();
std::unique_ptr<GestureTrackPositionDelegate> delegate(