Commit 21cbdffe authored by Kramer Ge's avatar Kramer Ge Committed by Commit Bot

[ozone/wayland]Move wl_surface and related fields out of WaylandWindow

Currently a wl_surface is in a 1:1 relationship with WaylandWindow. To
get wayland subsurface forwarding, fields that are 1:1 to wl_surface
should be grouped and moved out of WaylandWindow. In the future,
WaylandWindow can have 1 to many relationship with wl_surfaces, some of
which are assigned wl_subsurface role.

A new WaylandSurface class is created. Original WaylandSurface is now
renamed to WaylandToplevelWindow.

Bug: 1063865
Change-Id: I23feed2a98329e3c0cc5067065af6e7dd1b2e4b4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2261252Reviewed-by: default avatarMaksim Sisov <msisov@igalia.com>
Commit-Queue: Kramer Ge <fangzhoug@chromium.org>
Cr-Commit-Position: refs/heads/master@{#782022}
parent 5c42a704
......@@ -105,6 +105,8 @@ source_set("wayland") {
"host/wayland_subsurface.h",
"host/wayland_surface.cc",
"host/wayland_surface.h",
"host/wayland_toplevel_window.cc",
"host/wayland_toplevel_window.h",
"host/wayland_touch.cc",
"host/wayland_touch.h",
"host/wayland_window.cc",
......
......@@ -16,6 +16,7 @@
#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_shm.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_zwp_linux_dmabuf.h"
......@@ -55,10 +56,10 @@ std::string NumberToString(uint32_t number) {
class WaylandBufferManagerHost::Surface {
public:
Surface(WaylandWindow* window,
Surface(WaylandSurface* wayland_surface,
WaylandConnection* connection,
WaylandBufferManagerHost* buffer_manager)
: window_(window),
: wayland_surface_(wayland_surface),
connection_(connection),
buffer_manager_(buffer_manager) {}
~Surface() = default;
......@@ -67,7 +68,7 @@ class WaylandBufferManagerHost::Surface {
DCHECK(!pending_buffer_);
// The window has already been destroyed.
if (!window_)
if (!wayland_surface_)
return true;
WaylandBuffer* buffer = GetBuffer(buffer_id);
......@@ -126,7 +127,7 @@ class WaylandBufferManagerHost::Surface {
// the client about successful swap.
// If the window has already been destroyed, no need to complete the
// submission.
if (buffer && !buffer->released && submitted_buffer_ && window_)
if (buffer && !buffer->released && submitted_buffer_ && wayland_surface_)
CompleteSubmission();
if (prev_submitted_buffer_ == buffer)
......@@ -172,11 +173,11 @@ class WaylandBufferManagerHost::Surface {
}
void ResetSurfaceContents() {
if (!window_)
if (!wayland_surface_)
return;
wl_surface_attach(window_->surface(), nullptr, 0, 0);
wl_surface_commit(window_->surface());
wl_surface_attach(wayland_surface_->surface(), nullptr, 0, 0);
wl_surface_commit(wayland_surface_->surface());
// We cannot reset |prev_submitted_buffer_| here as long as the surface
// might have attached a new buffer and is about to receive a release
......@@ -199,8 +200,8 @@ class WaylandBufferManagerHost::Surface {
bool HasBuffers() const { return !buffers_.empty(); }
void OnWindowRemoved() { window_ = nullptr; }
bool HasWindow() const { return !!window_; }
void OnWindowRemoved() { wayland_surface_ = nullptr; }
bool HasWindow() const { return !!wayland_surface_; }
void OnWindowConfigured() {
if (configured_)
......@@ -226,7 +227,7 @@ class WaylandBufferManagerHost::Surface {
using PresentationFeedbackQueue = std::vector<FeedbackInfo>;
bool CommitBufferInternal(WaylandBuffer* buffer) {
DCHECK(buffer && window_);
DCHECK(buffer && wayland_surface_);
DCHECK(!pending_buffer_);
DCHECK(!submitted_buffer_);
......@@ -274,7 +275,7 @@ class WaylandBufferManagerHost::Surface {
}
void DamageBuffer(WaylandBuffer* buffer) {
DCHECK(window_);
DCHECK(wayland_surface_);
gfx::Rect pending_damage_region = std::move(buffer->damage_region);
// If the size of the damage region is empty, wl_surface_damage must be
......@@ -290,10 +291,10 @@ class WaylandBufferManagerHost::Surface {
// https://bit.ly/2u00lv6 for details.
// We don't need to apply any scaling because pending_damage_region is
// already in buffer coordinates.
wl_surface_damage_buffer(window_->surface(), pending_damage_region.x(),
pending_damage_region.y(),
pending_damage_region.width(),
pending_damage_region.height());
wl_surface_damage_buffer(
wayland_surface_->surface(), pending_damage_region.x(),
pending_damage_region.y(), pending_damage_region.width(),
pending_damage_region.height());
} else {
// The calculation for damage region relies on two assumptions:
// 1) The buffer is always attached at surface location (0, 0)
......@@ -304,8 +305,9 @@ class WaylandBufferManagerHost::Surface {
// Note: The damage region may not be an integer multiple of scale. To
// keep the implementation simple, the x() and y() coordinates round down,
// and the width() and height() calculations always add an extra pixel.
int scale = window_->buffer_scale();
wl_surface_damage(window_->surface(), pending_damage_region.x() / scale,
int scale = wayland_surface_->buffer_scale();
wl_surface_damage(wayland_surface_->surface(),
pending_damage_region.x() / scale,
pending_damage_region.y() / scale,
pending_damage_region.width() / scale + 1,
pending_damage_region.height() / scale + 1);
......@@ -313,31 +315,32 @@ class WaylandBufferManagerHost::Surface {
}
void AttachBuffer(WaylandBuffer* buffer) {
DCHECK(window_ && configured_);
DCHECK(wayland_surface_ && configured_);
// The logic in DamageBuffer currently relies on attachment coordinates of
// (0, 0). If this changes, then the calculation in DamageBuffer will also
// need to be updated.
wl_surface_attach(window_->surface(), buffer->wl_buffer.get(), 0, 0);
wl_surface_attach(wayland_surface_->surface(), buffer->wl_buffer.get(), 0,
0);
}
void CommitSurface() {
DCHECK(window_);
wl_surface_commit(window_->surface());
DCHECK(wayland_surface_);
wl_surface_commit(wayland_surface_->surface());
}
void SetupFrameCallback() {
DCHECK(window_);
DCHECK(wayland_surface_);
static const wl_callback_listener frame_listener = {
&Surface::FrameCallbackDone};
DCHECK(!wl_frame_callback_);
wl_frame_callback_.reset(wl_surface_frame(window_->surface()));
wl_frame_callback_.reset(wl_surface_frame(wayland_surface_->surface()));
wl_callback_add_listener(wl_frame_callback_.get(), &frame_listener, this);
}
void SetupPresentationFeedback(uint32_t buffer_id) {
DCHECK(window_);
DCHECK(wayland_surface_);
// Set up presentation feedback.
if (!connection_->presentation())
return;
......@@ -348,7 +351,7 @@ class WaylandBufferManagerHost::Surface {
feedback_queue_.push_back(
{wl::Object<struct wp_presentation_feedback>(wp_presentation_feedback(
connection_->presentation(), window_->surface())),
connection_->presentation(), wayland_surface_->surface())),
buffer_id, /*feedback=*/base::nullopt,
/*submission_completed=*/false});
wp_presentation_feedback_add_listener(
......@@ -438,13 +441,13 @@ class WaylandBufferManagerHost::Surface {
prev_submitted_buffer_ = submitted_buffer_;
submitted_buffer_ = nullptr;
if (!window_)
if (!wayland_surface_)
return;
// We can now complete the latest submission. We had to wait for this
// release because SwapCompletionCallback indicates to the client that the
// previous buffer is available for reuse.
buffer_manager_->OnSubmission(window_->GetWidget(), id,
buffer_manager_->OnSubmission(wayland_surface_->GetRootWidget(), id,
gfx::SwapResult::SWAP_ACK);
// If presentation feedback is not supported, use a fake feedback. This
......@@ -452,7 +455,7 @@ class WaylandBufferManagerHost::Surface {
if (!connection_->presentation()) {
DCHECK(feedback_queue_.empty());
buffer_manager_->OnPresentation(
window_->GetWidget(), id,
wayland_surface_->GetWidget(), id,
gfx::PresentationFeedback(base::TimeTicks::Now(), base::TimeDelta(),
GetPresentationKindFlags(0)));
} else {
......@@ -506,15 +509,15 @@ class WaylandBufferManagerHost::Surface {
// This function ensures that we send OnPresentation for each buffer that
// already has had OnSubmission called for it (condition #2).
void ProcessPresentationFeedbacks() {
if (!window_)
if (!wayland_surface_)
return;
while (!feedback_queue_.empty()) {
const auto& info = feedback_queue_.front();
if (!info.submission_completed || !info.feedback.has_value())
break;
buffer_manager_->OnPresentation(window_->GetWidget(), info.buffer_id,
*info.feedback);
buffer_manager_->OnPresentation(wayland_surface_->GetWidget(),
info.buffer_id, *info.feedback);
feedback_queue_.erase(feedback_queue_.begin());
}
// This queue should be small - if not it's likely a bug.
......@@ -560,7 +563,7 @@ class WaylandBufferManagerHost::Surface {
void MaybeProcessPendingBuffer() {
// There is nothing to process if there is no pending buffer or the window
// has been destroyed.
if (!pending_buffer_ || !window_)
if (!pending_buffer_ || !wayland_surface_)
return;
// This request may come earlier than the Wayland compositor has imported a
......@@ -589,7 +592,7 @@ class WaylandBufferManagerHost::Surface {
// WaylandWindow.
// Non-owned. The window this helper surface stores and submits buffers for.
const WaylandWindow* window_;
const WaylandSurface* wayland_surface_;
// Non-owned pointer to the connection.
WaylandConnection* const connection_;
......@@ -651,7 +654,7 @@ WaylandBufferManagerHost::~WaylandBufferManagerHost() {
void WaylandBufferManagerHost::OnWindowAdded(WaylandWindow* window) {
DCHECK(window);
surfaces_[window->GetWidget()] =
std::make_unique<Surface>(window, connection_, this);
std::make_unique<Surface>(window->wayland_surface(), connection_, this);
}
void WaylandBufferManagerHost::OnWindowRemoved(WaylandWindow* window) {
......
......@@ -4,351 +4,21 @@
#include "ui/ozone/platform/wayland/host/wayland_surface.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/hit_test.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/platform/wayland/host/shell_object_factory.h"
#include "ui/ozone/platform/wayland/host/shell_surface_wrapper.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_data_drag_controller.h"
#include "ui/ozone/platform/wayland/host/wayland_event_source.h"
#include "ui/platform_window/platform_window_handler/wm_drop_handler.h"
#include "ui/ozone/platform/wayland/host/wayland_window.h"
namespace ui {
WaylandSurface::WaylandSurface(PlatformWindowDelegate* delegate,
WaylandConnection* connection)
: WaylandWindow(delegate, connection),
state_(PlatformWindowState::kNormal) {
// Set a class property key, which allows |this| to be used for interactive
// events, e.g. move or resize.
SetWmMoveResizeHandler(this, AsWmMoveResizeHandler());
WaylandSurface::WaylandSurface() = default;
WaylandSurface::~WaylandSurface() = default;
// Set a class property key, which allows |this| to be used for drag action.
SetWmDragHandler(this, this);
gfx::AcceleratedWidget WaylandSurface::GetWidget() const {
if (!surface_)
return gfx::kNullAcceleratedWidget;
return surface_.id();
}
WaylandSurface::~WaylandSurface() {
if (drag_handler_delegate_) {
drag_handler_delegate_->OnDragFinished(
DragDropTypes::DragOperation::DRAG_NONE);
}
}
bool WaylandSurface::CreateShellSurface() {
ShellObjectFactory factory;
shell_surface_ = factory.CreateShellSurfaceWrapper(connection(), this);
if (!shell_surface_) {
LOG(ERROR) << "Failed to create a ShellSurface.";
return false;
}
shell_surface_->SetAppId(app_id_);
shell_surface_->SetTitle(window_title_);
SetSizeConstraints();
TriggerStateChanges();
return true;
}
void WaylandSurface::ApplyPendingBounds() {
if (pending_bounds_dip_.IsEmpty())
return;
DCHECK(shell_surface_);
SetBoundsDip(pending_bounds_dip_);
shell_surface_->SetWindowGeometry(pending_bounds_dip_);
pending_bounds_dip_ = gfx::Rect();
connection()->ScheduleFlush();
}
void WaylandSurface::DispatchHostWindowDragMovement(
int hittest,
const gfx::Point& pointer_location_in_px) {
DCHECK(shell_surface_);
connection()->event_source()->ResetPointerFlags();
if (hittest == HTCAPTION)
shell_surface_->SurfaceMove(connection());
else
shell_surface_->SurfaceResize(connection(), hittest);
connection()->ScheduleFlush();
}
void WaylandSurface::StartDrag(const ui::OSExchangeData& data,
int operation,
gfx::NativeCursor cursor,
WmDragHandler::Delegate* delegate) {
DCHECK(!drag_handler_delegate_);
drag_handler_delegate_ = delegate;
connection()->data_drag_controller()->StartSession(data, operation);
}
void WaylandSurface::Show(bool inactive) {
if (shell_surface_)
return;
if (!CreateShellSurface()) {
Close();
return;
}
UpdateBufferScale(false);
}
void WaylandSurface::Hide() {
if (!shell_surface_)
return;
if (child_window()) {
child_window()->Hide();
set_child_window(nullptr);
}
shell_surface_.reset();
connection()->ScheduleFlush();
// Detach buffer from surface in order to completely shutdown menus and
// tooltips, and release resources.
connection()->buffer_manager_host()->ResetSurfaceContents(GetWidget());
}
bool WaylandSurface::IsVisible() const {
// X and Windows return true if the window is minimized. For consistency, do
// the same.
return !!shell_surface_ || state_ == PlatformWindowState::kMinimized;
}
void WaylandSurface::SetTitle(const base::string16& title) {
if (window_title_ == title)
return;
window_title_ = title;
if (shell_surface_) {
shell_surface_->SetTitle(title);
connection()->ScheduleFlush();
}
}
void WaylandSurface::ToggleFullscreen() {
// TODO(msisov, tonikitoo): add multiscreen support. As the documentation says
// if xdg_toplevel_set_fullscreen() is not provided with wl_output, it's up
// to the compositor to choose which display will be used to map this surface.
// We must track the previous state to correctly say our state as long as it
// can be the maximized instead of normal one.
PlatformWindowState new_state = PlatformWindowState::kUnknown;
if (state_ == PlatformWindowState::kFullScreen) {
if (previous_state_ == PlatformWindowState::kMaximized)
new_state = previous_state_;
else
new_state = PlatformWindowState::kNormal;
} else {
new_state = PlatformWindowState::kFullScreen;
}
SetWindowState(new_state);
}
void WaylandSurface::Maximize() {
SetWindowState(PlatformWindowState::kMaximized);
}
void WaylandSurface::Minimize() {
SetWindowState(PlatformWindowState::kMinimized);
}
void WaylandSurface::Restore() {
DCHECK(shell_surface_);
SetWindowState(PlatformWindowState::kNormal);
}
PlatformWindowState WaylandSurface::GetPlatformWindowState() const {
return state_;
}
void WaylandSurface::SizeConstraintsChanged() {
// Size constraints only make sense for normal windows.
if (!shell_surface_)
return;
DCHECK(delegate());
min_size_ = delegate()->GetMinimumSizeForWindow();
max_size_ = delegate()->GetMaximumSizeForWindow();
SetSizeConstraints();
}
void WaylandSurface::HandleSurfaceConfigure(int32_t width,
int32_t height,
bool is_maximized,
bool is_fullscreen,
bool is_activated) {
// Store the old state to propagte state changes if Wayland decides to change
// the state to something else.
PlatformWindowState old_state = state_;
if (state_ == PlatformWindowState::kMinimized && !is_activated) {
state_ = PlatformWindowState::kMinimized;
} else if (is_fullscreen) {
state_ = PlatformWindowState::kFullScreen;
} else if (is_maximized) {
state_ = PlatformWindowState::kMaximized;
} else {
state_ = PlatformWindowState::kNormal;
}
const bool state_changed = old_state != state_;
const bool is_normal = state_ == PlatformWindowState::kNormal;
// Update state before notifying delegate.
const bool did_active_change = is_active_ != is_activated;
is_active_ = is_activated;
// Rather than call SetBounds here for every configure event, just save the
// most recent bounds, and have WaylandConnection call ApplyPendingBounds
// when it has finished processing events. We may get many configure events
// in a row during an interactive resize, and only the last one matters.
//
// Width or height set to 0 means that we should decide on width and height by
// ourselves, but we don't want to set them to anything else. Use restored
// bounds size or the current bounds iff the current state is normal (neither
// maximized nor fullscreen).
//
// Note: if the browser was started with --start-fullscreen and a user exits
// the fullscreen mode, wayland may set the width and height to be 1. Instead,
// explicitly set the bounds to the current desired ones or the previous
// bounds.
if (width > 1 && height > 1) {
pending_bounds_dip_ = gfx::Rect(0, 0, width, height);
} else if (is_normal) {
pending_bounds_dip_.set_size(
gfx::ScaleToRoundedSize(GetRestoredBoundsInPixels().IsEmpty()
? GetBounds().size()
: GetRestoredBoundsInPixels().size(),
1.0 / buffer_scale()));
}
// Store the restored bounds of current state differs from the normal state.
// It can be client or compositor side change from normal to something else.
// Thus, we must store previous bounds to restore later.
SetOrResetRestoredBounds();
ApplyPendingBounds();
if (state_changed)
delegate()->OnWindowStateChanged(state_);
if (did_active_change)
delegate()->OnActivationChanged(is_active_);
}
void WaylandSurface::OnDragEnter(const gfx::PointF& point,
std::unique_ptr<OSExchangeData> data,
int operation) {
WmDropHandler* drop_handler = GetWmDropHandler(*this);
if (!drop_handler)
return;
// Wayland sends locations in DIP so they need to be translated to
// physical pixels.
drop_handler->OnDragEnter(
gfx::ScalePoint(point, buffer_scale(), buffer_scale()), std::move(data),
operation);
}
int WaylandSurface::OnDragMotion(const gfx::PointF& point, int operation) {
WmDropHandler* drop_handler = GetWmDropHandler(*this);
if (!drop_handler)
return 0;
// Wayland sends locations in DIP so they need to be translated to
// physical pixels.
return drop_handler->OnDragMotion(
gfx::ScalePoint(point, buffer_scale(), buffer_scale()), operation);
}
void WaylandSurface::OnDragDrop(std::unique_ptr<OSExchangeData> data) {
WmDropHandler* drop_handler = GetWmDropHandler(*this);
if (!drop_handler)
return;
drop_handler->OnDragDrop(std::move(data));
}
void WaylandSurface::OnDragLeave() {
WmDropHandler* drop_handler = GetWmDropHandler(*this);
if (!drop_handler)
return;
drop_handler->OnDragLeave();
}
void WaylandSurface::OnDragSessionClose(uint32_t dnd_action) {
DCHECK(drag_handler_delegate_);
drag_handler_delegate_->OnDragFinished(dnd_action);
drag_handler_delegate_ = nullptr;
connection()->event_source()->ResetPointerFlags();
}
bool WaylandSurface::OnInitialize(PlatformWindowInitProperties properties) {
app_id_ = properties.wm_class_class;
return true;
}
void WaylandSurface::TriggerStateChanges() {
if (!shell_surface_)
return;
if (state_ == PlatformWindowState::kFullScreen)
shell_surface_->SetFullscreen();
else
shell_surface_->UnSetFullscreen();
// Call UnSetMaximized only if current state is normal. Otherwise, if the
// current state is fullscreen and the previous is maximized, calling
// UnSetMaximized may result in wrong restored window position that clients
// are not allowed to know about.
if (state_ == PlatformWindowState::kMaximized)
shell_surface_->SetMaximized();
else if (state_ == PlatformWindowState::kNormal)
shell_surface_->UnSetMaximized();
if (state_ == PlatformWindowState::kMinimized)
shell_surface_->SetMinimized();
connection()->ScheduleFlush();
}
void WaylandSurface::SetWindowState(PlatformWindowState state) {
previous_state_ = state_;
state_ = state;
TriggerStateChanges();
}
WmMoveResizeHandler* WaylandSurface::AsWmMoveResizeHandler() {
return static_cast<WmMoveResizeHandler*>(this);
}
void WaylandSurface::SetSizeConstraints() {
if (min_size_.has_value())
shell_surface_->SetMinSize(min_size_->width(), min_size_->height());
if (max_size_.has_value())
shell_surface_->SetMaxSize(max_size_->width(), max_size_->height());
connection()->ScheduleFlush();
}
void WaylandSurface::SetOrResetRestoredBounds() {
// The |restored_bounds_| are used when the window gets back to normal
// state after it went maximized or fullscreen. So we reset these if the
// window has just become normal and store the current bounds if it is
// either going out of normal state or simply changes the state and we don't
// have any meaningful value stored.
if (GetPlatformWindowState() == PlatformWindowState::kNormal) {
SetRestoredBoundsInPixels({});
} else if (GetRestoredBoundsInPixels().IsEmpty()) {
SetRestoredBoundsInPixels(GetBounds());
}
gfx::AcceleratedWidget WaylandSurface::GetRootWidget() const {
return root_window_->GetWidget();
}
} // namespace ui
......@@ -5,119 +5,38 @@
#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SURFACE_H_
#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SURFACE_H_
#include "ui/ozone/platform/wayland/host/wayland_window.h"
#include "ui/platform_window/platform_window_handler/wm_drag_handler.h"
#include "ui/platform_window/platform_window_handler/wm_move_resize_handler.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/platform/wayland/common/wayland_object.h"
namespace ui {
class ShellSurfaceWrapper;
class WaylandWindow;
class WaylandSurface : public WaylandWindow,
public WmMoveResizeHandler,
public WmDragHandler {
// Wrapper of a wl_surface, owned by a WaylandWindow or a WlSubsurface.
class WaylandSurface {
public:
WaylandSurface(PlatformWindowDelegate* delegate,
WaylandConnection* connection);
~WaylandSurface() override;
ShellSurfaceWrapper* shell_surface() const { return shell_surface_.get(); }
// Apply the bounds specified in the most recent configure event. This should
// be called after processing all pending events in the wayland connection.
void ApplyPendingBounds();
WaylandSurface();
WaylandSurface(const WaylandSurface&) = delete;
WaylandSurface& operator=(const WaylandSurface&) = delete;
~WaylandSurface();
// WmMoveResizeHandler
void DispatchHostWindowDragMovement(
int hittest,
const gfx::Point& pointer_location_in_px) override;
WaylandWindow* root_window() const { return root_window_; }
wl_surface* surface() const { return surface_.get(); }
int32_t buffer_scale() const { return buffer_scale_; }
// WmDragHandler
void StartDrag(const ui::OSExchangeData& data,
int operation,
gfx::NativeCursor cursor,
WmDragHandler::Delegate* delegate) override;
// PlatformWindow
void Show(bool inactive) override;
void Hide() override;
bool IsVisible() const override;
void SetTitle(const base::string16& title) override;
void ToggleFullscreen() override;
void Maximize() override;
void Minimize() override;
void Restore() override;
PlatformWindowState GetPlatformWindowState() const override;
void SizeConstraintsChanged() override;
// gfx::AcceleratedWidget identifies a wl_surface or a ui::WaylandWindow. Note
// that GetWidget() and GetRootWidget() do not necessarily return the same
// result.
gfx::AcceleratedWidget GetWidget() const;
gfx::AcceleratedWidget GetRootWidget() const;
private:
// WaylandWindow overrides:
void HandleSurfaceConfigure(int32_t widht,
int32_t height,
bool is_maximized,
bool is_fullscreen,
bool is_activated) override;
void OnDragEnter(const gfx::PointF& point,
std::unique_ptr<OSExchangeData> data,
int operation) override;
int OnDragMotion(const gfx::PointF& point, int operation) override;
void OnDragDrop(std::unique_ptr<OSExchangeData> data) override;
void OnDragLeave() override;
void OnDragSessionClose(uint32_t dnd_action) override;
bool OnInitialize(PlatformWindowInitProperties properties) override;
void TriggerStateChanges();
void SetWindowState(PlatformWindowState state);
// Creates a surface window, which is visible as a main window.
bool CreateShellSurface();
WmMoveResizeHandler* AsWmMoveResizeHandler();
// Propagates the |min_size_| and |max_size_| to the ShellSurface.
void SetSizeConstraints();
void SetOrResetRestoredBounds();
// Wrappers around shell surface.
std::unique_ptr<ShellSurfaceWrapper> shell_surface_;
WmDragHandler::Delegate* drag_handler_delegate_ = nullptr;
// These bounds attributes below have suffices that indicate units used.
// Wayland operates in DIP but the platform operates in physical pixels so
// our WaylandSurface is the link that has to translate the units. See also
// comments in the implementation.
//
// Bounds that will be applied when the window state is finalized. The window
// may get several configuration events that update the pending bounds, and
// only upon finalizing the state is the latest value stored as the current
// bounds via |ApplyPendingBounds|. Measured in DIP because updated in the
// handler that receives DIP from Wayland.
gfx::Rect pending_bounds_dip_;
// Contains the current state of the window.
PlatformWindowState state_;
// Contains the previous state of the window.
PlatformWindowState previous_state_;
bool is_active_ = false;
// Id of the chromium app passed through
// PlatformWindowInitProperties::wm_class_class. This is used by Wayland
// compositor to identify the app, unite it's windows into the same stack of
// windows and find *.desktop file to set various preferences including icons.
std::string app_id_;
// Title of the ShellSurface.
base::string16 window_title_;
// Max and min sizes of the WaylandSurface window.
base::Optional<gfx::Size> min_size_;
base::Optional<gfx::Size> max_size_;
DISALLOW_COPY_AND_ASSIGN(WaylandSurface);
WaylandWindow* root_window_ = nullptr;
wl::Object<wl_surface> surface_;
// Wayland's scale factor for the output that this window currently belongs
// to.
int32_t buffer_scale_ = 1;
friend class WaylandWindow;
};
} // 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.
#include "ui/ozone/platform/wayland/host/wayland_toplevel_window.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/hit_test.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/platform/wayland/host/shell_object_factory.h"
#include "ui/ozone/platform/wayland/host/shell_surface_wrapper.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_data_drag_controller.h"
#include "ui/ozone/platform/wayland/host/wayland_event_source.h"
#include "ui/platform_window/platform_window_handler/wm_drop_handler.h"
namespace ui {
WaylandToplevelWindow::WaylandToplevelWindow(PlatformWindowDelegate* delegate,
WaylandConnection* connection)
: WaylandWindow(delegate, connection),
state_(PlatformWindowState::kNormal) {
// Set a class property key, which allows |this| to be used for interactive
// events, e.g. move or resize.
SetWmMoveResizeHandler(this, AsWmMoveResizeHandler());
// Set a class property key, which allows |this| to be used for drag action.
SetWmDragHandler(this, this);
}
WaylandToplevelWindow::~WaylandToplevelWindow() {
if (drag_handler_delegate_) {
drag_handler_delegate_->OnDragFinished(
DragDropTypes::DragOperation::DRAG_NONE);
}
}
bool WaylandToplevelWindow::CreateShellSurface() {
ShellObjectFactory factory;
shell_surface_ = factory.CreateShellSurfaceWrapper(connection(), this);
if (!shell_surface_) {
LOG(ERROR) << "Failed to create a ShellSurface.";
return false;
}
shell_surface_->SetAppId(app_id_);
shell_surface_->SetTitle(window_title_);
SetSizeConstraints();
TriggerStateChanges();
return true;
}
void WaylandToplevelWindow::ApplyPendingBounds() {
if (pending_bounds_dip_.IsEmpty())
return;
DCHECK(shell_surface_);
SetBoundsDip(pending_bounds_dip_);
shell_surface_->SetWindowGeometry(pending_bounds_dip_);
pending_bounds_dip_ = gfx::Rect();
connection()->ScheduleFlush();
}
void WaylandToplevelWindow::DispatchHostWindowDragMovement(
int hittest,
const gfx::Point& pointer_location_in_px) {
DCHECK(shell_surface_);
connection()->event_source()->ResetPointerFlags();
if (hittest == HTCAPTION)
shell_surface_->SurfaceMove(connection());
else
shell_surface_->SurfaceResize(connection(), hittest);
connection()->ScheduleFlush();
}
void WaylandToplevelWindow::StartDrag(const ui::OSExchangeData& data,
int operation,
gfx::NativeCursor cursor,
WmDragHandler::Delegate* delegate) {
DCHECK(!drag_handler_delegate_);
drag_handler_delegate_ = delegate;
connection()->data_drag_controller()->StartSession(data, operation);
}
void WaylandToplevelWindow::Show(bool inactive) {
if (shell_surface_)
return;
if (!CreateShellSurface()) {
Close();
return;
}
UpdateBufferScale(false);
}
void WaylandToplevelWindow::Hide() {
if (!shell_surface_)
return;
if (child_window()) {
child_window()->Hide();
set_child_window(nullptr);
}
shell_surface_.reset();
connection()->ScheduleFlush();
// Detach buffer from surface in order to completely shutdown menus and
// tooltips, and release resources.
connection()->buffer_manager_host()->ResetSurfaceContents(GetWidget());
}
bool WaylandToplevelWindow::IsVisible() const {
// X and Windows return true if the window is minimized. For consistency, do
// the same.
return !!shell_surface_ || state_ == PlatformWindowState::kMinimized;
}
void WaylandToplevelWindow::SetTitle(const base::string16& title) {
if (window_title_ == title)
return;
window_title_ = title;
if (shell_surface_) {
shell_surface_->SetTitle(title);
connection()->ScheduleFlush();
}
}
void WaylandToplevelWindow::ToggleFullscreen() {
// TODO(msisov, tonikitoo): add multiscreen support. As the documentation says
// if xdg_toplevel_set_fullscreen() is not provided with wl_output, it's up
// to the compositor to choose which display will be used to map this surface.
// We must track the previous state to correctly say our state as long as it
// can be the maximized instead of normal one.
PlatformWindowState new_state = PlatformWindowState::kUnknown;
if (state_ == PlatformWindowState::kFullScreen) {
if (previous_state_ == PlatformWindowState::kMaximized)
new_state = previous_state_;
else
new_state = PlatformWindowState::kNormal;
} else {
new_state = PlatformWindowState::kFullScreen;
}
SetWindowState(new_state);
}
void WaylandToplevelWindow::Maximize() {
SetWindowState(PlatformWindowState::kMaximized);
}
void WaylandToplevelWindow::Minimize() {
SetWindowState(PlatformWindowState::kMinimized);
}
void WaylandToplevelWindow::Restore() {
DCHECK(shell_surface_);
SetWindowState(PlatformWindowState::kNormal);
}
PlatformWindowState WaylandToplevelWindow::GetPlatformWindowState() const {
return state_;
}
void WaylandToplevelWindow::SizeConstraintsChanged() {
// Size constraints only make sense for normal windows.
if (!shell_surface_)
return;
DCHECK(delegate());
min_size_ = delegate()->GetMinimumSizeForWindow();
max_size_ = delegate()->GetMaximumSizeForWindow();
SetSizeConstraints();
}
void WaylandToplevelWindow::HandleSurfaceConfigure(int32_t width,
int32_t height,
bool is_maximized,
bool is_fullscreen,
bool is_activated) {
// Store the old state to propagte state changes if Wayland decides to change
// the state to something else.
PlatformWindowState old_state = state_;
if (state_ == PlatformWindowState::kMinimized && !is_activated) {
state_ = PlatformWindowState::kMinimized;
} else if (is_fullscreen) {
state_ = PlatformWindowState::kFullScreen;
} else if (is_maximized) {
state_ = PlatformWindowState::kMaximized;
} else {
state_ = PlatformWindowState::kNormal;
}
const bool state_changed = old_state != state_;
const bool is_normal = state_ == PlatformWindowState::kNormal;
// Update state before notifying delegate.
const bool did_active_change = is_active_ != is_activated;
is_active_ = is_activated;
// Rather than call SetBounds here for every configure event, just save the
// most recent bounds, and have WaylandConnection call ApplyPendingBounds
// when it has finished processing events. We may get many configure events
// in a row during an interactive resize, and only the last one matters.
//
// Width or height set to 0 means that we should decide on width and height by
// ourselves, but we don't want to set them to anything else. Use restored
// bounds size or the current bounds iff the current state is normal (neither
// maximized nor fullscreen).
//
// Note: if the browser was started with --start-fullscreen and a user exits
// the fullscreen mode, wayland may set the width and height to be 1. Instead,
// explicitly set the bounds to the current desired ones or the previous
// bounds.
if (width > 1 && height > 1) {
pending_bounds_dip_ = gfx::Rect(0, 0, width, height);
} else if (is_normal) {
pending_bounds_dip_.set_size(
gfx::ScaleToRoundedSize(GetRestoredBoundsInPixels().IsEmpty()
? GetBounds().size()
: GetRestoredBoundsInPixels().size(),
1.0 / buffer_scale()));
}
// Store the restored bounds of current state differs from the normal state.
// It can be client or compositor side change from normal to something else.
// Thus, we must store previous bounds to restore later.
SetOrResetRestoredBounds();
ApplyPendingBounds();
if (state_changed)
delegate()->OnWindowStateChanged(state_);
if (did_active_change)
delegate()->OnActivationChanged(is_active_);
}
void WaylandToplevelWindow::OnDragEnter(const gfx::PointF& point,
std::unique_ptr<OSExchangeData> data,
int operation) {
WmDropHandler* drop_handler = GetWmDropHandler(*this);
if (!drop_handler)
return;
// Wayland sends locations in DIP so they need to be translated to
// physical pixels.
drop_handler->OnDragEnter(
gfx::ScalePoint(point, buffer_scale(), buffer_scale()), std::move(data),
operation);
}
int WaylandToplevelWindow::OnDragMotion(const gfx::PointF& point,
int operation) {
WmDropHandler* drop_handler = GetWmDropHandler(*this);
if (!drop_handler)
return 0;
// Wayland sends locations in DIP so they need to be translated to
// physical pixels.
return drop_handler->OnDragMotion(
gfx::ScalePoint(point, buffer_scale(), buffer_scale()), operation);
}
void WaylandToplevelWindow::OnDragDrop(std::unique_ptr<OSExchangeData> data) {
WmDropHandler* drop_handler = GetWmDropHandler(*this);
if (!drop_handler)
return;
drop_handler->OnDragDrop(std::move(data));
}
void WaylandToplevelWindow::OnDragLeave() {
WmDropHandler* drop_handler = GetWmDropHandler(*this);
if (!drop_handler)
return;
drop_handler->OnDragLeave();
}
void WaylandToplevelWindow::OnDragSessionClose(uint32_t dnd_action) {
DCHECK(drag_handler_delegate_);
drag_handler_delegate_->OnDragFinished(dnd_action);
drag_handler_delegate_ = nullptr;
connection()->event_source()->ResetPointerFlags();
}
bool WaylandToplevelWindow::OnInitialize(
PlatformWindowInitProperties properties) {
app_id_ = properties.wm_class_class;
return true;
}
void WaylandToplevelWindow::TriggerStateChanges() {
if (!shell_surface_)
return;
if (state_ == PlatformWindowState::kFullScreen)
shell_surface_->SetFullscreen();
else
shell_surface_->UnSetFullscreen();
// Call UnSetMaximized only if current state is normal. Otherwise, if the
// current state is fullscreen and the previous is maximized, calling
// UnSetMaximized may result in wrong restored window position that clients
// are not allowed to know about.
if (state_ == PlatformWindowState::kMaximized)
shell_surface_->SetMaximized();
else if (state_ == PlatformWindowState::kNormal)
shell_surface_->UnSetMaximized();
if (state_ == PlatformWindowState::kMinimized)
shell_surface_->SetMinimized();
connection()->ScheduleFlush();
}
void WaylandToplevelWindow::SetWindowState(PlatformWindowState state) {
previous_state_ = state_;
state_ = state;
TriggerStateChanges();
}
WmMoveResizeHandler* WaylandToplevelWindow::AsWmMoveResizeHandler() {
return static_cast<WmMoveResizeHandler*>(this);
}
void WaylandToplevelWindow::SetSizeConstraints() {
if (min_size_.has_value())
shell_surface_->SetMinSize(min_size_->width(), min_size_->height());
if (max_size_.has_value())
shell_surface_->SetMaxSize(max_size_->width(), max_size_->height());
connection()->ScheduleFlush();
}
void WaylandToplevelWindow::SetOrResetRestoredBounds() {
// The |restored_bounds_| are used when the window gets back to normal
// state after it went maximized or fullscreen. So we reset these if the
// window has just become normal and store the current bounds if it is
// either going out of normal state or simply changes the state and we don't
// have any meaningful value stored.
if (GetPlatformWindowState() == PlatformWindowState::kNormal) {
SetRestoredBoundsInPixels({});
} else if (GetRestoredBoundsInPixels().IsEmpty()) {
SetRestoredBoundsInPixels(GetBounds());
}
}
} // namespace ui
// 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.
#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_TOPLEVEL_WINDOW_H_
#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_TOPLEVEL_WINDOW_H_
#include "ui/ozone/platform/wayland/host/wayland_window.h"
#include "ui/platform_window/platform_window_handler/wm_drag_handler.h"
#include "ui/platform_window/platform_window_handler/wm_move_resize_handler.h"
namespace ui {
class ShellSurfaceWrapper;
class WaylandToplevelWindow : public WaylandWindow,
public WmMoveResizeHandler,
public WmDragHandler {
public:
WaylandToplevelWindow(PlatformWindowDelegate* delegate,
WaylandConnection* connection);
WaylandToplevelWindow(const WaylandToplevelWindow&) = delete;
WaylandToplevelWindow& operator=(const WaylandToplevelWindow&) = delete;
~WaylandToplevelWindow() override;
ShellSurfaceWrapper* shell_surface() const { return shell_surface_.get(); }
// Apply the bounds specified in the most recent configure event. This should
// be called after processing all pending events in the wayland connection.
void ApplyPendingBounds();
// WmMoveResizeHandler
void DispatchHostWindowDragMovement(
int hittest,
const gfx::Point& pointer_location_in_px) override;
// WmDragHandler
void StartDrag(const ui::OSExchangeData& data,
int operation,
gfx::NativeCursor cursor,
WmDragHandler::Delegate* delegate) override;
// PlatformWindow
void Show(bool inactive) override;
void Hide() override;
bool IsVisible() const override;
void SetTitle(const base::string16& title) override;
void ToggleFullscreen() override;
void Maximize() override;
void Minimize() override;
void Restore() override;
PlatformWindowState GetPlatformWindowState() const override;
void SizeConstraintsChanged() override;
private:
// WaylandWindow overrides:
void HandleSurfaceConfigure(int32_t widht,
int32_t height,
bool is_maximized,
bool is_fullscreen,
bool is_activated) override;
void OnDragEnter(const gfx::PointF& point,
std::unique_ptr<OSExchangeData> data,
int operation) override;
int OnDragMotion(const gfx::PointF& point, int operation) override;
void OnDragDrop(std::unique_ptr<OSExchangeData> data) override;
void OnDragLeave() override;
void OnDragSessionClose(uint32_t dnd_action) override;
bool OnInitialize(PlatformWindowInitProperties properties) override;
void TriggerStateChanges();
void SetWindowState(PlatformWindowState state);
// Creates a surface window, which is visible as a main window.
bool CreateShellSurface();
WmMoveResizeHandler* AsWmMoveResizeHandler();
// Propagates the |min_size_| and |max_size_| to the ShellSurface.
void SetSizeConstraints();
void SetOrResetRestoredBounds();
// Wrappers around shell surface.
std::unique_ptr<ShellSurfaceWrapper> shell_surface_;
WmDragHandler::Delegate* drag_handler_delegate_ = nullptr;
// These bounds attributes below have suffices that indicate units used.
// Wayland operates in DIP but the platform operates in physical pixels so
// our WaylandToplevelWindow is the link that has to translate the units. See
// also comments in the implementation.
//
// Bounds that will be applied when the window state is finalized. The window
// may get several configuration events that update the pending bounds, and
// only upon finalizing the state is the latest value stored as the current
// bounds via |ApplyPendingBounds|. Measured in DIP because updated in the
// handler that receives DIP from Wayland.
gfx::Rect pending_bounds_dip_;
// Contains the current state of the window.
PlatformWindowState state_;
// Contains the previous state of the window.
PlatformWindowState previous_state_;
bool is_active_ = false;
// Id of the chromium app passed through
// PlatformWindowInitProperties::wm_class_class. This is used by Wayland
// compositor to identify the app, unite it's windows into the same stack of
// windows and find *.desktop file to set various preferences including icons.
std::string app_id_;
// Title of the ShellSurface.
base::string16 window_title_;
// Max and min sizes of the WaylandToplevelWindow window.
base::Optional<gfx::Size> min_size_;
base::Optional<gfx::Size> max_size_;
};
} // namespace ui
#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_TOPLEVEL_WINDOW_H_
......@@ -30,7 +30,7 @@ WaylandWindow::WaylandWindow(PlatformWindowDelegate* delegate,
WaylandWindow::~WaylandWindow() {
PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
if (surface_)
if (surface())
connection_->wayland_window_manager()->RemoveWindow(GetWidget());
if (parent_window_)
......@@ -61,7 +61,7 @@ void WaylandWindow::UpdateBufferScale(bool update_bounds) {
int32_t new_scale = 0;
if (parent_window_) {
new_scale = parent_window_->buffer_scale_;
new_scale = parent_window_->buffer_scale();
ui_scale_ = parent_window_->ui_scale_;
} else {
const auto display = (widget == gfx::kNullAcceleratedWidget)
......@@ -80,9 +80,7 @@ void WaylandWindow::UpdateBufferScale(bool update_bounds) {
}
gfx::AcceleratedWidget WaylandWindow::GetWidget() const {
if (!surface_)
return gfx::kNullAcceleratedWidget;
return surface_.id();
return wayland_surface_.GetWidget();
}
void WaylandWindow::SetPointerFocus(bool focus) {
has_pointer_focus_ = focus;
......@@ -163,7 +161,7 @@ void WaylandWindow::Restore() {}
PlatformWindowState WaylandWindow::GetPlatformWindowState() const {
// Remove normal state for all the other types of windows as it's only the
// WaylandSurface that supports state changes.
// WaylandToplevelWindow that supports state changes.
return PlatformWindowState::kNormal;
}
......@@ -254,7 +252,7 @@ uint32_t WaylandWindow::DispatchEvent(const PlatformEvent& native_event) {
// Wayland sends locations in DIP so they need to be translated to
// physical pixels.
event->AsLocatedEvent()->set_location_f(gfx::ScalePoint(
event->AsLocatedEvent()->location_f(), buffer_scale_, buffer_scale_));
event->AsLocatedEvent()->location_f(), buffer_scale(), buffer_scale()));
// We must reroute the events to the event grabber iff these windows belong
// to the same root parent window. For example, there are 2 top level
......@@ -314,24 +312,26 @@ void WaylandWindow::OnDragLeave() {}
void WaylandWindow::OnDragSessionClose(uint32_t dnd_action) {}
void WaylandWindow::SetBoundsDip(const gfx::Rect& bounds_dip) {
SetBounds(gfx::ScaleToRoundedRect(bounds_dip, buffer_scale_));
SetBounds(gfx::ScaleToRoundedRect(bounds_dip, buffer_scale()));
}
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);
DCHECK_EQ(buffer_scale(), 1);
bounds_px_ = properties.bounds;
opacity_ = properties.opacity;
type_ = properties.type;
surface_.reset(wl_compositor_create_surface(connection_->compositor()));
if (!surface_) {
wayland_surface_.surface_.reset(
wl_compositor_create_surface(connection_->compositor()));
wayland_surface_.root_window_ = this;
if (!surface()) {
LOG(ERROR) << "Failed to create wl_surface";
return false;
}
wl_surface_set_user_data(surface_.get(), this);
wl_surface_set_user_data(surface(), this);
AddSurfaceListener();
connection_->wayland_window_manager()->AddWindow(GetWidget(), this);
......@@ -354,16 +354,16 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) {
void WaylandWindow::SetBufferScale(int32_t new_scale, bool update_bounds) {
DCHECK_GT(new_scale, 0);
if (new_scale == buffer_scale_)
if (new_scale == buffer_scale())
return;
auto old_scale = buffer_scale_;
buffer_scale_ = new_scale;
auto old_scale = buffer_scale();
wayland_surface_.buffer_scale_ = new_scale;
if (update_bounds)
SetBoundsDip(gfx::ScaleToRoundedRect(bounds_px_, 1.0 / old_scale));
DCHECK(surface());
wl_surface_set_buffer_scale(surface(), buffer_scale_);
wl_surface_set_buffer_scale(surface(), buffer_scale());
connection_->ScheduleFlush();
}
......@@ -398,7 +398,7 @@ void WaylandWindow::AddSurfaceListener() {
&WaylandWindow::Enter,
&WaylandWindow::Leave,
};
wl_surface_add_listener(surface_.get(), &surface_listener, this);
wl_surface_add_listener(surface(), &surface_listener, this);
}
void WaylandWindow::AddEnteredOutputId(struct wl_output* output) {
......@@ -511,7 +511,7 @@ void WaylandWindow::Enter(void* data,
struct wl_output* output) {
auto* window = static_cast<WaylandWindow*>(data);
if (window) {
DCHECK(window->surface_.get() == wl_surface);
DCHECK(window->surface() == wl_surface);
window->AddEnteredOutputId(output);
}
}
......@@ -522,7 +522,7 @@ void WaylandWindow::Leave(void* data,
struct wl_output* output) {
auto* window = static_cast<WaylandWindow*>(data);
if (window) {
DCHECK(window->surface_.get() == wl_surface);
DCHECK(window->surface() == wl_surface);
window->RemoveEnteredOutputId(output);
}
}
......
......@@ -17,6 +17,7 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/platform/wayland/common/wayland_object.h"
#include "ui/ozone/platform/wayland/host/wayland_surface.h"
#include "ui/platform_window/platform_window.h"
#include "ui/platform_window/platform_window_delegate.h"
#include "ui/platform_window/platform_window_init_properties.h"
......@@ -36,7 +37,7 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher {
~WaylandWindow() override;
// A factory method that can create any of the derived types of WaylandWindow
// (WaylandSurface, WaylandPopup and WaylandSubsurface).
// (WaylandToplevelWindow, WaylandPopup and WaylandSubsurface).
static std::unique_ptr<WaylandWindow> Create(
PlatformWindowDelegate* delegate,
WaylandConnection* connection,
......@@ -53,7 +54,8 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher {
// to do so (this is not needed upon window initialization).
void UpdateBufferScale(bool update_bounds);
wl_surface* surface() const { return surface_.get(); }
WaylandSurface* wayland_surface() { return &wayland_surface_; }
wl_surface* surface() const { return wayland_surface_.surface(); }
void set_parent_window(WaylandWindow* parent_window) {
parent_window_ = parent_window;
......@@ -80,7 +82,7 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher {
void set_child_window(WaylandWindow* window) { child_window_ = window; }
WaylandWindow* child_window() const { return child_window_; }
int32_t buffer_scale() const { return buffer_scale_; }
int32_t buffer_scale() const { return wayland_surface_.buffer_scale(); }
int32_t ui_scale() const { return ui_scale_; }
const base::flat_set<uint32_t>& entered_outputs_ids() const {
......@@ -214,7 +216,7 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher {
WaylandWindow* parent_window_ = nullptr;
WaylandWindow* child_window_ = nullptr;
wl::Object<wl_surface> surface_;
WaylandSurface wayland_surface_;
// The current cursor bitmap (immutable).
scoped_refptr<BitmapCursorOzone> bitmap_;
......@@ -227,9 +229,6 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher {
bool has_pointer_focus_ = false;
bool has_keyboard_focus_ = false;
bool has_touch_focus_ = false;
// Wayland's scale factor for the output that this window currently belongs
// to.
int32_t buffer_scale_ = 1;
// The UI scale may be forced through the command line, which means that it
// replaces the default value that is equal to the natural device scale.
// We need it to place and size the menus properly.
......
......@@ -8,7 +8,7 @@
#include "ui/ozone/platform/wayland/host/wayland_connection.h"
#include "ui/ozone/platform/wayland/host/wayland_popup.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_toplevel_window.h"
#include "ui/ozone/platform/wayland/host/wayland_window.h"
namespace ui {
......@@ -26,7 +26,7 @@ std::unique_ptr<WaylandWindow> WaylandWindow::Create(
// parent window to be set. Thus, create a normal window instead then.
if (properties.parent_widget == gfx::kNullAcceleratedWidget &&
!connection->wayland_window_manager()->GetCurrentFocusedWindow()) {
window.reset(new WaylandSurface(delegate, connection));
window.reset(new WaylandToplevelWindow(delegate, connection));
} else if (connection->IsDragInProgress()) {
// We are in the process of drag and requested a popup. Most probably,
// it is an arrow window.
......@@ -43,7 +43,7 @@ std::unique_ptr<WaylandWindow> WaylandWindow::Create(
case PlatformWindowType::kDrag:
// TODO(msisov): Figure out what kind of surface we need to create for
// bubble and drag windows.
window.reset(new WaylandSurface(delegate, connection));
window.reset(new WaylandToplevelWindow(delegate, connection));
break;
default:
NOTREACHED();
......
......@@ -316,9 +316,9 @@ TEST_P(WaylandWindowTest, Minimize) {
Sync();
// Wayland compositor doesn't notify clients about minimized state, but rather
// if a window is not activated. Thus, a WaylandSurface marks itself as being
// minimized and and sets state to minimized. Thus, the state mustn't change
// after the configuration event is sent.
// if a window is not activated. Thus, a WaylandToplevelWindow marks itself as
// being minimized and and sets state to minimized. Thus, the state mustn't
// change after the configuration event is sent.
EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kMinimized);
// Send one additional empty configuration event (which means the surface is
......@@ -1931,8 +1931,8 @@ TEST_P(WaylandWindowTest, SetsPropertiesOnShow) {
// We can't mock all those methods above as long as the xdg_toplevel is
// created and destroyed on each show and hide call. However, it is the same
// WaylandSurface object that cached the values we set and must restore them
// on Show().
// WaylandToplevelWindow object that cached the values we set and must restore
// them on Show().
EXPECT_EQ(mock_xdg_toplevel->min_size(), min_size.value());
EXPECT_EQ(mock_xdg_toplevel->max_size(), max_size.value());
EXPECT_EQ(std::string(kAppId), mock_xdg_toplevel->app_id());
......
......@@ -18,7 +18,7 @@
#include "ui/ozone/platform/wayland/host/wayland_event_source.h"
#include "ui/ozone/platform/wayland/host/wayland_pointer.h"
#include "ui/ozone/platform/wayland/host/wayland_popup.h"
#include "ui/ozone/platform/wayland/host/wayland_surface.h"
#include "ui/ozone/platform/wayland/host/wayland_toplevel_window.h"
#include "ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h"
namespace ui {
......@@ -286,8 +286,8 @@ bool XDGPopupWrapperImpl::Initialize(WaylandConnection* connection,
static_cast<XDGPopupWrapperImpl*>(wayland_popup->shell_popup());
parent_xdg_surface = popup->xdg_surface();
} else {
WaylandSurface* wayland_surface =
static_cast<WaylandSurface*>(wayland_window_->parent_window());
WaylandToplevelWindow* wayland_surface =
static_cast<WaylandToplevelWindow*>(wayland_window_->parent_window());
parent_xdg_surface =
static_cast<XDGSurfaceWrapperImpl*>(wayland_surface->shell_surface());
}
......
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