From 33a754dd22a0fa37654b569232ffd606aaa5e3b9 Mon Sep 17 00:00:00 2001 From: Maksim Sisov Date: Wed, 11 Dec 2019 10:04:19 +0000 Subject: [PATCH 7/9] ozone/wayland: Extract subsurface from WaylandWindow This CL does not bring any functional changes, but rather moves the subsurface methods to WaylandSubsurface. Test: ozone_unittests Bug: 1028919 Change-Id: I96dbf21267a80022779cd7eebeb56c96a243128b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1960265 Commit-Queue: Maksim Sisov Reviewed-by: Michael Spang Cr-Commit-Position: refs/heads/master@{#723758} --- ui/ozone/platform/wayland/BUILD.gn | 2 + .../wayland/host/wayland_subsurface.cc | 80 +++++++++++++++++++ .../wayland/host/wayland_subsurface.h | 37 +++++++++ .../platform/wayland/host/wayland_window.cc | 63 ++------------- .../platform/wayland/host/wayland_window.h | 9 +-- .../wayland/host/wayland_window_factory.cc | 4 +- 6 files changed, 127 insertions(+), 68 deletions(-) create mode 100644 ui/ozone/platform/wayland/host/wayland_subsurface.cc create mode 100644 ui/ozone/platform/wayland/host/wayland_subsurface.h diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn index 4bfe93352f34..f6f21cdb0161 100644 --- a/ui/ozone/platform/wayland/BUILD.gn +++ b/ui/ozone/platform/wayland/BUILD.gn @@ -93,6 +93,8 @@ source_set("wayland") { "host/wayland_shm.h", "host/wayland_shm_buffer.cc", "host/wayland_shm_buffer.h", + "host/wayland_subsurface.cc", + "host/wayland_subsurface.h", "host/wayland_surface.cc", "host/wayland_surface.h", "host/wayland_touch.cc", diff --git a/ui/ozone/platform/wayland/host/wayland_subsurface.cc b/ui/ozone/platform/wayland/host/wayland_subsurface.cc new file mode 100644 index 000000000000..d261b910fc97 --- /dev/null +++ b/ui/ozone/platform/wayland/host/wayland_subsurface.cc @@ -0,0 +1,80 @@ +// 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_subsurface.h" + +#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_manager.h" + +namespace ui { + +WaylandSubsurface::WaylandSubsurface(PlatformWindowDelegate* delegate, + WaylandConnection* connection) + : WaylandWindow(delegate, connection) {} + +WaylandSubsurface::~WaylandSubsurface() = default; + +void WaylandSubsurface::Show(bool inactive) { + CreateSubsurface(); + UpdateBufferScale(false); +} + +void WaylandSubsurface::Hide() { + subsurface_.reset(); + + // Detach buffer from surface in order to completely shutdown menus and + // tooltips, and release resources. + connection()->buffer_manager_host()->ResetSurfaceContents(GetWidget()); +} + +bool WaylandSubsurface::IsVisible() const { + return !!subsurface_; +} + +void WaylandSubsurface::CreateSubsurface() { + // Since Aura does not not provide a reference parent window, needed by + // Wayland, we get the current focused window to place and show the tooltips. + auto* parent_window = + connection()->wayland_window_manager()->GetCurrentFocusedWindow(); + + // Tooltip creation is an async operation. By the time Aura actually creates + // the tooltip, it is possible that the user has already moved the + // mouse/pointer out of the window that triggered the tooptip. In this case, + // parent_window is NULL. + if (!parent_window) + return; + + wl_subcompositor* subcompositor = connection()->subcompositor(); + DCHECK(subcompositor); + subsurface_.reset(wl_subcompositor_get_subsurface(subcompositor, surface(), + parent_window->surface())); + + // Chromium positions tooltip windows in screen coordinates, but Wayland + // requires them to be in local surface coordinates a.k.a relative to parent + // window. + const auto parent_bounds_dip = + gfx::ScaleToRoundedRect(parent_window->GetBounds(), 1.0 / ui_scale()); + auto new_bounds_dip = + wl::TranslateBoundsToParentCoordinates(GetBounds(), parent_bounds_dip); + auto bounds_px = + gfx::ScaleToRoundedRect(new_bounds_dip, ui_scale() / buffer_scale()); + + DCHECK(subsurface_); + // Convert position to DIP. + wl_subsurface_set_position(subsurface_.get(), bounds_px.x() / buffer_scale(), + bounds_px.y() / buffer_scale()); + wl_subsurface_set_desync(subsurface_.get()); + wl_surface_commit(parent_window->surface()); + connection()->ScheduleFlush(); +} + +bool WaylandSubsurface::OnInitialize(PlatformWindowInitProperties properties) { + // TODO(msisov): if the subsurface is not provided with a parent widget, then + // it must always use a focused window + return true; +} + +} // namespace ui diff --git a/ui/ozone/platform/wayland/host/wayland_subsurface.h b/ui/ozone/platform/wayland/host/wayland_subsurface.h new file mode 100644 index 000000000000..fd159a7bd465 --- /dev/null +++ b/ui/ozone/platform/wayland/host/wayland_subsurface.h @@ -0,0 +1,37 @@ +// 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_SUBSURFACE_H_ +#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SUBSURFACE_H_ + +#include "ui/ozone/platform/wayland/host/wayland_window.h" + +namespace ui { + +class WaylandSubsurface : public WaylandWindow { + public: + WaylandSubsurface(PlatformWindowDelegate* delegate, + WaylandConnection* connection); + ~WaylandSubsurface() override; + + // PlatformWindow overrides: + void Show(bool inactive) override; + void Hide() override; + bool IsVisible() const override; + + private: + // WaylandWindow overrides: + bool OnInitialize(PlatformWindowInitProperties properties) override; + + // Creates (if necessary) and shows a subsurface window. + void CreateSubsurface(); + + wl::Object subsurface_; + + DISALLOW_COPY_AND_ASSIGN(WaylandSubsurface); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SUBSURFACE_H_ diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc index 045f922a759e..c752ad3c0048 100644 --- a/ui/ozone/platform/wayland/host/wayland_window.cc +++ b/ui/ozone/platform/wayland/host/wayland_window.cc @@ -75,45 +75,6 @@ gfx::AcceleratedWidget WaylandWindow::GetWidget() const { return gfx::kNullAcceleratedWidget; return surface_.id(); } - -void WaylandWindow::CreateAndShowTooltipSubSurface() { - // Since Aura does not not provide a reference parent window, needed by - // Wayland, we get the current focused window to place and show the tooltips. - auto* parent_window = - connection_->wayland_window_manager()->GetCurrentFocusedWindow(); - - // Tooltip creation is an async operation. By the time Aura actually creates - // the tooltip, it is possible that the user has already moved the - // mouse/pointer out of the window that triggered the tooptip. In this case, - // parent_window is NULL. - if (!parent_window) - return; - - wl_subcompositor* subcompositor = connection_->subcompositor(); - DCHECK(subcompositor); - tooltip_subsurface_.reset(wl_subcompositor_get_subsurface( - subcompositor, surface_.get(), parent_window->surface())); - - // Chromium positions tooltip windows in screen coordinates, but Wayland - // requires them to be in local surface coordinates aka relative to parent - // window. - const auto parent_bounds_dip = - gfx::ScaleToRoundedRect(parent_window->GetBounds(), 1.0 / ui_scale_); - auto new_bounds_dip = - wl::TranslateBoundsToParentCoordinates(bounds_px_, parent_bounds_dip); - auto bounds_px = - gfx::ScaleToRoundedRect(new_bounds_dip, ui_scale_ / buffer_scale_); - - DCHECK(tooltip_subsurface_); - // Convert position to DIP. - wl_subsurface_set_position(tooltip_subsurface_.get(), - bounds_px.x() / buffer_scale_, - bounds_px.y() / buffer_scale_); - wl_subsurface_set_desync(tooltip_subsurface_.get()); - wl_surface_commit(parent_window->surface()); - connection_->ScheduleFlush(); -} - void WaylandWindow::SetPointerFocus(bool focus) { has_pointer_focus_ = focus; @@ -125,19 +86,11 @@ void WaylandWindow::SetPointerFocus(bool focus) { } void WaylandWindow::Show(bool inactive) { - DCHECK(is_tooltip_); - CreateAndShowTooltipSubSurface(); - - UpdateBufferScale(false); + NOTREACHED(); } void WaylandWindow::Hide() { - DCHECK(is_tooltip_); - tooltip_subsurface_.reset(); - - // Detach buffer from surface in order to completely shutdown menus and - // tooltips, and release resources. - connection_->buffer_manager_host()->ResetSurfaceContents(GetWidget()); + NOTREACHED(); } void WaylandWindow::Close() { @@ -145,7 +98,8 @@ void WaylandWindow::Close() { } bool WaylandWindow::IsVisible() const { - return !!tooltip_subsurface_; + NOTREACHED(); + return false; } void WaylandWindow::PrepareForShutdown() {} @@ -305,7 +259,7 @@ uint32_t WaylandWindow::DispatchEvent(const PlatformEvent& native_event) { // Parent window of the main menu window is not a menu, but rather an // xdg surface. DCHECK(!wl::IsMenuType(parent_window_->type()) || - !parent_window_->is_tooltip_); + parent_window_->type() != PlatformWindowType::kTooltip); auto* window = connection_->wayland_window_manager()->GetCurrentFocusedWindow(); if (window) { @@ -377,9 +331,6 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) { connection_->wayland_window_manager()->AddWindow(GetWidget(), this); - if (type_ == ui::PlatformWindowType::kTooltip) - is_tooltip_ = true; - if (!OnInitialize(std::move(properties))) return false; @@ -544,10 +495,6 @@ bool WaylandWindow::IsOpaqueWindow() const { return opacity_ == ui::PlatformWindowOpacity::kOpaqueWindow; } -bool WaylandWindow::OnInitialize(PlatformWindowInitProperties properties) { - return true; -} - // static void WaylandWindow::Enter(void* data, struct wl_surface* wl_surface, diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h index 3eca745b38c4..08658f1df87c 100644 --- a/ui/ozone/platform/wayland/host/wayland_window.h +++ b/ui/ozone/platform/wayland/host/wayland_window.h @@ -178,10 +178,6 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { // Initializes the WaylandWindow with supplied properties. bool Initialize(PlatformWindowInitProperties properties); - // Creates (if necessary) and show subsurface window, to host - // tooltip's content. - void CreateAndShowTooltipSubSurface(); - // Returns a root parent window. WaylandWindow* GetRootParentWindow(); @@ -202,7 +198,7 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { bool IsOpaqueWindow() const; // Additional initialization of derived classes. - virtual bool OnInitialize(PlatformWindowInitProperties properties); + virtual bool OnInitialize(PlatformWindowInitProperties properties) = 0; // wl_surface_listener static void Enter(void* data, @@ -218,7 +214,6 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { WaylandWindow* child_window_ = nullptr; wl::Object surface_; - wl::Object tooltip_subsurface_; // The current cursor bitmap (immutable). scoped_refptr bitmap_; @@ -243,8 +238,6 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { // Stores current opacity of the window. Set on ::Initialize call. ui::PlatformWindowOpacity opacity_; - bool is_tooltip_ = false; - // For top level window, stores IDs of outputs that the window is currently // rendered at. // diff --git a/ui/ozone/platform/wayland/host/wayland_window_factory.cc b/ui/ozone/platform/wayland/host/wayland_window_factory.cc index 4c887fa3c1c8..869c1d0aa1f8 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_factory.cc +++ b/ui/ozone/platform/wayland/host/wayland_window_factory.cc @@ -7,8 +7,8 @@ #include #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_window.h" namespace ui { @@ -26,7 +26,7 @@ std::unique_ptr WaylandWindow::Create( break; case PlatformWindowType::kTooltip: // TODO(msisov): Add WaylandSubsurface. - window.reset(new WaylandWindow(delegate, connection)); + window.reset(new WaylandSubsurface(delegate, connection)); break; case PlatformWindowType::kWindow: case PlatformWindowType::kBubble: -- 2.24.1