Commit 7e9eb60e authored by Maksim Sisov's avatar Maksim Sisov Committed by Commit Bot

ozone/Wayland: Add WaylandWindow factory method.

To hide future different types of WaylandWindows (WaylandSurface,
WaylandPopup and WaylandSubsurface), add a factory method, which
will handle everything on its own.

Also make unittests and OzonePlatformWayland use this factory.

Bug: 1028919
Change-Id: I745f99024b6657be3686ee92b0baf4c93f08b9a7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1954470
Commit-Queue: Maksim Sisov <msisov@igalia.com>
Reviewed-by: default avatarMichael Spang <spang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#722586}
parent 393e60bf
......@@ -95,6 +95,7 @@ source_set("wayland") {
"host/wayland_touch.h",
"host/wayland_window.cc",
"host/wayland_window.h",
"host/wayland_window_factory.cc",
"host/wayland_window_manager.cc",
"host/wayland_window_manager.h",
"host/wayland_window_observer.cc",
......
......@@ -72,14 +72,15 @@ TEST_P(WaylandPointerTest, Enter) {
TEST_P(WaylandPointerTest, Leave) {
MockPlatformWindowDelegate other_delegate;
WaylandWindow other_window(&other_delegate, connection_.get());
gfx::AcceleratedWidget other_widget = gfx::kNullAcceleratedWidget;
EXPECT_CALL(other_delegate, OnAcceleratedWidgetAvailable(_))
.WillOnce(SaveArg<0>(&other_widget));
PlatformWindowInitProperties properties;
properties.bounds = gfx::Rect(0, 0, 10, 10);
properties.type = PlatformWindowType::kWindow;
ASSERT_TRUE(other_window.Initialize(std::move(properties)));
auto other_window = WaylandWindow::Create(&other_delegate, connection_.get(),
std::move(properties));
ASSERT_NE(other_widget, gfx::kNullAcceleratedWidget);
Sync();
......
......@@ -89,13 +89,12 @@ class WaylandScreenTest : public WaylandTest {
PlatformWindowType window_type,
gfx::AcceleratedWidget parent_widget,
MockPlatformWindowDelegate* delegate) {
auto window = std::make_unique<WaylandWindow>(delegate, connection_.get());
PlatformWindowInitProperties properties;
properties.bounds = bounds;
properties.type = window_type;
properties.parent_widget = parent_widget;
EXPECT_TRUE(window->Initialize(std::move(properties)));
return window;
return WaylandWindow::Create(delegate, connection_.get(),
std::move(properties));
}
void UpdateOutputGeometry(wl_resource* output_resource,
......
......@@ -66,72 +66,6 @@ WaylandWindow* WaylandWindow::FromSurface(wl_surface* surface) {
wl_proxy_get_user_data(reinterpret_cast<wl_proxy*>(surface)));
}
bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) {
// Properties contain DIP bounds but the buffer scale is initially 1 so it's
// OK to assign. The bounds will be recalculated when the buffer scale
// changes.
DCHECK_EQ(buffer_scale_, 1);
bounds_px_ = properties.bounds;
opacity_ = properties.opacity;
surface_.reset(wl_compositor_create_surface(connection_->compositor()));
if (!surface_) {
LOG(ERROR) << "Failed to create wl_surface";
return false;
}
wl_surface_set_user_data(surface_.get(), this);
AddSurfaceListener();
connection_->wayland_window_manager()->AddWindow(GetWidget(), this);
ui::PlatformWindowType ui_window_type = properties.type;
switch (ui_window_type) {
case ui::PlatformWindowType::kMenu:
case ui::PlatformWindowType::kPopup:
parent_window_ = GetParentWindow(properties.parent_widget);
// Popups need to know their scale earlier to position themselves.
if (!parent_window_) {
LOG(ERROR) << "Failed to get a parent window for this popup";
return false;
}
SetBufferScale(parent_window_->buffer_scale_, false);
ui_scale_ = parent_window_->ui_scale_;
// TODO(msisov, jkim): Handle notification windows, which are marked
// as popup windows as well. Those are the windows that do not have
// parents and pop up when the browser receives a notification.
CreateShellPopup();
break;
case ui::PlatformWindowType::kTooltip:
// Tooltips subsurfaces are created on demand, upon ::Show calls.
is_tooltip_ = true;
break;
case ui::PlatformWindowType::kWindow:
case ui::PlatformWindowType::kBubble:
case ui::PlatformWindowType::kDrag:
// TODO(msisov): Figure out what kind of surface we need to create for
// bubble and drag windows.
CreateShellSurface();
break;
}
if (shell_surface_ && !properties.wm_class_class.empty())
shell_surface_->SetAppId(properties.wm_class_class);
connection_->ScheduleFlush();
PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
delegate_->OnAcceleratedWidgetAvailable(GetWidget());
// Will do nothing for popups because they have got their scale above.
UpdateBufferScale(false);
MaybeUpdateOpaqueRegion();
return true;
}
void WaylandWindow::UpdateBufferScale(bool update_bounds) {
DCHECK(connection_->wayland_output_manager());
const auto* screen = connection_->wayland_output_manager()->wayland_screen();
......@@ -773,6 +707,72 @@ void WaylandWindow::OnDragSessionClose(uint32_t dnd_action) {
connection_->ResetPointerFlags();
}
bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) {
// Properties contain DIP bounds but the buffer scale is initially 1 so it's
// OK to assign. The bounds will be recalculated when the buffer scale
// changes.
DCHECK_EQ(buffer_scale_, 1);
bounds_px_ = properties.bounds;
opacity_ = properties.opacity;
surface_.reset(wl_compositor_create_surface(connection_->compositor()));
if (!surface_) {
LOG(ERROR) << "Failed to create wl_surface";
return false;
}
wl_surface_set_user_data(surface_.get(), this);
AddSurfaceListener();
connection_->wayland_window_manager()->AddWindow(GetWidget(), this);
ui::PlatformWindowType ui_window_type = properties.type;
switch (ui_window_type) {
case ui::PlatformWindowType::kMenu:
case ui::PlatformWindowType::kPopup:
parent_window_ = GetParentWindow(properties.parent_widget);
// Popups need to know their scale earlier to position themselves.
if (!parent_window_) {
LOG(ERROR) << "Failed to get a parent window for this popup";
return false;
}
SetBufferScale(parent_window_->buffer_scale_, false);
ui_scale_ = parent_window_->ui_scale_;
// TODO(msisov, jkim): Handle notification windows, which are marked
// as popup windows as well. Those are the windows that do not have
// parents and pop up when the browser receives a notification.
CreateShellPopup();
break;
case ui::PlatformWindowType::kTooltip:
// Tooltips subsurfaces are created on demand, upon ::Show calls.
is_tooltip_ = true;
break;
case ui::PlatformWindowType::kWindow:
case ui::PlatformWindowType::kBubble:
case ui::PlatformWindowType::kDrag:
// TODO(msisov): Figure out what kind of surface we need to create for
// bubble and drag windows.
CreateShellSurface();
break;
}
if (shell_surface_ && !properties.wm_class_class.empty())
shell_surface_->SetAppId(properties.wm_class_class);
connection_->ScheduleFlush();
PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
delegate_->OnAcceleratedWidgetAvailable(GetWidget());
// Will do nothing for popups because they have got their scale above.
UpdateBufferScale(false);
MaybeUpdateOpaqueRegion();
return true;
}
void WaylandWindow::SetBoundsDip(const gfx::Rect& bounds_dip) {
SetBounds(gfx::ScaleToRoundedRect(bounds_dip, buffer_scale_));
}
......
......@@ -40,13 +40,16 @@ class WaylandWindow : public PlatformWindow,
public WmMoveResizeHandler,
public WmDragHandler {
public:
WaylandWindow(PlatformWindowDelegate* delegate,
WaylandConnection* connection);
~WaylandWindow() override;
static WaylandWindow* FromSurface(wl_surface* surface);
// A factory method that can create any of the derived types of WaylandWindow
// (WaylandSurface, WaylandPopup and WaylandSubsurface).
static std::unique_ptr<WaylandWindow> Create(
PlatformWindowDelegate* delegate,
WaylandConnection* connection,
PlatformWindowInitProperties properties);
bool Initialize(PlatformWindowInitProperties properties);
static WaylandWindow* FromSurface(wl_surface* surface);
// Updates the surface buffer scale of the window. Top level windows take
// scale from the output attached to either their current display or the
......@@ -168,6 +171,12 @@ class WaylandWindow : public PlatformWindow,
private:
FRIEND_TEST_ALL_PREFIXES(WaylandScreenTest, SetBufferScale);
WaylandWindow(PlatformWindowDelegate* delegate,
WaylandConnection* connection);
// Initializes the WaylandWindow with supplied properties.
bool Initialize(PlatformWindowInitProperties properties);
void SetBoundsDip(const gfx::Rect& bounds_dip);
void SetBufferScale(int32_t scale, bool update_bounds);
......
// Copyright 2019 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_window.h"
#include <memory>
#include "ui/ozone/platform/wayland/host/wayland_window.h"
namespace ui {
// static
std::unique_ptr<WaylandWindow> WaylandWindow::Create(
PlatformWindowDelegate* delegate,
WaylandConnection* connection,
PlatformWindowInitProperties properties) {
// TODO(msisov): once WaylandWindow becomes a base class, add switch cases to
// create different Wayland windows.
std::unique_ptr<WaylandWindow> window(
new WaylandWindow(delegate, connection));
return window->Initialize(std::move(properties)) ? std::move(window)
: nullptr;
}
} // namespace ui
\ No newline at end of file
......@@ -36,12 +36,8 @@ class WaylandWindowManagerTest : public WaylandTest {
PlatformWindowInitProperties properties;
properties.bounds = bounds;
properties.type = type;
std::unique_ptr<WaylandWindow> window =
std::make_unique<WaylandWindow>(delegate, connection_.get());
EXPECT_TRUE(window->Initialize(std::move(properties)));
return window;
return WaylandWindow::Create(delegate, connection_.get(),
std::move(properties));
}
WaylandWindowManager* manager_ = nullptr;
......
......@@ -107,10 +107,8 @@ class OzonePlatformWayland : public OzonePlatform {
std::unique_ptr<PlatformWindow> CreatePlatformWindow(
PlatformWindowDelegate* delegate,
PlatformWindowInitProperties properties) override {
auto window = std::make_unique<WaylandWindow>(delegate, connection_.get());
if (!window->Initialize(std::move(properties)))
return nullptr;
return std::move(window);
return WaylandWindow::Create(delegate, connection_.get(),
std::move(properties));
}
std::unique_ptr<display::NativeDisplayDelegate> CreateNativeDisplayDelegate()
......
......@@ -37,7 +37,6 @@ WaylandTest::WaylandTest()
buffer_manager_gpu_ = std::make_unique<WaylandBufferManagerGpu>();
surface_factory_ = std::make_unique<WaylandSurfaceFactory>(
connection_.get(), buffer_manager_gpu_.get());
window_ = std::make_unique<WaylandWindow>(&delegate_, connection_.get());
}
WaylandTest::~WaylandTest() {}
......@@ -52,7 +51,8 @@ void WaylandTest::SetUp() {
PlatformWindowInitProperties properties;
properties.bounds = gfx::Rect(0, 0, 800, 600);
properties.type = PlatformWindowType::kWindow;
ASSERT_TRUE(window_->Initialize(std::move(properties)));
window_ = WaylandWindow::Create(&delegate_, connection_.get(),
std::move(properties));
ASSERT_NE(widget_, gfx::kNullAcceleratedWidget);
// Wait for the client to flush all pending requests from initialization.
......
......@@ -189,12 +189,12 @@ class WaylandBufferManagerTest : public WaylandTest {
std::unique_ptr<WaylandWindow> CreateWindow() {
testing::Mock::VerifyAndClearExpectations(&delegate_);
auto new_window =
std::make_unique<WaylandWindow>(&delegate_, connection_.get());
PlatformWindowInitProperties properties;
properties.bounds = gfx::Rect(0, 0, 800, 600);
properties.type = PlatformWindowType::kWindow;
EXPECT_TRUE(new_window->Initialize(std::move(properties)));
auto new_window = WaylandWindow::Create(&delegate_, connection_.get(),
std::move(properties));
EXPECT_TRUE(new_window);
Sync();
......
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