summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Playfair Cal2019-08-09 01:26:09 +1000
committerDaniel Playfair Cal2019-08-09 01:26:09 +1000
commitaaa1f9a6be7a5f2883388b44fda07ecdf6263065 (patch)
tree70dc72948b8d1a618ff5af19d5c0e0309fa77d24
parentfc6ed6aa0254db2ff86daaba0b5aba2368872f0c (diff)
downloadaur-aaa1f9a6be7a5f2883388b44fda07ecdf6263065.tar.gz
More patches to fix freezes
-rw-r--r--.SRCINFO26
-rw-r--r--0001-ozone-wayland-Prepare-WaylandCanvasSurface-for-compl.patch2
-rw-r--r--0002-ozone-wayland-Sway-avoid-sending-presentation-early.patch2
-rw-r--r--0003-Ozone-Wayland-Manager-make-mojo-calls-on-IO-thread.patch2
-rw-r--r--0004-ozone-wayland-Fix-broken-software-rendering-path.patch2
-rw-r--r--0005-ozone-wayland-Use-mutex-before-accessing-surfaces-ma.patch3
-rw-r--r--0006-ozone-wayland-Reset-surface-contents-in-a-safe-way.patch171
-rw-r--r--0007-ozone-wayland-Stop-using-wl_display_roundtrip.patch472
-rw-r--r--0008-ozone-wayland-Added-HiDPI-support-for-Ozone-Wayland.patch (renamed from Added-HiDPI-support-for-Ozone-Wayland.patch)118
-rw-r--r--0009-Fixed-positioning-and-sizes-of-menus-when-the-scale-.patch315
-rw-r--r--0010-ozone-wayland-Extract-window-management-methods-to-o.patch810
-rw-r--r--0011-ozone-wayland-Do-not-use-possibly-blocking-dispatch-.patch315
-rw-r--r--PKGBUILD51
13 files changed, 2209 insertions, 80 deletions
diff --git a/.SRCINFO b/.SRCINFO
index 50cb1adc2b30..38ed22fb9e92 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,7 +1,7 @@
pkgbase = chromium-ozone
pkgdesc = Chromium built with patches for wayland support via Ozone
pkgver = 76.0.3809.87
- pkgrel = 2
+ pkgrel = 3
url = https://www.chromium.org/Home
install = chromium.install
arch = x86_64
@@ -68,19 +68,29 @@ pkgbase = chromium-ozone
source = 0003-Ozone-Wayland-Manager-make-mojo-calls-on-IO-thread.patch
source = 0004-ozone-wayland-Fix-broken-software-rendering-path.patch
source = 0005-ozone-wayland-Use-mutex-before-accessing-surfaces-ma.patch
- source = Added-HiDPI-support-for-Ozone-Wayland.patch
+ source = 0006-ozone-wayland-Reset-surface-contents-in-a-safe-way.patch
+ source = 0007-ozone-wayland-Stop-using-wl_display_roundtrip.patch
+ source = 0008-ozone-wayland-Added-HiDPI-support-for-Ozone-Wayland.patch
+ source = 0009-Fixed-positioning-and-sizes-of-menus-when-the-scale-.patch
+ source = 0010-ozone-wayland-Extract-window-management-methods-to-o.patch
+ source = 0011-ozone-wayland-Do-not-use-possibly-blocking-dispatch-.patch
sha256sums = 215ca6acee7b4fd3c95fe796260af4dc5454dbba3b701aa43afeb98a06dc4194
sha256sums = 04917e3cd4307d8e31bfb0027a5dce6d086edb10ff8a716024fbb8bb0c7dccf1
sha256sums = d87957d01be9fb59faf5fde523eb87a8256605b1533171416b7a56bfcbd6d056
sha256sums = e2d284311f49c529ea45083438a768db390bde52949995534034d2a814beab89
sha256sums = d081f2ef8793544685aad35dea75a7e6264a2cb987ff3541e6377f4a3650a28b
sha256sums = 771292942c0901092a402cc60ee883877a99fb804cb54d568c8c6c94565a48e1
- sha256sums = a16afeb448fc49904f4bb4f679db1a79b3305a04399d672787e708a32516ac91
- sha256sums = bddf821069a8037ce91c35787aa942d35ef880ca5e28dae1ddeb224c2d008548
- sha256sums = 1455cc2bb36f4247b3c16b805328b277c8538ad96f50d1e7f5fb816d5cad2d6d
- sha256sums = deba5fa9ebd64ca48bab71d51c3bf50a6c10e2704e60b7b50268fc2de15afb61
- sha256sums = 907be76f0906452b3327b0d469bf5bcff31eec9d9e6d6829c6a0159da73af68a
- sha256sums = b6b258a6d3b42731c9375395b4e6e896edef00617d5b7028c348a5d2dbb14eb7
+ sha256sums = 1fe3bb02ffd0445da8ea3b9eb09e8dff6b7bdd1ca26f4b439310a3e94aa16ebf
+ sha256sums = d9c5932f1af91a8c2e8b7687d9ad013d5895e3e03811d9f03e674afb77031ce5
+ sha256sums = 424c5c0e5b6ded87d0c00dd4755eb6e63bfdf42233ee60c354729f5cbba82334
+ sha256sums = fecdfa694a84b4dc688ec20970ea18b11d9e332b8423a935ba35cd3fae7485a5
+ sha256sums = 2359fdd84a3c10eeb576b15cfea86a34867097cb3e3d30ade6c823cf0d538d99
+ sha256sums = 13be86e54b14f5a9f21e371a0f2762c5ff9a4204877ded60600f5950f6a14885
+ sha256sums = ede2a4c0283f01f7653c0caabd8439d96c27da16dd557ebb0730c0b3e7134097
+ sha256sums = 9996ddaa8a83c58dcbe45e21746ffe41a9f8b56edc71a16090ebdb6adbc74541
+ sha256sums = 6f4fc0a82443f9bfaeecfd1a463b4bc10dfa29b9357f17592dfac8332d27cb3c
+ sha256sums = 470cf88aa6878bfaaf74f00791d33f4f922f31a13e0503b8bb11edb4bb89d29c
+ sha256sums = aaefa3a868024aa1eb118236bd528986db972646f762418764b5f0ab326468b0
pkgname = chromium-ozone
diff --git a/0001-ozone-wayland-Prepare-WaylandCanvasSurface-for-compl.patch b/0001-ozone-wayland-Prepare-WaylandCanvasSurface-for-compl.patch
index 461293033f96..33f838075076 100644
--- a/0001-ozone-wayland-Prepare-WaylandCanvasSurface-for-compl.patch
+++ b/0001-ozone-wayland-Prepare-WaylandCanvasSurface-for-compl.patch
@@ -1,7 +1,7 @@
From a3ca8acd6582c0169ad3e2d94dd9fcd423810a56 Mon Sep 17 00:00:00 2001
From: Maksim Sisov <msisov@igalia.com>
Date: Tue, 4 Jun 2019 06:24:59 +0000
-Subject: [PATCH 1/5] [ozone/wayland] Prepare WaylandCanvasSurface for
+Subject: [PATCH 01/11] [ozone/wayland] Prepare WaylandCanvasSurface for
completion callbacks
This is a prerequisite CL to make WaylandCanvasSurface listen
diff --git a/0002-ozone-wayland-Sway-avoid-sending-presentation-early.patch b/0002-ozone-wayland-Sway-avoid-sending-presentation-early.patch
index 4e5204c6fd26..c1f5e7ac317a 100644
--- a/0002-ozone-wayland-Sway-avoid-sending-presentation-early.patch
+++ b/0002-ozone-wayland-Sway-avoid-sending-presentation-early.patch
@@ -1,7 +1,7 @@
From c644b4aba05233a8a78d7708a98d9a583ff78a27 Mon Sep 17 00:00:00 2001
From: Maksim Sisov <msisov@igalia.com>
Date: Tue, 30 Jul 2019 05:53:48 +0000
-Subject: [PATCH 2/5] [ozone/wayland] Sway: avoid sending presentation early.
+Subject: [PATCH 02/11] [ozone/wayland] Sway: avoid sending presentation early.
In Sway, presentation callbacks may come much earlier than we send
submission callbacks. That results in unexpected crashes in
diff --git a/0003-Ozone-Wayland-Manager-make-mojo-calls-on-IO-thread.patch b/0003-Ozone-Wayland-Manager-make-mojo-calls-on-IO-thread.patch
index f0c378c64ffd..bf1f45114d7d 100644
--- a/0003-Ozone-Wayland-Manager-make-mojo-calls-on-IO-thread.patch
+++ b/0003-Ozone-Wayland-Manager-make-mojo-calls-on-IO-thread.patch
@@ -1,7 +1,7 @@
From 3be83bcae17f547f58b41640451471ab840c70c0 Mon Sep 17 00:00:00 2001
From: Maksim Sisov <msisov@igalia.com>
Date: Tue, 4 Jun 2019 07:56:29 +0000
-Subject: [PATCH 3/5] [Ozone/Wayland] Manager: make mojo calls on IO thread.
+Subject: [PATCH 03/11] [Ozone/Wayland] Manager: make mojo calls on IO thread.
Previously, the manager had been rerouting calls to GpuMainThread
to make mojo calls. That thread is not really meant for IPC.
diff --git a/0004-ozone-wayland-Fix-broken-software-rendering-path.patch b/0004-ozone-wayland-Fix-broken-software-rendering-path.patch
index 23bd3ded5718..528d86643f84 100644
--- a/0004-ozone-wayland-Fix-broken-software-rendering-path.patch
+++ b/0004-ozone-wayland-Fix-broken-software-rendering-path.patch
@@ -1,7 +1,7 @@
From 86c0a9aac3e872c98345cc761bfbbc9dbbb6fde2 Mon Sep 17 00:00:00 2001
From: Maksim Sisov <msisov@igalia.com>
Date: Thu, 6 Jun 2019 08:58:59 +0000
-Subject: [PATCH 4/5] [ozone/wayland] Fix broken software rendering path.
+Subject: [PATCH 04/11] [ozone/wayland] Fix broken software rendering path.
The "[Ozone/Wayland] Manager: make mojo calls on IO thread." CL:
https://crrev.com/c/1640398 broke the software rendering path,
diff --git a/0005-ozone-wayland-Use-mutex-before-accessing-surfaces-ma.patch b/0005-ozone-wayland-Use-mutex-before-accessing-surfaces-ma.patch
index 9a4e8e822cb3..b04ec01fde86 100644
--- a/0005-ozone-wayland-Use-mutex-before-accessing-surfaces-ma.patch
+++ b/0005-ozone-wayland-Use-mutex-before-accessing-surfaces-ma.patch
@@ -1,7 +1,8 @@
From fd1d8bfd55d5b1d073cbad3ebe8f058c49f3702a Mon Sep 17 00:00:00 2001
From: Maksim Sisov <msisov@igalia.com>
Date: Mon, 5 Aug 2019 16:14:47 +0300
-Subject: [PATCH 5/5] [ozone/wayland] Use mutex before accessing surfaces map.
+Subject: [PATCH 05/11] [ozone/wayland] Use mutex before accessing surfaces
+ map.
We must make sure that accessing surfaces map from different threads
is safe. Otherwise, this is subject to races and unexpected crashes.
diff --git a/0006-ozone-wayland-Reset-surface-contents-in-a-safe-way.patch b/0006-ozone-wayland-Reset-surface-contents-in-a-safe-way.patch
new file mode 100644
index 000000000000..6cf070677427
--- /dev/null
+++ b/0006-ozone-wayland-Reset-surface-contents-in-a-safe-way.patch
@@ -0,0 +1,171 @@
+From 739876012248a57964326a4dcc9f00039ad1ad73 Mon Sep 17 00:00:00 2001
+From: Maksim Sisov <msisov@igalia.com>
+Date: Tue, 4 Jun 2019 06:58:40 +0000
+Subject: [PATCH 06/11] [ozone/wayland] Reset surface contents in a safe way
+
+Currently, WaylandWindow may attach a null buffer to a surface,
+which makes the Wayland compositor skip the buffer release call even
+though there was a buffer attached.
+
+The skipped buffer release call results in a missed submission
+callback, and the Chromium display compositor starts to lag
+behind one frame.
+
+What is more, we no longer trigger a buffer swap completion
+callback before presention feedback is provided, which also
+results in DCHECK when checking the order of the callbacks.
+
+Bug: 968497
+Change-Id: I12494e78fa376d6c421b7366d0bddb52ae59a5af
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1636354
+Commit-Queue: Maksim Sisov <msisov@igalia.com>
+Reviewed-by: Robert Kroeger <rjkroege@chromium.org>
+Cr-Commit-Position: refs/heads/master@{#665833}
+---
+ .../host/wayland_buffer_manager_host.cc | 38 ++++++++++++++++++-
+ .../host/wayland_buffer_manager_host.h | 6 +++
+ .../platform/wayland/host/wayland_window.cc | 26 ++++++-------
+ 3 files changed, 55 insertions(+), 15 deletions(-)
+
+diff --git a/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc b/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc
+index 5f7efebac400..a6759bb798f4 100644
+--- a/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc
++++ b/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc
+@@ -103,6 +103,14 @@ class WaylandBufferManagerHost::Surface {
+
+ connection_->ScheduleFlush();
+
++ // If the contents were reset, there is no buffer attached. It means we have
++ // to behave the same way as if it was the very first frame. Check the
++ // comment below where the |contents_reset_| is declared.
++ if (contents_reset_) {
++ prev_submitted_buffer_ = nullptr;
++ contents_reset_ = false;
++ }
++
+ // If it was the very first frame, the surface has not had a back buffer
+ // before, and Wayland won't release the front buffer until next buffer is
+ // attached. Thus, notify about successful submission immediately.
+@@ -166,13 +174,26 @@ class WaylandBufferManagerHost::Surface {
+ wl_frame_callback_.reset();
+ presentation_feedbacks_ = PresentationFeedbackQueue();
+
+- wl_surface_attach(window_->surface(), nullptr, 0, 0);
++ ResetSurfaceContents();
++
+ prev_submitted_buffer_ = nullptr;
+ submitted_buffer_ = nullptr;
+
+ connection_->ScheduleFlush();
+ }
+
++ void ResetSurfaceContents() {
++ wl_surface_attach(window_->surface(), nullptr, 0, 0);
++ wl_surface_commit(window_->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
++ // callback. Check more comments below where the variable is declared.
++ contents_reset_ = true;
++
++ connection_->ScheduleFlush();
++ }
++
+ private:
+ using PresentationFeedbackQueue = base::queue<
+ std::pair<uint32_t, wl::Object<struct wp_presentation_feedback>>>;
+@@ -449,6 +470,14 @@ class WaylandBufferManagerHost::Surface {
+ // Previous submitted buffer.
+ WaylandBuffer* prev_submitted_buffer_ = nullptr;
+
++ // If WaylandWindow becomes hidden, it may need to attach a null buffer to the
++ // surface it backed to avoid its contents shown on screen. However, it
++ // means that the Wayland compositor no longer sends new buffer release events
++ // as long as there has not been buffer attached and no submission callback is
++ // sent. To avoid this, |contents_reset_| can be used as an identification of a
++ // need to call submission callback manually.
++ bool contents_reset_ = false;
++
+ DISALLOW_COPY_AND_ASSIGN(Surface);
+ };
+
+@@ -620,6 +649,13 @@ void WaylandBufferManagerHost::DestroyBuffer(gfx::AcceleratedWidget widget,
+ connection_->ScheduleFlush();
+ }
+
++void WaylandBufferManagerHost::ResetSurfaceContents(
++ gfx::AcceleratedWidget widget) {
++ auto* surface = GetSurface(widget);
++ DCHECK(surface);
++ surface->ResetSurfaceContents();
++}
++
+ bool WaylandBufferManagerHost::CreateBuffer(gfx::AcceleratedWidget& widget,
+ const gfx::Size& size,
+ uint32_t buffer_id) {
+diff --git a/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h b/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h
+index a2dd899e2de0..63fa02b4089d 100644
+--- a/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h
++++ b/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h
+@@ -94,6 +94,12 @@ class WaylandBufferManagerHost : ozone::mojom::WaylandBufferManagerHost {
+ uint32_t buffer_id,
+ const gfx::Rect& damage_region) override;
+
++ // When a surface is hidden, the client may want to detach the buffer attached
++ // to the surface backed by |widget| to ensure Wayland does not present those
++ // contents and do not composite in a wrong way. Otherwise, users may see the
++ // contents of a hidden surface on their screens.
++ void ResetSurfaceContents(gfx::AcceleratedWidget widget);
++
+ private:
+ // This is an internal representation of a real surface, which holds a pointer
+ // to WaylandWindow. Also, this object holds buffers, frame callbacks and
+diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc
+index 4b0a9908a13e..3d4229f466ff 100644
+--- a/ui/ozone/platform/wayland/host/wayland_window.cc
++++ b/ui/ozone/platform/wayland/host/wayland_window.cc
+@@ -16,6 +16,7 @@
+ #include "ui/events/event_utils.h"
+ #include "ui/events/ozone/events_ozone.h"
+ #include "ui/gfx/geometry/point_f.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_cursor_position.h"
+ #include "ui/ozone/platform/wayland/host/wayland_output_manager.h"
+@@ -300,22 +301,19 @@ void WaylandWindow::Show() {
+ void WaylandWindow::Hide() {
+ if (is_tooltip_) {
+ parent_window_ = nullptr;
+- wl_surface_attach(surface_.get(), NULL, 0, 0);
+- wl_surface_commit(surface_.get());
+- return;
++ } else {
++ if (child_window_)
++ child_window_->Hide();
++ if (xdg_popup_) {
++ parent_window_->set_child_window(nullptr);
++ xdg_popup_.reset();
++ }
+ }
+
+- if (child_window_)
+- child_window_->Hide();
+-
+- if (xdg_popup_) {
+- parent_window_->set_child_window(nullptr);
+- xdg_popup_.reset();
+- // Detach buffer from surface in order to completely shutdown popups and
+- // release resources.
+- wl_surface_attach(surface_.get(), NULL, 0, 0);
+- wl_surface_commit(surface_.get());
+- }
++ // Detach buffer from surface in order to completely shutdown popups and
++ // tooltips, and release resources.
++ if (!xdg_surface())
++ connection_->buffer_manager_host()->ResetSurfaceContents(GetWidget());
+ }
+
+ void WaylandWindow::Close() {
+--
+2.22.0
+
diff --git a/0007-ozone-wayland-Stop-using-wl_display_roundtrip.patch b/0007-ozone-wayland-Stop-using-wl_display_roundtrip.patch
new file mode 100644
index 000000000000..40da4077c1e1
--- /dev/null
+++ b/0007-ozone-wayland-Stop-using-wl_display_roundtrip.patch
@@ -0,0 +1,472 @@
+From baa6e8592ccb0f4975676e9d1cac4ffc8c1b6e2f Mon Sep 17 00:00:00 2001
+From: Maksim Sisov <msisov@igalia.com>
+Date: Thu, 8 Aug 2019 11:32:57 +0000
+Subject: [PATCH 07/11] [ozone/wayland] Stop using wl_display_roundtrip
+
+According to the Wayland documentation, wl_display_roundtrip is a
+blocking call that can block if the event queue is empty. That is,
+to be able to process buffer swap requests synchronously,
+that call blocks until a frame callback comes or a wl_buffer
+is attached. This results in blocking the CrBrowserMain thread.
+
+This change alters the logic so that the buffer manager processes
+one pending buffer at a time asynchronously avoiding blocking
+the thread if synchronous processing is not possible due to
+two conditions:
+1) a frame callback is not received,
+2) a wl_frame buffer is not created.
+
+That is, on a frame no 1, the manager does not have a
+frame callback installed and it may not process the buffer
+synchronously if a wl_buffer is not created.
+(note that wl_buffers can be created synchronously or asynchronously
+depending on the protocol version of the zwp_linux_dmabuf[1]).
+If such condition satisfies (there is no wl_buffer created), that
+buffer is stored as a pending one and is processed on a
+AttachWlBuffer call. Otherwise, the manager just processes
+the buffer swap for the frame no 1 synchronously.
+
+On frames no 2 and onwards, the manager may not process
+buffer swaps synchronously if a frame callback is set, but not
+received. That is, whenever the manager attaches
+buffers to surfaces and commits them, it sets frame callbacks,
+which Wayland compositor runs whenever it is time to send next
+frame. If such condition satisfies, the manager stores the buffer
+and processes it on next OnFrameCallback call. Otherwise, the swap
+request processed synchronously.
+
+[1] https://cs.chromium.org/chromium/src/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc?g=0&l=67
+
+Bug: 987821
+Test: WaylandBufferManagerTest.TestCommitBufferConditions
+Change-Id: I153b2071a453856a40e23a7f0a15f61dbc01d27f
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1726051
+Reviewed-by: Robert Kroeger <rjkroege@chromium.org>
+Commit-Queue: Maksim Sisov <msisov@igalia.com>
+Cr-Commit-Position: refs/heads/master@{#685143}
+---
+ .../host/wayland_buffer_manager_host.cc | 123 ++++++++++++------
+ .../test/mock_zwp_linux_buffer_params.cc | 50 +++++--
+ .../test/mock_zwp_linux_buffer_params.h | 17 +++
+ .../wayland/test/mock_zwp_linux_dmabuf.cc | 34 ++++-
+ .../wayland/test/mock_zwp_linux_dmabuf.h | 12 ++
+ 5 files changed, 175 insertions(+), 61 deletions(-)
+
+diff --git a/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc b/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc
+index a6759bb798f4..f58a9f1ed8fb 100644
+--- a/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc
++++ b/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc
+@@ -63,10 +63,22 @@ class WaylandBufferManagerHost::Surface {
+ ~Surface() = default;
+
+ bool CommitBuffer(uint32_t buffer_id, const gfx::Rect& damage_region) {
++ DCHECK(!pending_buffer_);
++
+ WaylandBuffer* buffer = GetBuffer(buffer_id);
+ if (!buffer)
+ return false;
+
++ buffer->damage_region = damage_region;
++
++ // If the wl_buffer has been attached, but the wl_buffer still is null, it
++ // means the Wayland server failed to create the buffer and we have to fail
++ // here.
++ //
++ // TODO(msisov): should we ask to recreate buffers instead of failing?
++ if (buffer->attached && !buffer->wl_buffer)
++ return false;
++
+ // This request may come earlier than the Wayland compositor has imported a
+ // wl_buffer. Wait until the buffer is created. The wait takes place only
+ // once. Though, the case when a request to attach a buffer comes earlier
+@@ -78,46 +90,12 @@ class WaylandBufferManagerHost::Surface {
+ // Another case, which always happen is waiting until the frame callback is
+ // completed. Thus, wait here when the Wayland compositor fires the frame
+ // callback.
+- while (!buffer->wl_buffer || !!wl_frame_callback_) {
+- // If the wl_buffer has been attached, but the wl_buffer still has been
+- // null, it means the Wayland server failed to create the buffer and we
+- // have to fail here.
+- if ((buffer->attached && !buffer->wl_buffer) ||
+- wl_display_roundtrip(connection_->display()) == -1)
+- return false;
++ if (!buffer->wl_buffer || wl_frame_callback_) {
++ pending_buffer_ = buffer;
++ return true;
+ }
+
+- // Once the BufferRelease is called, the buffer will be released.
+- DCHECK(buffer->released);
+- buffer->released = false;
+-
+- DCHECK(!submitted_buffer_);
+- submitted_buffer_ = buffer;
+-
+- AttachAndDamageBuffer(buffer, damage_region);
+-
+- SetupFrameCallback();
+- SetupPresentationFeedback(buffer_id);
+-
+- CommitSurface();
+-
+- connection_->ScheduleFlush();
+-
+- // If the contents were reset, there is no buffer attached. It means we have
+- // to behave the same way as if it was the very first frame. Check the
+- // comment below where the |contents_reset_| is declared.
+- if (contents_reset_) {
+- prev_submitted_buffer_ = nullptr;
+- contents_reset_ = false;
+- }
+-
+- // If it was the very first frame, the surface has not had a back buffer
+- // before, and Wayland won't release the front buffer until next buffer is
+- // attached. Thus, notify about successful submission immediately.
+- if (!prev_submitted_buffer_)
+- CompleteSubmission();
+-
+- return true;
++ return CommitBufferInternal(buffer);
+ }
+
+ bool CreateBuffer(const gfx::Size& size, uint32_t buffer_id) {
+@@ -150,6 +128,9 @@ class WaylandBufferManagerHost::Surface {
+ if (prev_submitted_buffer_ == buffer)
+ prev_submitted_buffer_ = nullptr;
+
++ if (pending_buffer_ == buffer)
++ pending_buffer_ = nullptr;
++
+ auto result = buffers_.erase(buffer_id);
+ return result;
+ }
+@@ -167,6 +148,9 @@ class WaylandBufferManagerHost::Surface {
+
+ if (buffer->wl_buffer)
+ SetupBufferReleaseListener(buffer);
++
++ if (pending_buffer_ == buffer)
++ ProcessPendingBuffer();
+ }
+
+ void ClearState() {
+@@ -213,6 +197,10 @@ class WaylandBufferManagerHost::Surface {
+ // Actual buffer size.
+ const gfx::Size size;
+
++ // Damage region this buffer describes. Must be emptied once buffer is
++ // submitted.
++ gfx::Rect damage_region;
++
+ // The id of this buffer.
+ const uint32_t buffer_id;
+
+@@ -239,9 +227,45 @@ class WaylandBufferManagerHost::Surface {
+ DISALLOW_COPY_AND_ASSIGN(WaylandBuffer);
+ };
+
+- void AttachAndDamageBuffer(WaylandBuffer* buffer,
+- const gfx::Rect& damage_region) {
+- gfx::Rect pending_damage_region = damage_region;
++ bool CommitBufferInternal(WaylandBuffer* buffer) {
++ DCHECK(buffer);
++ DCHECK(!pending_buffer_);
++
++ // Once the BufferRelease is called, the buffer will be released.
++ DCHECK(buffer->released);
++ buffer->released = false;
++
++ DCHECK(!submitted_buffer_);
++ submitted_buffer_ = buffer;
++
++ AttachAndDamageBuffer(buffer);
++
++ SetupFrameCallback();
++ SetupPresentationFeedback(buffer->buffer_id);
++
++ CommitSurface();
++
++ connection_->ScheduleFlush();
++
++ // If the contents were reset, there is no buffer attached. It means we have
++ // to behave the same way as if it was the very first frame. Check the
++ // comment below where the |contents_reset_| is declared.
++ if (contents_reset_) {
++ prev_submitted_buffer_ = nullptr;
++ contents_reset_ = false;
++ }
++
++ // If it was the very first frame, the surface has not had a back buffer
++ // before, and Wayland won't release the front buffer until next buffer is
++ // attached. Thus, notify about successful submission immediately.
++ if (!prev_submitted_buffer_)
++ CompleteSubmission();
++
++ return true;
++ }
++
++ void AttachAndDamageBuffer(WaylandBuffer* buffer) {
++ gfx::Rect pending_damage_region = std::move(buffer->damage_region);
+ // If the size of the damage region is empty, wl_surface_damage must be
+ // supplied with the actual size of the buffer, which is going to be
+ // committed.
+@@ -299,6 +323,8 @@ class WaylandBufferManagerHost::Surface {
+ void OnFrameCallback(struct wl_callback* callback) {
+ DCHECK(wl_frame_callback_.get() == callback);
+ wl_frame_callback_.reset();
++
++ ProcessPendingBuffer();
+ }
+
+ // wl_callback_listener
+@@ -390,7 +416,8 @@ class WaylandBufferManagerHost::Surface {
+ const gfx::PresentationFeedback& feedback) {
+ // The order of submission and presentation callbacks cannot be controlled.
+ // Some Wayland compositors may fire presentation callbacks earlier than we
+- // are able to send submission callbacks and this is bad. Thus, handle it here.
++ // are able to send submission callbacks and this is bad. Thus, handle it
++ // here.
+ if (submitted_buffer_ && submitted_buffer_->buffer_id == buffer_id) {
+ submitted_buffer_->needs_send_feedback = true;
+ submitted_buffer_->feedback = feedback;
+@@ -441,6 +468,15 @@ class WaylandBufferManagerHost::Surface {
+ gfx::PresentationFeedback::Failure());
+ }
+
++ void ProcessPendingBuffer() {
++ if (!pending_buffer_)
++ return;
++
++ auto* buffer = pending_buffer_;
++ pending_buffer_ = nullptr;
++ CommitBufferInternal(buffer);
++ }
++
+ // Widget this helper surface backs and has 1:1 relationship with the
+ // WaylandWindow.
+
+@@ -465,6 +501,9 @@ class WaylandBufferManagerHost::Surface {
+ // shown.
+ PresentationFeedbackQueue presentation_feedbacks_;
+
++ // A buffer, which is pending to be submitted (look the comment in the
++ // CommitBuffer method).
++ WaylandBuffer* pending_buffer_ = nullptr;
+ // Current submitted buffer.
+ WaylandBuffer* submitted_buffer_ = nullptr;
+ // Previous submitted buffer.
+diff --git a/ui/ozone/platform/wayland/test/mock_zwp_linux_buffer_params.cc b/ui/ozone/platform/wayland/test/mock_zwp_linux_buffer_params.cc
+index ca7fa6add5b9..8ebe4e6444db 100644
+--- a/ui/ozone/platform/wayland/test/mock_zwp_linux_buffer_params.cc
++++ b/ui/ozone/platform/wayland/test/mock_zwp_linux_buffer_params.cc
+@@ -5,6 +5,7 @@
+ #include "ui/ozone/platform/wayland/test/mock_zwp_linux_buffer_params.h"
+
+ #include "ui/ozone/platform/wayland/test/mock_buffer.h"
++#include "ui/ozone/platform/wayland/test/mock_zwp_linux_dmabuf.h"
+
+ namespace wl {
+
+@@ -25,6 +26,20 @@ void Add(wl_client* client,
+ modifier_hi, modifier_lo);
+ }
+
++void CreateCommon(MockZwpLinuxBufferParamsV1* buffer_params,
++ wl_client* client,
++ int32_t width,
++ int32_t height,
++ uint32_t format,
++ uint32_t flags) {
++ wl_resource* buffer_resource =
++ CreateResourceWithImpl<::testing::NiceMock<MockBuffer>>(
++ client, &wl_buffer_interface, 1, &kMockWlBufferImpl, 0,
++ std::move(buffer_params->fds_));
++
++ buffer_params->SetBufferResource(buffer_resource);
++}
++
+ void Create(wl_client* client,
+ wl_resource* buffer_params_resource,
+ int32_t width,
+@@ -33,28 +48,23 @@ void Create(wl_client* client,
+ uint32_t flags) {
+ auto* buffer_params =
+ GetUserDataAs<MockZwpLinuxBufferParamsV1>(buffer_params_resource);
+-
+- wl_resource* buffer_resource =
+- CreateResourceWithImpl<::testing::NiceMock<MockBuffer>>(
+- client, &wl_buffer_interface, 1, &kMockWlBufferImpl, 0,
+- std::move(buffer_params->fds_));
+-
+- zwp_linux_buffer_params_v1_send_created(buffer_params_resource,
+- buffer_resource);
+-
++ CreateCommon(buffer_params, client, width, height, format, flags);
+ buffer_params->Create(client, buffer_params_resource, width, height, format,
+ flags);
+ }
+
+ void CreateImmed(wl_client* client,
+- wl_resource* resource,
++ wl_resource* buffer_params_resource,
+ uint32_t buffer_id,
+ int32_t width,
+ int32_t height,
+ uint32_t format,
+ uint32_t flags) {
+- GetUserDataAs<MockZwpLinuxBufferParamsV1>(resource)->CreateImmed(
+- client, resource, buffer_id, width, height, format, flags);
++ auto* buffer_params =
++ GetUserDataAs<MockZwpLinuxBufferParamsV1>(buffer_params_resource);
++ CreateCommon(buffer_params, client, width, height, format, flags);
++ buffer_params->CreateImmed(client, buffer_params_resource, buffer_id, width,
++ height, format, flags);
+ }
+
+ } // namespace
+@@ -66,6 +76,20 @@ const struct zwp_linux_buffer_params_v1_interface
+ MockZwpLinuxBufferParamsV1::MockZwpLinuxBufferParamsV1(wl_resource* resource)
+ : ServerObject(resource) {}
+
+-MockZwpLinuxBufferParamsV1::~MockZwpLinuxBufferParamsV1() {}
++MockZwpLinuxBufferParamsV1::~MockZwpLinuxBufferParamsV1() {
++ DCHECK(linux_dmabuf_);
++ linux_dmabuf_->OnBufferParamsDestroyed(this);
++}
++
++void MockZwpLinuxBufferParamsV1::SetZwpLinuxDmabuf(
++ MockZwpLinuxDmabufV1* linux_dmabuf) {
++ DCHECK(!linux_dmabuf_);
++ linux_dmabuf_ = linux_dmabuf;
++}
++
++void MockZwpLinuxBufferParamsV1::SetBufferResource(wl_resource* resource) {
++ DCHECK(!buffer_resource_);
++ buffer_resource_ = resource;
++}
+
+ } // namespace wl
+diff --git a/ui/ozone/platform/wayland/test/mock_zwp_linux_buffer_params.h b/ui/ozone/platform/wayland/test/mock_zwp_linux_buffer_params.h
+index 57b4b9299a31..7da794a92c69 100644
+--- a/ui/ozone/platform/wayland/test/mock_zwp_linux_buffer_params.h
++++ b/ui/ozone/platform/wayland/test/mock_zwp_linux_buffer_params.h
+@@ -20,6 +20,8 @@ namespace wl {
+ extern const struct zwp_linux_buffer_params_v1_interface
+ kMockZwpLinuxBufferParamsV1Impl;
+
++class MockZwpLinuxDmabufV1;
++
+ // Manage zwp_linux_buffer_params_v1
+ class MockZwpLinuxBufferParamsV1 : public ServerObject {
+ public:
+@@ -52,9 +54,24 @@ class MockZwpLinuxBufferParamsV1 : public ServerObject {
+ uint32_t format,
+ uint32_t flags));
+
++ wl_resource* buffer_resource() const { return buffer_resource_; }
++
++ void SetZwpLinuxDmabuf(MockZwpLinuxDmabufV1* linux_dmabuf);
++
++ void SetBufferResource(wl_resource* resource);
++
+ std::vector<base::ScopedFD> fds_;
+
+ private:
++ // Non-owned pointer to the linux dmabuf object, which created this params
++ // resource and holds a pointer to it. On destruction, must notify it about
++ // going out of scope.
++ MockZwpLinuxDmabufV1* linux_dmabuf_ = nullptr;
++
++ // A buffer resource, which is created on Create or CreateImmed call. Can be
++ // null if not created/failed to be created.
++ wl_resource* buffer_resource_ = nullptr;
++
+ DISALLOW_COPY_AND_ASSIGN(MockZwpLinuxBufferParamsV1);
+ };
+
+diff --git a/ui/ozone/platform/wayland/test/mock_zwp_linux_dmabuf.cc b/ui/ozone/platform/wayland/test/mock_zwp_linux_dmabuf.cc
+index c44d41a40bb7..006d55ff40f4 100644
+--- a/ui/ozone/platform/wayland/test/mock_zwp_linux_dmabuf.cc
++++ b/ui/ozone/platform/wayland/test/mock_zwp_linux_dmabuf.cc
+@@ -17,12 +17,20 @@ namespace {
+ constexpr uint32_t kLinuxDmabufVersion = 1;
+
+ void CreateParams(wl_client* client, wl_resource* resource, uint32_t id) {
+- CreateResourceWithImpl<::testing::NiceMock<MockZwpLinuxBufferParamsV1>>(
+- client, &zwp_linux_buffer_params_v1_interface,
+- wl_resource_get_version(resource), &kMockZwpLinuxBufferParamsV1Impl, id);
++ wl_resource* params_resource =
++ CreateResourceWithImpl<::testing::NiceMock<MockZwpLinuxBufferParamsV1>>(
++ client, &zwp_linux_buffer_params_v1_interface,
++ wl_resource_get_version(resource), &kMockZwpLinuxBufferParamsV1Impl,
++ id);
+
+- GetUserDataAs<MockZwpLinuxDmabufV1>(resource)->CreateParams(client, resource,
+- id);
++ auto* zwp_linux_dmabuf = GetUserDataAs<MockZwpLinuxDmabufV1>(resource);
++ auto* buffer_params =
++ GetUserDataAs<MockZwpLinuxBufferParamsV1>(params_resource);
++
++ DCHECK(buffer_params);
++ zwp_linux_dmabuf->StoreBufferParams(buffer_params);
++ buffer_params->SetZwpLinuxDmabuf(zwp_linux_dmabuf);
++ zwp_linux_dmabuf->CreateParams(client, resource, id);
+ }
+
+ } // namespace
+@@ -37,6 +45,20 @@ MockZwpLinuxDmabufV1::MockZwpLinuxDmabufV1()
+ &kMockZwpLinuxDmabufV1Impl,
+ kLinuxDmabufVersion) {}
+
+-MockZwpLinuxDmabufV1::~MockZwpLinuxDmabufV1() {}
++MockZwpLinuxDmabufV1::~MockZwpLinuxDmabufV1() {
++ DCHECK(buffer_params_.empty());
++}
++
++void MockZwpLinuxDmabufV1::StoreBufferParams(
++ MockZwpLinuxBufferParamsV1* params) {
++ buffer_params_.push_back(params);
++}
++
++void MockZwpLinuxDmabufV1::OnBufferParamsDestroyed(
++ MockZwpLinuxBufferParamsV1* params) {
++ auto it = std::find(buffer_params_.begin(), buffer_params_.end(), params);
++ DCHECK(it != buffer_params_.end());
++ buffer_params_.erase(it);
++}
+
+ } // namespace wl
+diff --git a/ui/ozone/platform/wayland/test/mock_zwp_linux_dmabuf.h b/ui/ozone/platform/wayland/test/mock_zwp_linux_dmabuf.h
+index f63b92d34a50..9d2e1077d79f 100644
+--- a/ui/ozone/platform/wayland/test/mock_zwp_linux_dmabuf.h
++++ b/ui/ozone/platform/wayland/test/mock_zwp_linux_dmabuf.h
+@@ -18,6 +18,8 @@ namespace wl {
+
+ extern const struct zwp_linux_dmabuf_v1_interface kMockZwpLinuxDmabufV1Impl;
+
++class MockZwpLinuxBufferParamsV1;
++
+ // Manage zwp_linux_dmabuf_v1 object.
+ class MockZwpLinuxDmabufV1 : public GlobalObject {
+ public:
+@@ -30,7 +32,17 @@ class MockZwpLinuxDmabufV1 : public GlobalObject {
+ wl_resource* resource,
+ uint32_t params_id));
+
++ const std::vector<MockZwpLinuxBufferParamsV1*>& buffer_params() const {
++ return buffer_params_;
++ }
++
++ void StoreBufferParams(MockZwpLinuxBufferParamsV1* params);
++
++ void OnBufferParamsDestroyed(MockZwpLinuxBufferParamsV1* params);
++
+ private:
++ std::vector<MockZwpLinuxBufferParamsV1*> buffer_params_;
++
+ DISALLOW_COPY_AND_ASSIGN(MockZwpLinuxDmabufV1);
+ };
+
+--
+2.22.0
+
diff --git a/Added-HiDPI-support-for-Ozone-Wayland.patch b/0008-ozone-wayland-Added-HiDPI-support-for-Ozone-Wayland.patch
index 7f7bf66cd392..d9eb2d8925e4 100644
--- a/Added-HiDPI-support-for-Ozone-Wayland.patch
+++ b/0008-ozone-wayland-Added-HiDPI-support-for-Ozone-Wayland.patch
@@ -1,28 +1,47 @@
-commit c6b0f1086062d2949eae1c6c4446050db4273195
-Author: Alexander Dunaev <adunaev@igalia.com>
-Date: Mon Jun 10 08:28:04 2019 +0000
+From d0ddcd522423f533cec29e43c4cbaca7b8d8e45c Mon Sep 17 00:00:00 2001
+From: Alexander Dunaev <adunaev@igalia.com>
+Date: Mon, 10 Jun 2019 08:28:04 +0000
+Subject: [PATCH 08/11] [ozone/wayland] Added HiDPI support for Ozone/Wayland.
- [ozone/wayland] Added HiDPI support for Ozone/Wayland.
-
- Wayland operates in DIP but the platform level works with physical pixels
- so it's the application's responsibility to render properly and translate
- locations and sizes to physical pixels and back.
-
- This CL introduces the behaviour required to support HiDPI screens:
- * The backing buffer now takes the scale factor taken from the output device.
- * Windows update their buffer scale when moved between displays that have
- different scale factor, or when properties of the display are changed.
- * Windows translate DIP to physical pixels and back, where necessary.
-
- R=msisov@igalia.com, rjkroege@chromium.org
-
- Bug: 910797
- Change-Id: I1acb96ebc306194c13865149e026bcfdfb8046bf
- Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1647154
- Reviewed-by: Maksim Sisov <msisov@igalia.com>
- Reviewed-by: Robert Kroeger <rjkroege@chromium.org>
- Commit-Queue: Alexander Dunaev <adunaev@igalia.com>
- Cr-Commit-Position: refs/heads/master@{#667537}
+Wayland operates in DIP but the platform level works with physical pixels
+so it's the application's responsibility to render properly and translate
+locations and sizes to physical pixels and back.
+
+This CL introduces the behaviour required to support HiDPI screens:
+* The backing buffer now takes the scale factor taken from the output device.
+* Windows update their buffer scale when moved between displays that have
+ different scale factor, or when properties of the display are changed.
+* Windows translate DIP to physical pixels and back, where necessary.
+
+R=msisov@igalia.com, rjkroege@chromium.org
+
+Bug: 910797
+Change-Id: I1acb96ebc306194c13865149e026bcfdfb8046bf
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1647154
+Reviewed-by: Maksim Sisov <msisov@igalia.com>
+Reviewed-by: Robert Kroeger <rjkroege@chromium.org>
+Commit-Queue: Alexander Dunaev <adunaev@igalia.com>
+Cr-Commit-Position: refs/heads/master@{#667537}
+---
+ .../wayland/host/wayland_connection.cc | 10 +
+ .../wayland/host/wayland_connection.h | 5 +-
+ .../platform/wayland/host/wayland_output.cc | 10 +-
+ .../platform/wayland/host/wayland_output.h | 5 +-
+ .../wayland/host/wayland_output_manager.cc | 24 ++-
+ .../wayland/host/wayland_output_manager.h | 9 +-
+ .../platform/wayland/host/wayland_screen.cc | 33 ++--
+ .../platform/wayland/host/wayland_screen.h | 2 +-
+ .../wayland/host/wayland_screen_unittest.cc | 22 ++-
+ .../platform/wayland/host/wayland_window.cc | 183 ++++++++++++++----
+ .../platform/wayland/host/wayland_window.h | 48 ++++-
+ .../wayland/host/xdg_popup_wrapper_v6.cc | 9 +-
+ .../platform/wayland/test/mock_surface.cc | 6 +-
+ ui/ozone/platform/wayland/test/mock_surface.h | 1 +
+ ui/ozone/platform/wayland/test/test_output.cc | 5 +
+ ui/ozone/platform/wayland/test/test_output.h | 2 +
+ .../platform/wayland/test/wayland_test.cc | 4 +
+ ui/ozone/platform/wayland/test/wayland_test.h | 3 +
+ 18 files changed, 298 insertions(+), 83 deletions(-)
diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc
index 477ee110a0de..72617b5f37a3 100644
@@ -355,7 +374,7 @@ index 54e72fb5c916..f93ac20d51e0 100644
WaylandScreenTest,
::testing::Values(kXdgShellV5));
diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc
-index 153c8e87e124..193bd2a66150 100644
+index 3d4229f466ff..eb79b91892f9 100644
--- a/ui/ozone/platform/wayland/host/wayland_window.cc
+++ b/ui/ozone/platform/wayland/host/wayland_window.cc
@@ -123,7 +123,11 @@ WaylandWindow* WaylandWindow::FromSurface(wl_surface* surface) {
@@ -522,8 +541,8 @@ index 153c8e87e124..193bd2a66150 100644
}
void WaylandWindow::SetTitle(const base::string16& title) {
-@@ -452,12 +505,12 @@ void WaylandWindow::ConfineCursorToBounds(const gfx::Rect& bounds) {
- NOTIMPLEMENTED();
+@@ -457,12 +510,12 @@ PlatformImeController* WaylandWindow::GetPlatformImeController() {
+ return nullptr;
}
-void WaylandWindow::SetRestoredBoundsInPixels(const gfx::Rect& bounds) {
@@ -538,7 +557,7 @@ index 153c8e87e124..193bd2a66150 100644
}
bool WaylandWindow::CanDispatchEvent(const PlatformEvent& event) {
-@@ -488,6 +541,10 @@ uint32_t WaylandWindow::DispatchEvent(const PlatformEvent& native_event) {
+@@ -493,6 +546,10 @@ uint32_t WaylandWindow::DispatchEvent(const PlatformEvent& native_event) {
Event* event = static_cast<Event*>(native_event);
if (event->IsLocatedEvent()) {
@@ -549,7 +568,7 @@ index 153c8e87e124..193bd2a66150 100644
auto copied_event = Event::Clone(*event);
UpdateCursorPositionFromEvent(std::move(copied_event));
}
-@@ -569,11 +626,13 @@ void WaylandWindow::HandleSurfaceConfigure(int32_t width,
+@@ -574,11 +631,13 @@ void WaylandWindow::HandleSurfaceConfigure(int32_t width,
// explicitly set the bounds to the current desired ones or the previous
// bounds.
if (width > 1 && height > 1) {
@@ -567,7 +586,7 @@ index 153c8e87e124..193bd2a66150 100644
}
if (state_changed) {
-@@ -585,8 +644,8 @@ void WaylandWindow::HandleSurfaceConfigure(int32_t width,
+@@ -590,8 +649,8 @@ void WaylandWindow::HandleSurfaceConfigure(int32_t width,
if (is_normal) {
SetRestoredBoundsInPixels({});
} else if (old_state == PlatformWindowState::PLATFORM_WINDOW_STATE_NORMAL ||
@@ -578,7 +597,7 @@ index 153c8e87e124..193bd2a66150 100644
}
delegate_->OnWindowStateChanged(state_);
-@@ -598,9 +657,13 @@ void WaylandWindow::HandleSurfaceConfigure(int32_t width,
+@@ -603,9 +662,13 @@ void WaylandWindow::HandleSurfaceConfigure(int32_t width,
MaybeTriggerPendingStateChange();
}
@@ -594,7 +613,7 @@ index 153c8e87e124..193bd2a66150 100644
// It's not enough to just set new bounds. If it is a menu window, whose
// parent is a top level window aka browser window, it can be flipped
-@@ -618,10 +681,10 @@ void WaylandWindow::HandlePopupConfigure(const gfx::Rect& bounds) {
+@@ -623,10 +686,10 @@ void WaylandWindow::HandlePopupConfigure(const gfx::Rect& bounds) {
gfx::Rect parent_bounds = parent_window_->GetBounds();
// The menu window is flipped along y-axis and have x,-y origin. Shift the
// parent top level window instead.
@@ -608,7 +627,7 @@ index 153c8e87e124..193bd2a66150 100644
} else {
// If the menu window is located at correct origin from the browser point
// of view, return the top level window back to 0,0.
-@@ -633,11 +696,15 @@ void WaylandWindow::HandlePopupConfigure(const gfx::Rect& bounds) {
+@@ -638,11 +701,15 @@ void WaylandWindow::HandlePopupConfigure(const gfx::Rect& bounds) {
// Thus, the location must be translated to be relative to the top level
// window, which automatically becomes the same as relative to an origin of
// a display.
@@ -628,7 +647,7 @@ index 153c8e87e124..193bd2a66150 100644
}
void WaylandWindow::OnCloseRequest() {
-@@ -685,6 +752,26 @@ void WaylandWindow::OnDragSessionClose(uint32_t dnd_action) {
+@@ -690,6 +757,26 @@ void WaylandWindow::OnDragSessionClose(uint32_t dnd_action) {
connection_->ResetPointerFlags();
}
@@ -655,7 +674,7 @@ index 153c8e87e124..193bd2a66150 100644
bool WaylandWindow::IsMinimized() const {
return state_ == PlatformWindowState::PLATFORM_WINDOW_STATE_MINIMIZED;
}
-@@ -740,14 +827,28 @@ void WaylandWindow::AddSurfaceListener() {
+@@ -745,14 +832,28 @@ void WaylandWindow::AddSurfaceListener() {
}
void WaylandWindow::AddEnteredOutputId(struct wl_output* output) {
@@ -684,7 +703,7 @@ index 153c8e87e124..193bd2a66150 100644
const uint32_t left_output_id =
connection_->wayland_output_manager()->GetIdForOutput(output);
auto entered_output_id_it = entered_outputs_ids_.find(left_output_id);
-@@ -759,6 +860,8 @@ void WaylandWindow::RemoveEnteredOutputId(struct wl_output* output) {
+@@ -764,6 +865,8 @@ void WaylandWindow::RemoveEnteredOutputId(struct wl_output* output) {
// output only if it was stored before.
if (entered_output_id_it != entered_outputs_ids_.end())
entered_outputs_ids_.erase(entered_output_id_it);
@@ -693,7 +712,7 @@ index 153c8e87e124..193bd2a66150 100644
}
void WaylandWindow::UpdateCursorPositionFromEvent(
-@@ -807,11 +910,14 @@ gfx::Rect WaylandWindow::AdjustPopupWindowPosition() const {
+@@ -812,11 +915,14 @@ gfx::Rect WaylandWindow::AdjustPopupWindowPosition() const {
? parent_window_->parent_window_
: parent_window_;
DCHECK(parent_window);
@@ -710,7 +729,7 @@ index 153c8e87e124..193bd2a66150 100644
// Chromium may decide to position nested menu windows on the left side
// instead of the right side of parent menu windows when the size of the
-@@ -835,7 +941,8 @@ gfx::Rect WaylandWindow::AdjustPopupWindowPosition() const {
+@@ -840,7 +946,8 @@ gfx::Rect WaylandWindow::AdjustPopupWindowPosition() const {
// Position the child menu window on the right side of the parent window
// and let the Wayland compositor decide how to do constraint
// adjustements.
@@ -720,7 +739,7 @@ index 153c8e87e124..193bd2a66150 100644
new_bounds.set_x(new_x);
}
}
-@@ -852,7 +959,7 @@ void WaylandWindow::MaybeUpdateOpaqueRegion() {
+@@ -857,7 +964,7 @@ void WaylandWindow::MaybeUpdateOpaqueRegion() {
wl::Object<wl_region> region(
wl_compositor_create_region(connection_->compositor()));
@@ -730,7 +749,7 @@ index 153c8e87e124..193bd2a66150 100644
connection_->ScheduleFlush();
diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h
-index be9bb33481e7..f54115e0aef8 100644
+index 3d46ba1f4e7e..8fcf28fde934 100644
--- a/ui/ozone/platform/wayland/host/wayland_window.h
+++ b/ui/ozone/platform/wayland/host/wayland_window.h
@@ -51,10 +51,19 @@ class WaylandWindow : public PlatformWindow,
@@ -762,7 +781,7 @@ index be9bb33481e7..f54115e0aef8 100644
bool is_active() const { return is_active_; }
// WmMoveResizeHandler
-@@ -128,6 +139,10 @@ class WaylandWindow : public PlatformWindow,
+@@ -129,6 +140,10 @@ class WaylandWindow : public PlatformWindow,
bool CanDispatchEvent(const PlatformEvent& event) override;
uint32_t DispatchEvent(const PlatformEvent& event) override;
@@ -773,7 +792,7 @@ index be9bb33481e7..f54115e0aef8 100644
void HandleSurfaceConfigure(int32_t widht,
int32_t height,
bool is_maximized,
-@@ -146,6 +161,9 @@ class WaylandWindow : public PlatformWindow,
+@@ -147,6 +162,9 @@ class WaylandWindow : public PlatformWindow,
void OnDragSessionClose(uint32_t dnd_action);
private:
@@ -783,7 +802,7 @@ index be9bb33481e7..f54115e0aef8 100644
bool IsMinimized() const;
bool IsMaximized() const;
bool IsFullscreen() const;
-@@ -213,14 +231,27 @@ class WaylandWindow : public PlatformWindow,
+@@ -214,14 +232,27 @@ class WaylandWindow : public PlatformWindow,
base::OnceCallback<void(int)> drag_closed_callback_;
@@ -815,7 +834,7 @@ index be9bb33481e7..f54115e0aef8 100644
// Stores current states of the window.
ui::PlatformWindowState state_;
-@@ -236,7 +267,14 @@ class WaylandWindow : public PlatformWindow,
+@@ -237,7 +268,14 @@ class WaylandWindow : public PlatformWindow,
bool is_tooltip_ = false;
@@ -862,10 +881,10 @@ index a17719ea848f..742f8d46a71c 100644
// static
diff --git a/ui/ozone/platform/wayland/test/mock_surface.cc b/ui/ozone/platform/wayland/test/mock_surface.cc
-index 9d2333683a41..b086bdc85416 100644
+index 6ee1c0a9c543..fa53a037669b 100644
--- a/ui/ozone/platform/wayland/test/mock_surface.cc
+++ b/ui/ozone/platform/wayland/test/mock_surface.cc
-@@ -47,6 +47,10 @@ void Commit(wl_client* client, wl_resource* resource) {
+@@ -54,6 +54,10 @@ void Commit(wl_client* client, wl_resource* resource) {
GetUserDataAs<MockSurface>(resource)->Commit();
}
@@ -876,7 +895,7 @@ index 9d2333683a41..b086bdc85416 100644
void DamageBuffer(struct wl_client* client,
struct wl_resource* resource,
int32_t x,
-@@ -67,7 +71,7 @@ const struct wl_surface_interface kMockSurfaceImpl = {
+@@ -74,7 +78,7 @@ const struct wl_surface_interface kMockSurfaceImpl = {
SetInputRegion, // set_input_region
Commit, // commit
nullptr, // set_buffer_transform
@@ -886,7 +905,7 @@ index 9d2333683a41..b086bdc85416 100644
};
diff --git a/ui/ozone/platform/wayland/test/mock_surface.h b/ui/ozone/platform/wayland/test/mock_surface.h
-index 1ea9c52dea27..d283e44b2fe9 100644
+index 0b44ba090187..1d781d03d3dc 100644
--- a/ui/ozone/platform/wayland/test/mock_surface.h
+++ b/ui/ozone/platform/wayland/test/mock_surface.h
@@ -37,6 +37,7 @@ class MockSurface : public ServerObject {
@@ -967,3 +986,6 @@ index 0acdf07c39b3..85a095dfd309 100644
std::unique_ptr<WaylandWindow> window_;
gfx::AcceleratedWidget widget_ = gfx::kNullAcceleratedWidget;
+--
+2.22.0
+
diff --git a/0009-Fixed-positioning-and-sizes-of-menus-when-the-scale-.patch b/0009-Fixed-positioning-and-sizes-of-menus-when-the-scale-.patch
new file mode 100644
index 000000000000..2e153cf2ff0c
--- /dev/null
+++ b/0009-Fixed-positioning-and-sizes-of-menus-when-the-scale-.patch
@@ -0,0 +1,315 @@
+From 6077336fd2b3a5402ef07e980ebcd46106d8074e Mon Sep 17 00:00:00 2001
+From: Alexander Dunaev <adunaev@igalia.com>
+Date: Wed, 17 Jul 2019 05:26:49 +0000
+Subject: [PATCH 09/11] Fixed positioning and sizes of menus when the scale
+ factor is forced.
+
+When --force-device-scale-factor command line flag is present, the UI scale
+is replaced with the value passed with the flag, which should be taken into
+account when positioning and sizing the menus.
+
+R=msisov@igalia.com, rjkroege@chromium.org
+
+Bug: 910797
+Change-Id: I7880472c29fdaa33e20e2a896e48f922c20680ac
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1692578
+Auto-Submit: Alexander Dunaev <adunaev@igalia.com>
+Reviewed-by: Maksim Sisov <msisov@igalia.com>
+Reviewed-by: Robert Kroeger <rjkroege@chromium.org>
+Commit-Queue: Maksim Sisov <msisov@igalia.com>
+Cr-Commit-Position: refs/heads/master@{#678151}
+---
+ .../wayland/host/wayland_connection.cc | 2 +-
+ .../platform/wayland/host/wayland_screen.cc | 2 +-
+ .../wayland/host/wayland_screen_unittest.cc | 38 +++++++++++++--
+ .../platform/wayland/host/wayland_window.cc | 46 ++++++++++---------
+ .../platform/wayland/host/wayland_window.h | 37 +++++++++------
+ 5 files changed, 81 insertions(+), 44 deletions(-)
+
+diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc
+index 72617b5f37a3..a949baf5a934 100644
+--- a/ui/ozone/platform/wayland/host/wayland_connection.cc
++++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
+@@ -164,7 +164,7 @@ std::vector<WaylandWindow*> WaylandConnection::GetWindowsOnOutput(
+ uint32_t output_id) {
+ std::vector<WaylandWindow*> result;
+ for (auto entry : window_map_) {
+- if (entry.second->GetEnteredOutputsIds().count(output_id) > 0)
++ if (entry.second->entered_outputs_ids().count(output_id) > 0)
+ result.push_back(entry.second);
+ }
+ return result;
+diff --git a/ui/ozone/platform/wayland/host/wayland_screen.cc b/ui/ozone/platform/wayland/host/wayland_screen.cc
+index 694c13f4e4d2..ef372ad794d3 100644
+--- a/ui/ozone/platform/wayland/host/wayland_screen.cc
++++ b/ui/ozone/platform/wayland/host/wayland_screen.cc
+@@ -107,7 +107,7 @@ display::Display WaylandScreen::GetDisplayForAcceleratedWidget(
+ return GetPrimaryDisplay();
+
+ const auto* parent_window = window->parent_window();
+- const std::set<uint32_t> entered_outputs_ids = window->GetEnteredOutputsIds();
++ const auto entered_outputs_ids = window->entered_outputs_ids();
+ // Although spec says a surface receives enter/leave surface events on
+ // create/move/resize actions, this might be called right after a window is
+ // created, but it has not been configured by a Wayland compositor and it has
+diff --git a/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc b/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc
+index f93ac20d51e0..0a18b8366cae 100644
+--- a/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc
++++ b/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc
+@@ -5,8 +5,11 @@
+ #include <wayland-server.h>
+ #include <memory>
+
++#include "base/strings/stringprintf.h"
++#include "base/test/scoped_command_line.h"
+ #include "testing/gtest/include/gtest/gtest.h"
+ #include "ui/display/display_observer.h"
++#include "ui/display/display_switches.h"
+ #include "ui/ozone/platform/wayland/host/wayland_connection.h"
+ #include "ui/ozone/platform/wayland/host/wayland_output_manager.h"
+ #include "ui/ozone/platform/wayland/host/wayland_screen.h"
+@@ -586,14 +589,39 @@ TEST_P(WaylandScreenTest, SetBufferScale) {
+ wl_surface_send_enter(surface_->resource(), output_->resource());
+
+ // Change the scale of the output. Windows looking into that output must get
+- // the new scale and update scale of their buffers.
+- const int32_t kNewScale = 3;
+- EXPECT_CALL(*surface_, SetBufferScale(kNewScale));
+- output_->SetScale(kNewScale);
++ // the new scale and update scale of their buffers. The default UI scale
++ // equals the output scale.
++ const int32_t kTripleScale = 3;
++ EXPECT_CALL(*surface_, SetBufferScale(kTripleScale));
++ output_->SetScale(kTripleScale);
+
+ Sync();
+
+- EXPECT_EQ(window_->buffer_scale(), kNewScale);
++ EXPECT_EQ(window_->buffer_scale(), kTripleScale);
++ EXPECT_EQ(window_->ui_scale_, kTripleScale);
++
++ // Now simulate the --force-device-scale-factor=1.5
++ const float kForcedUIScale = 1.5;
++ base::test::ScopedCommandLine command_line;
++ command_line.GetProcessCommandLine()->AppendSwitchASCII(
++ switches::kForceDeviceScaleFactor,
++ base::StringPrintf("%.1f", kForcedUIScale));
++ display::Display::ResetForceDeviceScaleFactorForTesting();
++
++ // Change the scale of the output again. Windows must update scale of
++ // their buffers but the UI scale must get the forced value.
++ const int32_t kDoubleScale = 2;
++ // Question ourselves before questioning others!
++ EXPECT_NE(kForcedUIScale, kDoubleScale);
++ EXPECT_CALL(*surface_, SetBufferScale(kDoubleScale));
++ output_->SetScale(kDoubleScale);
++
++ Sync();
++
++ EXPECT_EQ(window_->buffer_scale(), kDoubleScale);
++ EXPECT_EQ(window_->ui_scale_, kForcedUIScale);
++
++ display::Display::ResetForceDeviceScaleFactorForTesting();
+ }
+
+ INSTANTIATE_TEST_SUITE_P(XdgVersionV5Test,
+diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc
+index eb79b91892f9..9afed0cc87fb 100644
+--- a/ui/ozone/platform/wayland/host/wayland_window.cc
++++ b/ui/ozone/platform/wayland/host/wayland_window.cc
+@@ -147,6 +147,7 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) {
+ // Popups need to know their scale earlier to position themselves.
+ DCHECK(parent_window_);
+ 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
+@@ -184,15 +185,19 @@ void WaylandWindow::UpdateBufferScale(bool update_bounds) {
+ int32_t new_scale = 0;
+ if (parent_window_) {
+ new_scale = parent_window_->buffer_scale_;
+- } else if (widget == gfx::kNullAcceleratedWidget) {
+- new_scale = screen->GetPrimaryDisplay().device_scale_factor();
++ ui_scale_ = parent_window_->ui_scale_;
+ } else {
+- // This is the main window that is fully set up so we can ask which display
+- // we are at currently.
+- new_scale =
+- connection_->wayland_output_manager()
+- ->GetOutput(screen->GetDisplayForAcceleratedWidget(widget).id())
+- ->scale_factor();
++ const auto display = (widget == gfx::kNullAcceleratedWidget)
++ ? screen->GetPrimaryDisplay()
++ : screen->GetDisplayForAcceleratedWidget(widget);
++ new_scale = connection_->wayland_output_manager()
++ ->GetOutput(display.id())
++ ->scale_factor();
++
++ if (display::Display::HasForceDeviceScaleFactor())
++ ui_scale_ = display::Display::GetForcedDeviceScaleFactor();
++ else
++ ui_scale_ = display.device_scale_factor();
+ }
+ SetBufferScale(new_scale, update_bounds);
+ }
+@@ -203,10 +208,6 @@ gfx::AcceleratedWidget WaylandWindow::GetWidget() const {
+ return surface_.id();
+ }
+
+-std::set<uint32_t> WaylandWindow::GetEnteredOutputsIds() const {
+- return entered_outputs_ids_;
+-}
+-
+ void WaylandWindow::CreateXdgPopup() {
+ if (bounds_px_.IsEmpty())
+ return;
+@@ -333,7 +334,7 @@ void WaylandWindow::Show() {
+ // bounds. This makes a difference against the normal flow when the
+ // window is created (see |Initialize|). To equalize things, rescale
+ // |bounds_px_| to DIP. It will be adjusted while creating the popup.
+- bounds_px_ = gfx::ScaleToRoundedRect(bounds_px_, 1.0 / buffer_scale_);
++ bounds_px_ = gfx::ScaleToRoundedRect(bounds_px_, 1.0 / ui_scale_);
+ CreateXdgPopup();
+ connection_->ScheduleFlush();
+ }
+@@ -916,13 +917,14 @@ gfx::Rect WaylandWindow::AdjustPopupWindowPosition() const {
+ : parent_window_;
+ DCHECK(parent_window);
+ DCHECK(buffer_scale_ == parent_window->buffer_scale_);
++ DCHECK(ui_scale_ == parent_window->ui_scale_);
+
+ // Chromium positions windows in screen coordinates, but Wayland requires them
+ // to be in local surface coordinates aka relative to parent window.
+- const gfx::Rect parent_bounds_px =
+- gfx::ScaleToRoundedRect(parent_window_->GetBounds(), 1.0 / buffer_scale_);
+- gfx::Rect new_bounds =
+- TranslateBoundsToParentCoordinates(bounds_px_, parent_bounds_px);
++ const gfx::Rect parent_bounds_dip =
++ gfx::ScaleToRoundedRect(parent_window_->GetBounds(), 1.0 / ui_scale_);
++ gfx::Rect new_bounds_dip =
++ TranslateBoundsToParentCoordinates(bounds_px_, parent_bounds_dip);
+
+ // Chromium may decide to position nested menu windows on the left side
+ // instead of the right side of parent menu windows when the size of the
+@@ -942,16 +944,16 @@ gfx::Rect WaylandWindow::AdjustPopupWindowPosition() const {
+ !parent_window_->parent_window_->IsMaximized()) {
+ auto* top_level_window = parent_window_->parent_window_;
+ DCHECK(top_level_window && !top_level_window->xdg_popup());
+- if (new_bounds.x() <= 0 && !top_level_window->IsMaximized()) {
++ if (new_bounds_dip.x() <= 0 && !top_level_window->IsMaximized()) {
+ // Position the child menu window on the right side of the parent window
+ // and let the Wayland compositor decide how to do constraint
+ // adjustements.
+- int new_x =
+- parent_bounds_px.width() - (new_bounds.width() + new_bounds.x());
+- new_bounds.set_x(new_x);
++ int new_x = parent_bounds_dip.width() -
++ (new_bounds_dip.width() + new_bounds_dip.x());
++ new_bounds_dip.set_x(new_x);
+ }
+ }
+- return new_bounds;
++ return gfx::ScaleToRoundedRect(new_bounds_dip, ui_scale_ / buffer_scale_);
+ }
+
+ WaylandWindow* WaylandWindow::GetTopLevelWindow() {
+diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h
+index 8fcf28fde934..d21e5f48e8ff 100644
+--- a/ui/ozone/platform/wayland/host/wayland_window.h
++++ b/ui/ozone/platform/wayland/host/wayland_window.h
+@@ -10,6 +10,8 @@
+ #include <vector>
+
+ #include "base/callback.h"
++#include "base/containers/flat_set.h"
++#include "base/gtest_prod_util.h"
+ #include "base/memory/ref_counted.h"
+ #include "ui/events/platform/platform_event_dispatcher.h"
+ #include "ui/gfx/geometry/rect.h"
+@@ -52,10 +54,10 @@ class WaylandWindow : public PlatformWindow,
+ bool Initialize(PlatformWindowInitProperties properties);
+
+ // Updates the surface buffer scale of the window. Top level windows take
+- // scale according to the scale of their current display or the primary one if
+- // their widget is not yet created, children inherit scale from their parent.
+- // The method recalculates window bounds appropriately if asked to do so
+- // (this is not needed upon window initialization).
++ // scale from the output attached to either their current display or the
++ // primary one if their widget is not yet created, children inherit scale from
++ // their parent. The method recalculates window bounds appropriately if asked
++ // to do so (this is not needed upon window initialization).
+ void UpdateBufferScale(bool update_bounds);
+
+ wl_surface* surface() const { return surface_.get(); }
+@@ -66,13 +68,6 @@ class WaylandWindow : public PlatformWindow,
+
+ gfx::AcceleratedWidget GetWidget() const;
+
+- // Returns the list of wl_outputs aka displays, which this window occupies.
+- // The window can be shown on one or more displays at the same time. An empty
+- // vector can also be returned if the window is not configured on the
+- // compositor side or it has been moved due to unplug action (check the
+- // comment in RemoveEnteredOutputId).
+- std::set<uint32_t> GetEnteredOutputsIds() const;
+-
+ // 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();
+@@ -102,6 +97,10 @@ class WaylandWindow : public PlatformWindow,
+
+ bool is_active() const { return is_active_; }
+
++ const base::flat_set<uint32_t>& entered_outputs_ids() const {
++ return entered_outputs_ids_;
++ }
++
+ // WmMoveResizeHandler
+ void DispatchHostWindowDragMovement(
+ int hittest,
+@@ -162,6 +161,8 @@ class WaylandWindow : public PlatformWindow,
+ void OnDragSessionClose(uint32_t dnd_action);
+
+ private:
++ FRIEND_TEST_ALL_PREFIXES(WaylandScreenTest, SetBufferScale);
++
+ void SetBoundsDip(const gfx::Rect& bounds_dip);
+ void SetBufferScale(int32_t scale, bool update_bounds);
+
+@@ -252,7 +253,13 @@ class WaylandWindow : public PlatformWindow,
+ bool has_keyboard_focus_ = false;
+ bool has_touch_focus_ = false;
+ bool has_implicit_grab_ = 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.
++ float ui_scale_ = 1.0;
+
+ // Stores current states of the window.
+ ui::PlatformWindowState state_;
+@@ -268,15 +275,15 @@ class WaylandWindow : public PlatformWindow,
+
+ bool is_tooltip_ = false;
+
+- // For top level window, stores the list of entered outputs that the window
+- // is currently in.
++ // For top level window, stores IDs of outputs that the window is currently
++ // rendered at.
+ //
+ // Not used by popups. When sub-menus are hidden and shown again, Wayland
+- // 'repositions' sub-menus to wrong outputs by sending them leave and enter
++ // 'repositions' them to wrong outputs by sending them leave and enter
+ // events so their list of entered outputs becomes meaningless after they have
+ // been hidden at least once. To determine which output the popup belongs to,
+ // we ask its parent.
+- std::set<uint32_t> entered_outputs_ids_;
++ base::flat_set<uint32_t> entered_outputs_ids_;
+
+ DISALLOW_COPY_AND_ASSIGN(WaylandWindow);
+ };
+--
+2.22.0
+
diff --git a/0010-ozone-wayland-Extract-window-management-methods-to-o.patch b/0010-ozone-wayland-Extract-window-management-methods-to-o.patch
new file mode 100644
index 000000000000..c784acd8e0f1
--- /dev/null
+++ b/0010-ozone-wayland-Extract-window-management-methods-to-o.patch
@@ -0,0 +1,810 @@
+From 1cac377724089974aef3dd66b215301bfd6c3dbd Mon Sep 17 00:00:00 2001
+From: Maksim Sisov <msisov@igalia.com>
+Date: Fri, 26 Jul 2019 04:56:22 +0000
+Subject: [PATCH 10/11] [ozone/wayland]: Extract window management methods to
+ own class
+
+WaylandConnection still has been overloaded with different tasks.
+
+Thus, to make code cleaner, extract window management methods into
+a separate class called WaylandWindowManager, which is responsible
+for managing windows.
+
+Bug: 987239
+Change-Id: Ic74291842e24e919dae7335ebb7c89b08a81a61c
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1715193
+Commit-Queue: Maksim Sisov <msisov@igalia.com>
+Reviewed-by: Antonio Gomes <tonikitoo@igalia.com>
+Cr-Commit-Position: refs/heads/master@{#681191}
+---
+ ui/ozone/platform/wayland/BUILD.gn | 3 +
+ .../wayland/gpu/wayland_surface_factory.cc | 4 +-
+ .../wayland/host/wayland_connection.cc | 69 +-----
+ .../wayland/host/wayland_connection.h | 23 +-
+ .../wayland/host/wayland_data_device.cc | 4 +-
+ .../wayland/host/wayland_data_source.cc | 3 +-
+ .../host/wayland_input_method_context.cc | 3 +-
+ .../platform/wayland/host/wayland_screen.cc | 13 +-
+ .../platform/wayland/host/wayland_window.cc | 18 +-
+ .../wayland/host/wayland_window_manager.cc | 90 +++++++
+ .../wayland/host/wayland_window_manager.h | 60 +++++
+ .../host/wayland_window_manager_unittests.cc | 222 ++++++++++++++++++
+ 12 files changed, 424 insertions(+), 88 deletions(-)
+ create mode 100644 ui/ozone/platform/wayland/host/wayland_window_manager.cc
+ create mode 100644 ui/ozone/platform/wayland/host/wayland_window_manager.h
+ create mode 100644 ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc
+
+diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn
+index a1560a20fe23..157d1beea880 100644
+--- a/ui/ozone/platform/wayland/BUILD.gn
++++ b/ui/ozone/platform/wayland/BUILD.gn
+@@ -74,6 +74,8 @@ source_set("wayland") {
+ "host/wayland_touch.h",
+ "host/wayland_window.cc",
+ "host/wayland_window.h",
++ "host/wayland_window_manager.cc",
++ "host/wayland_window_manager.h",
+ "host/wayland_zwp_linux_dmabuf.cc",
+ "host/wayland_zwp_linux_dmabuf.h",
+ "host/xdg_popup_wrapper.h",
+@@ -250,6 +252,7 @@ source_set("wayland_unittests") {
+ "host/wayland_pointer_unittest.cc",
+ "host/wayland_screen_unittest.cc",
+ "host/wayland_touch_unittest.cc",
++ "host/wayland_window_manager_unittests.cc",
+ "host/wayland_window_unittest.cc",
+ "test/wayland_test.cc",
+ "test/wayland_test.h",
+diff --git a/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc b/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
+index b5dba5fd525b..a5db42ef1b18 100644
+--- a/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
++++ b/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
+@@ -16,6 +16,7 @@
+ #include "ui/ozone/platform/wayland/gpu/wayland_canvas_surface.h"
+ #include "ui/ozone/platform/wayland/host/wayland_connection.h"
+ #include "ui/ozone/platform/wayland/host/wayland_window.h"
++#include "ui/ozone/platform/wayland/host/wayland_window_manager.h"
+
+ #if defined(WAYLAND_GBM)
+ #include "ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h"
+@@ -61,7 +62,8 @@ scoped_refptr<gl::GLSurface> GLOzoneEGLWayland::CreateViewGLSurface(
+ !connection_)
+ return nullptr;
+
+- WaylandWindow* window = connection_->GetWindow(widget);
++ WaylandWindow* window =
++ connection_->wayland_window_manager()->GetWindow(widget);
+ if (!window)
+ return nullptr;
+
+diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc
+index a949baf5a934..bf6d12717861 100644
+--- a/ui/ozone/platform/wayland/host/wayland_connection.cc
++++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
+@@ -45,7 +45,8 @@ constexpr uint32_t kMaxTextInputManagerVersion = 1;
+ constexpr uint32_t kMinWlOutputVersion = 2;
+ } // namespace
+
+-WaylandConnection::WaylandConnection() : controller_(FROM_HERE) {}
++WaylandConnection::WaylandConnection()
++ : wayland_window_manager_(this), controller_(FROM_HERE) {}
+
+ WaylandConnection::~WaylandConnection() = default;
+
+@@ -122,70 +123,17 @@ void WaylandConnection::ScheduleFlush() {
+ scheduled_flush_ = true;
+ }
+
+-WaylandWindow* WaylandConnection::GetWindow(
+- gfx::AcceleratedWidget widget) const {
+- auto it = window_map_.find(widget);
+- return it == window_map_.end() ? nullptr : it->second;
+-}
+-
+-WaylandWindow* WaylandConnection::GetWindowWithLargestBounds() const {
+- WaylandWindow* window_with_largest_bounds = nullptr;
+- for (auto entry : window_map_) {
+- if (!window_with_largest_bounds) {
+- window_with_largest_bounds = entry.second;
+- continue;
+- }
+- WaylandWindow* window = entry.second;
+- if (window_with_largest_bounds->GetBounds() < window->GetBounds())
+- window_with_largest_bounds = window;
+- }
+- return window_with_largest_bounds;
+-}
+-
+-WaylandWindow* WaylandConnection::GetCurrentFocusedWindow() const {
+- for (auto entry : window_map_) {
+- WaylandWindow* window = entry.second;
+- if (window->has_pointer_focus())
+- return window;
+- }
+- return nullptr;
+-}
+-
+-WaylandWindow* WaylandConnection::GetCurrentKeyboardFocusedWindow() const {
+- for (auto entry : window_map_) {
+- WaylandWindow* window = entry.second;
+- if (window->has_keyboard_focus())
+- return window;
+- }
+- return nullptr;
+-}
+-
+-std::vector<WaylandWindow*> WaylandConnection::GetWindowsOnOutput(
+- uint32_t output_id) {
+- std::vector<WaylandWindow*> result;
+- for (auto entry : window_map_) {
+- if (entry.second->entered_outputs_ids().count(output_id) > 0)
+- result.push_back(entry.second);
+- }
+- return result;
+-}
+-
+-void WaylandConnection::AddWindow(gfx::AcceleratedWidget widget,
+- WaylandWindow* window) {
++void WaylandConnection::OnWindowAdded(WaylandWindow* window) {
+ DCHECK(buffer_manager_host_);
+ buffer_manager_host_->OnWindowAdded(window);
+-
+- window_map_[widget] = window;
+ }
+
+-void WaylandConnection::RemoveWindow(gfx::AcceleratedWidget widget) {
++void WaylandConnection::OnWindowRemoved(WaylandWindow* window) {
+ if (touch_)
+- touch_->RemoveTouchPoints(window_map_[widget]);
++ touch_->RemoveTouchPoints(window);
+
+ DCHECK(buffer_manager_host_);
+- buffer_manager_host_->OnWindowRemoved(window_map_[widget]);
+-
+- window_map_.erase(widget);
++ buffer_manager_host_->OnWindowRemoved(window);
+ }
+
+ void WaylandConnection::SetCursorBitmap(const std::vector<SkBitmap>& bitmaps,
+@@ -260,8 +208,9 @@ void WaylandConnection::DispatchUiEvent(Event* event) {
+
+ void WaylandConnection::OnFileCanReadWithoutBlocking(int fd) {
+ wl_display_dispatch(display_.get());
+- for (const auto& window : window_map_)
+- window.second->ApplyPendingBounds();
++ std::vector<WaylandWindow*> windows = wayland_window_manager_.GetAllWindows();
++ for (auto* window : windows)
++ window->ApplyPendingBounds();
+ }
+
+ void WaylandConnection::OnFileCanWriteWithoutBlocking(int fd) {}
+diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h
+index 9ae6527337c6..8a56ebc6b921 100644
+--- a/ui/ozone/platform/wayland/host/wayland_connection.h
++++ b/ui/ozone/platform/wayland/host/wayland_connection.h
+@@ -25,6 +25,7 @@
+ #include "ui/ozone/platform/wayland/host/wayland_output.h"
+ #include "ui/ozone/platform/wayland/host/wayland_pointer.h"
+ #include "ui/ozone/platform/wayland/host/wayland_touch.h"
++#include "ui/ozone/platform/wayland/host/wayland_window_manager.h"
+
+ namespace ui {
+
+@@ -46,6 +47,9 @@ class WaylandConnection : public PlatformEventSource,
+ // Schedules a flush of the Wayland connection.
+ void ScheduleFlush();
+
++ void OnWindowAdded(WaylandWindow* window);
++ void OnWindowRemoved(WaylandWindow* window);
++
+ wl_display* display() const { return display_.get(); }
+ wl_compositor* compositor() const { return compositor_.get(); }
+ wl_subcompositor* subcompositor() const { return subcompositor_.get(); }
+@@ -58,16 +62,6 @@ class WaylandConnection : public PlatformEventSource,
+ return text_input_manager_v1_.get();
+ }
+
+- WaylandWindow* GetWindow(gfx::AcceleratedWidget widget) const;
+- WaylandWindow* GetWindowWithLargestBounds() const;
+- WaylandWindow* GetCurrentFocusedWindow() const;
+- WaylandWindow* GetCurrentKeyboardFocusedWindow() const;
+- // TODO(crbug.com/971525): remove this in favor of targeted subscription of
+- // windows to their outputs.
+- std::vector<WaylandWindow*> GetWindowsOnOutput(uint32_t output_id);
+- void AddWindow(gfx::AcceleratedWidget widget, WaylandWindow* window);
+- void RemoveWindow(gfx::AcceleratedWidget widget);
+-
+ void set_serial(uint32_t serial) { serial_ = serial; }
+ uint32_t serial() const { return serial_; }
+
+@@ -102,6 +96,10 @@ class WaylandConnection : public PlatformEventSource,
+
+ WaylandShm* shm() const { return shm_.get(); }
+
++ WaylandWindowManager* wayland_window_manager() {
++ return &wayland_window_manager_;
++ }
++
+ std::vector<gfx::BufferFormat> GetSupportedBufferFormats();
+
+ // Starts drag with |data| to be delivered, |operation| supported by the
+@@ -166,8 +164,6 @@ class WaylandConnection : public PlatformEventSource,
+ // xdg_shell_listener
+ static void Ping(void* data, xdg_shell* shell, uint32_t serial);
+
+- base::flat_map<gfx::AcceleratedWidget, WaylandWindow*> window_map_;
+-
+ wl::Object<wl_display> display_;
+ wl::Object<wl_registry> registry_;
+ wl::Object<wl_compositor> compositor_;
+@@ -191,6 +187,9 @@ class WaylandConnection : public PlatformEventSource,
+ std::unique_ptr<WaylandShm> shm_;
+ std::unique_ptr<WaylandBufferManagerHost> buffer_manager_host_;
+
++ // Manages Wayland windows.
++ WaylandWindowManager wayland_window_manager_;
++
+ bool scheduled_flush_ = false;
+ bool watching_ = false;
+ base::MessagePumpLibevent::FdWatchController controller_;
+diff --git a/ui/ozone/platform/wayland/host/wayland_data_device.cc b/ui/ozone/platform/wayland/host/wayland_data_device.cc
+index f258e8ddba2d..a36cd3b7a888 100644
+--- a/ui/ozone/platform/wayland/host/wayland_data_device.cc
++++ b/ui/ozone/platform/wayland/host/wayland_data_device.cc
+@@ -146,7 +146,9 @@ void WaylandDataDevice::DeliverDragData(const std::string& mime_type,
+ void WaylandDataDevice::StartDrag(wl_data_source* data_source,
+ const ui::OSExchangeData& data) {
+ DCHECK(data_source);
+- WaylandWindow* window = connection_->GetCurrentFocusedWindow();
++
++ WaylandWindow* window =
++ connection_->wayland_window_manager()->GetCurrentFocusedWindow();
+ if (!window) {
+ LOG(ERROR) << "Failed to get focused window.";
+ return;
+diff --git a/ui/ozone/platform/wayland/host/wayland_data_source.cc b/ui/ozone/platform/wayland/host/wayland_data_source.cc
+index f8ba38a0fa51..dcd6b75aa299 100644
+--- a/ui/ozone/platform/wayland/host/wayland_data_source.cc
++++ b/ui/ozone/platform/wayland/host/wayland_data_source.cc
+@@ -50,7 +50,8 @@ void WaylandDataSource::Offer(const ui::OSExchangeData& data) {
+ mime_types.push_back(kTextMimeType);
+ mime_types.push_back(kTextMimeTypeUtf8);
+
+- source_window_ = connection_->GetCurrentFocusedWindow();
++ source_window_ =
++ connection_->wayland_window_manager()->GetCurrentFocusedWindow();
+ for (auto& mime_type : mime_types)
+ wl_data_source_offer(data_source_.get(), mime_type.data());
+ }
+diff --git a/ui/ozone/platform/wayland/host/wayland_input_method_context.cc b/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
+index 700232b9b36e..37feebecc9dc 100644
+--- a/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
++++ b/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
+@@ -103,7 +103,8 @@ void WaylandInputMethodContext::Reset() {
+ }
+
+ void WaylandInputMethodContext::Focus() {
+- WaylandWindow* window = connection_->GetCurrentKeyboardFocusedWindow();
++ WaylandWindow* window =
++ connection_->wayland_window_manager()->GetCurrentKeyboardFocusedWindow();
+ if (!text_input_ || !window)
+ return;
+
+diff --git a/ui/ozone/platform/wayland/host/wayland_screen.cc b/ui/ozone/platform/wayland/host/wayland_screen.cc
+index ef372ad794d3..126b252624ab 100644
+--- a/ui/ozone/platform/wayland/host/wayland_screen.cc
++++ b/ui/ozone/platform/wayland/host/wayland_screen.cc
+@@ -81,7 +81,8 @@ void WaylandScreen::OnOutputMetricsChanged(uint32_t output_id,
+ changed_display, is_primary ? display::DisplayList::Type::PRIMARY
+ : display::DisplayList::Type::NOT_PRIMARY);
+
+- for (auto* window : connection_->GetWindowsOnOutput(output_id))
++ auto* wayland_window_manager = connection_->wayland_window_manager();
++ for (auto* window : wayland_window_manager->GetWindowsOnOutput(output_id))
+ window->UpdateBufferScale(true);
+ }
+
+@@ -101,7 +102,7 @@ display::Display WaylandScreen::GetPrimaryDisplay() const {
+
+ display::Display WaylandScreen::GetDisplayForAcceleratedWidget(
+ gfx::AcceleratedWidget widget) const {
+- auto* window = connection_->GetWindow(widget);
++ auto* window = connection_->wayland_window_manager()->GetWindow(widget);
+ // A window might be destroyed by this time on shutting down the browser.
+ if (!window)
+ return GetPrimaryDisplay();
+@@ -139,6 +140,7 @@ display::Display WaylandScreen::GetDisplayForAcceleratedWidget(
+ }
+
+ gfx::Point WaylandScreen::GetCursorScreenPoint() const {
++ auto* wayland_window_manager = connection_->wayland_window_manager();
+ // Wayland does not provide either location of surfaces in global space
+ // coordinate system or location of a pointer. Instead, only locations of
+ // mouse/touch events are known. Given that Chromium assumes top-level windows
+@@ -149,10 +151,10 @@ gfx::Point WaylandScreen::GetCursorScreenPoint() const {
+ // last known cursor position. Otherwise, return such a point, which is not
+ // contained by any of the windows.
+ auto* cursor_position = connection_->wayland_cursor_position();
+- if (connection_->GetCurrentFocusedWindow() && cursor_position)
++ if (wayland_window_manager->GetCurrentFocusedWindow() && cursor_position)
+ return cursor_position->GetCursorSurfacePoint();
+
+- WaylandWindow* window = connection_->GetWindowWithLargestBounds();
++ auto* window = wayland_window_manager->GetWindowWithLargestBounds();
+ DCHECK(window);
+ const gfx::Rect bounds = window->GetBounds();
+ return gfx::Point(bounds.width() + 10, bounds.height() + 10);
+@@ -162,7 +164,8 @@ gfx::AcceleratedWidget WaylandScreen::GetAcceleratedWidgetAtScreenPoint(
+ const gfx::Point& point) const {
+ // It is safe to check only for focused windows and test if they contain the
+ // point or not.
+- auto* window = connection_->GetCurrentFocusedWindow();
++ auto* window =
++ connection_->wayland_window_manager()->GetCurrentFocusedWindow();
+ if (window && window->GetBounds().Contains(point))
+ return window->GetWidget();
+ return gfx::kNullAcceleratedWidget;
+diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc
+index 9afed0cc87fb..12b3661985a6 100644
+--- a/ui/ozone/platform/wayland/host/wayland_window.cc
++++ b/ui/ozone/platform/wayland/host/wayland_window.cc
+@@ -105,7 +105,7 @@ WaylandWindow::~WaylandWindow() {
+ }
+
+ PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
+- connection_->RemoveWindow(GetWidget());
++ connection_->wayland_window_manager()->RemoveWindow(GetWidget());
+
+ if (parent_window_)
+ parent_window_->set_child_window(nullptr);
+@@ -165,7 +165,7 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) {
+
+ connection_->ScheduleFlush();
+
+- connection_->AddWindow(GetWidget(), this);
++ connection_->wayland_window_manager()->AddWindow(GetWidget(), this);
+ PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
+ delegate_->OnAcceleratedWidgetAvailable(GetWidget());
+
+@@ -249,7 +249,8 @@ void WaylandWindow::CreateXdgSurface() {
+ 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.
+- parent_window_ = connection_->GetCurrentFocusedWindow();
++ 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
+@@ -563,7 +564,8 @@ uint32_t WaylandWindow::DispatchEvent(const PlatformEvent& native_event) {
+ // Parent window of the main menu window is not a popup, but rather an
+ // xdg surface.
+ DCHECK(!parent_window_->xdg_popup() && parent_window_->xdg_surface());
+- WaylandWindow* window = connection_->GetCurrentFocusedWindow();
++ auto* window =
++ connection_->wayland_window_manager()->GetCurrentFocusedWindow();
+ if (window) {
+ ConvertEventLocationToTargetWindowLocation(GetBounds().origin(),
+ window->GetBounds().origin(),
+@@ -802,7 +804,8 @@ void WaylandWindow::MaybeTriggerPendingStateChange() {
+
+ WaylandWindow* WaylandWindow::GetParentWindow(
+ gfx::AcceleratedWidget parent_widget) {
+- WaylandWindow* parent_window = connection_->GetWindow(parent_widget);
++ auto* parent_window =
++ connection_->wayland_window_manager()->GetWindow(parent_widget);
+
+ // If propagated parent has already had a child, it means that |this| is a
+ // submenu of a 3-dot menu. In aura, the parent of a 3-dot menu and its
+@@ -816,7 +819,7 @@ WaylandWindow* WaylandWindow::GetParentWindow(
+ if (parent_window && parent_window->child_window_)
+ return parent_window->child_window_;
+ if (!parent_window)
+- return connection_->GetCurrentFocusedWindow();
++ return connection_->wayland_window_manager()->GetCurrentFocusedWindow();
+ return parent_window;
+ }
+
+@@ -873,7 +876,8 @@ void WaylandWindow::RemoveEnteredOutputId(struct wl_output* output) {
+ void WaylandWindow::UpdateCursorPositionFromEvent(
+ std::unique_ptr<Event> event) {
+ DCHECK(event->IsLocatedEvent());
+- auto* window = connection_->GetCurrentFocusedWindow();
++ auto* window =
++ connection_->wayland_window_manager()->GetCurrentFocusedWindow();
+ // This is a tricky part. Initially, Wayland sends events to surfaces the
+ // events are targeted for. But, in order to fulfill Chromium's assumptions
+ // about event targets, some of the events are rerouted and their locations
+diff --git a/ui/ozone/platform/wayland/host/wayland_window_manager.cc b/ui/ozone/platform/wayland/host/wayland_window_manager.cc
+new file mode 100644
+index 000000000000..c7cae0c9f937
+--- /dev/null
++++ b/ui/ozone/platform/wayland/host/wayland_window_manager.cc
+@@ -0,0 +1,90 @@
++// 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_manager.h"
++
++#include "ui/ozone/platform/wayland/host/wayland_connection.h"
++#include "ui/ozone/platform/wayland/host/wayland_window.h"
++
++namespace ui {
++
++WaylandWindowManager::WaylandWindowManager(WaylandConnection* connection)
++ : connection_(connection) {}
++
++WaylandWindowManager::~WaylandWindowManager() = default;
++
++WaylandWindow* WaylandWindowManager::GetWindow(
++ gfx::AcceleratedWidget widget) const {
++ auto it = window_map_.find(widget);
++ return it == window_map_.end() ? nullptr : it->second;
++}
++
++WaylandWindow* WaylandWindowManager::GetWindowWithLargestBounds() const {
++ WaylandWindow* window_with_largest_bounds = nullptr;
++ for (auto entry : window_map_) {
++ if (!window_with_largest_bounds) {
++ window_with_largest_bounds = entry.second;
++ continue;
++ }
++ WaylandWindow* window = entry.second;
++ if (window_with_largest_bounds->GetBounds() < window->GetBounds())
++ window_with_largest_bounds = window;
++ }
++ return window_with_largest_bounds;
++}
++
++WaylandWindow* WaylandWindowManager::GetCurrentFocusedWindow() const {
++ for (auto entry : window_map_) {
++ WaylandWindow* window = entry.second;
++ if (window->has_pointer_focus())
++ return window;
++ }
++ return nullptr;
++}
++
++WaylandWindow* WaylandWindowManager::GetCurrentKeyboardFocusedWindow() const {
++ for (auto entry : window_map_) {
++ WaylandWindow* window = entry.second;
++ if (window->has_keyboard_focus())
++ return window;
++ }
++ return nullptr;
++}
++
++std::vector<WaylandWindow*> WaylandWindowManager::GetWindowsOnOutput(
++ uint32_t output_id) {
++ std::vector<WaylandWindow*> result;
++ for (auto entry : window_map_) {
++ if (entry.second->entered_outputs_ids().count(output_id) > 0)
++ result.push_back(entry.second);
++ }
++ return result;
++}
++
++void WaylandWindowManager::AddWindow(gfx::AcceleratedWidget widget,
++ WaylandWindow* window) {
++ window_map_[widget] = window;
++
++ // TODO(msisov): use observers instead.
++ connection_->OnWindowAdded(window);
++}
++
++void WaylandWindowManager::RemoveWindow(gfx::AcceleratedWidget widget) {
++ auto* window = window_map_[widget];
++ DCHECK(window);
++
++ window_map_.erase(widget);
++
++ // TODO(msisov): use observers instead.
++ connection_->OnWindowRemoved(window);
++}
++
++std::vector<WaylandWindow*> WaylandWindowManager::GetAllWindows() const {
++ std::vector<WaylandWindow*> result;
++ for (auto entry : window_map_)
++ result.push_back(entry.second);
++ return result;
++}
++
++} // namespace ui
+diff --git a/ui/ozone/platform/wayland/host/wayland_window_manager.h b/ui/ozone/platform/wayland/host/wayland_window_manager.h
+new file mode 100644
+index 000000000000..d149bda262d9
+--- /dev/null
++++ b/ui/ozone/platform/wayland/host/wayland_window_manager.h
+@@ -0,0 +1,60 @@
++// 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_WINDOW_MANAGER_H_
++#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_WINDOW_MANAGER_H_
++
++#include <memory>
++
++#include "base/containers/flat_map.h"
++#include "base/macros.h"
++#include "ui/gfx/native_widget_types.h"
++
++namespace ui {
++
++class WaylandConnection;
++class WaylandWindow;
++
++// Stores and returns WaylandWindows. Clients that are interested in knowing
++// when a new window is added or removed, but set self as an observer.
++class WaylandWindowManager {
++ public:
++ // TODO(msisov): Do not pass WaylandConnection here. Instead, add support for
++ // observers.
++ explicit WaylandWindowManager(WaylandConnection* connection);
++ ~WaylandWindowManager();
++
++ // Returns a window found by |widget|.
++ WaylandWindow* GetWindow(gfx::AcceleratedWidget widget) const;
++
++ // Returns a window with largests bounds.
++ WaylandWindow* GetWindowWithLargestBounds() const;
++
++ // Returns a current focused window by pointer.
++ WaylandWindow* GetCurrentFocusedWindow() const;
++
++ // Returns a current focused window by keyboard.
++ WaylandWindow* GetCurrentKeyboardFocusedWindow() const;
++
++ // TODO(crbug.com/971525): remove this in favor of targeted subscription of
++ // windows to their outputs.
++ std::vector<WaylandWindow*> GetWindowsOnOutput(uint32_t output_id);
++
++ // Returns all stored windows.
++ std::vector<WaylandWindow*> GetAllWindows() const;
++
++ void AddWindow(gfx::AcceleratedWidget widget, WaylandWindow* window);
++ void RemoveWindow(gfx::AcceleratedWidget widget);
++
++ private:
++ WaylandConnection* const connection_;
++
++ base::flat_map<gfx::AcceleratedWidget, WaylandWindow*> window_map_;
++
++ DISALLOW_COPY_AND_ASSIGN(WaylandWindowManager);
++};
++
++} // namespace ui
++
++#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_WINDOW_MANAGER_H_
+diff --git a/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc b/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc
+new file mode 100644
+index 000000000000..a38267564a0d
+--- /dev/null
++++ b/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc
+@@ -0,0 +1,222 @@
++// 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 "testing/gtest/include/gtest/gtest.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/test_keyboard.h"
++#include "ui/ozone/platform/wayland/test/wayland_test.h"
++#include "ui/ozone/test/mock_platform_window_delegate.h"
++
++namespace ui {
++
++namespace {
++
++constexpr gfx::Rect kDefaultBounds(0, 0, 100, 100);
++
++} // namespace
++
++class WaylandWindowManagerTest : public WaylandTest {
++ public:
++ WaylandWindowManagerTest() {}
++
++ void SetUp() override {
++ WaylandTest::SetUp();
++
++ manager_ = connection_->wayland_window_manager();
++ DCHECK(manager_);
++ }
++
++ protected:
++ std::unique_ptr<WaylandWindow> CreateWaylandWindowWithParams(
++ PlatformWindowType type,
++ const gfx::Rect bounds,
++ MockPlatformWindowDelegate* delegate) {
++ 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;
++ }
++
++ WaylandWindowManager* manager_ = nullptr;
++
++ private:
++ DISALLOW_COPY_AND_ASSIGN(WaylandWindowManagerTest);
++};
++
++TEST_P(WaylandWindowManagerTest, GetWindow) {
++ MockPlatformWindowDelegate delegate;
++
++ auto window1 = CreateWaylandWindowWithParams(PlatformWindowType::kWindow,
++ kDefaultBounds, &delegate);
++ gfx::AcceleratedWidget window1_widget = window1->GetWidget();
++
++ auto window2 = CreateWaylandWindowWithParams(
++ PlatformWindowType::kWindow, gfx::Rect(0, 0, 300, 300), &delegate);
++
++ EXPECT_TRUE(window1.get() == manager_->GetWindow(window1->GetWidget()));
++ EXPECT_TRUE(window2.get() == manager_->GetWindow(window2->GetWidget()));
++
++ window1.reset();
++
++ EXPECT_FALSE(manager_->GetWindow(window1_widget));
++}
++
++TEST_P(WaylandWindowManagerTest, GetWindowWithLargestBounds) {
++ MockPlatformWindowDelegate delegate;
++
++ auto window1 = CreateWaylandWindowWithParams(PlatformWindowType::kWindow,
++ kDefaultBounds, &delegate);
++ // There is also default window create by the WaylandTest. Thus, make bounds
++ // of this window large enough.
++ auto window2 = CreateWaylandWindowWithParams(
++ PlatformWindowType::kWindow, gfx::Rect(0, 0, 3000, 3000), &delegate);
++
++ EXPECT_TRUE(window2.get() == manager_->GetWindowWithLargestBounds());
++}
++
++TEST_P(WaylandWindowManagerTest, GetCurrentFocusedWindow) {
++ MockPlatformWindowDelegate delegate;
++
++ wl_seat_send_capabilities(server_.seat()->resource(),
++ WL_SEAT_CAPABILITY_POINTER);
++
++ Sync();
++
++ auto window1 = CreateWaylandWindowWithParams(PlatformWindowType::kWindow,
++ kDefaultBounds, &delegate);
++
++ Sync();
++
++ EXPECT_FALSE(manager_->GetCurrentFocusedWindow());
++
++ auto* pointer = server_.seat()->pointer();
++ ASSERT_TRUE(pointer);
++
++ wl::MockSurface* surface =
++ server_.GetObject<wl::MockSurface>(window1->GetWidget());
++ wl_pointer_send_enter(pointer->resource(), 1, surface->resource(), 0, 0);
++
++ Sync();
++
++ EXPECT_FALSE(manager_->GetCurrentKeyboardFocusedWindow());
++ EXPECT_TRUE(window1.get() == manager_->GetCurrentFocusedWindow());
++
++ wl_pointer_send_leave(pointer->resource(), 2, surface->resource());
++
++ Sync();
++
++ EXPECT_FALSE(manager_->GetCurrentFocusedWindow());
++}
++
++TEST_P(WaylandWindowManagerTest, GetCurrentKeyboardFocusedWindow) {
++ MockPlatformWindowDelegate delegate;
++
++ wl_seat_send_capabilities(server_.seat()->resource(),
++ WL_SEAT_CAPABILITY_KEYBOARD);
++
++ Sync();
++
++ auto window1 = CreateWaylandWindowWithParams(PlatformWindowType::kWindow,
++ kDefaultBounds, &delegate);
++
++ Sync();
++
++ EXPECT_FALSE(manager_->GetCurrentKeyboardFocusedWindow());
++
++ auto* keyboard = server_.seat()->keyboard();
++ ASSERT_TRUE(keyboard);
++
++ wl::MockSurface* surface =
++ server_.GetObject<wl::MockSurface>(window1->GetWidget());
++
++ struct wl_array empty;
++ wl_array_init(&empty);
++ wl_keyboard_send_enter(keyboard->resource(), 1, surface->resource(), &empty);
++
++ Sync();
++
++ EXPECT_FALSE(manager_->GetCurrentFocusedWindow());
++ EXPECT_TRUE(window1.get() == manager_->GetCurrentKeyboardFocusedWindow());
++
++ wl_keyboard_send_leave(keyboard->resource(), 2, surface->resource());
++
++ Sync();
++
++ EXPECT_FALSE(manager_->GetCurrentKeyboardFocusedWindow());
++}
++
++TEST_P(WaylandWindowManagerTest, GetWindowsOnOutput) {
++ MockPlatformWindowDelegate delegate;
++
++ wl::TestOutput* output = server_.CreateAndInitializeOutput();
++
++ auto window1 = CreateWaylandWindowWithParams(PlatformWindowType::kWindow,
++ kDefaultBounds, &delegate);
++
++ auto window2 = CreateWaylandWindowWithParams(PlatformWindowType::kWindow,
++ kDefaultBounds, &delegate);
++
++ Sync();
++
++ wl::MockSurface* surface =
++ server_.GetObject<wl::MockSurface>(window1->GetWidget());
++ ASSERT_TRUE(surface);
++ wl_surface_send_enter(surface->resource(), output->resource());
++
++ Sync();
++
++ auto entered_outputs_window1 = window1->entered_outputs_ids();
++ EXPECT_EQ(1u, entered_outputs_window1.size());
++
++ uint32_t output_id = *entered_outputs_window1.begin();
++
++ auto windows_on_output = manager_->GetWindowsOnOutput(output_id);
++ EXPECT_EQ(1u, windows_on_output.size());
++
++ EXPECT_TRUE(window1.get() == *windows_on_output.begin());
++
++ surface = server_.GetObject<wl::MockSurface>(window2->GetWidget());
++ ASSERT_TRUE(surface);
++ wl_surface_send_enter(surface->resource(), output->resource());
++
++ Sync();
++
++ windows_on_output = manager_->GetWindowsOnOutput(output_id);
++ EXPECT_EQ(2u, windows_on_output.size());
++}
++
++TEST_P(WaylandWindowManagerTest, GetAllWindows) {
++ MockPlatformWindowDelegate delegate;
++
++ // There is a default window created by WaylandTest.
++ auto windows = manager_->GetAllWindows();
++ EXPECT_EQ(1u, windows.size());
++
++ window_.reset();
++
++ auto window1 = CreateWaylandWindowWithParams(PlatformWindowType::kWindow,
++ kDefaultBounds, &delegate);
++
++ auto window2 = CreateWaylandWindowWithParams(PlatformWindowType::kWindow,
++ kDefaultBounds, &delegate);
++
++ windows = manager_->GetAllWindows();
++ EXPECT_EQ(2u, windows.size());
++}
++
++INSTANTIATE_TEST_SUITE_P(XdgVersionV5Test,
++ WaylandWindowManagerTest,
++ ::testing::Values(kXdgShellV5));
++
++INSTANTIATE_TEST_SUITE_P(XdgVersionV6Test,
++ WaylandWindowManagerTest,
++ ::testing::Values(kXdgShellV6));
++
++} // namespace ui
+--
+2.22.0
+
diff --git a/0011-ozone-wayland-Do-not-use-possibly-blocking-dispatch-.patch b/0011-ozone-wayland-Do-not-use-possibly-blocking-dispatch-.patch
new file mode 100644
index 000000000000..def2841ee476
--- /dev/null
+++ b/0011-ozone-wayland-Do-not-use-possibly-blocking-dispatch-.patch
@@ -0,0 +1,315 @@
+From 4f4c199c6654ef75319eabf3977e916b2a744d3f Mon Sep 17 00:00:00 2001
+From: Maksim Sisov <msisov@igalia.com>
+Date: Thu, 8 Aug 2019 11:47:41 +0000
+Subject: [PATCH 11/11] [ozone/wayland] Do not use possibly blocking dispatch
+ API
+
+Using wl_display_dispatch is a wrong thing to do as it is a blocking
+method (see [1]). It can cause freezes and deadlocks.
+
+Instead, we need to do something like this -
+
+while (wl_display_prepare_read_queue(display, queue) != 0)
+ wl_display_dispatch_queue_pending(display, queue);
+wl_display_flush(display);
+
+ret = poll(fds, nfds, -1);
+if (has_error(ret))
+ wl_display_cancel_read(display);
+else
+ wl_display_read_events(display);
+
+wl_display_dispatch_queue_pending(display, queue);
+
+However, there is no need to do a second poll as long
+as we are notified by libevent that the display fd is
+non-blocking. However, to ensure we can read, we have
+to prepare the queue, which tells other clients we
+are going to read from the queue. If prepare fails,
+it means there is nothing to read. Thus, we push
+the events into the queue and return early instead.
+
+We have also to add an "automatic" flush as part
+of the polling mechanism. This poll must ensure
+that all the data has been written to the queue.
+If not, -1 is returned and EAGAIN is set. In this
+case, we have to stop watching the fd for read
+access and start watching it for the write access.
+
+As soon as all the data is written, we can get
+back to reading.
+
+[1] https://people.freedesktop.org/~whot/wayland-doxygen/wayland/Client/classwl__display.html#a30a9c4f020f3e77581c7a81ecdb4913d
+
+Bug: 987821
+Change-Id: I536513034c18a47da079a2b56a75d32f20f72ad6
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1730159
+Reviewed-by: Robert Kroeger <rjkroege@chromium.org>
+Commit-Queue: Maksim Sisov <msisov@igalia.com>
+Cr-Commit-Position: refs/heads/master@{#685148}
+---
+ .../wayland/host/wayland_connection.cc | 74 +++++++++++++++----
+ .../wayland/host/wayland_connection.h | 4 +
+ .../wayland/host/wayland_data_device.cc | 2 +-
+ .../wayland/host/wayland_data_source.cc | 2 +-
+ .../platform/wayland/host/wayland_keyboard.cc | 2 +-
+ .../platform/wayland/host/wayland_window.cc | 3 +-
+ .../wayland/host/wayland_window_unittest.cc | 17 +++--
+ .../wayland/host/xdg_surface_wrapper_v5.cc | 1 +
+ .../wayland/host/xdg_surface_wrapper_v6.cc | 3 +-
+ 9 files changed, 84 insertions(+), 24 deletions(-)
+
+diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc
+index bf6d12717861..203db09c7f15 100644
+--- a/ui/ozone/platform/wayland/host/wayland_connection.cc
++++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
+@@ -101,20 +101,29 @@ bool WaylandConnection::StartProcessingEvents() {
+ return true;
+
+ DCHECK(display_);
++
++ MaybePrepareReadQueue();
++
++ // Displatch event from display to server.
+ wl_display_flush(display_.get());
+
+- DCHECK(base::MessageLoopCurrentForUI::IsSet());
+- if (!base::MessageLoopCurrentForUI::Get()->WatchFileDescriptor(
+- wl_display_get_fd(display_.get()), true,
+- base::MessagePumpLibevent::WATCH_READ, &controller_, this))
+- return false;
++ return BeginWatchingFd(base::MessagePumpLibevent::WATCH_READ);
++}
+
+- watching_ = true;
+- return true;
++void WaylandConnection::MaybePrepareReadQueue() {
++ if (prepared_)
++ return;
++
++ if (wl_display_prepare_read(display()) != -1) {
++ prepared_ = true;
++ return;
++ }
++ // Nothing to read, send events to the queue.
++ wl_display_dispatch_pending(display());
+ }
+
+ void WaylandConnection::ScheduleFlush() {
+- if (scheduled_flush_ || !watching_)
++ if (scheduled_flush_)
+ return;
+ DCHECK(base::MessageLoopCurrentForUI::IsSet());
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+@@ -207,13 +216,38 @@ void WaylandConnection::DispatchUiEvent(Event* event) {
+ }
+
+ void WaylandConnection::OnFileCanReadWithoutBlocking(int fd) {
+- wl_display_dispatch(display_.get());
+- std::vector<WaylandWindow*> windows = wayland_window_manager_.GetAllWindows();
+- for (auto* window : windows)
+- window->ApplyPendingBounds();
++ if (prepared_) {
++ prepared_ = false;
++ if (wl_display_read_events(display()) == -1)
++ return;
++ wl_display_dispatch_pending(display());
++ }
++
++ MaybePrepareReadQueue();
++
++ if (!prepared_)
++ return;
++
++ // Automatic Flush.
++ int ret = wl_display_flush(display_.get());
++ if (ret != -1 || errno != EAGAIN)
++ return;
++
++ // if all data could not be written, errno will be set to EAGAIN and -1
++ // returned. In that case, use poll on the display file descriptor to wait for
++ // it to become writable again.
++ BeginWatchingFd(base::MessagePumpLibevent::WATCH_WRITE);
+ }
+
+-void WaylandConnection::OnFileCanWriteWithoutBlocking(int fd) {}
++void WaylandConnection::OnFileCanWriteWithoutBlocking(int fd) {
++ int ret = wl_display_flush(display_.get());
++ if (ret != -1 || errno != EAGAIN)
++ BeginWatchingFd(base::MessagePumpLibevent::WATCH_READ);
++ else if (ret < 0 && errno != EPIPE && prepared_)
++ wl_display_cancel_read(display());
++
++ // Otherwise just continue watching in the same mode.
++}
+
+ void WaylandConnection::EnsureDataDevice() {
+ if (!data_device_manager_ || !seat_)
+@@ -225,6 +259,20 @@ void WaylandConnection::EnsureDataDevice() {
+ data_device_.get());
+ }
+
++bool WaylandConnection::BeginWatchingFd(
++ base::WatchableIOMessagePumpPosix::Mode mode) {
++ if (watching_) {
++ // Stop watching first.
++ watching_ = !controller_.StopWatchingFileDescriptor();
++ DCHECK(!watching_);
++ }
++
++ DCHECK(base::MessageLoopCurrentForUI::IsSet());
++ watching_ = base::MessageLoopCurrentForUI::Get()->WatchFileDescriptor(
++ wl_display_get_fd(display_.get()), true, mode, &controller_, this);
++ return watching_;
++}
++
+ // static
+ void WaylandConnection::Global(void* data,
+ wl_registry* registry,
+diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h
+index 8a56ebc6b921..ff587ae9ee6f 100644
+--- a/ui/ozone/platform/wayland/host/wayland_connection.h
++++ b/ui/ozone/platform/wayland/host/wayland_connection.h
+@@ -146,6 +146,9 @@ class WaylandConnection : public PlatformEventSource,
+ // Make sure data device is properly initialized
+ void EnsureDataDevice();
+
++ bool BeginWatchingFd(base::WatchableIOMessagePumpPosix::Mode mode);
++ void MaybePrepareReadQueue();
++
+ // wl_registry_listener
+ static void Global(void* data,
+ wl_registry* registry,
+@@ -192,6 +195,7 @@ class WaylandConnection : public PlatformEventSource,
+
+ bool scheduled_flush_ = false;
+ bool watching_ = false;
++ bool prepared_ = false;
+ base::MessagePumpLibevent::FdWatchController controller_;
+
+ uint32_t serial_ = 0;
+diff --git a/ui/ozone/platform/wayland/host/wayland_data_device.cc b/ui/ozone/platform/wayland/host/wayland_data_device.cc
+index a36cd3b7a888..56e568fbd164 100644
+--- a/ui/ozone/platform/wayland/host/wayland_data_device.cc
++++ b/ui/ozone/platform/wayland/host/wayland_data_device.cc
+@@ -355,7 +355,7 @@ void WaylandDataDevice::RegisterDeferredReadCallback() {
+ deferred_read_callback_.reset(wl_display_sync(connection_->display()));
+ wl_callback_add_listener(deferred_read_callback_.get(),
+ &kDeferredReadListener, this);
+- wl_display_flush(connection_->display());
++ connection_->ScheduleFlush();
+ }
+
+ void WaylandDataDevice::DeferredReadCallback(void* data,
+diff --git a/ui/ozone/platform/wayland/host/wayland_data_source.cc b/ui/ozone/platform/wayland/host/wayland_data_source.cc
+index dcd6b75aa299..1f41fd6786b9 100644
+--- a/ui/ozone/platform/wayland/host/wayland_data_source.cc
++++ b/ui/ozone/platform/wayland/host/wayland_data_source.cc
+@@ -36,7 +36,7 @@ void WaylandDataSource::WriteToClipboard(
+ wl_data_device_set_selection(connection_->data_device(), data_source_.get(),
+ connection_->serial());
+
+- wl_display_flush(connection_->display());
++ connection_->ScheduleFlush();
+ }
+
+ void WaylandDataSource::UpdateDataMap(
+diff --git a/ui/ozone/platform/wayland/host/wayland_keyboard.cc b/ui/ozone/platform/wayland/host/wayland_keyboard.cc
+index 181e6e56b4b6..69cd9686bdf8 100644
+--- a/ui/ozone/platform/wayland/host/wayland_keyboard.cc
++++ b/ui/ozone/platform/wayland/host/wayland_keyboard.cc
+@@ -165,7 +165,7 @@ void WaylandKeyboard::FlushInput(base::OnceClosure closure) {
+ // get spurious repeats.
+ sync_callback_.reset(wl_display_sync(connection_->display()));
+ wl_callback_add_listener(sync_callback_.get(), &callback_listener_, this);
+- wl_display_flush(connection_->display());
++ connection_->ScheduleFlush();
+ }
+
+ void WaylandKeyboard::DispatchKey(uint32_t key,
+diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc
+index 12b3661985a6..cf0f3c336414 100644
+--- a/ui/ozone/platform/wayland/host/wayland_window.cc
++++ b/ui/ozone/platform/wayland/host/wayland_window.cc
+@@ -285,7 +285,6 @@ void WaylandWindow::ApplyPendingBounds() {
+
+ SetBoundsDip(pending_bounds_dip_);
+ xdg_surface_->SetWindowGeometry(pending_bounds_dip_);
+- xdg_surface_->AckConfigure();
+ pending_bounds_dip_ = gfx::Rect();
+ connection_->ScheduleFlush();
+
+@@ -659,6 +658,8 @@ void WaylandWindow::HandleSurfaceConfigure(int32_t width,
+ delegate_->OnWindowStateChanged(state_);
+ }
+
++ ApplyPendingBounds();
++
+ if (did_active_change)
+ delegate_->OnActivationChanged(is_active_);
+
+diff --git a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
+index 8083f7a84dcd..5fdf4a6184ba 100644
+--- a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
++++ b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
+@@ -677,19 +677,26 @@ TEST_P(WaylandWindowTest, HasCaptureUpdatedOnPointerEvents) {
+
+ TEST_P(WaylandWindowTest, ConfigureEvent) {
+ ScopedWlArray states;
+- SendConfigureEvent(1000, 1000, 12, states.get());
+- SendConfigureEvent(1500, 1000, 13, states.get());
+
+- // Make sure that the implementation does not call OnBoundsChanged for each
+- // configure event if it receives multiple in a row.
+- EXPECT_CALL(delegate_, OnBoundsChanged(Eq(gfx::Rect(0, 0, 1500, 1000))));
++ // The surface must react on each configure event and send bounds to its
++ // delegate.
++
++ EXPECT_CALL(delegate_, OnBoundsChanged(Eq(gfx::Rect(0, 0, 1000, 1000))));
+ // Responding to a configure event, the window geometry in here must respect
+ // the sizing negotiations specified by the configure event.
+ // |xdg_surface_| must receive the following calls in both xdg_shell_v5 and
+ // xdg_shell_v6. Other calls like SetTitle or SetMaximized are recieved by
+ // xdg_toplevel in xdg_shell_v6 and by xdg_surface_ in xdg_shell_v5.
++ EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, 1000, 1000)).Times(1);
++ EXPECT_CALL(*xdg_surface_, AckConfigure(12));
++ SendConfigureEvent(1000, 1000, 12, states.get());
++
++ Sync();
++
++ EXPECT_CALL(delegate_, OnBoundsChanged(Eq(gfx::Rect(0, 0, 1500, 1000))));
+ EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, 1500, 1000)).Times(1);
+ EXPECT_CALL(*xdg_surface_, AckConfigure(13));
++ SendConfigureEvent(1500, 1000, 13, states.get());
+ }
+
+ TEST_P(WaylandWindowTest, ConfigureEventWithNulledSize) {
+diff --git a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_v5.cc b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_v5.cc
+index 7d4172d2f0cb..c89fa87bff9b 100644
+--- a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_v5.cc
++++ b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_v5.cc
+@@ -99,6 +99,7 @@ void XDGSurfaceWrapperV5::Configure(void* data,
+ surface->pending_configure_serial_ = serial;
+ surface->wayland_window_->HandleSurfaceConfigure(width, height, is_maximized,
+ is_fullscreen, is_activated);
++ surface->AckConfigure();
+ }
+
+ // static
+diff --git a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_v6.cc b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_v6.cc
+index 9cac792bf630..c7c9fc079590 100644
+--- a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_v6.cc
++++ b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_v6.cc
+@@ -123,8 +123,7 @@ void XDGSurfaceWrapperV6::Configure(void* data,
+ XDGSurfaceWrapperV6* surface = static_cast<XDGSurfaceWrapperV6*>(data);
+ surface->pending_configure_serial_ = serial;
+
+- if (surface->surface_for_popup_)
+- surface->AckConfigure();
++ surface->AckConfigure();
+ }
+
+ // static
+--
+2.22.0
+
diff --git a/PKGBUILD b/PKGBUILD
index 27b8199fe5c1..ec88a8859104 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -6,7 +6,7 @@
pkgname=chromium-ozone
pkgver=76.0.3809.87
-pkgrel=2
+pkgrel=3
_launcher_ver=6
_meta_browser_sha=38b36f421f8d984c7004c9d9a6d514ed2fb6cf8e
pkgdesc="Chromium built with patches for wayland support via Ozone"
@@ -33,23 +33,33 @@ source=(https://commondatastorage.googleapis.com/chromium-browser-official/chrom
chromium-widevine.patch
chromium-skia-harmony.patch
0001-ozone-wayland-Prepare-WaylandCanvasSurface-for-compl.patch
- 0002-ozone-wayland-Sway-avoid-sending-presentation-early.patch
- 0003-Ozone-Wayland-Manager-make-mojo-calls-on-IO-thread.patch
- 0004-ozone-wayland-Fix-broken-software-rendering-path.patch
- 0005-ozone-wayland-Use-mutex-before-accessing-surfaces-ma.patch
- Added-HiDPI-support-for-Ozone-Wayland.patch)
+ 0002-ozone-wayland-Sway-avoid-sending-presentation-early.patch
+ 0003-Ozone-Wayland-Manager-make-mojo-calls-on-IO-thread.patch
+ 0004-ozone-wayland-Fix-broken-software-rendering-path.patch
+ 0005-ozone-wayland-Use-mutex-before-accessing-surfaces-ma.patch
+ 0006-ozone-wayland-Reset-surface-contents-in-a-safe-way.patch
+ 0007-ozone-wayland-Stop-using-wl_display_roundtrip.patch
+ 0008-ozone-wayland-Added-HiDPI-support-for-Ozone-Wayland.patch
+ 0009-Fixed-positioning-and-sizes-of-menus-when-the-scale-.patch
+ 0010-ozone-wayland-Extract-window-management-methods-to-o.patch
+ 0011-ozone-wayland-Do-not-use-possibly-blocking-dispatch-.patch)
sha256sums=('215ca6acee7b4fd3c95fe796260af4dc5454dbba3b701aa43afeb98a06dc4194'
'04917e3cd4307d8e31bfb0027a5dce6d086edb10ff8a716024fbb8bb0c7dccf1'
'd87957d01be9fb59faf5fde523eb87a8256605b1533171416b7a56bfcbd6d056'
'e2d284311f49c529ea45083438a768db390bde52949995534034d2a814beab89'
'd081f2ef8793544685aad35dea75a7e6264a2cb987ff3541e6377f4a3650a28b'
'771292942c0901092a402cc60ee883877a99fb804cb54d568c8c6c94565a48e1'
- 'a16afeb448fc49904f4bb4f679db1a79b3305a04399d672787e708a32516ac91'
- 'bddf821069a8037ce91c35787aa942d35ef880ca5e28dae1ddeb224c2d008548'
- '1455cc2bb36f4247b3c16b805328b277c8538ad96f50d1e7f5fb816d5cad2d6d'
- 'deba5fa9ebd64ca48bab71d51c3bf50a6c10e2704e60b7b50268fc2de15afb61'
- '907be76f0906452b3327b0d469bf5bcff31eec9d9e6d6829c6a0159da73af68a'
- 'b6b258a6d3b42731c9375395b4e6e896edef00617d5b7028c348a5d2dbb14eb7')
+ '1fe3bb02ffd0445da8ea3b9eb09e8dff6b7bdd1ca26f4b439310a3e94aa16ebf'
+ 'd9c5932f1af91a8c2e8b7687d9ad013d5895e3e03811d9f03e674afb77031ce5'
+ '424c5c0e5b6ded87d0c00dd4755eb6e63bfdf42233ee60c354729f5cbba82334'
+ 'fecdfa694a84b4dc688ec20970ea18b11d9e332b8423a935ba35cd3fae7485a5'
+ '2359fdd84a3c10eeb576b15cfea86a34867097cb3e3d30ade6c823cf0d538d99'
+ '13be86e54b14f5a9f21e371a0f2762c5ff9a4204877ded60600f5950f6a14885'
+ 'ede2a4c0283f01f7653c0caabd8439d96c27da16dd557ebb0730c0b3e7134097'
+ '9996ddaa8a83c58dcbe45e21746ffe41a9f8b56edc71a16090ebdb6adbc74541'
+ '6f4fc0a82443f9bfaeecfd1a463b4bc10dfa29b9357f17592dfac8332d27cb3c'
+ '470cf88aa6878bfaaf74f00791d33f4f922f31a13e0503b8bb11edb4bb89d29c'
+ 'aaefa3a868024aa1eb118236bd528986db972646f762418764b5f0ab326468b0')
# Possible replacements are listed in build/linux/unbundle/replace_gn_files.py
# Keys are the names in the above script; values are the dependencies in Arch
@@ -102,10 +112,16 @@ _mb_wayland_patches=(
_bugfix_patches=(
'0001-ozone-wayland-Prepare-WaylandCanvasSurface-for-compl.patch'
- '0002-ozone-wayland-Sway-avoid-sending-presentation-early.patch'
- '0003-Ozone-Wayland-Manager-make-mojo-calls-on-IO-thread.patch'
- '0004-ozone-wayland-Fix-broken-software-rendering-path.patch'
- '0005-ozone-wayland-Use-mutex-before-accessing-surfaces-ma.patch'
+ '0002-ozone-wayland-Sway-avoid-sending-presentation-early.patch'
+ '0003-Ozone-Wayland-Manager-make-mojo-calls-on-IO-thread.patch'
+ '0004-ozone-wayland-Fix-broken-software-rendering-path.patch'
+ '0005-ozone-wayland-Use-mutex-before-accessing-surfaces-ma.patch'
+ '0006-ozone-wayland-Reset-surface-contents-in-a-safe-way.patch'
+ '0007-ozone-wayland-Stop-using-wl_display_roundtrip.patch'
+ '0008-ozone-wayland-Added-HiDPI-support-for-Ozone-Wayland.patch'
+ '0009-Fixed-positioning-and-sizes-of-menus-when-the-scale-.patch'
+ '0010-ozone-wayland-Extract-window-management-methods-to-o.patch'
+ '0011-ozone-wayland-Do-not-use-possibly-blocking-dispatch-.patch'
)
prepare() {
@@ -143,9 +159,6 @@ prepare() {
patch -Np1 -i $srcdir/${PATCH}
done
- # https://chromium-review.googlesource.com/c/chromium/src/+/1647154
- patch -Np1 -i ../Added-HiDPI-support-for-Ozone-Wayland.patch
-
# Force script incompatible with Python 3 to use /usr/bin/python2
sed -i '1s|python$|&2|' third_party/dom_distiller_js/protoc_plugins/*.py