diff options
author | Daniel Playfair Cal | 2019-08-09 01:26:09 +1000 |
---|---|---|
committer | Daniel Playfair Cal | 2019-08-09 01:26:09 +1000 |
commit | aaa1f9a6be7a5f2883388b44fda07ecdf6263065 (patch) | |
tree | 70dc72948b8d1a618ff5af19d5c0e0309fa77d24 | |
parent | fc6ed6aa0254db2ff86daaba0b5aba2368872f0c (diff) | |
download | aur-aaa1f9a6be7a5f2883388b44fda07ecdf6263065.tar.gz |
More patches to fix freezes
-rw-r--r-- | .SRCINFO | 26 | ||||
-rw-r--r-- | 0001-ozone-wayland-Prepare-WaylandCanvasSurface-for-compl.patch | 2 | ||||
-rw-r--r-- | 0002-ozone-wayland-Sway-avoid-sending-presentation-early.patch | 2 | ||||
-rw-r--r-- | 0003-Ozone-Wayland-Manager-make-mojo-calls-on-IO-thread.patch | 2 | ||||
-rw-r--r-- | 0004-ozone-wayland-Fix-broken-software-rendering-path.patch | 2 | ||||
-rw-r--r-- | 0005-ozone-wayland-Use-mutex-before-accessing-surfaces-ma.patch | 3 | ||||
-rw-r--r-- | 0006-ozone-wayland-Reset-surface-contents-in-a-safe-way.patch | 171 | ||||
-rw-r--r-- | 0007-ozone-wayland-Stop-using-wl_display_roundtrip.patch | 472 | ||||
-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-.patch | 315 | ||||
-rw-r--r-- | 0010-ozone-wayland-Extract-window-management-methods-to-o.patch | 810 | ||||
-rw-r--r-- | 0011-ozone-wayland-Do-not-use-possibly-blocking-dispatch-.patch | 315 | ||||
-rw-r--r-- | PKGBUILD | 51 |
13 files changed, 2209 insertions, 80 deletions
@@ -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 + @@ -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 |