chore: cherry-pick d42c3e5fb7c3 from chromium (#38199)

This commit is contained in:
Valentin Hăloiu
2023-05-09 09:07:06 +01:00
committed by GitHub
parent de3a8a5389
commit 5af5b42422
2 changed files with 110 additions and 0 deletions

View File

@@ -156,3 +156,4 @@ check_callback_availability_in.patch
cherry-pick-63686953dc22.patch
cherry-pick-f098ff0d1230.patch
cherry-pick-f58218891f8c.patch
wayland_ensure_dnd_buffer_size_is_a_multiple_of_scale.patch

View File

@@ -0,0 +1,109 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom Anderson <thomasanderson@chromium.org>
Date: Tue, 13 Dec 2022 22:49:47 +0000
Subject: Ensure DND buffer size is a multiple of scale
When using a scale factor of 2.0 on Sway ToT, this fixes a crash when
trying to DND an image or text that happens to have an odd width or
height. The issue is Wlroots will not allow attaching a buffer to a
surface when the buffer's size isn't a multiple of the surface's scale
factor.
R=nickdiego
Bug: 578890
Change-Id: I283ed27a7d0051b895e0eed3b9a74d83feac3a37
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4099423
Reviewed-by: Nick Yamane <nickdiego@igalia.com>
Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1082777}
diff --git a/ui/ozone/platform/wayland/common/wayland_util.cc b/ui/ozone/platform/wayland/common/wayland_util.cc
index 4e8aa4b1e5530311338fbb43483e16d845707d2f..9b5806895a92cc92176644a0477d48bf79a35606 100644
--- a/ui/ozone/platform/wayland/common/wayland_util.cc
+++ b/ui/ozone/platform/wayland/common/wayland_util.cc
@@ -115,7 +115,8 @@ uint32_t IdentifyDirection(const ui::WaylandConnection& connection,
bool DrawBitmap(const SkBitmap& bitmap, ui::WaylandShmBuffer* out_buffer) {
DCHECK(out_buffer);
DCHECK(out_buffer->GetMemory());
- DCHECK_EQ(out_buffer->size(), gfx::Size(bitmap.width(), bitmap.height()));
+ DCHECK(gfx::Rect(out_buffer->size())
+ .Contains(gfx::Rect(bitmap.width(), bitmap.height())));
auto* mapped_memory = out_buffer->GetMemory();
auto size = out_buffer->size();
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
index f2123ec8bac3f6afe9f46ba358cb9c829b2e9325..2bb7d0f4de6f8c50cc2bbaba6baaa0b684531115 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
+++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
@@ -140,7 +140,8 @@ bool WaylandDataDragController::StartSession(const OSExchangeData& data,
icon_surface_ = std::make_unique<WaylandSurface>(connection_, nullptr);
if (icon_surface_->Initialize()) {
// Corresponds to actual scale factor of the origin surface.
- icon_surface_->set_surface_buffer_scale(origin_window->window_scale());
+ icon_surface_buffer_scale_ = origin_window->window_scale();
+ icon_surface_->set_surface_buffer_scale(icon_surface_buffer_scale_);
// Icon surface do not need input.
const gfx::Rect empty_region_px;
icon_surface_->set_input_region(&empty_region_px);
@@ -153,6 +154,7 @@ bool WaylandDataDragController::StartSession(const OSExchangeData& data,
} else {
LOG(ERROR) << "Failed to create drag icon surface.";
icon_surface_.reset();
+ icon_surface_buffer_scale_ = 1.0f;
}
}
@@ -225,21 +227,28 @@ void WaylandDataDragController::DrawIconInternal() {
return;
DCHECK(!icon_bitmap_->empty());
- gfx::Size size(icon_bitmap_->width(), icon_bitmap_->height());
+ // The protocol expects the attached buffer to have a pixel size that is a
+ // multiple of the surface's scale factor. Some compositors (eg. Wlroots) will
+ // refuse to attach the buffer if this condition is not met.
+ const gfx::Size size_dip =
+ gfx::ScaleToCeiledSize({icon_bitmap_->width(), icon_bitmap_->height()},
+ 1.0f / icon_surface_buffer_scale_);
+ const gfx::Size size_px =
+ gfx::ScaleToCeiledSize(size_dip, icon_surface_buffer_scale_);
icon_buffer_ = std::make_unique<WaylandShmBuffer>(
- connection_->wayland_buffer_factory(), size);
+ connection_->wayland_buffer_factory(), size_px);
if (!icon_buffer_->IsValid()) {
LOG(ERROR) << "Failed to create drag icon buffer.";
return;
}
- DVLOG(3) << "Drawing drag icon. size=" << size.ToString();
+ DVLOG(3) << "Drawing drag icon. size_px=" << size_px.ToString();
wl::DrawBitmap(*icon_bitmap_, icon_buffer_.get());
auto* const surface = icon_surface_->surface();
wl_surface_attach(surface, icon_buffer_->get(), icon_offset_.x(),
icon_offset_.y());
- wl_surface_damage(surface, 0, 0, size.width(), size.height());
+ wl_surface_damage(surface, 0, 0, size_px.width(), size_px.height());
wl_surface_commit(surface);
}
@@ -370,6 +379,7 @@ void WaylandDataDragController::OnDataSourceFinish(bool completed) {
data_offer_.reset();
icon_buffer_.reset();
icon_surface_.reset();
+ icon_surface_buffer_scale_ = 1.0f;
icon_bitmap_ = nullptr;
icon_frame_callback_.reset();
offered_exchange_data_provider_.reset();
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h
index 9912f1e0aebaf8289d2cdcdbff472a0baa91a981..39acda6bae9eb3a3f7837f6c93fafcee493bf78b 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h
+++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h
@@ -224,6 +224,7 @@ class WaylandDataDragController : public WaylandDataDevice::DragDelegate,
// Drag icon related variables.
std::unique_ptr<WaylandSurface> icon_surface_;
+ float icon_surface_buffer_scale_ = 1.0f;
std::unique_ptr<WaylandShmBuffer> icon_buffer_;
raw_ptr<const SkBitmap> icon_bitmap_ = nullptr;
gfx::Point icon_offset_;