Commit fd58f167 authored by Kramer Ge's avatar Kramer Ge Committed by Commit Bot

[ozone/wayland] Add WaylandSubsurface class for subsurface forwarding.

WaylandSubsurface wraps a WaylandSurface and wl_subsurface, it can be
configured by |parent_| to forward overlays scheduled on WaylandWindow.

Proposal doc: https://docs.google.com/document/d/1qdioeaZmfv8df0qbVTVoVQ8qSaHBZ0T3cjF4eEpARi8/edit?usp=sharing

This is 2/? CL for overlay forwarding using wl_subsurface.

Bug: 1063865
Change-Id: I45397fa00b5deb958d4e9c519626a56cecf88f68
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2288073
Commit-Queue: Kramer Ge <fangzhoug@chromium.org>
Reviewed-by: default avatarRobert Kroeger <rjkroege@chromium.org>
Reviewed-by: default avatarMaksim Sisov (GMT+3) <msisov@igalia.com>
Cr-Commit-Position: refs/heads/master@{#793372}
parent bc664bc7
...@@ -103,6 +103,8 @@ source_set("wayland") { ...@@ -103,6 +103,8 @@ source_set("wayland") {
"host/wayland_shm.h", "host/wayland_shm.h",
"host/wayland_shm_buffer.cc", "host/wayland_shm_buffer.cc",
"host/wayland_shm_buffer.h", "host/wayland_shm_buffer.h",
"host/wayland_subsurface.cc",
"host/wayland_subsurface.h",
"host/wayland_surface.cc", "host/wayland_surface.cc",
"host/wayland_surface.h", "host/wayland_surface.h",
"host/wayland_toplevel_window.cc", "host/wayland_toplevel_window.cc",
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "ui/ozone/platform/wayland/host/wayland_connection.h" #include "ui/ozone/platform/wayland/host/wayland_connection.h"
#include "ui/ozone/platform/wayland/host/wayland_drm.h" #include "ui/ozone/platform/wayland/host/wayland_drm.h"
#include "ui/ozone/platform/wayland/host/wayland_shm.h" #include "ui/ozone/platform/wayland/host/wayland_shm.h"
#include "ui/ozone/platform/wayland/host/wayland_subsurface.h"
#include "ui/ozone/platform/wayland/host/wayland_surface.h" #include "ui/ozone/platform/wayland/host/wayland_surface.h"
#include "ui/ozone/platform/wayland/host/wayland_window.h" #include "ui/ozone/platform/wayland/host/wayland_window.h"
#include "ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.h" #include "ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.h"
...@@ -615,6 +616,29 @@ void WaylandBufferManagerHost::OnWindowConfigured(WaylandWindow* window) { ...@@ -615,6 +616,29 @@ void WaylandBufferManagerHost::OnWindowConfigured(WaylandWindow* window) {
it->second->OnSurfaceConfigured(); it->second->OnSurfaceConfigured();
} }
void WaylandBufferManagerHost::OnSubsurfaceAdded(
WaylandWindow* window,
WaylandSubsurface* subsurface) {
DCHECK(subsurface);
surfaces_[subsurface->wayland_surface()] = std::make_unique<Surface>(
subsurface->wayland_surface(), connection_, this);
// WaylandSubsurface is always configured.
surfaces_[subsurface->wayland_surface()]->OnSurfaceConfigured();
}
void WaylandBufferManagerHost::OnSubsurfaceRemoved(
WaylandWindow* window,
WaylandSubsurface* subsurface) {
DCHECK(subsurface);
auto it = surfaces_.find(subsurface->wayland_surface());
DCHECK(it != surfaces_.end());
if (it->second->HasBuffers()) {
it->second->OnSurfaceRemoved();
surface_graveyard_.emplace_back(std::move(it->second));
}
surfaces_.erase(it);
}
void WaylandBufferManagerHost::SetTerminateGpuCallback( void WaylandBufferManagerHost::SetTerminateGpuCallback(
base::OnceCallback<void(std::string)> terminate_callback) { base::OnceCallback<void(std::string)> terminate_callback) {
terminate_gpu_cb_ = std::move(terminate_callback); terminate_gpu_cb_ = std::move(terminate_callback);
...@@ -800,6 +824,12 @@ void WaylandBufferManagerHost::DestroyBuffer(gfx::AcceleratedWidget widget, ...@@ -800,6 +824,12 @@ void WaylandBufferManagerHost::DestroyBuffer(gfx::AcceleratedWidget widget,
if (!surface->HasBuffers() && !surface->HasSurface()) if (!surface->HasBuffers() && !surface->HasSurface())
surfaces_.erase(window->root_surface()); surfaces_.erase(window->root_surface());
} }
const auto& subsurfaces = window->wayland_subsurfaces();
for (const auto& it : subsurfaces) {
Surface* subsurface = GetSurface((*it).wayland_surface());
if (subsurface)
destroyed_count += subsurface->DestroyBuffer(buffer_id);
}
} else { } else {
// Case 3) // Case 3)
auto it = surface_graveyard_.begin(); auto it = surface_graveyard_.begin();
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
namespace ui { namespace ui {
class WaylandConnection; class WaylandConnection;
class WaylandSubsurface;
class WaylandWindow; class WaylandWindow;
class WaylandSurface; class WaylandSurface;
...@@ -83,6 +84,10 @@ class WaylandBufferManagerHost : public ozone::mojom::WaylandBufferManagerHost, ...@@ -83,6 +84,10 @@ class WaylandBufferManagerHost : public ozone::mojom::WaylandBufferManagerHost,
void OnWindowAdded(WaylandWindow* window) override; void OnWindowAdded(WaylandWindow* window) override;
void OnWindowRemoved(WaylandWindow* window) override; void OnWindowRemoved(WaylandWindow* window) override;
void OnWindowConfigured(WaylandWindow* window) override; void OnWindowConfigured(WaylandWindow* window) override;
void OnSubsurfaceAdded(WaylandWindow* window,
WaylandSubsurface* subsurface) override;
void OnSubsurfaceRemoved(WaylandWindow* window,
WaylandSubsurface* subsurface) override;
void SetTerminateGpuCallback( void SetTerminateGpuCallback(
base::OnceCallback<void(std::string)> terminate_gpu_cb); base::OnceCallback<void(std::string)> terminate_gpu_cb);
......
// Copyright 2020 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/ozone/platform/wayland/host/wayland_subsurface.h"
#include <wayland-client.h>
#include <cstdint>
#include "ui/ozone/platform/wayland/common/wayland_util.h"
#include "ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h"
#include "ui/ozone/platform/wayland/host/wayland_connection.h"
#include "ui/ozone/platform/wayland/host/wayland_window.h"
namespace {
gfx::Rect AdjustSubsurfaceBounds(const gfx::Rect& bounds_px,
const gfx::Rect& parent_bounds_px,
float ui_scale,
int32_t parent_buffer_scale) {
// TODO(fangzhoug): Verify the correctness of using ui_scale here, and in
// other ozone wayland files.
const auto parent_bounds_dip =
gfx::ScaleToRoundedRect(parent_bounds_px, 1.0 / ui_scale);
const auto bounds_dip = gfx::ScaleToRoundedRect(bounds_px, 1.0 / ui_scale);
auto new_bounds_dip =
wl::TranslateBoundsToParentCoordinates(bounds_dip, parent_bounds_dip);
return gfx::ScaleToRoundedRect(new_bounds_dip,
ui_scale / parent_buffer_scale);
}
} // namespace
namespace ui {
WaylandSubsurface::WaylandSubsurface(WaylandConnection* connection,
WaylandWindow* parent)
: wayland_surface_(connection, parent),
connection_(connection),
parent_(parent) {
DCHECK(parent_);
DCHECK(connection_);
if (!surface()) {
LOG(ERROR) << "Failed to create wl_surface";
return;
}
}
WaylandSubsurface::~WaylandSubsurface() = default;
gfx::AcceleratedWidget WaylandSubsurface::GetWidget() const {
return wayland_surface_.GetWidget();
}
void WaylandSubsurface::Show() {
if (!subsurface_)
CreateSubsurface();
}
void WaylandSubsurface::Hide() {
if (!subsurface_)
return;
subsurface_.reset();
connection_->buffer_manager_host()->ResetSurfaceContents(wayland_surface());
}
bool WaylandSubsurface::IsVisible() const {
return !!subsurface_;
}
void WaylandSubsurface::UpdateOpaqueRegion() {
gfx::Size region_size = enable_blend_ ? gfx::Size() : bounds_px_.size();
wl::Object<wl_region> region(
wl_compositor_create_region(connection_->compositor()));
wl_region_add(region.get(), 0, 0, region_size.width(), region_size.height());
wl_surface_set_opaque_region(surface(), region.get());
}
void WaylandSubsurface::SetBounds(const gfx::Rect& bounds) {
if (bounds_px_ == bounds)
return;
bounds_px_ = bounds;
if (IsVisible()) {
// Translate location from screen to surface coordinates.
auto bounds_px =
AdjustSubsurfaceBounds(bounds_px_, parent_->GetBounds(),
parent_->ui_scale(), parent_->buffer_scale());
wl_subsurface_set_position(subsurface_.get(), bounds_px.x(), bounds_px.y());
}
}
void WaylandSubsurface::CreateSubsurface() {
DCHECK(parent_);
wl_subcompositor* subcompositor = connection_->subcompositor();
DCHECK(subcompositor);
subsurface_ = wayland_surface()->CreateSubsurface(parent_->root_surface());
// Chromium positions quads in display::Display coordinates in physical
// pixels, but Wayland requires them to be in local surface coordinates a.k.a
// relative to parent window.
auto bounds_px =
AdjustSubsurfaceBounds(bounds_px_, parent_->GetBounds(),
parent_->ui_scale(), parent_->buffer_scale());
DCHECK(subsurface_);
wl_subsurface_set_position(subsurface_.get(), bounds_px.x(), bounds_px.y());
wl_subsurface_set_sync(subsurface_.get());
// Subsurfaces don't need to trap input events. Its display rect is fully
// contained in |parent_|'s. Setting input_region to empty allows |parent_| to
// dispatch all of the input to platform window.
wl::Object<wl_region> region(
wl_compositor_create_region(connection_->compositor()));
wl_region_add(region.get(), 0, 0, 0, 0);
wl_surface_set_input_region(surface(), region.get());
}
void WaylandSubsurface::ConfigureAndShowSurface(
gfx::OverlayTransform transform,
const gfx::Rect& bounds_rect,
bool enable_blend,
const WaylandSurface* reference_below,
const WaylandSurface* reference_above) {
wayland_surface()->SetBufferScale(parent_->buffer_scale(), false);
gfx::Rect bounds_px{
bounds_rect.origin() + parent_->GetBounds().origin().OffsetFromOrigin(),
bounds_rect.size()};
auto old_bounds = bounds_px_;
SetBounds(bounds_px);
if (old_bounds != bounds_px_ || enable_blend_ != enable_blend) {
enable_blend_ = enable_blend;
UpdateOpaqueRegion();
}
Show();
DCHECK(!reference_above || !reference_below);
if (reference_below) {
wl_subsurface_place_above(subsurface_.get(), reference_below->surface());
} else if (reference_above) {
wl_subsurface_place_below(subsurface_.get(), reference_above->surface());
}
}
} // namespace ui
// Copyright 2020 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_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SUBSURFACE_H_
#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SUBSURFACE_H_
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/overlay_transform.h"
#include "ui/ozone/platform/wayland/common/wayland_object.h"
#include "ui/ozone/platform/wayland/host/wayland_surface.h"
namespace ui {
class WaylandConnection;
class WaylandWindow;
// Wraps a wl_surface with a wl_subsurface role assigned. It is used to submit a
// buffer as a sub region of WaylandWindow.
class WaylandSubsurface {
public:
WaylandSubsurface(WaylandConnection* connection, WaylandWindow* parent);
WaylandSubsurface(const WaylandSubsurface&) = delete;
WaylandSubsurface& operator=(const WaylandSubsurface&) = delete;
~WaylandSubsurface();
wl_surface* surface() const { return wayland_surface_.surface(); }
int32_t buffer_scale() const { return wayland_surface_.buffer_scale(); }
WaylandSurface* wayland_surface() { return &wayland_surface_; }
gfx::Rect bounds_px() { return bounds_px_; }
bool IsOpaque() const { return !enable_blend_; }
gfx::AcceleratedWidget GetWidget() const;
// Sets up wl_surface and wl_subsurface. Allows an overlay to be shown
// correctly once a wl_buffer is attached.
void ConfigureAndShowSurface(gfx::OverlayTransform transform,
const gfx::Rect& bounds_rect,
bool enable_blend,
const WaylandSurface* reference_below,
const WaylandSurface* reference_above);
// Assigns wl_subsurface role to the wl_surface so it is visible when a
// wl_buffer is attached.
void Show();
// Remove wl_subsurface role to make this invisible.
void Hide();
bool IsVisible() const;
private:
// Helper of Show(). It does the role-assigning to wl_surface.
void CreateSubsurface();
void SetBounds(const gfx::Rect& bounds);
// Tells wayland compositor to update the opaque region according to
// |enable_blend_| and |bounds_px_|.
void UpdateOpaqueRegion();
WaylandSurface wayland_surface_;
wl::Object<wl_subsurface> subsurface_;
WaylandConnection* const connection_;
// |parent_| refers to the WaylandWindow whose wl_surface is the parent to
// this subsurface.
WaylandWindow* const parent_;
// Pixel bounds within the display to position this subsurface.
gfx::Rect bounds_px_;
bool enable_blend_ = true;
};
} // namespace ui
#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SUBSURFACE_H_
...@@ -62,7 +62,7 @@ class WaylandSurface { ...@@ -62,7 +62,7 @@ class WaylandSurface {
private: private:
WaylandConnection* const connection_; WaylandConnection* const connection_;
WaylandWindow* root_window_ = nullptr; WaylandWindow* const root_window_;
wl::Object<wl_surface> surface_; wl::Object<wl_surface> surface_;
// Wayland's scale factor for the output that this window currently belongs // Wayland's scale factor for the output that this window currently belongs
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "ui/ozone/platform/wayland/host/wayland_cursor_position.h" #include "ui/ozone/platform/wayland/host/wayland_cursor_position.h"
#include "ui/ozone/platform/wayland/host/wayland_output_manager.h" #include "ui/ozone/platform/wayland/host/wayland_output_manager.h"
#include "ui/ozone/platform/wayland/host/wayland_pointer.h" #include "ui/ozone/platform/wayland/host/wayland_pointer.h"
#include "ui/ozone/platform/wayland/host/wayland_subsurface.h"
namespace ui { namespace ui {
...@@ -32,6 +33,11 @@ WaylandWindow::~WaylandWindow() { ...@@ -32,6 +33,11 @@ WaylandWindow::~WaylandWindow() {
shutting_down_ = true; shutting_down_ = true;
PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
for (const auto& widget_subsurface : wayland_subsurfaces()) {
connection_->wayland_window_manager()->RemoveSubsurface(
GetWidget(), widget_subsurface.get());
}
if (root_surface_) if (root_surface_)
connection_->wayland_window_manager()->RemoveWindow(GetWidget()); connection_->wayland_window_manager()->RemoveWindow(GetWidget());
...@@ -469,4 +475,15 @@ std::unique_ptr<WaylandSurface> WaylandWindow::TakeWaylandSurface() { ...@@ -469,4 +475,15 @@ std::unique_ptr<WaylandSurface> WaylandWindow::TakeWaylandSurface() {
return std::move(root_surface_); return std::move(root_surface_);
} }
bool WaylandWindow::RequestSubsurface() {
auto subsurface = std::make_unique<WaylandSubsurface>(connection_, this);
if (!subsurface->surface())
return false;
connection_->wayland_window_manager()->AddSubsurface(GetWidget(),
subsurface.get());
auto result = wayland_subsurfaces_.emplace(std::move(subsurface));
DCHECK(result.second);
return true;
}
} // namespace ui } // namespace ui
...@@ -31,8 +31,11 @@ namespace ui { ...@@ -31,8 +31,11 @@ namespace ui {
class BitmapCursorOzone; class BitmapCursorOzone;
class OSExchangeData; class OSExchangeData;
class WaylandConnection; class WaylandConnection;
class WaylandSubsurface;
class WaylandWindowDragController; class WaylandWindowDragController;
using WidgetSubsurfaceSet = base::flat_set<std::unique_ptr<WaylandSubsurface>>;
class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher {
public: public:
~WaylandWindow() override; ~WaylandWindow() override;
...@@ -54,6 +57,9 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { ...@@ -54,6 +57,9 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher {
void UpdateBufferScale(bool update_bounds); void UpdateBufferScale(bool update_bounds);
WaylandSurface* root_surface() const { return root_surface_.get(); } WaylandSurface* root_surface() const { return root_surface_.get(); }
const WidgetSubsurfaceSet& wayland_subsurfaces() const {
return wayland_subsurfaces_;
}
void set_parent_window(WaylandWindow* parent_window) { void set_parent_window(WaylandWindow* parent_window) {
parent_window_ = parent_window; parent_window_ = parent_window;
...@@ -62,6 +68,10 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { ...@@ -62,6 +68,10 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher {
gfx::AcceleratedWidget GetWidget() const; gfx::AcceleratedWidget GetWidget() const;
// Creates a WaylandSubsurface to put into |wayland_subsurfaces_|. Called if
// more subsurfaces are needed when a frame arrives.
bool RequestSubsurface();
// Set whether this window has pointer focus and should dispatch mouse events. // Set whether this window has pointer focus and should dispatch mouse events.
void SetPointerFocus(bool focus); void SetPointerFocus(bool focus);
bool has_pointer_focus() const { return has_pointer_focus_; } bool has_pointer_focus() const { return has_pointer_focus_; }
...@@ -210,6 +220,7 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { ...@@ -210,6 +220,7 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher {
WaylandWindow* child_window_ = nullptr; WaylandWindow* child_window_ = nullptr;
std::unique_ptr<WaylandSurface> root_surface_; std::unique_ptr<WaylandSurface> root_surface_;
WidgetSubsurfaceSet wayland_subsurfaces_;
// The current cursor bitmap (immutable). // The current cursor bitmap (immutable).
scoped_refptr<BitmapCursorOzone> bitmap_; scoped_refptr<BitmapCursorOzone> bitmap_;
......
...@@ -110,6 +110,24 @@ void WaylandWindowManager::RemoveWindow(gfx::AcceleratedWidget widget) { ...@@ -110,6 +110,24 @@ void WaylandWindowManager::RemoveWindow(gfx::AcceleratedWidget widget) {
observer.OnWindowRemoved(window); observer.OnWindowRemoved(window);
} }
void WaylandWindowManager::AddSubsurface(gfx::AcceleratedWidget widget,
WaylandSubsurface* subsurface) {
auto* window = window_map_[widget];
DCHECK(window);
for (WaylandWindowObserver& observer : observers_)
observer.OnSubsurfaceAdded(window, subsurface);
}
void WaylandWindowManager::RemoveSubsurface(gfx::AcceleratedWidget widget,
WaylandSubsurface* subsurface) {
auto* window = window_map_[widget];
DCHECK(window);
for (WaylandWindowObserver& observer : observers_)
observer.OnSubsurfaceRemoved(window, subsurface);
}
std::vector<WaylandWindow*> WaylandWindowManager::GetAllWindows() const { std::vector<WaylandWindow*> WaylandWindowManager::GetAllWindows() const {
std::vector<WaylandWindow*> result; std::vector<WaylandWindow*> result;
for (auto entry : window_map_) for (auto entry : window_map_)
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
namespace ui { namespace ui {
class WaylandWindow; class WaylandWindow;
class WaylandSubsurface;
// Stores and returns WaylandWindows. Clients that are interested in knowing // Stores and returns WaylandWindows. Clients that are interested in knowing
// when a new window is added or removed, but set self as an observer. // when a new window is added or removed, but set self as an observer.
...@@ -63,6 +64,10 @@ class WaylandWindowManager { ...@@ -63,6 +64,10 @@ class WaylandWindowManager {
void AddWindow(gfx::AcceleratedWidget widget, WaylandWindow* window); void AddWindow(gfx::AcceleratedWidget widget, WaylandWindow* window);
void RemoveWindow(gfx::AcceleratedWidget widget); void RemoveWindow(gfx::AcceleratedWidget widget);
void AddSubsurface(gfx::AcceleratedWidget widget,
WaylandSubsurface* subsurface);
void RemoveSubsurface(gfx::AcceleratedWidget widget,
WaylandSubsurface* subsurface);
private: private:
base::ObserverList<WaylandWindowObserver> observers_; base::ObserverList<WaylandWindowObserver> observers_;
......
...@@ -14,4 +14,11 @@ void WaylandWindowObserver::OnWindowRemoved(WaylandWindow* window) {} ...@@ -14,4 +14,11 @@ void WaylandWindowObserver::OnWindowRemoved(WaylandWindow* window) {}
void WaylandWindowObserver::OnWindowConfigured(WaylandWindow* window) {} void WaylandWindowObserver::OnWindowConfigured(WaylandWindow* window) {}
void WaylandWindowObserver::OnSubsurfaceAdded(WaylandWindow* window,
WaylandSubsurface* subsurface) {}
void WaylandWindowObserver::OnSubsurfaceRemoved(WaylandWindow* window,
WaylandSubsurface* subsurface) {
}
} // namespace ui } // namespace ui
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
namespace ui { namespace ui {
class WaylandWindow; class WaylandWindow;
class WaylandSubsurface;
// Observers for window management notifications. // Observers for window management notifications.
class WaylandWindowObserver : public base::CheckedObserver { class WaylandWindowObserver : public base::CheckedObserver {
...@@ -23,6 +24,14 @@ class WaylandWindowObserver : public base::CheckedObserver { ...@@ -23,6 +24,14 @@ class WaylandWindowObserver : public base::CheckedObserver {
// Called when |window| has been ack configured. // Called when |window| has been ack configured.
virtual void OnWindowConfigured(WaylandWindow* window); virtual void OnWindowConfigured(WaylandWindow* window);
// Called when |window| adds |subsurface|.
virtual void OnSubsurfaceAdded(WaylandWindow* window,
WaylandSubsurface* subsurface);
// Called when |window| removes |subsurface|.
virtual void OnSubsurfaceRemoved(WaylandWindow* window,
WaylandSubsurface* subsurface);
protected: protected:
~WaylandWindowObserver() override; ~WaylandWindowObserver() override;
}; };
......
...@@ -19,7 +19,9 @@ ...@@ -19,7 +19,9 @@
#include "ui/base/hit_test.h" #include "ui/base/hit_test.h"
#include "ui/events/base_event_utils.h" #include "ui/events/base_event_utils.h"
#include "ui/events/event.h" #include "ui/events/event.h"
#include "ui/gfx/overlay_transform.h"
#include "ui/ozone/platform/wayland/common/wayland_util.h" #include "ui/ozone/platform/wayland/common/wayland_util.h"
#include "ui/ozone/platform/wayland/host/wayland_subsurface.h"
#include "ui/ozone/platform/wayland/test/mock_pointer.h" #include "ui/ozone/platform/wayland/test/mock_pointer.h"
#include "ui/ozone/platform/wayland/test/mock_surface.h" #include "ui/ozone/platform/wayland/test/mock_surface.h"
#include "ui/ozone/platform/wayland/test/test_keyboard.h" #include "ui/ozone/platform/wayland/test/test_keyboard.h"
...@@ -2090,6 +2092,43 @@ TEST_P(WaylandWindowTest, DoesNotGrabPopupIfNoSeat) { ...@@ -2090,6 +2092,43 @@ TEST_P(WaylandWindowTest, DoesNotGrabPopupIfNoSeat) {
EXPECT_EQ(test_popup->grab_serial(), 0u); EXPECT_EQ(test_popup->grab_serial(), 0u);
} }
TEST_P(WaylandWindowTest, OneWaylandSubsurface) {
VerifyAndClearExpectations();
std::unique_ptr<WaylandWindow> window = CreateWaylandWindowWithParams(
PlatformWindowType::kWindow, gfx::kNullAcceleratedWidget,
gfx::Rect(0, 0, 640, 480), &delegate_);
EXPECT_TRUE(window);
gfx::Rect subsurface_bounds(gfx::Point(15, 15), gfx::Size(10, 10));
bool result = window->RequestSubsurface();
EXPECT_TRUE(result);
WaylandSubsurface* wayland_subsurface =
window->wayland_subsurfaces().begin()->get();
Sync();
auto* mock_surface_root_window = server_.GetObject<wl::MockSurface>(
window->root_surface()->GetSurfaceId());
auto* mock_surface_subsurface = server_.GetObject<wl::MockSurface>(
wayland_subsurface->wayland_surface()->GetSurfaceId());
EXPECT_TRUE(mock_surface_subsurface);
wayland_subsurface->ConfigureAndShowSurface(
gfx::OVERLAY_TRANSFORM_NONE, subsurface_bounds, true, nullptr, nullptr);
connection_->ScheduleFlush();
Sync();
auto* test_subsurface = mock_surface_subsurface->sub_surface();
EXPECT_TRUE(test_subsurface);
auto* parent_resource = mock_surface_root_window->resource();
EXPECT_EQ(parent_resource, test_subsurface->parent_resource());
EXPECT_EQ(test_subsurface->position(), subsurface_bounds.origin());
EXPECT_TRUE(test_subsurface->sync());
}
INSTANTIATE_TEST_SUITE_P(XdgVersionStableTest, INSTANTIATE_TEST_SUITE_P(XdgVersionStableTest,
WaylandWindowTest, WaylandWindowTest,
::testing::Values(kXdgShellStable)); ::testing::Values(kXdgShellStable));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment