diff options
author | Daniel Playfair Cal | 2020-02-09 17:52:36 +1100 |
---|---|---|
committer | Daniel Playfair Cal | 2020-02-11 23:48:18 +1100 |
commit | 87bed1bf632b6f78c76aa4b95b32fefdea713503 (patch) | |
tree | 8879db8e95927f10a733bede3165a9130b1cb623 | |
parent | 53d0cef916c867c66e7391ea89b57da33e5cb018 (diff) | |
download | aur-87bed1bf632b6f78c76aa4b95b32fefdea713503.tar.gz |
80.0.3987.87-1
26 files changed, 518 insertions, 6690 deletions
@@ -1,6 +1,6 @@ pkgbase = chromium-beta-ozone pkgdesc = Chromium built with patches for wayland support via Ozone (beta channel) - pkgver = 80.0.3987.42 + pkgver = 80.0.3987.87 pkgrel = 1 url = https://www.chromium.org/Home install = chromium.install @@ -14,6 +14,7 @@ pkgbase = chromium-beta-ozone makedepends = ninja makedepends = nodejs makedepends = git + makedepends = pipewire makedepends = clang makedepends = lld makedepends = gn @@ -25,18 +26,19 @@ pkgbase = chromium-beta-ozone depends = libxss depends = libcups depends = libgcrypt - depends = ttf-font + depends = ttf-liberation depends = systemd depends = dbus depends = libpulse depends = pciutils depends = json-glib - depends = libva depends = desktop-file-utils depends = hicolor-icon-theme depends = icu + depends = libxml2 depends = fontconfig depends = harfbuzz + depends = libvpx depends = libjpeg depends = re2 depends = snappy @@ -48,6 +50,7 @@ pkgbase = chromium-beta-ozone depends = freetype2 depends = opus optdepends = pepper-flash: support for Flash content + optdepends = pipewire: WebRTC desktop sharing under Wayland optdepends = kdialog: needed for file dialogs in KDE optdepends = org.freedesktop.secrets: password storage backend on GNOME / Xfce optdepends = kwallet: for storing passwords in KWallet on KDE desktops @@ -55,24 +58,34 @@ pkgbase = chromium-beta-ozone conflicts = chromium options = debug options = !strip - source = https://commondatastorage.googleapis.com/chromium-browser-official/chromium-80.0.3987.42.tar.xz + source = https://commondatastorage.googleapis.com/chromium-browser-official/chromium-80.0.3987.87.tar.xz source = chromium-launcher-6.tar.gz::https://github.com/foutrelis/chromium-launcher/archive/v6.tar.gz source = 0001-Add-missing-algorithm-header-in-bitmap_cursor_factor.patch - source = 0001-cros-search-service-Include-cmath-for-std-pow.patch - source = 0001-BookmarkModelMerger-Move-RemoteTreeNode-declaration-.patch - source = chromium-system-icu.patch - source = chromium-system-zlib.patch - source = fix-spammy-unique-font-matching-log.patch + source = cros-search-service-Include-cmath-for-std-pow.patch + source = move-RemoteTreeNode-declaration.patch + source = sync-enable-USSPasswords-by-default.patch + source = fix-shim-header-generation-when-unbundling-ICU.patch + source = fix-building-with-system-zlib.patch + source = remove-verbose-logging-in-local-unique-font-matching.patch + source = fix-building-with-unbundled-libxml.patch + source = fix-browser-frame-view-not-getting-a-relayout.patch + source = rename-Relayout-in-DesktopWindowTreeHostPlatform.patch + source = rebuild-Linux-frame-button-cache-when-activation.patch source = chromium-widevine.patch source = chromium-skia-harmony.patch - sha256sums = 160c02ed00d45a074246c8984144a35b092102e9b9a31e2bc9c2dad49f297945 + sha256sums = f51f6fca5d9abbef855aa6b5bf427410c6e96ae58b64a7d45f843868cfb0ac8e sha256sums = 04917e3cd4307d8e31bfb0027a5dce6d086edb10ff8a716024fbb8bb0c7dccf1 sha256sums = 716c28bed9f6e9c32e3617e125c1b04806700aef691763923cd4ed14b8d23279 - sha256sums = 4c892f046ab10df609aa39d9985248d368c77306783a64d335ff713dabad60b0 - sha256sums = a44ed59db5258221ee187dc2501040e5ebfc5c1353ac98d4313ac6a12ae32d1f - sha256sums = e73cc2ee8d3ea35aab18c478d76fdfc68ca4463e1e10306fa1e738c03b3f26b5 - sha256sums = eb67eda4945a89c3b90473fa8dc20637511ca4dcb58879a8ed6bf403700ca9c8 - sha256sums = 6fbffe59b886195b92c9a55137cef83021c16593f49714acb20023633e3ebb19 + sha256sums = 0a8d1af2a3734b5f99ea8462940e332db4acee7130fe436ad3e4b7ad133e5ae5 + sha256sums = 21f631851cdcb347f40793485b168cb5d0da65ae26ae39ba58d624c66197d0a5 + sha256sums = 08ef82476780e0864b5bf7f20eb19db320e73b9a5d4f595351e12e97dda8746f + sha256sums = e477aa48a11ca4d53927f66a9593567fcd053325fb38af30ac3508465f1dd1f6 + sha256sums = 18276e65c68a0c328601b12fefb7e8bfc632346f34b87e64944c9de8c95c5cfa + sha256sums = 5bc775c0ece84d67855f51b30eadcf96fa8163b416d2036e9f9ba19072f54dfe + sha256sums = e530d1b39504c2ab247e16f1602359c484e9e8be4ef6d4824d68b14d29a7f60b + sha256sums = 5db225565336a3d9b9e9f341281680433c0b7bb343dff2698b2acffd86585cbe + sha256sums = ae3bf107834bd8eda9a3ec7899fe35fde62e6111062e5def7d24bf49b53db3db + sha256sums = 46f7fc9768730c460b27681ccf3dc2685c7e1fd22d70d3a82d9e57e3389bb014 sha256sums = 709e2fddba3c1f2ed4deb3a239fc0479bfa50c46e054e7f32db4fb1365fed070 sha256sums = 771292942c0901092a402cc60ee883877a99fb804cb54d568c8c6c94565a48e1 diff --git a/0001-Refactor-bookmark-GUID-matching-logic.patch b/0001-Refactor-bookmark-GUID-matching-logic.patch deleted file mode 100644 index 3c0a732efc6e..000000000000 --- a/0001-Refactor-bookmark-GUID-matching-logic.patch +++ /dev/null @@ -1,329 +0,0 @@ -From afc8770181f528d391e74af41e9be125814e3009 Mon Sep 17 00:00:00 2001 -From: Mikel Astiz <mastiz@chromium.org> -Date: Mon, 25 Nov 2019 10:53:45 +0000 -Subject: [PATCH] Refactor bookmark GUID-matching logic - -Prior to this patch, the two existing functions to build GUID-keyed maps -were heavily coupled and there were fragile underlying assumptions that -made it work (e.g. there were potentially entries in -|guid_to_remote_node_map_| that didn't actually match any local GUID). - -Instead, let's centralize the matching logic into one single function, -and adopt a unified map to represent the matches. This simplifies the -code and enforces more strict invariants without the need for DCHECKs. - -Bug: 978430 -Change-Id: Ieea0db8d43376e204b793dcc64b2dc84d521b289 -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1929216 -Commit-Queue: Mikel Astiz <mastiz@chromium.org> -Reviewed-by: Mohamed Amir Yosef <mamir@chromium.org> -Cr-Commit-Position: refs/heads/master@{#718580} ---- - .../sync_bookmarks/bookmark_model_merger.cc | 133 ++++++++---------- - .../sync_bookmarks/bookmark_model_merger.h | 40 ++---- - .../bookmark_specifics_conversions.cc | 6 + - 3 files changed, 81 insertions(+), 98 deletions(-) - -diff --git a/components/sync_bookmarks/bookmark_model_merger.cc b/components/sync_bookmarks/bookmark_model_merger.cc -index 861403dbe05a..dfd19a27a592 100644 ---- a/components/sync_bookmarks/bookmark_model_merger.cc -+++ b/components/sync_bookmarks/bookmark_model_merger.cc -@@ -237,9 +237,8 @@ BookmarkModelMerger::BookmarkModelMerger( - favicon_service_(favicon_service), - bookmark_tracker_(bookmark_tracker), - remote_forest_(BuildRemoteForest(std::move(updates))), -- guid_to_remote_node_map_(BuildGUIDToRemoteNodeMap(remote_forest_)), -- guid_to_local_node_map_( -- BuildGUIDToLocalNodeMap(bookmark_model_, guid_to_remote_node_map_)) { -+ guid_to_match_map_( -+ FindGuidMatchesOrReassignLocal(remote_forest_, bookmark_model_)) { - DCHECK(bookmark_tracker_->IsEmpty()); - DCHECK(favicon_service); - } -@@ -307,63 +306,62 @@ BookmarkModelMerger::RemoteForest BookmarkModelMerger::BuildRemoteForest( - } - - // static --std::unordered_map<std::string, const BookmarkModelMerger::RemoteTreeNode*> --BookmarkModelMerger::BuildGUIDToRemoteNodeMap( -- const RemoteForest& remote_forest) { -+std::unordered_map<std::string, BookmarkModelMerger::GuidMatch> -+BookmarkModelMerger::FindGuidMatchesOrReassignLocal( -+ const RemoteForest& remote_forest, -+ bookmarks::BookmarkModel* bookmark_model) { -+ DCHECK(bookmark_model); -+ - // TODO(crbug.com/978430): Handle potential duplicate GUIDs within remote - // updates. -- std::unordered_map<std::string, const RemoteTreeNode*> -- guid_to_remote_node_map; -+ - if (!base::FeatureList::IsEnabled(switches::kMergeBookmarksUsingGUIDs)) { -- return guid_to_remote_node_map; -+ return {}; - } - -+ // Build a temporary lookup table for remote GUIDs. -+ std::unordered_map<std::string, const RemoteTreeNode*> -+ guid_to_remote_node_map; - for (const auto& tree_tag_and_root : remote_forest) { - tree_tag_and_root.second.EmplaceSelfAndDescendantsByGUID( - &guid_to_remote_node_map); - } - -- return guid_to_remote_node_map; --} -- --// static --std::unordered_map<std::string, const bookmarks::BookmarkNode*> --BookmarkModelMerger::BuildGUIDToLocalNodeMap( -- bookmarks::BookmarkModel* bookmark_model, -- const std::unordered_map<std::string, const RemoteTreeNode*>& -- guid_to_remote_node_map) { -- DCHECK(bookmark_model); -- -- std::unordered_map<std::string, const bookmarks::BookmarkNode*> -- guid_to_local_node_map; -- if (!base::FeatureList::IsEnabled(switches::kMergeBookmarksUsingGUIDs)) { -- return guid_to_local_node_map; -- } -- -+ // Iterate through all local bookmarks to find matches by GUID. -+ std::unordered_map<std::string, BookmarkModelMerger::GuidMatch> -+ guid_to_match_map; - ui::TreeNodeIterator<const bookmarks::BookmarkNode> iterator( - bookmark_model->root_node()); - while (iterator.has_next()) { -- const bookmarks::BookmarkNode* node = iterator.Next(); -+ const bookmarks::BookmarkNode* const node = iterator.Next(); - DCHECK(base::IsValidGUID(node->guid())); -+ - if (node->is_permanent_node()) { - continue; - } -+ - const auto remote_it = guid_to_remote_node_map.find(node->guid()); - if (remote_it == guid_to_remote_node_map.end()) { - continue; - } -- // If local node and its remote node match are conflicting in node type or -- // URL, replace local GUID with a random GUID. -- const syncer::EntityData& remote_entity = remote_it->second->entity(); -+ -+ const RemoteTreeNode* const remote_node = remote_it->second; -+ const syncer::EntityData& remote_entity = remote_node->entity(); - if (node->is_folder() != remote_entity.is_folder || - (node->is_url() && - node->url() != remote_entity.specifics.bookmark().url())) { -- node = -- ReplaceBookmarkNodeGUID(node, base::GenerateGUID(), bookmark_model); -+ // If local node and its remote node match are conflicting in node type or -+ // URL, replace local GUID with a random GUID. -+ // TODO(crbug.com/978430): Local GUIDs should also be reassigned if they -+ // match a remote originator_item_id. -+ ReplaceBookmarkNodeGUID(node, base::GenerateGUID(), bookmark_model); -+ continue; - } -- guid_to_local_node_map.emplace(node->guid(), node); -+ -+ guid_to_match_map.emplace(node->guid(), GuidMatch{node, remote_node}); - } -- return guid_to_local_node_map; -+ -+ return guid_to_match_map; - } - - void BookmarkModelMerger::MergeSubtree( -@@ -422,25 +420,27 @@ const bookmarks::BookmarkNode* BookmarkModelMerger::FindMatchingLocalNode( - const bookmarks::BookmarkNode* local_parent, - size_t local_child_start_index) const { - // Try to match child by GUID. If we can't, try to match child by semantics. -- const bookmarks::BookmarkNode* matching_local_node = -+ const bookmarks::BookmarkNode* matching_local_node_by_guid = - FindMatchingLocalNodeByGUID(remote_child); -- if (!matching_local_node) { -- // All local nodes up to |remote_index-1| have processed already. Look for a -- // matching local node starting with the local node at position -- // |local_child_start_index|. FindMatchingChildBySemanticsStartingAt() -- // returns kInvalidIndex in the case where no semantics match was found or -- // the semantics match found is GUID-matchable to a different node. -- const size_t local_index = FindMatchingChildBySemanticsStartingAt( -- /*remote_node=*/remote_child, -- /*local_parent=*/local_parent, -- /*starting_child_index=*/local_child_start_index); -- if (local_index == kInvalidIndex) { -- // If no match found, return. -- return nullptr; -- } -- matching_local_node = local_parent->children()[local_index].get(); -+ if (matching_local_node_by_guid) { -+ return matching_local_node_by_guid; -+ } -+ -+ // All local nodes up to |remote_index-1| have processed already. Look for a -+ // matching local node starting with the local node at position -+ // |local_child_start_index|. FindMatchingChildBySemanticsStartingAt() -+ // returns kInvalidIndex in the case where no semantics match was found or -+ // the semantics match found is GUID-matchable to a different node. -+ const size_t local_index = FindMatchingChildBySemanticsStartingAt( -+ /*remote_node=*/remote_child, -+ /*local_parent=*/local_parent, -+ /*starting_child_index=*/local_child_start_index); -+ if (local_index == kInvalidIndex) { -+ // If no match found, return. -+ return nullptr; - } -- return matching_local_node; -+ -+ return local_parent->children()[local_index].get(); - } - - const bookmarks::BookmarkNode* -@@ -471,8 +471,6 @@ BookmarkModelMerger::UpdateBookmarkNodeFromSpecificsIncludingGUID( - return local_node; - } - DCHECK(base::IsValidGUID(specifics.guid())); -- // We do not update the GUID maps upon node replacement as per the comment -- // in bookmark_model_merger.h. - return ReplaceBookmarkNodeGUID(local_node, specifics.guid(), bookmark_model_); - } - -@@ -574,7 +572,7 @@ void BookmarkModelMerger::ProcessLocalCreation( - if (FindMatchingRemoteNodeByGUID(node->children()[i].get())) { - continue; - } -- ProcessLocalCreation(node, i); -+ ProcessLocalCreation(/*parent=*/node, i); - } - } - -@@ -612,36 +610,25 @@ const BookmarkModelMerger::RemoteTreeNode* - BookmarkModelMerger::FindMatchingRemoteNodeByGUID( - const bookmarks::BookmarkNode* local_node) const { - DCHECK(local_node); -- // Ensure matching nodes are of the same type and have the same URL, -- // guaranteed by BuildGUIDToLocalNodeMap(). -- const auto it = guid_to_remote_node_map_.find(local_node->guid()); -- if (it == guid_to_remote_node_map_.end()) { -+ -+ const auto it = guid_to_match_map_.find(local_node->guid()); -+ if (it == guid_to_match_map_.end()) { - return nullptr; - } - -- const RemoteTreeNode* const remote_node = it->second; -- DCHECK(remote_node); -- DCHECK_EQ(local_node->is_folder(), remote_node->entity().is_folder); -- DCHECK_EQ(local_node->url(), -- remote_node->entity().specifics.bookmark().url()); -- return remote_node; -+ return it->second.remote_node; - } - - const bookmarks::BookmarkNode* BookmarkModelMerger::FindMatchingLocalNodeByGUID( - const RemoteTreeNode& remote_node) const { - const syncer::EntityData& remote_entity = remote_node.entity(); - const auto it = -- guid_to_local_node_map_.find(remote_entity.specifics.bookmark().guid()); -- if (it == guid_to_local_node_map_.end()) { -+ guid_to_match_map_.find(remote_entity.specifics.bookmark().guid()); -+ if (it == guid_to_match_map_.end()) { - return nullptr; - } -- DCHECK(!remote_entity.specifics.bookmark().guid().empty()); -- const bookmarks::BookmarkNode* local_node = it->second; -- // Ensure matching nodes are of the same type and have the same URL, -- // guaranteed by BuildGUIDToLocalNodeMap(). -- DCHECK_EQ(local_node->is_folder(), remote_entity.is_folder); -- DCHECK_EQ(local_node->url(), remote_entity.specifics.bookmark().url()); -- return local_node; -+ -+ return it->second.local_node; - } - - } // namespace sync_bookmarks -diff --git a/components/sync_bookmarks/bookmark_model_merger.h b/components/sync_bookmarks/bookmark_model_merger.h -index 1a40fad2a074..18744920a1a4 100644 ---- a/components/sync_bookmarks/bookmark_model_merger.h -+++ b/components/sync_bookmarks/bookmark_model_merger.h -@@ -56,6 +56,14 @@ class BookmarkModelMerger { - // a permanent node, keyed by server-defined unique tag of the root. - using RemoteForest = std::unordered_map<std::string, RemoteTreeNode>; - -+ // Represents a pair of bookmarks, one local and one remote, that have been -+ // matched by GUID. They are guaranteed to have the same type and URL (if -+ // applicable). -+ struct GuidMatch { -+ const bookmarks::BookmarkNode* local_node; -+ const RemoteTreeNode* remote_node; -+ }; -+ - // Constructs the remote bookmark tree to be merged. Each entry in the - // returned map is a permanent node, identified (keyed) by the server-defined - // tag. All invalid updates are filtered out, including invalid bookmark -@@ -63,22 +71,12 @@ class BookmarkModelMerger { - // sends tombstones as part of the initial download. - static RemoteForest BuildRemoteForest(syncer::UpdateResponseDataList updates); - -- // Constructs a map from GUID to corresponding remote nodes, used in the merge -- // process to determine GUID-based node matches. -- static std::unordered_map<std::string, const RemoteTreeNode*> -- BuildGUIDToRemoteNodeMap(const RemoteForest& remote_forest); -- -- // Constructs a map from GUID to corresponding local node, used in the merge -- // process to determine GUID-based node matches. |bookmark_model| must not be -- // null. |guid_to_remote_node_map| is used to detect conflicting GUID matches -- // between local and remote bookmarks for the cases where they cannot be -- // merged (e.g. folder vs non-folder) and in such cases regenerate a random -- // GUID for the local bookmark. -- static std::unordered_map<std::string, const bookmarks::BookmarkNode*> -- BuildGUIDToLocalNodeMap( -- bookmarks::BookmarkModel* bookmark_model, -- const std::unordered_map<std::string, const RemoteTreeNode*>& -- guid_to_remote_node_map); -+ // Computes bookmark pairs that should be matched by GUID. Local bookmark -+ // GUIDs may be regenerated for the case where they collide with a remote GUID -+ // that is not compatible (e.g. folder vs non-folder). -+ static std::unordered_map<std::string, GuidMatch> -+ FindGuidMatchesOrReassignLocal(const RemoteForest& remote_forest, -+ bookmarks::BookmarkModel* bookmark_model); - - // Merges a local and a remote subtrees. The input nodes are two equivalent - // local and remote nodes. This method tries to recursively match their -@@ -151,15 +149,7 @@ class BookmarkModelMerger { - // Preprocessed remote nodes in the form a forest where each tree's root is a - // permanent node. Computed upon construction via BuildRemoteForest(). - const RemoteForest remote_forest_; -- // Maps GUIDs to their respective remote nodes. Used for GUID-based node -- // matching and is populated at the beginning of the merge process. -- const std::unordered_map<std::string, const RemoteTreeNode*> -- guid_to_remote_node_map_; -- // Maps GUIDs to their respective local nodes. Used for GUID-based -- // node matching and is populated at the beginning of the merge process. -- // Is not updated upon potential changes to the model during merge. -- const std::unordered_map<std::string, const bookmarks::BookmarkNode*> -- guid_to_local_node_map_; -+ std::unordered_map<std::string, GuidMatch> guid_to_match_map_; - - DISALLOW_COPY_AND_ASSIGN(BookmarkModelMerger); - }; -diff --git a/components/sync_bookmarks/bookmark_specifics_conversions.cc b/components/sync_bookmarks/bookmark_specifics_conversions.cc -index 98725dce2a61..74914f187509 100644 ---- a/components/sync_bookmarks/bookmark_specifics_conversions.cc -+++ b/components/sync_bookmarks/bookmark_specifics_conversions.cc -@@ -255,6 +255,12 @@ const bookmarks::BookmarkNode* ReplaceBookmarkNodeGUID( - } - const bookmarks::BookmarkNode* new_node; - DCHECK(base::IsValidGUID(guid)); -+ -+ if (node->guid() == guid) { -+ // Nothing to do. -+ return node; -+ } -+ - if (node->is_folder()) { - new_node = - model->AddFolder(node->parent(), node->parent()->GetIndexOf(node), --- -2.24.1 - diff --git a/0001-ozone-wayland-Extract-ShellObjectFactory-to-a-separa.patch b/0001-ozone-wayland-Extract-ShellObjectFactory-to-a-separa.patch deleted file mode 100644 index ff7a44ce17c5..000000000000 --- a/0001-ozone-wayland-Extract-ShellObjectFactory-to-a-separa.patch +++ /dev/null @@ -1,788 +0,0 @@ -From 40bbda2b7265437d6dea1ce9d3361f85147fedf1 Mon Sep 17 00:00:00 2001 -From: Maksim Sisov <msisov@igalia.com> -Date: Fri, 6 Dec 2019 19:35:16 +0000 -Subject: [PATCH 1/9] ozone/wayland: Extract ShellObjectFactory to a separate - file. - -This CL -1) extracts ShellObjectFactory into a separate file and keeps -the same creation and initialization logic of wrappers of shell objects, -2) extends ShellPopupWrapper and ShellSurfaceWrapper interfaces by adding -Initialize method so that it is more convenient to initialize -XdgPopupWrapperImpl XdgSurfaceWrapperImpl and let them handle initialization -based on the available xdg-shell version, -3) makes WaylandWindow use the extracted ShellObjectFactory, -4) makes InitializeStable and InitializeV6 methods of -XDGWrapper objects be private members. The decision on which -one to call is made in the main Initialize method now. -5) reconsiders the logging whether we need to keep pointers to -some objects or not. - -Bug: 1028919 -Change-Id: I87fd5fc0d0b35222f26c460c9174da6053dc320e -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1953708 -Reviewed-by: Michael Spang <spang@chromium.org> -Commit-Queue: Maksim Sisov <msisov@igalia.com> -Cr-Commit-Position: refs/heads/master@{#722572} ---- - ui/ozone/platform/wayland/BUILD.gn | 2 + - .../wayland/host/shell_object_factory.cc | 47 +++++ - .../wayland/host/shell_object_factory.h | 44 +++++ - .../wayland/host/shell_popup_wrapper.h | 6 + - .../wayland/host/shell_surface_wrapper.h | 4 + - .../platform/wayland/host/wayland_window.cc | 72 +------ - .../platform/wayland/host/wayland_window.h | 7 - - .../wayland/host/xdg_popup_wrapper_impl.cc | 48 ++--- - .../wayland/host/xdg_popup_wrapper_impl.h | 19 +- - .../wayland/host/xdg_surface_wrapper_impl.cc | 181 ++++++++++-------- - .../wayland/host/xdg_surface_wrapper_impl.h | 27 +-- - 11 files changed, 261 insertions(+), 196 deletions(-) - create mode 100644 ui/ozone/platform/wayland/host/shell_object_factory.cc - create mode 100644 ui/ozone/platform/wayland/host/shell_object_factory.h - -diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn -index 37e7ffb5d83c..9c2cbc52500b 100644 ---- a/ui/ozone/platform/wayland/BUILD.gn -+++ b/ui/ozone/platform/wayland/BUILD.gn -@@ -45,6 +45,8 @@ source_set("wayland") { - "host/internal/wayland_data_offer_base.h", - "host/internal/wayland_data_source_base.cc", - "host/internal/wayland_data_source_base.h", -+ "host/shell_object_factory.cc", -+ "host/shell_object_factory.h", - "host/shell_popup_wrapper.cc", - "host/shell_popup_wrapper.h", - "host/shell_surface_wrapper.cc", -diff --git a/ui/ozone/platform/wayland/host/shell_object_factory.cc b/ui/ozone/platform/wayland/host/shell_object_factory.cc -new file mode 100644 -index 000000000000..57383be20da5 ---- /dev/null -+++ b/ui/ozone/platform/wayland/host/shell_object_factory.cc -@@ -0,0 +1,47 @@ -+// 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/shell_object_factory.h" -+ -+#include "ui/ozone/platform/wayland/host/wayland_connection.h" -+#include "ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h" -+#include "ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h" -+ -+namespace ui { -+ -+ShellObjectFactory::ShellObjectFactory() = default; -+ShellObjectFactory::~ShellObjectFactory() = default; -+ -+std::unique_ptr<ShellSurfaceWrapper> -+ShellObjectFactory::CreateShellSurfaceWrapper(WaylandConnection* connection, -+ WaylandWindow* wayland_window) { -+ if (connection->shell() || connection->shell_v6()) { -+ auto surface = -+ std::make_unique<XDGSurfaceWrapperImpl>(wayland_window, connection); -+ return surface->Initialize(true /* with_top_level */) ? std::move(surface) -+ : nullptr; -+ } -+ LOG(WARNING) << "Shell protocol is not available."; -+ return nullptr; -+} -+ -+std::unique_ptr<ShellPopupWrapper> ShellObjectFactory::CreateShellPopupWrapper( -+ WaylandConnection* connection, -+ WaylandWindow* wayland_window, -+ const gfx::Rect& bounds) { -+ if (connection->shell() || connection->shell_v6()) { -+ auto surface = -+ std::make_unique<XDGSurfaceWrapperImpl>(wayland_window, connection); -+ if (!surface->Initialize(false /* with_top_level */)) -+ return nullptr; -+ -+ auto popup = std::make_unique<XDGPopupWrapperImpl>(std::move(surface), -+ wayland_window); -+ return popup->Initialize(connection, bounds) ? std::move(popup) : nullptr; -+ } -+ LOG(WARNING) << "Shell protocol is not available."; -+ return nullptr; -+} -+ -+} // namespace ui -\ No newline at end of file -diff --git a/ui/ozone/platform/wayland/host/shell_object_factory.h b/ui/ozone/platform/wayland/host/shell_object_factory.h -new file mode 100644 -index 000000000000..a915326c23fb ---- /dev/null -+++ b/ui/ozone/platform/wayland/host/shell_object_factory.h -@@ -0,0 +1,44 @@ -+// 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_SHELL_OBJECT_FACTORY_H_ -+#define UI_OZONE_PLATFORM_WAYLAND_HOST_SHELL_OBJECT_FACTORY_H_ -+ -+#include <memory> -+ -+namespace gfx { -+class Rect; -+} -+ -+namespace ui { -+ -+class ShellSurfaceWrapper; -+class ShellPopupWrapper; -+class WaylandConnection; -+class WaylandWindow; -+ -+// Shell factory that creates shell objects for different protocols. Preferred -+// protocols are defined in the following order: -+// 1) xdg-shell-stable-protocol. -+// 2) xdg-shell-v6-unstable-protocol. -+class ShellObjectFactory { -+ public: -+ ShellObjectFactory(); -+ ~ShellObjectFactory(); -+ -+ // Creates and initializes a ShellSurfaceWrapper. -+ std::unique_ptr<ShellSurfaceWrapper> CreateShellSurfaceWrapper( -+ WaylandConnection* connection, -+ WaylandWindow* wayland_window); -+ -+ // Creates and intitializes a ShellPopupSurface. -+ std::unique_ptr<ShellPopupWrapper> CreateShellPopupWrapper( -+ WaylandConnection* connection, -+ WaylandWindow* wayland_window, -+ const gfx::Rect& bounds); -+}; -+ -+} // namespace ui -+ -+#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_SHELL_OBJECT_FACTORY_H_ -\ No newline at end of file -diff --git a/ui/ozone/platform/wayland/host/shell_popup_wrapper.h b/ui/ozone/platform/wayland/host/shell_popup_wrapper.h -index 952c0a2a278a..2970549dd09b 100644 ---- a/ui/ozone/platform/wayland/host/shell_popup_wrapper.h -+++ b/ui/ozone/platform/wayland/host/shell_popup_wrapper.h -@@ -10,6 +10,8 @@ - - namespace ui { - -+class WaylandConnection; -+ - enum class MenuType { - TYPE_RIGHT_CLICK, - TYPE_3DOT_PARENT_MENU, -@@ -67,6 +69,10 @@ inline WlConstraintAdjustment operator&(WlConstraintAdjustment a, - class ShellPopupWrapper { - public: - virtual ~ShellPopupWrapper() {} -+ -+ // Initializes the popup surface. -+ virtual bool Initialize(WaylandConnection* connection, -+ const gfx::Rect& bounds) = 0; - }; - - gfx::Rect GetAnchorRect(MenuType menu_type, -diff --git a/ui/ozone/platform/wayland/host/shell_surface_wrapper.h b/ui/ozone/platform/wayland/host/shell_surface_wrapper.h -index 49b27e4c7214..c75e87a627b4 100644 ---- a/ui/ozone/platform/wayland/host/shell_surface_wrapper.h -+++ b/ui/ozone/platform/wayland/host/shell_surface_wrapper.h -@@ -21,6 +21,10 @@ class ShellSurfaceWrapper { - public: - virtual ~ShellSurfaceWrapper() {} - -+ // Initializes the ShellSurface. Some protocols may require to create shell -+ // surface without toplevel role and assign a popup role to it later. -+ virtual bool Initialize(bool with_toplevel) = 0; -+ - // Sets a native window to maximized state. - virtual void SetMaximized() = 0; - -diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc -index 4787a1f3b396..95c6e5a46b3e 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/shell_object_factory.h" - #include "ui/ozone/platform/wayland/host/shell_popup_wrapper.h" - #include "ui/ozone/platform/wayland/host/shell_surface_wrapper.h" - #include "ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h" -@@ -23,50 +24,12 @@ - #include "ui/ozone/platform/wayland/host/wayland_cursor_position.h" - #include "ui/ozone/platform/wayland/host/wayland_output_manager.h" - #include "ui/ozone/platform/wayland/host/wayland_pointer.h" --#include "ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h" --#include "ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h" - #include "ui/platform_window/platform_window_handler/wm_drop_handler.h" - - namespace ui { - - namespace { - --// Factory, which decides which version type of xdg object to build. --class XDGShellObjectFactory { -- public: -- XDGShellObjectFactory() = default; -- ~XDGShellObjectFactory() = default; -- -- std::unique_ptr<ShellPopupWrapper> CreateXDGPopup( -- WaylandConnection* connection, -- WaylandWindow* wayland_window, -- const gfx::Rect& bounds) { -- std::unique_ptr<XDGSurfaceWrapperImpl> surface = -- std::make_unique<XDGSurfaceWrapperImpl>(wayland_window); -- if (connection->shell()) { -- surface->InitializeStable(connection, wayland_window->surface(), false); -- std::unique_ptr<XDGPopupWrapperImpl> popup = -- std::make_unique<XDGPopupWrapperImpl>(std::move(surface), -- wayland_window); -- popup->InitializeStable(connection, wayland_window->surface(), -- wayland_window->parent_window(), bounds); -- return popup; -- } -- DCHECK(connection->shell_v6()); -- -- surface->InitializeV6(connection, wayland_window->surface(), false); -- std::unique_ptr<XDGPopupWrapperImpl> popup = -- std::make_unique<XDGPopupWrapperImpl>(std::move(surface), -- wayland_window); -- popup->InitializeV6(connection, wayland_window->surface(), -- wayland_window->parent_window(), bounds); -- return popup; -- } -- -- private: -- DISALLOW_COPY_AND_ASSIGN(XDGShellObjectFactory); --}; -- - // Translates bounds relative to top level window to specified parent. - gfx::Rect TranslateBoundsToParentCoordinates(const gfx::Rect& child_bounds, - const gfx::Rect& parent_bounds) { -@@ -89,7 +52,6 @@ WaylandWindow::WaylandWindow(PlatformWindowDelegate* delegate, - WaylandConnection* connection) - : delegate_(delegate), - connection_(connection), -- xdg_shell_objects_factory_(new XDGShellObjectFactory()), - state_(PlatformWindowState::kNormal), - pending_state_(PlatformWindowState::kUnknown) { - // Set a class property key, which allows |this| to be used for interactive -@@ -124,8 +86,6 @@ WaylandWindow* WaylandWindow::FromSurface(wl_surface* surface) { - } - - bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) { -- DCHECK(xdg_shell_objects_factory_); -- - // Properties contain DIP bounds but the buffer scale is initially 1 so it's - // OK to assign. The bounds will be recalculated when the buffer scale - // changes. -@@ -244,35 +204,19 @@ void WaylandWindow::CreateShellPopup() { - - auto bounds_px = AdjustPopupWindowPosition(); - -- shell_popup_ = -- xdg_shell_objects_factory_->CreateXDGPopup(connection_, this, bounds_px); -- -- if (!shell_popup_) { -+ ShellObjectFactory factory; -+ shell_popup_ = factory.CreateShellPopupWrapper(connection_, this, bounds_px); -+ if (!shell_popup_) - CHECK(false) << "Failed to create Wayland shell popup"; -- } - - parent_window_->set_child_window(this); - } - - void WaylandWindow::CreateShellSurface() { -- std::unique_ptr<XDGSurfaceWrapperImpl> xdg_surface = -- std::make_unique<XDGSurfaceWrapperImpl>(this); -- if (!xdg_surface) { -- CHECK(false) << "Failed to create Wayland shell surface"; -- return; -- } -- -- if (connection_->shell()) { -- if (!xdg_surface->InitializeStable(connection_, surface_.get())) { -- CHECK(false) << "Failed to initialize Wayland shell surface"; -- } -- } else { -- DCHECK(connection_->shell_v6()); -- if (!xdg_surface->InitializeV6(connection_, surface_.get())) { -- CHECK(false) << "Failed to initialize Wayland shell surface"; -- } -- } -- shell_surface_ = std::move(xdg_surface); -+ ShellObjectFactory factory; -+ shell_surface_ = factory.CreateShellSurfaceWrapper(connection_, this); -+ if (!shell_surface_) -+ CHECK(false) << "Failed to initialize Wayland shell surface"; - } - - void WaylandWindow::CreateAndShowTooltipSubSurface() { -diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h -index 2745dde85c32..4233216d7a6f 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window.h -+++ b/ui/ozone/platform/wayland/host/wayland_window.h -@@ -35,10 +35,6 @@ class WaylandConnection; - class ShellPopupWrapper; - class ShellSurfaceWrapper; - --namespace { --class XDGShellObjectFactory; --} // namespace -- - class WaylandWindow : public PlatformWindow, - public PlatformEventDispatcher, - public WmMoveResizeHandler, -@@ -229,9 +225,6 @@ class WaylandWindow : public PlatformWindow, - WaylandWindow* parent_window_ = nullptr; - WaylandWindow* child_window_ = nullptr; - -- // Creates xdg objects based on xdg shell version. -- std::unique_ptr<XDGShellObjectFactory> xdg_shell_objects_factory_; -- - wl::Object<wl_surface> surface_; - wl::Object<wl_subsurface> tooltip_subsurface_; - -diff --git a/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc b/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc -index 0c6683828e74..abf6e7fa6461 100644 ---- a/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc -+++ b/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc -@@ -260,40 +260,45 @@ XDGPopupWrapperImpl::XDGPopupWrapperImpl( - WaylandWindow* wayland_window) - : wayland_window_(wayland_window), xdg_surface_(std::move(surface)) { - DCHECK(xdg_surface_); -+ DCHECK(wayland_window_ && wayland_window_->parent_window()); - } - --XDGPopupWrapperImpl::~XDGPopupWrapperImpl() {} -+XDGPopupWrapperImpl::~XDGPopupWrapperImpl() = default; -+ -+bool XDGPopupWrapperImpl::Initialize(WaylandConnection* connection, -+ const gfx::Rect& bounds) { -+ if (connection->shell()) -+ return InitializeStable(connection, bounds); -+ else if (connection->shell_v6()) -+ return InitializeV6(connection, bounds); -+ NOTREACHED() << "Wrong shell protocol"; -+ return false; -+} - - bool XDGPopupWrapperImpl::InitializeStable(WaylandConnection* connection, -- wl_surface* surface, -- WaylandWindow* parent_window, - const gfx::Rect& bounds) { -- DCHECK(connection && surface && parent_window); - static const struct xdg_popup_listener xdg_popup_listener = { - &XDGPopupWrapperImpl::ConfigureStable, - &XDGPopupWrapperImpl::PopupDoneStable, - }; - -- if (!xdg_surface_) -- return false; -- - XDGSurfaceWrapperImpl* parent_xdg_surface; - // If the parent window is a popup, the surface of that popup must be used as - // a parent. -- if (parent_window->shell_popup()) { -- XDGPopupWrapperImpl* popup = -- reinterpret_cast<XDGPopupWrapperImpl*>(parent_window->shell_popup()); -+ if (wayland_window_->parent_window()->shell_popup()) { -+ XDGPopupWrapperImpl* popup = reinterpret_cast<XDGPopupWrapperImpl*>( -+ wayland_window_->parent_window()->shell_popup()); - parent_xdg_surface = popup->xdg_surface(); - } else { - parent_xdg_surface = reinterpret_cast<XDGSurfaceWrapperImpl*>( -- parent_window->shell_surface()); -+ wayland_window_->parent_window()->shell_surface()); - } - - if (!parent_xdg_surface) - return false; - -- struct xdg_positioner* positioner = -- CreatePositionerStable(connection, parent_window, bounds); -+ struct xdg_positioner* positioner = CreatePositionerStable( -+ connection, wayland_window_->parent_window(), bounds); - if (!positioner) - return false; - -@@ -337,7 +342,7 @@ bool XDGPopupWrapperImpl::InitializeStable(WaylandConnection* connection, - } - xdg_popup_add_listener(xdg_popup_.get(), &xdg_popup_listener, this); - -- wl_surface_commit(surface); -+ wl_surface_commit(wayland_window_->surface()); - return true; - } - -@@ -383,10 +388,7 @@ struct xdg_positioner* XDGPopupWrapperImpl::CreatePositionerStable( - } - - bool XDGPopupWrapperImpl::InitializeV6(WaylandConnection* connection, -- wl_surface* surface, -- WaylandWindow* parent_window, - const gfx::Rect& bounds) { -- DCHECK(connection && surface && parent_window); - static const struct zxdg_popup_v6_listener zxdg_popup_v6_listener = { - &XDGPopupWrapperImpl::ConfigureV6, - &XDGPopupWrapperImpl::PopupDoneV6, -@@ -398,20 +400,20 @@ bool XDGPopupWrapperImpl::InitializeV6(WaylandConnection* connection, - XDGSurfaceWrapperImpl* parent_xdg_surface; - // If the parent window is a popup, the surface of that popup must be used as - // a parent. -- if (parent_window->shell_popup()) { -- XDGPopupWrapperImpl* popup = -- reinterpret_cast<XDGPopupWrapperImpl*>(parent_window->shell_popup()); -+ if (wayland_window_->parent_window()->shell_popup()) { -+ XDGPopupWrapperImpl* popup = reinterpret_cast<XDGPopupWrapperImpl*>( -+ wayland_window_->parent_window()->shell_popup()); - parent_xdg_surface = popup->xdg_surface(); - } else { - parent_xdg_surface = reinterpret_cast<XDGSurfaceWrapperImpl*>( -- parent_window->shell_surface()); -+ wayland_window_->parent_window()->shell_surface()); - } - - if (!parent_xdg_surface) - return false; - - zxdg_positioner_v6* positioner = -- CreatePositionerV6(connection, parent_window, bounds); -+ CreatePositionerV6(connection, wayland_window_->parent_window(), bounds); - if (!positioner) - return false; - -@@ -457,7 +459,7 @@ bool XDGPopupWrapperImpl::InitializeV6(WaylandConnection* connection, - zxdg_popup_v6_add_listener(zxdg_popup_v6_.get(), &zxdg_popup_v6_listener, - this); - -- wl_surface_commit(surface); -+ wl_surface_commit(wayland_window_->surface()); - return true; - } - -diff --git a/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h b/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h -index 371f18157d73..2a900818ff6a 100644 ---- a/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h -+++ b/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h -@@ -23,19 +23,16 @@ class XDGPopupWrapperImpl : public ShellPopupWrapper { - ~XDGPopupWrapperImpl() override; - - // XDGPopupWrapper: -- bool InitializeStable(WaylandConnection* connection, -- wl_surface* surface, -- WaylandWindow* parent_window, -- const gfx::Rect& bounds); -- bool InitializeV6(WaylandConnection* connection, -- wl_surface* surface, -- WaylandWindow* parent_window, -- const gfx::Rect& bounds); -+ bool Initialize(WaylandConnection* connection, -+ const gfx::Rect& bounds) override; - - private: -+ bool InitializeStable(WaylandConnection* connection, const gfx::Rect& bounds); - struct xdg_positioner* CreatePositionerStable(WaylandConnection* connection, - WaylandWindow* parent_window, - const gfx::Rect& bounds); -+ -+ bool InitializeV6(WaylandConnection* connection, const gfx::Rect& bounds); - struct zxdg_positioner_v6* CreatePositionerV6(WaylandConnection* connection, - WaylandWindow* parent_window, - const gfx::Rect& bounds); -@@ -64,9 +61,15 @@ class XDGPopupWrapperImpl : public ShellPopupWrapper { - - XDGSurfaceWrapperImpl* xdg_surface(); - -+ // Non-owned WaylandWindow that uses this popup. - WaylandWindow* const wayland_window_; -+ -+ // Ground surface for this popup. - std::unique_ptr<XDGSurfaceWrapperImpl> xdg_surface_; -+ -+ // XDG Shell Stable object. - wl::Object<xdg_popup> xdg_popup_; -+ // XDG Shell V6 object. - wl::Object<zxdg_popup_v6> zxdg_popup_v6_; - - DISALLOW_COPY_AND_ASSIGN(XDGPopupWrapperImpl); -diff --git a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc -index d4078e1bc139..e7df772ae472 100644 ---- a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc -+++ b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc -@@ -15,84 +15,19 @@ - - namespace ui { - --XDGSurfaceWrapperImpl::XDGSurfaceWrapperImpl(WaylandWindow* wayland_window) -- : wayland_window_(wayland_window) {} -+XDGSurfaceWrapperImpl::XDGSurfaceWrapperImpl(WaylandWindow* wayland_window, -+ WaylandConnection* connection) -+ : wayland_window_(wayland_window), connection_(connection) {} - - XDGSurfaceWrapperImpl::~XDGSurfaceWrapperImpl() {} - --bool XDGSurfaceWrapperImpl::InitializeStable(WaylandConnection* connection, -- wl_surface* surface, -- bool with_toplevel) { -- static const xdg_surface_listener xdg_surface_listener = { -- &XDGSurfaceWrapperImpl::ConfigureStable, -- }; -- static const xdg_toplevel_listener xdg_toplevel_listener = { -- &XDGSurfaceWrapperImpl::ConfigureTopLevelStable, -- &XDGSurfaceWrapperImpl::CloseTopLevelStable, -- }; -- -- // if this surface is created for the popup role, mark that it requires -- // configuration acknowledgement on each configure event. -- surface_for_popup_ = !with_toplevel; -- -- xdg_surface_.reset(xdg_wm_base_get_xdg_surface(connection->shell(), surface)); -- if (!xdg_surface_) { -- LOG(ERROR) << "Failed to create xdg_surface"; -- return false; -- } -- xdg_surface_add_listener(xdg_surface_.get(), &xdg_surface_listener, this); -- // XDGPopup requires a separate surface to be created, so this is just a -- // request to get an xdg_surface for it. -- if (surface_for_popup_) -- return true; -- -- xdg_toplevel_.reset(xdg_surface_get_toplevel(xdg_surface_.get())); -- if (!xdg_toplevel_) { -- LOG(ERROR) << "Failed to create xdg_toplevel"; -- return false; -- } -- xdg_toplevel_add_listener(xdg_toplevel_.get(), &xdg_toplevel_listener, this); -- wl_surface_commit(surface); -- return true; --} -- --bool XDGSurfaceWrapperImpl::InitializeV6(WaylandConnection* connection, -- wl_surface* surface, -- bool with_toplevel) { -- static const zxdg_surface_v6_listener zxdg_surface_v6_listener = { -- &XDGSurfaceWrapperImpl::ConfigureV6, -- }; -- static const zxdg_toplevel_v6_listener zxdg_toplevel_v6_listener = { -- &XDGSurfaceWrapperImpl::ConfigureTopLevelV6, -- &XDGSurfaceWrapperImpl::CloseTopLevelV6, -- }; -- -- // if this surface is created for the popup role, mark that it requires -- // configuration acknowledgement on each configure event. -- surface_for_popup_ = !with_toplevel; -- -- zxdg_surface_v6_.reset( -- zxdg_shell_v6_get_xdg_surface(connection->shell_v6(), surface)); -- if (!zxdg_surface_v6_) { -- LOG(ERROR) << "Failed to create zxdg_surface"; -- return false; -- } -- zxdg_surface_v6_add_listener(zxdg_surface_v6_.get(), -- &zxdg_surface_v6_listener, this); -- // XDGPopupV6 requires a separate surface to be created, so this is just a -- // request to get an xdg_surface for it. -- if (surface_for_popup_) -- return true; -- -- zxdg_toplevel_v6_.reset(zxdg_surface_v6_get_toplevel(zxdg_surface_v6_.get())); -- if (!zxdg_toplevel_v6_) { -- LOG(ERROR) << "Failed to create zxdg_toplevel"; -- return false; -- } -- zxdg_toplevel_v6_add_listener(zxdg_toplevel_v6_.get(), -- &zxdg_toplevel_v6_listener, this); -- wl_surface_commit(surface); -- return true; -+bool XDGSurfaceWrapperImpl::Initialize(bool with_toplevel) { -+ if (connection_->shell()) -+ return InitializeStable(with_toplevel); -+ else if (connection_->shell_v6()) -+ return InitializeV6(with_toplevel); -+ NOTREACHED() << "Wrong shell protocol"; -+ return false; - } - - void XDGSurfaceWrapperImpl::SetMaximized() { -@@ -142,25 +77,25 @@ void XDGSurfaceWrapperImpl::SetMinimized() { - - void XDGSurfaceWrapperImpl::SurfaceMove(WaylandConnection* connection) { - if (xdg_toplevel_) { -- xdg_toplevel_move(xdg_toplevel_.get(), connection->seat(), -- connection->serial()); -+ xdg_toplevel_move(xdg_toplevel_.get(), connection_->seat(), -+ connection_->serial()); - } else { - DCHECK(zxdg_toplevel_v6_); -- zxdg_toplevel_v6_move(zxdg_toplevel_v6_.get(), connection->seat(), -- connection->serial()); -+ zxdg_toplevel_v6_move(zxdg_toplevel_v6_.get(), connection_->seat(), -+ connection_->serial()); - } - } - - void XDGSurfaceWrapperImpl::SurfaceResize(WaylandConnection* connection, - uint32_t hittest) { - if (xdg_toplevel_) { -- xdg_toplevel_resize(xdg_toplevel_.get(), connection->seat(), -- connection->serial(), -+ xdg_toplevel_resize(xdg_toplevel_.get(), connection_->seat(), -+ connection_->serial(), - wl::IdentifyDirection(*connection, hittest)); - } else { - DCHECK(zxdg_toplevel_v6_); -- zxdg_toplevel_v6_resize(zxdg_toplevel_v6_.get(), connection->seat(), -- connection->serial(), -+ zxdg_toplevel_v6_resize(zxdg_toplevel_v6_.get(), connection_->seat(), -+ connection_->serial(), - wl::IdentifyDirection(*connection, hittest)); - } - } -@@ -317,4 +252,84 @@ xdg_surface* XDGSurfaceWrapperImpl::xdg_surface() const { - return xdg_surface_.get(); - } - -+bool XDGSurfaceWrapperImpl::InitializeStable(bool with_toplevel) { -+ static const xdg_surface_listener xdg_surface_listener = { -+ &XDGSurfaceWrapperImpl::ConfigureStable, -+ }; -+ static const xdg_toplevel_listener xdg_toplevel_listener = { -+ &XDGSurfaceWrapperImpl::ConfigureTopLevelStable, -+ &XDGSurfaceWrapperImpl::CloseTopLevelStable, -+ }; -+ -+ // if this surface is created for the popup role, mark that it requires -+ // configuration acknowledgement on each configure event. -+ surface_for_popup_ = !with_toplevel; -+ -+ xdg_surface_.reset(xdg_wm_base_get_xdg_surface(connection_->shell(), -+ wayland_window_->surface())); -+ if (!xdg_surface_) { -+ LOG(ERROR) << "Failed to create xdg_surface"; -+ return false; -+ } -+ xdg_surface_add_listener(xdg_surface_.get(), &xdg_surface_listener, this); -+ // XDGPopup requires a separate surface to be created, so this is just a -+ // request to get an xdg_surface for it. -+ if (surface_for_popup_) { -+ connection_->ScheduleFlush(); -+ return true; -+ } -+ -+ xdg_toplevel_.reset(xdg_surface_get_toplevel(xdg_surface_.get())); -+ if (!xdg_toplevel_) { -+ LOG(ERROR) << "Failed to create xdg_toplevel"; -+ return false; -+ } -+ xdg_toplevel_add_listener(xdg_toplevel_.get(), &xdg_toplevel_listener, this); -+ wl_surface_commit(wayland_window_->surface()); -+ -+ connection_->ScheduleFlush(); -+ return true; -+} -+ -+bool XDGSurfaceWrapperImpl::InitializeV6(bool with_toplevel) { -+ static const zxdg_surface_v6_listener zxdg_surface_v6_listener = { -+ &XDGSurfaceWrapperImpl::ConfigureV6, -+ }; -+ static const zxdg_toplevel_v6_listener zxdg_toplevel_v6_listener = { -+ &XDGSurfaceWrapperImpl::ConfigureTopLevelV6, -+ &XDGSurfaceWrapperImpl::CloseTopLevelV6, -+ }; -+ -+ // if this surface is created for the popup role, mark that it requires -+ // configuration acknowledgement on each configure event. -+ surface_for_popup_ = !with_toplevel; -+ -+ zxdg_surface_v6_.reset(zxdg_shell_v6_get_xdg_surface( -+ connection_->shell_v6(), wayland_window_->surface())); -+ if (!zxdg_surface_v6_) { -+ LOG(ERROR) << "Failed to create zxdg_surface"; -+ return false; -+ } -+ zxdg_surface_v6_add_listener(zxdg_surface_v6_.get(), -+ &zxdg_surface_v6_listener, this); -+ // XDGPopupV6 requires a separate surface to be created, so this is just a -+ // request to get an xdg_surface for it. -+ if (surface_for_popup_) { -+ connection_->ScheduleFlush(); -+ return true; -+ } -+ -+ zxdg_toplevel_v6_.reset(zxdg_surface_v6_get_toplevel(zxdg_surface_v6_.get())); -+ if (!zxdg_toplevel_v6_) { -+ LOG(ERROR) << "Failed to create zxdg_toplevel"; -+ return false; -+ } -+ zxdg_toplevel_v6_add_listener(zxdg_toplevel_v6_.get(), -+ &zxdg_toplevel_v6_listener, this); -+ wl_surface_commit(wayland_window_->surface()); -+ -+ connection_->ScheduleFlush(); -+ return true; -+} -+ - } // namespace ui -diff --git a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h -index e14956ebe3e7..b34f4b2281ec 100644 ---- a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h -+++ b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h -@@ -7,11 +7,10 @@ - - #include "ui/ozone/platform/wayland/host/shell_surface_wrapper.h" - -+#include "base/macros.h" - #include "base/strings/string16.h" - #include "ui/ozone/platform/wayland/common/wayland_object.h" - --#include "base/macros.h" -- - namespace gfx { - class Rect; - } -@@ -24,15 +23,12 @@ class WaylandWindow; - // Surface wrapper for xdg-shell stable and xdg-shell-unstable-v6 - class XDGSurfaceWrapperImpl : public ShellSurfaceWrapper { - public: -- XDGSurfaceWrapperImpl(WaylandWindow* wayland_window); -+ XDGSurfaceWrapperImpl(WaylandWindow* wayland_window, -+ WaylandConnection* connection); - ~XDGSurfaceWrapperImpl() override; - -- bool InitializeV6(WaylandConnection* connection, -- wl_surface* surface, -- bool with_toplevel = true); -- bool InitializeStable(WaylandConnection* connection, -- wl_surface* surface, -- bool with_toplevel = true); -+ // ShellSurfaceWrapper overrides: -+ bool Initialize(bool with_toplevel) override; - void SetMaximized() override; - void UnSetMaximized() override; - void SetFullscreen() override; -@@ -76,8 +72,17 @@ class XDGSurfaceWrapperImpl : public ShellSurfaceWrapper { - zxdg_surface_v6* zxdg_surface() const; - - private: -- WaylandWindow* wayland_window_; -- uint32_t pending_configure_serial_; -+ // Initializes using XDG Shell Stable protocol. -+ bool InitializeStable(bool with_toplevel); -+ // Initializes using XDG Shell V6 protocol. -+ bool InitializeV6(bool with_toplevel); -+ -+ // Non-owing WaylandWindow that uses this surface wrapper. -+ WaylandWindow* const wayland_window_; -+ WaylandConnection* const connection_; -+ -+ uint32_t pending_configure_serial_ = 0; -+ - wl::Object<zxdg_surface_v6> zxdg_surface_v6_; - wl::Object<zxdg_toplevel_v6> zxdg_toplevel_v6_; - wl::Object<struct xdg_surface> xdg_surface_; --- -2.24.1 - diff --git a/0002-ozone-Wayland-Add-WaylandWindow-factory-method.patch b/0002-ozone-Wayland-Add-WaylandWindow-factory-method.patch deleted file mode 100644 index 5962d788740d..000000000000 --- a/0002-ozone-Wayland-Add-WaylandWindow-factory-method.patch +++ /dev/null @@ -1,646 +0,0 @@ -From 53e253ee8daeff98359dfd1fd8f9374879e6aaa5 Mon Sep 17 00:00:00 2001 -From: Maksim Sisov <msisov@igalia.com> -Date: Fri, 6 Dec 2019 19:55:37 +0000 -Subject: [PATCH 2/9] ozone/Wayland: Add WaylandWindow factory method. - -To hide future different types of WaylandWindows (WaylandSurface, -WaylandPopup and WaylandSubsurface), add a factory method, which -will handle everything on its own. - -Also make unittests and OzonePlatformWayland use this factory. - -Bug: 1028919 -Change-Id: I745f99024b6657be3686ee92b0baf4c93f08b9a7 -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1954470 -Commit-Queue: Maksim Sisov <msisov@igalia.com> -Reviewed-by: Michael Spang <spang@chromium.org> -Cr-Commit-Position: refs/heads/master@{#722586} ---- - ui/ozone/platform/wayland/BUILD.gn | 1 + - .../wayland/host/wayland_pointer_unittest.cc | 5 +- - .../wayland/host/wayland_screen_unittest.cc | 5 +- - .../platform/wayland/host/wayland_window.cc | 132 +++++++++--------- - .../platform/wayland/host/wayland_window.h | 17 ++- - .../wayland/host/wayland_window_factory.cc | 26 ++++ - .../host/wayland_window_manager_unittests.cc | 8 +- - .../wayland/host/wayland_window_unittest.cc | 120 ++++++++-------- - .../wayland/ozone_platform_wayland.cc | 6 +- - .../platform/wayland/test/wayland_test.cc | 4 +- - .../wayland_buffer_manager_unittest.cc | 6 +- - 11 files changed, 184 insertions(+), 146 deletions(-) - create mode 100644 ui/ozone/platform/wayland/host/wayland_window_factory.cc - -diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn -index 9c2cbc52500b..a9c0302f162f 100644 ---- a/ui/ozone/platform/wayland/BUILD.gn -+++ b/ui/ozone/platform/wayland/BUILD.gn -@@ -95,6 +95,7 @@ source_set("wayland") { - "host/wayland_touch.h", - "host/wayland_window.cc", - "host/wayland_window.h", -+ "host/wayland_window_factory.cc", - "host/wayland_window_manager.cc", - "host/wayland_window_manager.h", - "host/wayland_window_observer.cc", -diff --git a/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc b/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc -index be9cd942d6ec..b96f2e6f73f9 100644 ---- a/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc -+++ b/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc -@@ -72,14 +72,15 @@ TEST_P(WaylandPointerTest, Enter) { - - TEST_P(WaylandPointerTest, Leave) { - MockPlatformWindowDelegate other_delegate; -- WaylandWindow other_window(&other_delegate, connection_.get()); - gfx::AcceleratedWidget other_widget = gfx::kNullAcceleratedWidget; - EXPECT_CALL(other_delegate, OnAcceleratedWidgetAvailable(_)) - .WillOnce(SaveArg<0>(&other_widget)); -+ - PlatformWindowInitProperties properties; - properties.bounds = gfx::Rect(0, 0, 10, 10); - properties.type = PlatformWindowType::kWindow; -- ASSERT_TRUE(other_window.Initialize(std::move(properties))); -+ auto other_window = WaylandWindow::Create(&other_delegate, connection_.get(), -+ std::move(properties)); - ASSERT_NE(other_widget, gfx::kNullAcceleratedWidget); - - Sync(); -diff --git a/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc b/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc -index e1e3cc823ac3..9198aa88e054 100644 ---- a/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc -+++ b/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc -@@ -89,13 +89,12 @@ class WaylandScreenTest : public WaylandTest { - PlatformWindowType window_type, - gfx::AcceleratedWidget parent_widget, - MockPlatformWindowDelegate* delegate) { -- auto window = std::make_unique<WaylandWindow>(delegate, connection_.get()); - PlatformWindowInitProperties properties; - properties.bounds = bounds; - properties.type = window_type; - properties.parent_widget = parent_widget; -- EXPECT_TRUE(window->Initialize(std::move(properties))); -- return window; -+ return WaylandWindow::Create(delegate, connection_.get(), -+ std::move(properties)); - } - - void UpdateOutputGeometry(wl_resource* output_resource, -diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc -index 95c6e5a46b3e..da9a4cb368b8 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window.cc -+++ b/ui/ozone/platform/wayland/host/wayland_window.cc -@@ -85,72 +85,6 @@ WaylandWindow* WaylandWindow::FromSurface(wl_surface* surface) { - wl_proxy_get_user_data(reinterpret_cast<wl_proxy*>(surface))); - } - --bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) { -- // Properties contain DIP bounds but the buffer scale is initially 1 so it's -- // OK to assign. The bounds will be recalculated when the buffer scale -- // changes. -- DCHECK_EQ(buffer_scale_, 1); -- bounds_px_ = properties.bounds; -- opacity_ = properties.opacity; -- -- surface_.reset(wl_compositor_create_surface(connection_->compositor())); -- if (!surface_) { -- LOG(ERROR) << "Failed to create wl_surface"; -- return false; -- } -- wl_surface_set_user_data(surface_.get(), this); -- AddSurfaceListener(); -- -- connection_->wayland_window_manager()->AddWindow(GetWidget(), this); -- -- ui::PlatformWindowType ui_window_type = properties.type; -- switch (ui_window_type) { -- case ui::PlatformWindowType::kMenu: -- case ui::PlatformWindowType::kPopup: -- parent_window_ = GetParentWindow(properties.parent_widget); -- -- // Popups need to know their scale earlier to position themselves. -- if (!parent_window_) { -- LOG(ERROR) << "Failed to get a parent window for this popup"; -- return false; -- } -- -- 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 -- // parents and pop up when the browser receives a notification. -- CreateShellPopup(); -- break; -- case ui::PlatformWindowType::kTooltip: -- // Tooltips subsurfaces are created on demand, upon ::Show calls. -- is_tooltip_ = true; -- break; -- case ui::PlatformWindowType::kWindow: -- case ui::PlatformWindowType::kBubble: -- case ui::PlatformWindowType::kDrag: -- // TODO(msisov): Figure out what kind of surface we need to create for -- // bubble and drag windows. -- CreateShellSurface(); -- break; -- } -- -- if (shell_surface_ && !properties.wm_class_class.empty()) -- shell_surface_->SetAppId(properties.wm_class_class); -- -- connection_->ScheduleFlush(); -- -- PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); -- delegate_->OnAcceleratedWidgetAvailable(GetWidget()); -- -- // Will do nothing for popups because they have got their scale above. -- UpdateBufferScale(false); -- -- MaybeUpdateOpaqueRegion(); -- return true; --} -- - void WaylandWindow::UpdateBufferScale(bool update_bounds) { - DCHECK(connection_->wayland_output_manager()); - const auto* screen = connection_->wayland_output_manager()->wayland_screen(); -@@ -792,6 +726,72 @@ void WaylandWindow::OnDragSessionClose(uint32_t dnd_action) { - connection_->ResetPointerFlags(); - } - -+bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) { -+ // Properties contain DIP bounds but the buffer scale is initially 1 so it's -+ // OK to assign. The bounds will be recalculated when the buffer scale -+ // changes. -+ DCHECK_EQ(buffer_scale_, 1); -+ bounds_px_ = properties.bounds; -+ opacity_ = properties.opacity; -+ -+ surface_.reset(wl_compositor_create_surface(connection_->compositor())); -+ if (!surface_) { -+ LOG(ERROR) << "Failed to create wl_surface"; -+ return false; -+ } -+ wl_surface_set_user_data(surface_.get(), this); -+ AddSurfaceListener(); -+ -+ connection_->wayland_window_manager()->AddWindow(GetWidget(), this); -+ -+ ui::PlatformWindowType ui_window_type = properties.type; -+ switch (ui_window_type) { -+ case ui::PlatformWindowType::kMenu: -+ case ui::PlatformWindowType::kPopup: -+ parent_window_ = GetParentWindow(properties.parent_widget); -+ -+ // Popups need to know their scale earlier to position themselves. -+ if (!parent_window_) { -+ LOG(ERROR) << "Failed to get a parent window for this popup"; -+ return false; -+ } -+ -+ 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 -+ // parents and pop up when the browser receives a notification. -+ CreateShellPopup(); -+ break; -+ case ui::PlatformWindowType::kTooltip: -+ // Tooltips subsurfaces are created on demand, upon ::Show calls. -+ is_tooltip_ = true; -+ break; -+ case ui::PlatformWindowType::kWindow: -+ case ui::PlatformWindowType::kBubble: -+ case ui::PlatformWindowType::kDrag: -+ // TODO(msisov): Figure out what kind of surface we need to create for -+ // bubble and drag windows. -+ CreateShellSurface(); -+ break; -+ } -+ -+ if (shell_surface_ && !properties.wm_class_class.empty()) -+ shell_surface_->SetAppId(properties.wm_class_class); -+ -+ connection_->ScheduleFlush(); -+ -+ PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); -+ delegate_->OnAcceleratedWidgetAvailable(GetWidget()); -+ -+ // Will do nothing for popups because they have got their scale above. -+ UpdateBufferScale(false); -+ -+ MaybeUpdateOpaqueRegion(); -+ return true; -+} -+ - void WaylandWindow::SetBoundsDip(const gfx::Rect& bounds_dip) { - SetBounds(gfx::ScaleToRoundedRect(bounds_dip, buffer_scale_)); - } -diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h -index 4233216d7a6f..b8cdc991e30e 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window.h -+++ b/ui/ozone/platform/wayland/host/wayland_window.h -@@ -40,13 +40,16 @@ class WaylandWindow : public PlatformWindow, - public WmMoveResizeHandler, - public WmDragHandler { - public: -- WaylandWindow(PlatformWindowDelegate* delegate, -- WaylandConnection* connection); - ~WaylandWindow() override; - -- static WaylandWindow* FromSurface(wl_surface* surface); -+ // A factory method that can create any of the derived types of WaylandWindow -+ // (WaylandSurface, WaylandPopup and WaylandSubsurface). -+ static std::unique_ptr<WaylandWindow> Create( -+ PlatformWindowDelegate* delegate, -+ WaylandConnection* connection, -+ PlatformWindowInitProperties properties); - -- bool Initialize(PlatformWindowInitProperties properties); -+ static WaylandWindow* FromSurface(wl_surface* surface); - - // Updates the surface buffer scale of the window. Top level windows take - // scale from the output attached to either their current display or the -@@ -168,6 +171,12 @@ class WaylandWindow : public PlatformWindow, - private: - FRIEND_TEST_ALL_PREFIXES(WaylandScreenTest, SetBufferScale); - -+ WaylandWindow(PlatformWindowDelegate* delegate, -+ WaylandConnection* connection); -+ -+ // Initializes the WaylandWindow with supplied properties. -+ bool Initialize(PlatformWindowInitProperties properties); -+ - void SetBoundsDip(const gfx::Rect& bounds_dip); - void SetBufferScale(int32_t scale, bool update_bounds); - -diff --git a/ui/ozone/platform/wayland/host/wayland_window_factory.cc b/ui/ozone/platform/wayland/host/wayland_window_factory.cc -new file mode 100644 -index 000000000000..19da59357d55 ---- /dev/null -+++ b/ui/ozone/platform/wayland/host/wayland_window_factory.cc -@@ -0,0 +1,26 @@ -+// 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.h" -+ -+#include <memory> -+ -+#include "ui/ozone/platform/wayland/host/wayland_window.h" -+ -+namespace ui { -+ -+// static -+std::unique_ptr<WaylandWindow> WaylandWindow::Create( -+ PlatformWindowDelegate* delegate, -+ WaylandConnection* connection, -+ PlatformWindowInitProperties properties) { -+ // TODO(msisov): once WaylandWindow becomes a base class, add switch cases to -+ // create different Wayland windows. -+ std::unique_ptr<WaylandWindow> window( -+ new WaylandWindow(delegate, connection)); -+ return window->Initialize(std::move(properties)) ? std::move(window) -+ : nullptr; -+} -+ -+} // namespace ui -\ No newline at end of file -diff --git a/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc b/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc -index 737c7cdd25d9..64a387723560 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc -+++ b/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc -@@ -36,12 +36,8 @@ class WaylandWindowManagerTest : public WaylandTest { - 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; -+ return WaylandWindow::Create(delegate, connection_.get(), -+ std::move(properties)); - } - - WaylandWindowManager* manager_ = nullptr; -diff --git a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc -index f8dc4429c073..b03a28daadf2 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc -+++ b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc -@@ -150,20 +150,19 @@ class WaylandWindowTest : public WaylandTest { - return result; - } - -- bool CreateWaylandWindowWithParams(PlatformWindowType type, -- gfx::AcceleratedWidget parent_widget, -- const gfx::Rect bounds, -- MockPlatformWindowDelegate* delegate, -- std::unique_ptr<WaylandWindow>* window) { -+ std::unique_ptr<WaylandWindow> CreateWaylandWindowWithParams( -+ PlatformWindowType type, -+ gfx::AcceleratedWidget parent_widget, -+ const gfx::Rect bounds, -+ MockPlatformWindowDelegate* delegate) { - PlatformWindowInitProperties properties; - // TODO(msisov): use a fancy method to calculate position of a popup window. - properties.bounds = bounds; - properties.type = type; - properties.parent_widget = parent_widget; - -- *window = std::make_unique<WaylandWindow>(delegate, connection_.get()); -- -- return (*window)->Initialize(std::move(properties)); -+ return WaylandWindow::Create(delegate, connection_.get(), -+ std::move(properties)); - } - - void InitializeWithSupportedHitTestValues(std::vector<int>* hit_tests) { -@@ -736,27 +735,29 @@ TEST_P(WaylandWindowTest, CanCreateMenuWindow) { - ASSERT_TRUE(connection_->pointer() && connection_->touch()); - window_->SetPointerFocus(true); - -- std::unique_ptr<WaylandWindow> menu_window; -- EXPECT_TRUE(CreateWaylandWindowWithParams( -+ std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams( - PlatformWindowType::kMenu, gfx::kNullAcceleratedWidget, -- gfx::Rect(0, 0, 10, 10), &menu_window_delegate, &menu_window)); -+ gfx::Rect(0, 0, 10, 10), &menu_window_delegate); -+ EXPECT_TRUE(menu_window); - - Sync(); - - window_->SetPointerFocus(false); - window_->set_touch_focus(false); - -- EXPECT_FALSE(CreateWaylandWindowWithParams( -+ menu_window = CreateWaylandWindowWithParams( - PlatformWindowType::kMenu, gfx::kNullAcceleratedWidget, -- gfx::Rect(0, 0, 10, 10), &menu_window_delegate, &menu_window)); -+ gfx::Rect(0, 0, 10, 10), &menu_window_delegate); -+ EXPECT_FALSE(menu_window); - - Sync(); - - window_->set_touch_focus(true); - -- EXPECT_TRUE(CreateWaylandWindowWithParams( -+ menu_window = CreateWaylandWindowWithParams( - PlatformWindowType::kMenu, gfx::kNullAcceleratedWidget, -- gfx::Rect(0, 0, 10, 10), &menu_window_delegate, &menu_window)); -+ gfx::Rect(0, 0, 10, 10), &menu_window_delegate); -+ EXPECT_TRUE(menu_window); - - Sync(); - } -@@ -767,29 +768,30 @@ TEST_P(WaylandWindowTest, CreateAndDestroyNestedMenuWindow) { - EXPECT_CALL(menu_window_delegate, OnAcceleratedWidgetAvailable(_)) - .WillOnce(SaveArg<0>(&menu_window_widget)); - -- std::unique_ptr<WaylandWindow> menu_window; -- EXPECT_TRUE(CreateWaylandWindowWithParams( -+ std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams( - PlatformWindowType::kMenu, widget_, gfx::Rect(0, 0, 10, 10), -- &menu_window_delegate, &menu_window)); -+ &menu_window_delegate); -+ EXPECT_TRUE(menu_window); - ASSERT_NE(menu_window_widget, gfx::kNullAcceleratedWidget); - - Sync(); - - MockPlatformWindowDelegate nested_menu_window_delegate; -- std::unique_ptr<WaylandWindow> nested_menu_window; -- EXPECT_TRUE(CreateWaylandWindowWithParams( -- PlatformWindowType::kMenu, menu_window_widget, gfx::Rect(20, 0, 10, 10), -- &nested_menu_window_delegate, &nested_menu_window)); -+ std::unique_ptr<WaylandWindow> nested_menu_window = -+ CreateWaylandWindowWithParams( -+ PlatformWindowType::kMenu, menu_window_widget, -+ gfx::Rect(20, 0, 10, 10), &nested_menu_window_delegate); -+ EXPECT_TRUE(nested_menu_window); - - Sync(); - } - - TEST_P(WaylandWindowTest, CanDispatchEventToMenuWindowNonNested) { - MockPlatformWindowDelegate menu_window_delegate; -- std::unique_ptr<WaylandWindow> menu_window; -- EXPECT_TRUE(CreateWaylandWindowWithParams( -+ std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams( - PlatformWindowType::kMenu, widget_, gfx::Rect(0, 0, 10, 10), -- &menu_window_delegate, &menu_window)); -+ &menu_window_delegate); -+ EXPECT_TRUE(menu_window); - - wl_seat_send_capabilities(server_.seat()->resource(), - WL_SEAT_CAPABILITY_POINTER); -@@ -812,18 +814,19 @@ TEST_P(WaylandWindowTest, CanDispatchEventToMenuWindowNested) { - EXPECT_CALL(menu_window_delegate, OnAcceleratedWidgetAvailable(_)) - .WillOnce(SaveArg<0>(&menu_window_widget)); - -- std::unique_ptr<WaylandWindow> menu_window; -- EXPECT_TRUE(CreateWaylandWindowWithParams( -+ std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams( - PlatformWindowType::kMenu, widget_, gfx::Rect(0, 0, 10, 10), -- &menu_window_delegate, &menu_window)); -+ &menu_window_delegate); -+ EXPECT_TRUE(menu_window); - - Sync(); - - MockPlatformWindowDelegate nested_menu_window_delegate; -- std::unique_ptr<WaylandWindow> nested_menu_window; -- EXPECT_TRUE(CreateWaylandWindowWithParams( -- PlatformWindowType::kMenu, menu_window_widget, gfx::Rect(20, 0, 10, 10), -- &nested_menu_window_delegate, &nested_menu_window)); -+ std::unique_ptr<WaylandWindow> nested_menu_window = -+ CreateWaylandWindowWithParams( -+ PlatformWindowType::kMenu, menu_window_widget, -+ gfx::Rect(20, 0, 10, 10), &nested_menu_window_delegate); -+ EXPECT_TRUE(nested_menu_window); - - Sync(); - -@@ -903,10 +906,10 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) { - MockPlatformWindowDelegate menu_window_delegate; - gfx::Rect menu_window_bounds(gfx::Point(440, 76), - menu_window_positioner.size); -- std::unique_ptr<WaylandWindow> menu_window; -- EXPECT_TRUE(CreateWaylandWindowWithParams( -+ std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams( - PlatformWindowType::kMenu, toplevel_window->GetWidget(), -- menu_window_bounds, &menu_window_delegate, &menu_window)); -+ menu_window_bounds, &menu_window_delegate); -+ EXPECT_TRUE(menu_window); - - Sync(); - -@@ -924,10 +927,11 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) { - MockPlatformWindowDelegate nested_menu_window_delegate; - gfx::Rect nested_menu_window_bounds(gfx::Point(723, 156), - nested_menu_window_positioner.size); -- std::unique_ptr<WaylandWindow> nested_menu_window; -- EXPECT_TRUE(CreateWaylandWindowWithParams( -- PlatformWindowType::kMenu, menu_window_widget, nested_menu_window_bounds, -- &nested_menu_window_delegate, &nested_menu_window)); -+ std::unique_ptr<WaylandWindow> nested_menu_window = -+ CreateWaylandWindowWithParams( -+ PlatformWindowType::kMenu, menu_window_widget, -+ nested_menu_window_bounds, &nested_menu_window_delegate); -+ EXPECT_TRUE(nested_menu_window); - - Sync(); - -@@ -985,9 +989,10 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) { - // side. Thus, we have to check that anchor rect is correct. - nested_menu_window.reset(); - nested_menu_window_bounds.set_origin({723, 258}); -- EXPECT_TRUE(CreateWaylandWindowWithParams( -+ nested_menu_window = CreateWaylandWindowWithParams( - PlatformWindowType::kMenu, menu_window_widget, nested_menu_window_bounds, -- &nested_menu_window_delegate, &nested_menu_window)); -+ &nested_menu_window_delegate); -+ EXPECT_TRUE(nested_menu_window); - - Sync(); - -@@ -1050,9 +1055,10 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) { - window_->SetBounds(gfx::Rect(0, 0, 2493, 1413)); - - menu_window_bounds.set_origin({2206, 67}); -- EXPECT_TRUE(CreateWaylandWindowWithParams( -+ menu_window = CreateWaylandWindowWithParams( - PlatformWindowType::kMenu, toplevel_window->GetWidget(), -- menu_window_bounds, &menu_window_delegate, &menu_window)); -+ menu_window_bounds, &menu_window_delegate); -+ EXPECT_TRUE(menu_window); - - Sync(); - -@@ -1066,9 +1072,10 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) { - Sync(); - - nested_menu_window_bounds.set_origin({1905, 147}); -- EXPECT_TRUE(CreateWaylandWindowWithParams( -+ nested_menu_window = CreateWaylandWindowWithParams( - PlatformWindowType::kMenu, menu_window_widget, nested_menu_window_bounds, -- &nested_menu_window_delegate, &nested_menu_window)); -+ &nested_menu_window_delegate); -+ EXPECT_TRUE(nested_menu_window); - - Sync(); - -@@ -1096,9 +1103,10 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) { - - nested_menu_window.reset(); - -- EXPECT_TRUE(CreateWaylandWindowWithParams( -+ nested_menu_window = CreateWaylandWindowWithParams( - PlatformWindowType::kMenu, menu_window_widget, nested_menu_window_bounds, -- &nested_menu_window_delegate, &nested_menu_window)); -+ &nested_menu_window_delegate); -+ EXPECT_TRUE(nested_menu_window); - - Sync(); - -@@ -1174,10 +1182,10 @@ TEST_P(WaylandWindowTest, TooltipSimpleParent) { - VerifyAndClearExpectations(); - - gfx::Rect tooltip_window_bounds(gfx::Point(15, 15), gfx::Size(10, 10)); -- std::unique_ptr<WaylandWindow> tooltip_window; -- EXPECT_TRUE(CreateWaylandWindowWithParams( -+ std::unique_ptr<WaylandWindow> tooltip_window = CreateWaylandWindowWithParams( - PlatformWindowType::kTooltip, window_->GetWidget(), tooltip_window_bounds, -- &delegate_, &tooltip_window)); -+ &delegate_); -+ EXPECT_TRUE(tooltip_window); - - window_->SetPointerFocus(true); - -@@ -1199,18 +1207,18 @@ TEST_P(WaylandWindowTest, TooltipNestedParent) { - VerifyAndClearExpectations(); - - gfx::Rect menu_window_bounds(gfx::Point(10, 10), gfx::Size(100, 100)); -- std::unique_ptr<WaylandWindow> menu_window; -- EXPECT_TRUE(CreateWaylandWindowWithParams( -+ std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams( - PlatformWindowType::kMenu, window_->GetWidget(), menu_window_bounds, -- &delegate_, &menu_window)); -+ &delegate_); -+ EXPECT_TRUE(menu_window); - - VerifyAndClearExpectations(); - - gfx::Rect tooltip_window_bounds(gfx::Point(15, 15), gfx::Size(10, 10)); -- std::unique_ptr<WaylandWindow> tooltip_window; -- EXPECT_TRUE(CreateWaylandWindowWithParams( -+ std::unique_ptr<WaylandWindow> tooltip_window = CreateWaylandWindowWithParams( - PlatformWindowType::kTooltip, menu_window->GetWidget(), -- tooltip_window_bounds, &delegate_, &tooltip_window)); -+ tooltip_window_bounds, &delegate_); -+ EXPECT_TRUE(tooltip_window); - - VerifyAndClearExpectations(); - -diff --git a/ui/ozone/platform/wayland/ozone_platform_wayland.cc b/ui/ozone/platform/wayland/ozone_platform_wayland.cc -index 541d9c4848d7..dbf880e9a0c1 100644 ---- a/ui/ozone/platform/wayland/ozone_platform_wayland.cc -+++ b/ui/ozone/platform/wayland/ozone_platform_wayland.cc -@@ -107,10 +107,8 @@ class OzonePlatformWayland : public OzonePlatform { - std::unique_ptr<PlatformWindow> CreatePlatformWindow( - PlatformWindowDelegate* delegate, - PlatformWindowInitProperties properties) override { -- auto window = std::make_unique<WaylandWindow>(delegate, connection_.get()); -- if (!window->Initialize(std::move(properties))) -- return nullptr; -- return std::move(window); -+ return WaylandWindow::Create(delegate, connection_.get(), -+ std::move(properties)); - } - - std::unique_ptr<display::NativeDisplayDelegate> CreateNativeDisplayDelegate() -diff --git a/ui/ozone/platform/wayland/test/wayland_test.cc b/ui/ozone/platform/wayland/test/wayland_test.cc -index 2bd8c38219c1..2543981d8c38 100644 ---- a/ui/ozone/platform/wayland/test/wayland_test.cc -+++ b/ui/ozone/platform/wayland/test/wayland_test.cc -@@ -37,7 +37,6 @@ WaylandTest::WaylandTest() - buffer_manager_gpu_ = std::make_unique<WaylandBufferManagerGpu>(); - surface_factory_ = std::make_unique<WaylandSurfaceFactory>( - connection_.get(), buffer_manager_gpu_.get()); -- window_ = std::make_unique<WaylandWindow>(&delegate_, connection_.get()); - } - - WaylandTest::~WaylandTest() {} -@@ -52,7 +51,8 @@ void WaylandTest::SetUp() { - PlatformWindowInitProperties properties; - properties.bounds = gfx::Rect(0, 0, 800, 600); - properties.type = PlatformWindowType::kWindow; -- ASSERT_TRUE(window_->Initialize(std::move(properties))); -+ window_ = WaylandWindow::Create(&delegate_, connection_.get(), -+ std::move(properties)); - ASSERT_NE(widget_, gfx::kNullAcceleratedWidget); - - // Wait for the client to flush all pending requests from initialization. -diff --git a/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc b/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc -index 21b0c3eefd9b..767f9354f6da 100644 ---- a/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc -+++ b/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc -@@ -189,12 +189,12 @@ class WaylandBufferManagerTest : public WaylandTest { - - std::unique_ptr<WaylandWindow> CreateWindow() { - testing::Mock::VerifyAndClearExpectations(&delegate_); -- auto new_window = -- std::make_unique<WaylandWindow>(&delegate_, connection_.get()); - PlatformWindowInitProperties properties; - properties.bounds = gfx::Rect(0, 0, 800, 600); - properties.type = PlatformWindowType::kWindow; -- EXPECT_TRUE(new_window->Initialize(std::move(properties))); -+ auto new_window = WaylandWindow::Create(&delegate_, connection_.get(), -+ std::move(properties)); -+ EXPECT_TRUE(new_window); - - Sync(); - --- -2.24.1 - diff --git a/0003-ozone-Wayland-move-bounds-translation-util-to-utilit.patch b/0003-ozone-Wayland-move-bounds-translation-util-to-utilit.patch deleted file mode 100644 index 14d5143a81e3..000000000000 --- a/0003-ozone-Wayland-move-bounds-translation-util-to-utilit.patch +++ /dev/null @@ -1,137 +0,0 @@ -From d7680c81c95c4609bf4ffbad05656a09d589a382 Mon Sep 17 00:00:00 2001 -From: Maksim Sisov <msisov@igalia.com> -Date: Fri, 6 Dec 2019 19:49:45 +0000 -Subject: [PATCH 3/9] ozone/Wayland: move bounds translation util to utilities. - -Just moving the translation helper method to utilities. - -Bug: 1028919 -Change-Id: I6e60bcdf804e4aaff9cb39d437e4302af2ed3fd2 -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1953710 -Commit-Queue: Maksim Sisov <msisov@igalia.com> -Reviewed-by: Michael Spang <spang@chromium.org> -Cr-Commit-Position: refs/heads/master@{#722582} ---- - .../platform/wayland/common/wayland_util.cc | 14 ++++++++++ - .../platform/wayland/common/wayland_util.h | 8 ++++++ - .../platform/wayland/host/wayland_window.cc | 27 +++---------------- - 3 files changed, 26 insertions(+), 23 deletions(-) - -diff --git a/ui/ozone/platform/wayland/common/wayland_util.cc b/ui/ozone/platform/wayland/common/wayland_util.cc -index 0201f689e90d..e0430b860adf 100644 ---- a/ui/ozone/platform/wayland/common/wayland_util.cc -+++ b/ui/ozone/platform/wayland/common/wayland_util.cc -@@ -141,4 +141,18 @@ void ReadDataFromFD(base::ScopedFD fd, std::vector<uint8_t>* contents) { - contents->insert(contents->end(), buffer, buffer + length); - } - -+gfx::Rect TranslateBoundsToParentCoordinates(const gfx::Rect& child_bounds, -+ const gfx::Rect& parent_bounds) { -+ return gfx::Rect( -+ (child_bounds.origin() - parent_bounds.origin().OffsetFromOrigin()), -+ child_bounds.size()); -+} -+ -+gfx::Rect TranslateBoundsToTopLevelCoordinates(const gfx::Rect& child_bounds, -+ const gfx::Rect& parent_bounds) { -+ return gfx::Rect( -+ (child_bounds.origin() + parent_bounds.origin().OffsetFromOrigin()), -+ child_bounds.size()); -+} -+ - } // namespace wl -diff --git a/ui/ozone/platform/wayland/common/wayland_util.h b/ui/ozone/platform/wayland/common/wayland_util.h -index 368f3d9a9427..48332e059da0 100644 ---- a/ui/ozone/platform/wayland/common/wayland_util.h -+++ b/ui/ozone/platform/wayland/common/wayland_util.h -@@ -13,6 +13,7 @@ - #include "base/containers/flat_map.h" - #include "base/files/scoped_file.h" - #include "base/macros.h" -+#include "ui/gfx/geometry/rect.h" - #include "ui/ozone/platform/wayland/common/wayland_object.h" - - class SkBitmap; -@@ -50,6 +51,13 @@ bool DrawBitmap(const SkBitmap& bitmap, ui::WaylandShmBuffer* out_buffer); - // Helper function to read data from a file. - void ReadDataFromFD(base::ScopedFD fd, std::vector<uint8_t>* contents); - -+// Translates bounds relative to top level window to specified parent. -+gfx::Rect TranslateBoundsToParentCoordinates(const gfx::Rect& child_bounds, -+ const gfx::Rect& parent_bounds); -+// Translates bounds relative to parent window to top level window. -+gfx::Rect TranslateBoundsToTopLevelCoordinates(const gfx::Rect& child_bounds, -+ const gfx::Rect& parent_bounds); -+ - } // namespace wl - - #endif // UI_OZONE_PLATFORM_WAYLAND_COMMON_WAYLAND_UTIL_H_ -diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc -index da9a4cb368b8..709fb681f7d9 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/common/wayland_util.h" - #include "ui/ozone/platform/wayland/host/shell_object_factory.h" - #include "ui/ozone/platform/wayland/host/shell_popup_wrapper.h" - #include "ui/ozone/platform/wayland/host/shell_surface_wrapper.h" -@@ -28,26 +29,6 @@ - - namespace ui { - --namespace { -- --// Translates bounds relative to top level window to specified parent. --gfx::Rect TranslateBoundsToParentCoordinates(const gfx::Rect& child_bounds, -- const gfx::Rect& parent_bounds) { -- return gfx::Rect(gfx::Point(child_bounds.x() - parent_bounds.x(), -- child_bounds.y() - parent_bounds.y()), -- child_bounds.size()); --} -- --// Translates bounds relative to parent window to top level window. --gfx::Rect TranslateBoundsToTopLevelCoordinates(const gfx::Rect& child_bounds, -- const gfx::Rect& parent_bounds) { -- return gfx::Rect(gfx::Point(child_bounds.x() + parent_bounds.x(), -- child_bounds.y() + parent_bounds.y()), -- child_bounds.size()); --} -- --} // namespace -- - WaylandWindow::WaylandWindow(PlatformWindowDelegate* delegate, - WaylandConnection* connection) - : delegate_(delegate), -@@ -177,7 +158,7 @@ void WaylandWindow::CreateAndShowTooltipSubSurface() { - const auto parent_bounds_dip = - gfx::ScaleToRoundedRect(parent_window->GetBounds(), 1.0 / ui_scale_); - auto new_bounds_dip = -- TranslateBoundsToParentCoordinates(bounds_px_, parent_bounds_dip); -+ wl::TranslateBoundsToParentCoordinates(bounds_px_, parent_bounds_dip); - auto bounds_px = - gfx::ScaleToRoundedRect(new_bounds_dip, ui_scale_ / buffer_scale_); - -@@ -671,7 +652,7 @@ void WaylandWindow::HandlePopupConfigure(const gfx::Rect& bounds_dip) { - // window, which automatically becomes the same as relative to an origin of - // a display. - new_bounds_dip = gfx::ScaleToRoundedRect( -- TranslateBoundsToTopLevelCoordinates( -+ wl::TranslateBoundsToTopLevelCoordinates( - gfx::ScaleToRoundedRect(new_bounds_dip, buffer_scale_), - parent_window_->GetBounds()), - 1.0 / buffer_scale_); -@@ -962,7 +943,7 @@ gfx::Rect WaylandWindow::AdjustPopupWindowPosition() const { - 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); -+ wl::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 --- -2.24.1 - diff --git a/0004-ozone-wayland-Fix-regression-with-hiding-nested-wind.patch b/0004-ozone-wayland-Fix-regression-with-hiding-nested-wind.patch deleted file mode 100644 index 2e6b2a4b770c..000000000000 --- a/0004-ozone-wayland-Fix-regression-with-hiding-nested-wind.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 738a0d76c3102509e052927e49f978b197bc3a3c Mon Sep 17 00:00:00 2001 -From: Maksim Sisov <msisov@igalia.com> -Date: Fri, 6 Dec 2019 19:19:30 +0000 -Subject: [PATCH 4/9] ozone/wayland: Fix regression with hiding nested windows. - -It must be non-tooltip that closes children windows. - -Bug: 1028046 -Change-Id: I9b5212873cb2c1a4179a28e915edd5fe84b29c5e -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1954483 -Reviewed-by: Michael Spang <spang@chromium.org> -Commit-Queue: Maksim Sisov <msisov@igalia.com> -Cr-Commit-Position: refs/heads/master@{#722560} ---- - ui/ozone/platform/wayland/host/wayland_window.cc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc -index 709fb681f7d9..1f8cc423d4aa 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window.cc -+++ b/ui/ozone/platform/wayland/host/wayland_window.cc -@@ -247,7 +247,7 @@ void WaylandWindow::Show(bool inactive) { - } - - void WaylandWindow::Hide() { -- if (!is_tooltip_) { -+ if (is_tooltip_) { - tooltip_subsurface_.reset(); - } else { - if (child_window_) --- -2.24.1 - diff --git a/0005-ozone-Wayland-extract-toplevel-surface-methods-into-.patch b/0005-ozone-Wayland-extract-toplevel-surface-methods-into-.patch deleted file mode 100644 index 2307bfec56ac..000000000000 --- a/0005-ozone-Wayland-extract-toplevel-surface-methods-into-.patch +++ /dev/null @@ -1,1424 +0,0 @@ -From 0bbc15f0d57b4bcbd389776b3bee492a75fd60a5 Mon Sep 17 00:00:00 2001 -From: Maksim Sisov <msisov@igalia.com> -Date: Fri, 6 Dec 2019 20:31:04 +0000 -Subject: [PATCH 5/9] ozone/Wayland: extract toplevel surface methods into - WaylandSurface. - -WaylandWindow handles too many things and confuses developers that -are not familiar with it. To make things better, extract -surface methods into WaylandSurface. - -This change does not bring any functional changes except removed -is_active() method that was only used by tests. Instead, tests -just rely on the PlatformWindowDelegate::OnActivationChanged calls. - -Test: ozone_unittests -Bug: 1028919 -Change-Id: Ia58577f86d8e31ec93b113d887b34166fbe19cf0 -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1954478 -Commit-Queue: Maksim Sisov <msisov@igalia.com> -Reviewed-by: Michael Spang <spang@chromium.org> -Cr-Commit-Position: refs/heads/master@{#722592} ---- - ui/ozone/platform/wayland/BUILD.gn | 2 + - .../platform/wayland/host/wayland_surface.cc | 348 ++++++++++++++++++ - .../platform/wayland/host/wayland_surface.h | 114 ++++++ - .../platform/wayland/host/wayland_window.cc | 346 ++--------------- - .../platform/wayland/host/wayland_window.h | 110 ++---- - .../wayland/host/wayland_window_factory.cc | 31 +- - .../wayland/host/wayland_window_unittest.cc | 14 +- - .../wayland/host/xdg_popup_wrapper_impl.cc | 9 +- - 8 files changed, 572 insertions(+), 402 deletions(-) - create mode 100644 ui/ozone/platform/wayland/host/wayland_surface.cc - create mode 100644 ui/ozone/platform/wayland/host/wayland_surface.h - -diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn -index a9c0302f162f..b6059c7d9962 100644 ---- a/ui/ozone/platform/wayland/BUILD.gn -+++ b/ui/ozone/platform/wayland/BUILD.gn -@@ -91,6 +91,8 @@ source_set("wayland") { - "host/wayland_shm.h", - "host/wayland_shm_buffer.cc", - "host/wayland_shm_buffer.h", -+ "host/wayland_surface.cc", -+ "host/wayland_surface.h", - "host/wayland_touch.cc", - "host/wayland_touch.h", - "host/wayland_window.cc", -diff --git a/ui/ozone/platform/wayland/host/wayland_surface.cc b/ui/ozone/platform/wayland/host/wayland_surface.cc -new file mode 100644 -index 000000000000..cfd4349db885 ---- /dev/null -+++ b/ui/ozone/platform/wayland/host/wayland_surface.cc -@@ -0,0 +1,348 @@ -+// 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_surface.h" -+ -+#include "ui/base/dragdrop/drag_drop_types.h" -+#include "ui/base/dragdrop/os_exchange_data.h" -+#include "ui/base/hit_test.h" -+#include "ui/gfx/native_widget_types.h" -+#include "ui/ozone/platform/wayland/host/shell_object_factory.h" -+#include "ui/ozone/platform/wayland/host/shell_surface_wrapper.h" -+#include "ui/ozone/platform/wayland/host/wayland_connection.h" -+#include "ui/platform_window/platform_window_handler/wm_drop_handler.h" -+ -+namespace ui { -+ -+WaylandSurface::WaylandSurface(PlatformWindowDelegate* delegate, -+ WaylandConnection* connection) -+ : WaylandWindow(delegate, connection), -+ state_(PlatformWindowState::kNormal), -+ pending_state_(PlatformWindowState::kUnknown) { -+ // Set a class property key, which allows |this| to be used for interactive -+ // events, e.g. move or resize. -+ SetWmMoveResizeHandler(this, AsWmMoveResizeHandler()); -+ -+ // Set a class property key, which allows |this| to be used for drag action. -+ SetWmDragHandler(this, this); -+} -+ -+WaylandSurface::~WaylandSurface() { -+ if (drag_closed_callback_) { -+ std::move(drag_closed_callback_) -+ .Run(DragDropTypes::DragOperation::DRAG_NONE); -+ } -+} -+ -+void WaylandSurface::CreateShellSurface() { -+ ShellObjectFactory factory; -+ shell_surface_ = factory.CreateShellSurfaceWrapper(connection(), this); -+ if (!shell_surface_) -+ CHECK(false) << "Failed to initialize Wayland shell surface"; -+} -+ -+void WaylandSurface::ApplyPendingBounds() { -+ if (pending_bounds_dip_.IsEmpty()) -+ return; -+ DCHECK(shell_surface_); -+ -+ SetBoundsDip(pending_bounds_dip_); -+ shell_surface_->SetWindowGeometry(pending_bounds_dip_); -+ pending_bounds_dip_ = gfx::Rect(); -+ connection()->ScheduleFlush(); -+} -+ -+void WaylandSurface::DispatchHostWindowDragMovement( -+ int hittest, -+ const gfx::Point& pointer_location_in_px) { -+ DCHECK(shell_surface_); -+ -+ connection()->ResetPointerFlags(); -+ if (hittest == HTCAPTION) -+ shell_surface_->SurfaceMove(connection()); -+ else -+ shell_surface_->SurfaceResize(connection(), hittest); -+ -+ connection()->ScheduleFlush(); -+} -+ -+void WaylandSurface::StartDrag(const ui::OSExchangeData& data, -+ int operation, -+ gfx::NativeCursor cursor, -+ base::OnceCallback<void(int)> callback) { -+ DCHECK(!drag_closed_callback_); -+ drag_closed_callback_ = std::move(callback); -+ connection()->StartDrag(data, operation); -+} -+ -+void WaylandSurface::Show(bool inactive) { -+ set_keyboard_focus(true); -+ // TODO(msisov): recreate |shell_surface_| on show calls. -+} -+ -+void WaylandSurface::Hide() { -+ // TODO(msisov): destroy |shell_surface_| on hide calls. -+} -+ -+bool WaylandSurface::IsVisible() const { -+ // X and Windows return true if the window is minimized. For consistency, do -+ // the same. -+ return !!shell_surface_ || IsMinimized(); -+} -+ -+void WaylandSurface::SetTitle(const base::string16& title) { -+ DCHECK(shell_surface_); -+ shell_surface_->SetTitle(title); -+ connection()->ScheduleFlush(); -+} -+ -+void WaylandSurface::ToggleFullscreen() { -+ DCHECK(shell_surface_); -+ -+ // There are some cases, when Chromium triggers a fullscreen state change -+ // before the surface is activated. In such cases, Wayland may ignore state -+ // changes and such flags as --kiosk or --start-fullscreen will be ignored. -+ // To overcome this, set a pending state, and once the surface is activated, -+ // trigger the change. -+ if (!is_active_) { -+ DCHECK(!IsFullscreen()); -+ pending_state_ = PlatformWindowState::kFullScreen; -+ return; -+ } -+ -+ // TODO(msisov, tonikitoo): add multiscreen support. As the documentation says -+ // if shell_surface_set_fullscreen() is not provided with wl_output, it's up -+ // to the compositor to choose which display will be used to map this surface. -+ if (!IsFullscreen()) { -+ // Fullscreen state changes have to be handled manually and then checked -+ // against configuration events, which come from a compositor. The reason -+ // of manually changing the |state_| is that the compositor answers about -+ // state changes asynchronously, which leads to a wrong return value in -+ // DesktopWindowTreeHostPlatform::IsFullscreen, for example, and media -+ // files can never be set to fullscreen. -+ state_ = PlatformWindowState::kFullScreen; -+ shell_surface_->SetFullscreen(); -+ } else { -+ // Check the comment above. If it's not handled synchronously, media files -+ // may not leave the fullscreen mode. -+ state_ = PlatformWindowState::kUnknown; -+ shell_surface_->UnSetFullscreen(); -+ } -+ -+ connection()->ScheduleFlush(); -+} -+ -+void WaylandSurface::Maximize() { -+ DCHECK(shell_surface_); -+ -+ if (IsFullscreen()) -+ ToggleFullscreen(); -+ -+ shell_surface_->SetMaximized(); -+ connection()->ScheduleFlush(); -+} -+ -+void WaylandSurface::Minimize() { -+ DCHECK(shell_surface_); -+ DCHECK(!is_minimizing_); -+ // Wayland doesn't explicitly say if a window is minimized. Instead, it -+ // notifies that the window is not activated. But there are many cases, when -+ // the window is not minimized and deactivated. In order to properly record -+ // the minimized state, mark this window as being minimized. And as soon as a -+ // configuration event comes, check if the window has been deactivated and has -+ // |is_minimizing_| set. -+ is_minimizing_ = true; -+ shell_surface_->SetMinimized(); -+ connection()->ScheduleFlush(); -+} -+ -+void WaylandSurface::Restore() { -+ DCHECK(shell_surface_); -+ -+ // Unfullscreen the window if it is fullscreen. -+ if (IsFullscreen()) -+ ToggleFullscreen(); -+ -+ shell_surface_->UnSetMaximized(); -+ connection()->ScheduleFlush(); -+} -+ -+PlatformWindowState WaylandSurface::GetPlatformWindowState() const { -+ return state_; -+} -+ -+void WaylandSurface::SizeConstraintsChanged() { -+ // Size constraints only make sense for normal windows. -+ if (!shell_surface_) -+ return; -+ -+ DCHECK(delegate()); -+ auto min_size = delegate()->GetMinimumSizeForWindow(); -+ auto max_size = delegate()->GetMaximumSizeForWindow(); -+ -+ if (min_size.has_value()) -+ shell_surface_->SetMinSize(min_size->width(), min_size->height()); -+ if (max_size.has_value()) -+ shell_surface_->SetMaxSize(max_size->width(), max_size->height()); -+ -+ connection()->ScheduleFlush(); -+} -+ -+void WaylandSurface::HandleSurfaceConfigure(int32_t width, -+ int32_t height, -+ bool is_maximized, -+ bool is_fullscreen, -+ bool is_activated) { -+ // Propagate the window state information to the client. -+ PlatformWindowState old_state = state_; -+ -+ // Ensure that manually handled state changes to fullscreen correspond to the -+ // configuration events from a compositor. -+ DCHECK_EQ(is_fullscreen, IsFullscreen()); -+ -+ // There are two cases, which must be handled for the minimized state. -+ // The first one is the case, when the surface goes into the minimized state -+ // (check comment in WaylandSurface::Minimize), and the second case is when -+ // the surface still has been minimized, but another configuration event with -+ // !is_activated comes. For this, check if the WaylandSurface has been -+ // minimized before and !is_activated is sent. -+ if ((is_minimizing_ || IsMinimized()) && !is_activated) { -+ is_minimizing_ = false; -+ state_ = PlatformWindowState::kMinimized; -+ } else if (is_fullscreen) { -+ // To ensure the |delegate()| is notified about state changes to fullscreen, -+ // assume the old_state is UNKNOWN (check comment in ToggleFullscreen). -+ old_state = PlatformWindowState::kUnknown; -+ DCHECK(state_ == PlatformWindowState::kFullScreen); -+ } else if (is_maximized) { -+ state_ = PlatformWindowState::kMaximized; -+ } else { -+ state_ = PlatformWindowState::kNormal; -+ } -+ const bool state_changed = old_state != state_; -+ const bool is_normal = !IsFullscreen() && !IsMaximized(); -+ -+ // Update state before notifying delegate. -+ const bool did_active_change = is_active_ != is_activated; -+ is_active_ = is_activated; -+ -+ // Rather than call SetBounds here for every configure event, just save the -+ // most recent bounds, and have WaylandConnection call ApplyPendingBounds -+ // when it has finished processing events. We may get many configure events -+ // in a row during an interactive resize, and only the last one matters. -+ // -+ // Width or height set to 0 means that we should decide on width and height by -+ // ourselves, but we don't want to set them to anything else. Use restored -+ // bounds size or the current bounds iff the current state is normal (neither -+ // maximized nor fullscreen). -+ // -+ // Note: if the browser was started with --start-fullscreen and a user exits -+ // the fullscreen mode, wayland may set the width and height to be 1. Instead, -+ // explicitly set the bounds to the current desired ones or the previous -+ // bounds. -+ if (width > 1 && height > 1) { -+ pending_bounds_dip_ = gfx::Rect(0, 0, width, height); -+ } else if (is_normal) { -+ pending_bounds_dip_.set_size( -+ gfx::ScaleToRoundedSize(GetRestoredBoundsInPixels().IsEmpty() -+ ? GetBounds().size() -+ : GetRestoredBoundsInPixels().size(), -+ -+ 1.0 / buffer_scale())); -+ } -+ -+ if (state_changed) { -+ // The |restored_bounds_| are used when the window gets back to normal -+ // state after it went maximized or fullscreen. So we reset these if the -+ // window has just become normal and store the current bounds if it is -+ // either going out of normal state or simply changes the state and we don't -+ // have any meaningful value stored. -+ if (is_normal) { -+ SetRestoredBoundsInPixels({}); -+ } else if (old_state == PlatformWindowState::kNormal || -+ GetRestoredBoundsInPixels().IsEmpty()) { -+ SetRestoredBoundsInPixels(GetBounds()); -+ } -+ -+ delegate()->OnWindowStateChanged(state_); -+ } -+ -+ ApplyPendingBounds(); -+ -+ if (did_active_change) -+ delegate()->OnActivationChanged(is_active_); -+ -+ MaybeTriggerPendingStateChange(); -+} -+ -+void WaylandSurface::OnDragEnter(const gfx::PointF& point, -+ std::unique_ptr<OSExchangeData> data, -+ int operation) { -+ WmDropHandler* drop_handler = GetWmDropHandler(*this); -+ if (!drop_handler) -+ return; -+ drop_handler->OnDragEnter(point, std::move(data), operation); -+} -+ -+int WaylandSurface::OnDragMotion(const gfx::PointF& point, -+ uint32_t time, -+ int operation) { -+ WmDropHandler* drop_handler = GetWmDropHandler(*this); -+ if (!drop_handler) -+ return 0; -+ -+ return drop_handler->OnDragMotion(point, operation); -+} -+ -+void WaylandSurface::OnDragDrop(std::unique_ptr<OSExchangeData> data) { -+ WmDropHandler* drop_handler = GetWmDropHandler(*this); -+ if (!drop_handler) -+ return; -+ drop_handler->OnDragDrop(std::move(data)); -+} -+ -+void WaylandSurface::OnDragLeave() { -+ WmDropHandler* drop_handler = GetWmDropHandler(*this); -+ if (!drop_handler) -+ return; -+ drop_handler->OnDragLeave(); -+} -+ -+void WaylandSurface::OnDragSessionClose(uint32_t dnd_action) { -+ std::move(drag_closed_callback_).Run(dnd_action); -+ connection()->ResetPointerFlags(); -+} -+ -+bool WaylandSurface::OnInitialize(PlatformWindowInitProperties properties) { -+ CreateShellSurface(); -+ if (shell_surface_ && !properties.wm_class_class.empty()) -+ shell_surface_->SetAppId(properties.wm_class_class); -+ return !!shell_surface_; -+} -+ -+bool WaylandSurface::IsMinimized() const { -+ return state_ == PlatformWindowState::kMinimized; -+} -+ -+bool WaylandSurface::IsMaximized() const { -+ return state_ == PlatformWindowState::kMaximized; -+} -+ -+bool WaylandSurface::IsFullscreen() const { -+ return state_ == PlatformWindowState::kFullScreen; -+} -+ -+void WaylandSurface::MaybeTriggerPendingStateChange() { -+ if (pending_state_ == PlatformWindowState::kUnknown || !is_active_) -+ return; -+ DCHECK_EQ(pending_state_, PlatformWindowState::kFullScreen); -+ pending_state_ = PlatformWindowState::kUnknown; -+ ToggleFullscreen(); -+} -+ -+WmMoveResizeHandler* WaylandSurface::AsWmMoveResizeHandler() { -+ return static_cast<WmMoveResizeHandler*>(this); -+} -+ -+} // namespace ui -diff --git a/ui/ozone/platform/wayland/host/wayland_surface.h b/ui/ozone/platform/wayland/host/wayland_surface.h -new file mode 100644 -index 000000000000..0f7204db3c48 ---- /dev/null -+++ b/ui/ozone/platform/wayland/host/wayland_surface.h -@@ -0,0 +1,114 @@ -+// 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_SURFACE_H_ -+#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SURFACE_H_ -+ -+#include "ui/ozone/platform/wayland/host/wayland_window.h" -+ -+#include "ui/platform_window/platform_window_handler/wm_drag_handler.h" -+#include "ui/platform_window/platform_window_handler/wm_move_resize_handler.h" -+ -+namespace ui { -+ -+class ShellSurfaceWrapper; -+ -+class WaylandSurface : public WaylandWindow, -+ public WmMoveResizeHandler, -+ public WmDragHandler { -+ public: -+ WaylandSurface(PlatformWindowDelegate* delegate, -+ WaylandConnection* connection); -+ ~WaylandSurface() override; -+ -+ ShellSurfaceWrapper* shell_surface() const { return shell_surface_.get(); } -+ -+ // Apply the bounds specified in the most recent configure event. This should -+ // be called after processing all pending events in the wayland connection. -+ void ApplyPendingBounds(); -+ -+ // WmMoveResizeHandler -+ void DispatchHostWindowDragMovement( -+ int hittest, -+ const gfx::Point& pointer_location_in_px) override; -+ -+ // WmDragHandler -+ void StartDrag(const ui::OSExchangeData& data, -+ int operation, -+ gfx::NativeCursor cursor, -+ base::OnceCallback<void(int)> callback) override; -+ -+ // PlatformWindow -+ void Show(bool inactive) override; -+ void Hide() override; -+ bool IsVisible() const override; -+ void SetTitle(const base::string16& title) override; -+ void ToggleFullscreen() override; -+ void Maximize() override; -+ void Minimize() override; -+ void Restore() override; -+ PlatformWindowState GetPlatformWindowState() const override; -+ void SizeConstraintsChanged() override; -+ -+ private: -+ // WaylandWindow overrides: -+ void HandleSurfaceConfigure(int32_t widht, -+ int32_t height, -+ bool is_maximized, -+ bool is_fullscreen, -+ bool is_activated) override; -+ void OnDragEnter(const gfx::PointF& point, -+ std::unique_ptr<OSExchangeData> data, -+ int operation) override; -+ int OnDragMotion(const gfx::PointF& point, -+ uint32_t time, -+ int operation) override; -+ void OnDragDrop(std::unique_ptr<OSExchangeData> data) override; -+ void OnDragLeave() override; -+ void OnDragSessionClose(uint32_t dnd_action) override; -+ bool OnInitialize(PlatformWindowInitProperties properties) override; -+ -+ bool IsMinimized() const; -+ bool IsMaximized() const; -+ bool IsFullscreen() const; -+ -+ void MaybeTriggerPendingStateChange(); -+ -+ // Creates a surface window, which is visible as a main window. -+ void CreateShellSurface(); -+ -+ WmMoveResizeHandler* AsWmMoveResizeHandler(); -+ -+ // Wrappers around shell surface. -+ std::unique_ptr<ShellSurfaceWrapper> shell_surface_; -+ -+ base::OnceCallback<void(int)> drag_closed_callback_; -+ -+ // These bounds attributes below have suffices that indicate units used. -+ // Wayland operates in DIP but the platform operates in physical pixels so -+ // our WaylandSurface is the link that has to translate the units. See also -+ // comments in the implementation. -+ // -+ // Bounds that will be applied when the window state is finalized. The window -+ // may get several configuration events that update the pending bounds, and -+ // only upon finalizing the state is the latest value stored as the current -+ // bounds via |ApplyPendingBounds|. Measured in DIP because updated in the -+ // handler that receives DIP from Wayland. -+ gfx::Rect pending_bounds_dip_; -+ -+ // Stores current states of the window. -+ PlatformWindowState state_; -+ // Stores a pending state of the window, which is used before the surface is -+ // activated. -+ PlatformWindowState pending_state_; -+ -+ bool is_active_ = false; -+ bool is_minimizing_ = false; -+ -+ DISALLOW_COPY_AND_ASSIGN(WaylandSurface); -+}; -+ -+} // namespace ui -+ -+#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SURFACE_H_ -diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc -index 1f8cc423d4aa..cdc95f904347 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window.cc -+++ b/ui/ozone/platform/wayland/host/wayland_window.cc -@@ -9,9 +9,6 @@ - - #include "base/bind.h" - #include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h" --#include "ui/base/dragdrop/drag_drop_types.h" --#include "ui/base/dragdrop/os_exchange_data.h" --#include "ui/base/hit_test.h" - #include "ui/events/event.h" - #include "ui/events/event_utils.h" - #include "ui/events/ozone/events_ozone.h" -@@ -19,36 +16,19 @@ - #include "ui/ozone/platform/wayland/common/wayland_util.h" - #include "ui/ozone/platform/wayland/host/shell_object_factory.h" - #include "ui/ozone/platform/wayland/host/shell_popup_wrapper.h" --#include "ui/ozone/platform/wayland/host/shell_surface_wrapper.h" - #include "ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h" - #include "ui/ozone/platform/wayland/host/wayland_connection.h" - #include "ui/ozone/platform/wayland/host/wayland_cursor_position.h" - #include "ui/ozone/platform/wayland/host/wayland_output_manager.h" - #include "ui/ozone/platform/wayland/host/wayland_pointer.h" --#include "ui/platform_window/platform_window_handler/wm_drop_handler.h" - - namespace ui { - - WaylandWindow::WaylandWindow(PlatformWindowDelegate* delegate, - WaylandConnection* connection) -- : delegate_(delegate), -- connection_(connection), -- state_(PlatformWindowState::kNormal), -- pending_state_(PlatformWindowState::kUnknown) { -- // Set a class property key, which allows |this| to be used for interactive -- // events, e.g. move or resize. -- SetWmMoveResizeHandler(this, AsWmMoveResizeHandler()); -- -- // Set a class property key, which allows |this| to be used for drag action. -- SetWmDragHandler(this, this); --} -+ : delegate_(delegate), connection_(connection) {} - - WaylandWindow::~WaylandWindow() { -- if (drag_closed_callback_) { -- std::move(drag_closed_callback_) -- .Run(DragDropTypes::DragOperation::DRAG_NONE); -- } -- - PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); - if (surface_) - connection_->wayland_window_manager()->RemoveWindow(GetWidget()); -@@ -127,13 +107,6 @@ void WaylandWindow::CreateShellPopup() { - parent_window_->set_child_window(this); - } - --void WaylandWindow::CreateShellSurface() { -- ShellObjectFactory factory; -- shell_surface_ = factory.CreateShellSurfaceWrapper(connection_, this); -- if (!shell_surface_) -- CHECK(false) << "Failed to initialize Wayland shell surface"; --} -- - 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. -@@ -172,21 +145,6 @@ void WaylandWindow::CreateAndShowTooltipSubSurface() { - connection_->ScheduleFlush(); - } - --void WaylandWindow::ApplyPendingBounds() { -- if (pending_bounds_dip_.IsEmpty()) -- return; -- DCHECK(shell_surface_); -- -- SetBoundsDip(pending_bounds_dip_); -- shell_surface_->SetWindowGeometry(pending_bounds_dip_); -- pending_bounds_dip_ = gfx::Rect(); -- connection_->ScheduleFlush(); -- -- // Opaque region is based on the size of the window. Thus, update the region -- // on each update. -- MaybeUpdateOpaqueRegion(); --} -- - void WaylandWindow::SetPointerFocus(bool focus) { - has_pointer_focus_ = focus; - -@@ -197,36 +155,10 @@ void WaylandWindow::SetPointerFocus(bool focus) { - connection_->SetCursorBitmap(bitmap_->bitmaps(), bitmap_->hotspot()); - } - --void WaylandWindow::DispatchHostWindowDragMovement( -- int hittest, -- const gfx::Point& pointer_location_in_px) { -- DCHECK(shell_surface_); -- -- connection_->ResetPointerFlags(); -- if (hittest == HTCAPTION) -- shell_surface_->SurfaceMove(connection_); -- else -- shell_surface_->SurfaceResize(connection_, hittest); -- -- connection_->ScheduleFlush(); --} -- --void WaylandWindow::StartDrag(const ui::OSExchangeData& data, -- int operation, -- gfx::NativeCursor cursor, -- base::OnceCallback<void(int)> callback) { -- DCHECK(!drag_closed_callback_); -- drag_closed_callback_ = std::move(callback); -- connection_->StartDrag(data, operation); --} -- - void WaylandWindow::Show(bool inactive) { - if (!is_tooltip_) // Tooltip windows should not get keyboard focus - set_keyboard_focus(true); - -- if (shell_surface_) -- return; -- - if (is_tooltip_) { - CreateAndShowTooltipSubSurface(); - return; -@@ -260,8 +192,7 @@ void WaylandWindow::Hide() { - - // Detach buffer from surface in order to completely shutdown popups and - // tooltips, and release resources. -- if (!shell_surface()) -- connection_->buffer_manager_host()->ResetSurfaceContents(GetWidget()); -+ connection_->buffer_manager_host()->ResetSurfaceContents(GetWidget()); - } - - void WaylandWindow::Close() { -@@ -269,9 +200,7 @@ void WaylandWindow::Close() { - } - - bool WaylandWindow::IsVisible() const { -- // X and Windows return true if the window is minimized. For consistency, do -- // the same. -- return (!!shell_surface_ || !!shell_popup_) || IsMinimized(); -+ return !!shell_popup_; - } - - void WaylandWindow::PrepareForShutdown() {} -@@ -281,6 +210,10 @@ void WaylandWindow::SetBounds(const gfx::Rect& bounds_px) { - return; - bounds_px_ = bounds_px; - -+ // Opaque region is based on the size of the window. Thus, update the region -+ // on each update. -+ MaybeUpdateOpaqueRegion(); -+ - delegate_->OnBoundsChanged(bounds_px_); - } - -@@ -288,11 +221,7 @@ gfx::Rect WaylandWindow::GetBounds() { - return bounds_px_; - } - --void WaylandWindow::SetTitle(const base::string16& title) { -- DCHECK(shell_surface_); -- shell_surface_->SetTitle(title); -- connection_->ScheduleFlush(); --} -+void WaylandWindow::SetTitle(const base::string16& title) {} - - void WaylandWindow::SetCapture() { - // Wayland does implicit grabs, and doesn't allow for explicit grabs. The -@@ -309,79 +238,18 @@ bool WaylandWindow::HasCapture() const { - return shell_popup() ? true : has_implicit_grab_; - } - --void WaylandWindow::ToggleFullscreen() { -- DCHECK(shell_surface_); -+void WaylandWindow::ToggleFullscreen() {} - -- // There are some cases, when Chromium triggers a fullscreen state change -- // before the surface is activated. In such cases, Wayland may ignore state -- // changes and such flags as --kiosk or --start-fullscreen will be ignored. -- // To overcome this, set a pending state, and once the surface is activated, -- // trigger the change. -- if (!is_active_) { -- DCHECK(!IsFullscreen()); -- pending_state_ = PlatformWindowState::kFullScreen; -- return; -- } -- -- // TODO(msisov, tonikitoo): add multiscreen support. As the documentation says -- // if shell_surface_set_fullscreen() is not provided with wl_output, it's up -- // to the compositor to choose which display will be used to map this surface. -- if (!IsFullscreen()) { -- // Fullscreen state changes have to be handled manually and then checked -- // against configuration events, which come from a compositor. The reason -- // of manually changing the |state_| is that the compositor answers about -- // state changes asynchronously, which leads to a wrong return value in -- // DesktopWindowTreeHostPlatform::IsFullscreen, for example, and media -- // files can never be set to fullscreen. -- state_ = PlatformWindowState::kFullScreen; -- shell_surface_->SetFullscreen(); -- } else { -- // Check the comment above. If it's not handled synchronously, media files -- // may not leave the fullscreen mode. -- state_ = PlatformWindowState::kUnknown; -- shell_surface_->UnSetFullscreen(); -- } -- -- connection_->ScheduleFlush(); --} -+void WaylandWindow::Maximize() {} - --void WaylandWindow::Maximize() { -- DCHECK(shell_surface_); -+void WaylandWindow::Minimize() {} - -- if (IsFullscreen()) -- ToggleFullscreen(); -- -- shell_surface_->SetMaximized(); -- connection_->ScheduleFlush(); --} -- --void WaylandWindow::Minimize() { -- DCHECK(shell_surface_); -- DCHECK(!is_minimizing_); -- // Wayland doesn't explicitly say if a window is minimized. Instead, it -- // notifies that the window is not activated. But there are many cases, when -- // the window is not minimized and deactivated. In order to properly record -- // the minimized state, mark this window as being minimized. And as soon as a -- // configuration event comes, check if the window has been deactivated and has -- // |is_minimizing_| set. -- is_minimizing_ = true; -- shell_surface_->SetMinimized(); -- connection_->ScheduleFlush(); --} -- --void WaylandWindow::Restore() { -- DCHECK(shell_surface_); -- -- // Unfullscreen the window if it is fullscreen. -- if (IsFullscreen()) -- ToggleFullscreen(); -- -- shell_surface_->UnSetMaximized(); -- connection_->ScheduleFlush(); --} -+void WaylandWindow::Restore() {} - - PlatformWindowState WaylandWindow::GetPlatformWindowState() const { -- return state_; -+ // Remove normal state for all the other types of windows as it's only the -+ // WaylandSurface that supports state changes. -+ return PlatformWindowState::kNormal; - } - - void WaylandWindow::Activate() { -@@ -448,22 +316,7 @@ void WaylandWindow::SetWindowIcons(const gfx::ImageSkia& window_icon, - NOTIMPLEMENTED_LOG_ONCE(); - } - --void WaylandWindow::SizeConstraintsChanged() { -- // Size constraints only make sense for normal windows. -- if (!shell_surface_) -- return; -- -- DCHECK(delegate_); -- auto min_size = delegate_->GetMinimumSizeForWindow(); -- auto max_size = delegate_->GetMaximumSizeForWindow(); -- -- if (min_size.has_value()) -- shell_surface_->SetMinSize(min_size->width(), min_size->height()); -- if (max_size.has_value()) -- shell_surface_->SetMaxSize(max_size->width(), max_size->height()); -- -- connection_->ScheduleFlush(); --} -+void WaylandWindow::SizeConstraintsChanged() {} - - bool WaylandWindow::CanDispatchEvent(const PlatformEvent& event) { - // This window is a nested popup window, all the events must be forwarded -@@ -508,7 +361,7 @@ uint32_t WaylandWindow::DispatchEvent(const PlatformEvent& native_event) { - if (event->IsLocatedEvent() && shell_popup()) { - // Parent window of the main menu window is not a popup, but rather an - // xdg surface. -- DCHECK(!parent_window_->shell_popup() && parent_window_->shell_surface()); -+ DCHECK(!parent_window_->shell_popup() || !parent_window_->is_tooltip_); - auto* window = - connection_->wayland_window_manager()->GetCurrentFocusedWindow(); - if (window) { -@@ -524,92 +377,13 @@ uint32_t WaylandWindow::DispatchEvent(const PlatformEvent& native_event) { - return POST_DISPATCH_STOP_PROPAGATION; - } - --void WaylandWindow::HandleSurfaceConfigure(int32_t width, -+void WaylandWindow::HandleSurfaceConfigure(int32_t widht, - int32_t height, - bool is_maximized, - bool is_fullscreen, - bool is_activated) { -- DCHECK(!shell_popup()); -- -- // Propagate the window state information to the client. -- PlatformWindowState old_state = state_; -- -- // Ensure that manually handled state changes to fullscreen correspond to the -- // configuration events from a compositor. -- DCHECK_EQ(is_fullscreen, IsFullscreen()); -- -- // There are two cases, which must be handled for the minimized state. -- // The first one is the case, when the surface goes into the minimized state -- // (check comment in WaylandWindow::Minimize), and the second case is when the -- // surface still has been minimized, but another cofiguration event with -- // !is_activated comes. For this, check if the WaylandWindow has been -- // minimized before and !is_activated is sent. -- if ((is_minimizing_ || IsMinimized()) && !is_activated) { -- is_minimizing_ = false; -- state_ = PlatformWindowState::kMinimized; -- } else if (is_fullscreen) { -- // To ensure the |delegate_| is notified about state changes to fullscreen, -- // assume the old_state is UNKNOWN (check comment in ToggleFullscreen). -- old_state = PlatformWindowState::kUnknown; -- DCHECK(state_ == PlatformWindowState::kFullScreen); -- } else if (is_maximized) { -- state_ = PlatformWindowState::kMaximized; -- } else { -- state_ = PlatformWindowState::kNormal; -- } -- const bool state_changed = old_state != state_; -- const bool is_normal = !IsFullscreen() && !IsMaximized(); -- -- // Update state before notifying delegate. -- const bool did_active_change = is_active_ != is_activated; -- is_active_ = is_activated; -- -- // Rather than call SetBounds here for every configure event, just save the -- // most recent bounds, and have WaylandConnection call ApplyPendingBounds -- // when it has finished processing events. We may get many configure events -- // in a row during an interactive resize, and only the last one matters. -- // -- // Width or height set to 0 means that we should decide on width and height by -- // ourselves, but we don't want to set them to anything else. Use restored -- // bounds size or the current bounds iff the current state is normal (neither -- // maximized nor fullscreen). -- // -- // Note: if the browser was started with --start-fullscreen and a user exits -- // the fullscreen mode, wayland may set the width and height to be 1. Instead, -- // explicitly set the bounds to the current desired ones or the previous -- // bounds. -- if (width > 1 && height > 1) { -- pending_bounds_dip_ = gfx::Rect(0, 0, width, height); -- } else if (is_normal) { -- pending_bounds_dip_.set_size(gfx::ScaleToRoundedSize( -- restored_bounds_px_.IsEmpty() ? GetBounds().size() -- : restored_bounds_px_.size(), -- -- 1.0 / buffer_scale_)); -- } -- -- if (state_changed) { -- // The |restored_bounds_| are used when the window gets back to normal -- // state after it went maximized or fullscreen. So we reset these if the -- // window has just become normal and store the current bounds if it is -- // either going out of normal state or simply changes the state and we don't -- // have any meaningful value stored. -- if (is_normal) { -- SetRestoredBoundsInPixels({}); -- } else if (old_state == PlatformWindowState::kNormal || -- restored_bounds_px_.IsEmpty()) { -- SetRestoredBoundsInPixels(bounds_px_); -- } -- -- delegate_->OnWindowStateChanged(state_); -- } -- -- ApplyPendingBounds(); -- -- if (did_active_change) -- delegate_->OnActivationChanged(is_active_); -- -- MaybeTriggerPendingStateChange(); -+ NOTREACHED() -+ << "Only shell surfaces must receive HandleSurfaceConfigure calls."; - } - - void WaylandWindow::HandlePopupConfigure(const gfx::Rect& bounds_dip) { -@@ -671,40 +445,22 @@ void WaylandWindow::OnCloseRequest() { - - void WaylandWindow::OnDragEnter(const gfx::PointF& point, - std::unique_ptr<OSExchangeData> data, -- int operation) { -- WmDropHandler* drop_handler = GetWmDropHandler(*this); -- if (!drop_handler) -- return; -- drop_handler->OnDragEnter(point, std::move(data), operation); --} -+ int operation) {} - - int WaylandWindow::OnDragMotion(const gfx::PointF& point, - uint32_t time, - int operation) { -- WmDropHandler* drop_handler = GetWmDropHandler(*this); -- if (!drop_handler) -- return 0; -- -- return drop_handler->OnDragMotion(point, operation); -+ return -1; - } - --void WaylandWindow::OnDragDrop(std::unique_ptr<OSExchangeData> data) { -- WmDropHandler* drop_handler = GetWmDropHandler(*this); -- if (!drop_handler) -- return; -- drop_handler->OnDragDrop(std::move(data)); --} -+void WaylandWindow::OnDragDrop(std::unique_ptr<OSExchangeData> data) {} - --void WaylandWindow::OnDragLeave() { -- WmDropHandler* drop_handler = GetWmDropHandler(*this); -- if (!drop_handler) -- return; -- drop_handler->OnDragLeave(); --} -+void WaylandWindow::OnDragLeave() {} - --void WaylandWindow::OnDragSessionClose(uint32_t dnd_action) { -- std::move(drag_closed_callback_).Run(dnd_action); -- connection_->ResetPointerFlags(); -+void WaylandWindow::OnDragSessionClose(uint32_t dnd_action) {} -+ -+void WaylandWindow::SetBoundsDip(const gfx::Rect& bounds_dip) { -+ SetBounds(gfx::ScaleToRoundedRect(bounds_dip, buffer_scale_)); - } - - bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) { -@@ -752,15 +508,11 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) { - case ui::PlatformWindowType::kWindow: - case ui::PlatformWindowType::kBubble: - case ui::PlatformWindowType::kDrag: -- // TODO(msisov): Figure out what kind of surface we need to create for -- // bubble and drag windows. -- CreateShellSurface(); -+ if (!OnInitialize(std::move(properties))) -+ return false; - break; - } - -- if (shell_surface_ && !properties.wm_class_class.empty()) -- shell_surface_->SetAppId(properties.wm_class_class); -- - connection_->ScheduleFlush(); - - PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); -@@ -773,10 +525,6 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) { - return true; - } - --void WaylandWindow::SetBoundsDip(const gfx::Rect& bounds_dip) { -- SetBounds(gfx::ScaleToRoundedRect(bounds_dip, buffer_scale_)); --} -- - void WaylandWindow::SetBufferScale(int32_t new_scale, bool update_bounds) { - DCHECK_GT(new_scale, 0); - -@@ -793,26 +541,6 @@ void WaylandWindow::SetBufferScale(int32_t new_scale, bool update_bounds) { - connection_->ScheduleFlush(); - } - --bool WaylandWindow::IsMinimized() const { -- return state_ == PlatformWindowState::kMinimized; --} -- --bool WaylandWindow::IsMaximized() const { -- return state_ == PlatformWindowState::kMaximized; --} -- --bool WaylandWindow::IsFullscreen() const { -- return state_ == PlatformWindowState::kFullScreen; --} -- --void WaylandWindow::MaybeTriggerPendingStateChange() { -- if (pending_state_ == PlatformWindowState::kUnknown || !is_active_) -- return; -- DCHECK_EQ(pending_state_, PlatformWindowState::kFullScreen); -- pending_state_ = PlatformWindowState::kUnknown; -- ToggleFullscreen(); --} -- - WaylandWindow* WaylandWindow::GetParentWindow( - gfx::AcceleratedWidget parent_widget) { - auto* parent_window = -@@ -838,10 +566,6 @@ WaylandWindow* WaylandWindow::GetRootParentWindow() { - return parent_window_ ? parent_window_->GetRootParentWindow() : this; - } - --WmMoveResizeHandler* WaylandWindow::AsWmMoveResizeHandler() { -- return static_cast<WmMoveResizeHandler*>(this); --} -- - void WaylandWindow::AddSurfaceListener() { - static struct wl_surface_listener surface_listener = { - &WaylandWindow::Enter, -@@ -960,10 +684,12 @@ gfx::Rect WaylandWindow::AdjustPopupWindowPosition() const { - // the parent menu window, which results in showing it on a second display if - // more than one display is used. - if (parent_window_->shell_popup() && parent_window_->parent_window_ && -- !parent_window_->parent_window_->IsMaximized()) { -+ (parent_window_->parent_window()->GetPlatformWindowState() != -+ PlatformWindowState::kMaximized)) { - auto* top_level_window = parent_window_->parent_window_; - DCHECK(top_level_window && !top_level_window->shell_popup()); -- if (new_bounds_dip.x() <= 0 && !top_level_window->IsMaximized()) { -+ if (new_bounds_dip.x() <= 0 && top_level_window->GetPlatformWindowState() != -+ PlatformWindowState::kMaximized) { - // Position the child menu window on the right side of the parent window - // and let the Wayland compositor decide how to do constraint - // adjustements. -@@ -995,6 +721,10 @@ bool WaylandWindow::IsOpaqueWindow() const { - return opacity_ == ui::PlatformWindowOpacity::kOpaqueWindow; - } - -+bool WaylandWindow::OnInitialize(PlatformWindowInitProperties properties) { -+ return true; -+} -+ - // static - void WaylandWindow::Enter(void* data, - struct wl_surface* wl_surface, -diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h -index b8cdc991e30e..b9ee70d0ecd2 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window.h -+++ b/ui/ozone/platform/wayland/host/wayland_window.h -@@ -19,8 +19,6 @@ - #include "ui/ozone/platform/wayland/common/wayland_object.h" - #include "ui/platform_window/platform_window.h" - #include "ui/platform_window/platform_window_delegate.h" --#include "ui/platform_window/platform_window_handler/wm_drag_handler.h" --#include "ui/platform_window/platform_window_handler/wm_move_resize_handler.h" - #include "ui/platform_window/platform_window_init_properties.h" - - namespace gfx { -@@ -33,12 +31,8 @@ class BitmapCursorOzone; - class OSExchangeData; - class WaylandConnection; - class ShellPopupWrapper; --class ShellSurfaceWrapper; - --class WaylandWindow : public PlatformWindow, -- public PlatformEventDispatcher, -- public WmMoveResizeHandler, -- public WmDragHandler { -+class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { - public: - ~WaylandWindow() override; - -@@ -59,17 +53,12 @@ class WaylandWindow : public PlatformWindow, - void UpdateBufferScale(bool update_bounds); - - wl_surface* surface() const { return surface_.get(); } -- ShellSurfaceWrapper* shell_surface() const { return shell_surface_.get(); } - ShellPopupWrapper* shell_popup() const { return shell_popup_.get(); } - - WaylandWindow* parent_window() const { return parent_window_; } - - gfx::AcceleratedWidget GetWidget() 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(); -- - // Set whether this window has pointer focus and should dispatch mouse events. - void SetPointerFocus(bool focus); - bool has_pointer_focus() const { return has_pointer_focus_; } -@@ -94,23 +83,10 @@ class WaylandWindow : public PlatformWindow, - - int32_t buffer_scale() const { return buffer_scale_; } - -- 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, -- const gfx::Point& pointer_location_in_px) override; -- -- // WmDragHandler -- void StartDrag(const ui::OSExchangeData& data, -- int operation, -- gfx::NativeCursor cursor, -- base::OnceCallback<void(int)> callback) override; -- - // PlatformWindow - void Show(bool inactive) override; - void Hide() override; -@@ -147,49 +123,49 @@ class WaylandWindow : public PlatformWindow, - bool CanDispatchEvent(const PlatformEvent& event) override; - uint32_t DispatchEvent(const PlatformEvent& event) override; - -- // Handles the configuration events coming from the surface (see -- // |XDGSurfaceWrapperStable::ConfigureTopLevel| and -- // |XDGSurfaceWrapperV6::ConfigureTopLevel|. The width and height come in -- // DIP of the output that the surface is currently bound to. -- void HandleSurfaceConfigure(int32_t widht, -- int32_t height, -- bool is_maximized, -- bool is_fullscreen, -- bool is_activated); -+ // Handles the configuration events coming from the shell objects. -+ // The width and height come in DIP of the output that the surface is -+ // currently bound to. -+ virtual void HandleSurfaceConfigure(int32_t widht, -+ int32_t height, -+ bool is_maximized, -+ bool is_fullscreen, -+ bool is_activated); - void HandlePopupConfigure(const gfx::Rect& bounds); - - void OnCloseRequest(); - -- void OnDragEnter(const gfx::PointF& point, -- std::unique_ptr<OSExchangeData> data, -- int operation); -- int OnDragMotion(const gfx::PointF& point, uint32_t time, int operation); -- void OnDragDrop(std::unique_ptr<OSExchangeData> data); -- void OnDragLeave(); -- void OnDragSessionClose(uint32_t dnd_action); -+ // Notifies about drag/drop session events. -+ virtual void OnDragEnter(const gfx::PointF& point, -+ std::unique_ptr<OSExchangeData> data, -+ int operation); -+ virtual int OnDragMotion(const gfx::PointF& point, -+ uint32_t time, -+ int operation); -+ virtual void OnDragDrop(std::unique_ptr<OSExchangeData> data); -+ virtual void OnDragLeave(); -+ virtual void OnDragSessionClose(uint32_t dnd_action); -+ -+ protected: -+ WaylandWindow(PlatformWindowDelegate* delegate, -+ WaylandConnection* connection); -+ -+ WaylandConnection* connection() { return connection_; } -+ PlatformWindowDelegate* delegate() { return delegate_; } -+ -+ // Sets bounds in dip. -+ void SetBoundsDip(const gfx::Rect& bounds_dip); - - private: - FRIEND_TEST_ALL_PREFIXES(WaylandScreenTest, SetBufferScale); - -- WaylandWindow(PlatformWindowDelegate* delegate, -- WaylandConnection* connection); -- - // Initializes the WaylandWindow with supplied properties. - bool Initialize(PlatformWindowInitProperties properties); - -- void SetBoundsDip(const gfx::Rect& bounds_dip); - void SetBufferScale(int32_t scale, bool update_bounds); - -- bool IsMinimized() const; -- bool IsMaximized() const; -- bool IsFullscreen() const; -- -- void MaybeTriggerPendingStateChange(); -- - // Creates a popup window, which is visible as a menu window. - void CreateShellPopup(); -- // Creates a surface window, which is visible as a main window. -- void CreateShellSurface(); - // Creates (if necessary) and show subsurface window, to host - // tooltip's content. - void CreateAndShowTooltipSubSurface(); -@@ -200,8 +176,6 @@ class WaylandWindow : public PlatformWindow, - // Returns a root parent window. - WaylandWindow* GetRootParentWindow(); - -- WmMoveResizeHandler* AsWmMoveResizeHandler(); -- - // Install a surface listener and start getting wl_output enter/leave events. - void AddSurfaceListener(); - -@@ -221,6 +195,9 @@ class WaylandWindow : public PlatformWindow, - - bool IsOpaqueWindow() const; - -+ // Additional initialization of derived classes. -+ virtual bool OnInitialize(PlatformWindowInitProperties properties); -+ - // wl_surface_listener - static void Enter(void* data, - struct wl_surface* wl_surface, -@@ -239,25 +216,11 @@ class WaylandWindow : public PlatformWindow, - - // Wrappers around xdg v5 and xdg v6 objects. WaylandWindow doesn't - // know anything about the version. -- std::unique_ptr<ShellSurfaceWrapper> shell_surface_; - std::unique_ptr<ShellPopupWrapper> shell_popup_; - - // The current cursor bitmap (immutable). - scoped_refptr<BitmapCursorOzone> bitmap_; - -- base::OnceCallback<void(int)> drag_closed_callback_; -- -- // These bounds attributes below have suffices that indicate units used. -- // Wayland operates in DIP but the platform operates in physical pixels so -- // our WaylandWindow is the link that has to translate the units. See also -- // comments in the implementation. -- // -- // Bounds that will be applied when the window state is finalized. The window -- // may get several configuration events that update the pending bounds, and -- // only upon finalizing the state is the latest value stored as the current -- // bounds via |ApplyPendingBounds|. Measured in DIP because updated in the -- // handler that receives DIP from Wayland. -- gfx::Rect pending_bounds_dip_; - // Current bounds of the platform window. - gfx::Rect bounds_px_; - // The bounds of the platform window before it went maximized or fullscreen. -@@ -275,18 +238,9 @@ class WaylandWindow : public PlatformWindow, - // We need it to place and size the menus properly. - float ui_scale_ = 1.0; - -- // Stores current states of the window. -- PlatformWindowState state_; -- // Stores a pending state of the window, which is used before the surface is -- // activated. -- PlatformWindowState pending_state_; -- - // Stores current opacity of the window. Set on ::Initialize call. - ui::PlatformWindowOpacity opacity_; - -- bool is_active_ = false; -- bool is_minimizing_ = false; -- - bool is_tooltip_ = false; - - // For top level window, stores IDs of outputs that the window is currently -diff --git a/ui/ozone/platform/wayland/host/wayland_window_factory.cc b/ui/ozone/platform/wayland/host/wayland_window_factory.cc -index 19da59357d55..892902e7f845 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window_factory.cc -+++ b/ui/ozone/platform/wayland/host/wayland_window_factory.cc -@@ -6,6 +6,7 @@ - - #include <memory> - -+#include "ui/ozone/platform/wayland/host/wayland_surface.h" - #include "ui/ozone/platform/wayland/host/wayland_window.h" - - namespace ui { -@@ -15,12 +16,30 @@ std::unique_ptr<WaylandWindow> WaylandWindow::Create( - PlatformWindowDelegate* delegate, - WaylandConnection* connection, - PlatformWindowInitProperties properties) { -- // TODO(msisov): once WaylandWindow becomes a base class, add switch cases to -- // create different Wayland windows. -- std::unique_ptr<WaylandWindow> window( -- new WaylandWindow(delegate, connection)); -- return window->Initialize(std::move(properties)) ? std::move(window) -- : nullptr; -+ std::unique_ptr<WaylandWindow> window; -+ switch (properties.type) { -+ case PlatformWindowType::kMenu: -+ case PlatformWindowType::kPopup: -+ // TODO(msisov): Add WaylandPopup. -+ window.reset(new WaylandWindow(delegate, connection)); -+ break; -+ case PlatformWindowType::kTooltip: -+ // TODO(msisov): Add WaylandSubsurface. -+ window.reset(new WaylandWindow(delegate, connection)); -+ break; -+ case PlatformWindowType::kWindow: -+ case PlatformWindowType::kBubble: -+ case PlatformWindowType::kDrag: -+ // TODO(msisov): Figure out what kind of surface we need to create for -+ // bubble and drag windows. -+ window.reset(new WaylandSurface(delegate, connection)); -+ break; -+ default: -+ NOTREACHED(); -+ break; -+ } -+ return window && window->Initialize(std::move(properties)) ? std::move(window) -+ : nullptr; - } - - } // namespace ui -\ No newline at end of file -diff --git a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc -index b03a28daadf2..132f740b0eb1 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc -+++ b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc -@@ -26,6 +26,7 @@ - #include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h" - #include "ui/ozone/platform/wayland/test/wayland_test.h" - #include "ui/ozone/test/mock_platform_window_delegate.h" -+#include "ui/platform_window/platform_window_handler/wm_move_resize_handler.h" - #include "ui/platform_window/platform_window_init_properties.h" - - using ::testing::_; -@@ -249,7 +250,6 @@ TEST_P(WaylandWindowTest, MaximizeAndRestore) { - SendConfigureEvent(kMaximizedBounds.width(), kMaximizedBounds.height(), 2, - inactive_maximized.get()); - Sync(); -- EXPECT_FALSE(window_->is_active()); - VerifyAndClearExpectations(); - - EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, kMaximizedBounds.width(), -@@ -259,7 +259,6 @@ TEST_P(WaylandWindowTest, MaximizeAndRestore) { - SendConfigureEvent(kMaximizedBounds.width(), kMaximizedBounds.height(), 3, - active_maximized.get()); - Sync(); -- EXPECT_TRUE(window_->is_active()); - VerifyAndClearExpectations(); - - EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, kNormalBounds.width(), -@@ -703,21 +702,17 @@ TEST_P(WaylandWindowTest, ConfigureEventWithNulledSize) { - } - - TEST_P(WaylandWindowTest, OnActivationChanged) { -- EXPECT_FALSE(window_->is_active()); -- - { - ScopedWlArray states = InitializeWlArrayWithActivatedState(); - EXPECT_CALL(delegate_, OnActivationChanged(Eq(true))); - SendConfigureEvent(0, 0, 1, states.get()); - Sync(); -- EXPECT_TRUE(window_->is_active()); - } - - ScopedWlArray states; - EXPECT_CALL(delegate_, OnActivationChanged(Eq(false))); - SendConfigureEvent(0, 0, 2, states.get()); - Sync(); -- EXPECT_FALSE(window_->is_active()); - } - - TEST_P(WaylandWindowTest, OnAcceleratedWidgetDestroy) { -@@ -847,7 +842,7 @@ TEST_P(WaylandWindowTest, CanDispatchEventToMenuWindowNested) { - - TEST_P(WaylandWindowTest, DispatchWindowMove) { - EXPECT_CALL(*GetXdgSurface(), Move(_)); -- window_->DispatchHostWindowDragMovement(HTCAPTION, gfx::Point()); -+ ui::GetWmMoveResizeHandler(*window_)->DispatchHostWindowDragMovement(HTCAPTION, gfx::Point()); - } - - // Makes sure hit tests are converted into right edges. -@@ -855,11 +850,14 @@ TEST_P(WaylandWindowTest, DispatchWindowResize) { - std::vector<int> hit_test_values; - InitializeWithSupportedHitTestValues(&hit_test_values); - -+ auto* wm_move_resize_handler = ui::GetWmMoveResizeHandler(*window_); -+ - for (const int value : hit_test_values) { - { - uint32_t direction = wl::IdentifyDirection(*(connection_.get()), value); - EXPECT_CALL(*GetXdgSurface(), Resize(_, Eq(direction))); -- window_->DispatchHostWindowDragMovement(value, gfx::Point()); -+ wm_move_resize_handler->DispatchHostWindowDragMovement(value, -+ gfx::Point()); - } - } - } -diff --git a/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc b/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc -index abf6e7fa6461..e85236ce47d7 100644 ---- a/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc -+++ b/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc -@@ -14,6 +14,7 @@ - #include "ui/gfx/geometry/rect.h" - #include "ui/ozone/platform/wayland/host/wayland_connection.h" - #include "ui/ozone/platform/wayland/host/wayland_pointer.h" -+#include "ui/ozone/platform/wayland/host/wayland_surface.h" - #include "ui/ozone/platform/wayland/host/wayland_window.h" - #include "ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h" - -@@ -290,8 +291,10 @@ bool XDGPopupWrapperImpl::InitializeStable(WaylandConnection* connection, - wayland_window_->parent_window()->shell_popup()); - parent_xdg_surface = popup->xdg_surface(); - } else { -+ WaylandSurface* wayland_surface = -+ static_cast<WaylandSurface*>(wayland_window_->parent_window()); - parent_xdg_surface = reinterpret_cast<XDGSurfaceWrapperImpl*>( -- wayland_window_->parent_window()->shell_surface()); -+ wayland_surface->shell_surface()); - } - - if (!parent_xdg_surface) -@@ -405,8 +408,10 @@ bool XDGPopupWrapperImpl::InitializeV6(WaylandConnection* connection, - wayland_window_->parent_window()->shell_popup()); - parent_xdg_surface = popup->xdg_surface(); - } else { -+ WaylandSurface* wayland_surface = -+ static_cast<WaylandSurface*>(wayland_window_->parent_window()); - parent_xdg_surface = reinterpret_cast<XDGSurfaceWrapperImpl*>( -- wayland_window_->parent_window()->shell_surface()); -+ wayland_surface->shell_surface()); - } - - if (!parent_xdg_surface) --- -2.24.1 - diff --git a/0006-ozone-wayland-extract-popup-methods-to-WaylandPopup.patch b/0006-ozone-wayland-extract-popup-methods-to-WaylandPopup.patch deleted file mode 100644 index 2d62b81885fd..000000000000 --- a/0006-ozone-wayland-extract-popup-methods-to-WaylandPopup.patch +++ /dev/null @@ -1,1043 +0,0 @@ -From 0cff96c5189fee16e0b2f79685c86e73216652aa Mon Sep 17 00:00:00 2001 -From: Maksim Sisov <msisov@igalia.com> -Date: Wed, 11 Dec 2019 09:50:09 +0000 -Subject: [PATCH 6/9] ozone/wayland: extract popup methods to WaylandPopup - -This change does not bring any functional changes and just -extracts menus/popups methods to a separate class named -WaylandPopup. - -Also, to avoid code duplicate, the XdgPopupWrapperImpl::Initialize -gets a parent xdg surface and passes it to ::InitializeStable and -::InitializeV6 methods. - -Test: ozone_unittests -Bug: 1028919 -Change-Id: I216e1374b7e6e97080e40043634db91a20a7b4cf -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1958989 -Reviewed-by: Michael Spang <spang@chromium.org> -Commit-Queue: Maksim Sisov <msisov@igalia.com> -Cr-Commit-Position: refs/heads/master@{#723755} ---- - ui/ozone/platform/wayland/BUILD.gn | 2 + - .../platform/wayland/common/wayland_util.cc | 5 + - .../platform/wayland/common/wayland_util.h | 4 + - .../platform/wayland/host/wayland_popup.cc | 210 +++++++++++++++ - .../platform/wayland/host/wayland_popup.h | 49 ++++ - .../platform/wayland/host/wayland_window.cc | 243 +++--------------- - .../platform/wayland/host/wayland_window.h | 41 +-- - .../wayland/host/wayland_window_factory.cc | 3 +- - .../wayland/host/xdg_popup_wrapper_impl.cc | 83 +++--- - .../wayland/host/xdg_popup_wrapper_impl.h | 8 +- - 10 files changed, 371 insertions(+), 277 deletions(-) - create mode 100644 ui/ozone/platform/wayland/host/wayland_popup.cc - create mode 100644 ui/ozone/platform/wayland/host/wayland_popup.h - -diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn -index b6059c7d9962..4bfe93352f34 100644 ---- a/ui/ozone/platform/wayland/BUILD.gn -+++ b/ui/ozone/platform/wayland/BUILD.gn -@@ -85,6 +85,8 @@ source_set("wayland") { - "host/wayland_output_manager.h", - "host/wayland_pointer.cc", - "host/wayland_pointer.h", -+ "host/wayland_popup.cc", -+ "host/wayland_popup.h", - "host/wayland_screen.cc", - "host/wayland_screen.h", - "host/wayland_shm.cc", -diff --git a/ui/ozone/platform/wayland/common/wayland_util.cc b/ui/ozone/platform/wayland/common/wayland_util.cc -index e0430b860adf..578bab8930c8 100644 ---- a/ui/ozone/platform/wayland/common/wayland_util.cc -+++ b/ui/ozone/platform/wayland/common/wayland_util.cc -@@ -155,4 +155,9 @@ gfx::Rect TranslateBoundsToTopLevelCoordinates(const gfx::Rect& child_bounds, - child_bounds.size()); - } - -+bool IsMenuType(ui::PlatformWindowType type) { -+ return type == ui::PlatformWindowType::kMenu || -+ type == ui::PlatformWindowType::kPopup; -+} -+ - } // namespace wl -diff --git a/ui/ozone/platform/wayland/common/wayland_util.h b/ui/ozone/platform/wayland/common/wayland_util.h -index 48332e059da0..3db369654025 100644 ---- a/ui/ozone/platform/wayland/common/wayland_util.h -+++ b/ui/ozone/platform/wayland/common/wayland_util.h -@@ -15,6 +15,7 @@ - #include "base/macros.h" - #include "ui/gfx/geometry/rect.h" - #include "ui/ozone/platform/wayland/common/wayland_object.h" -+#include "ui/platform_window/platform_window_init_properties.h" - - class SkBitmap; - -@@ -58,6 +59,9 @@ gfx::Rect TranslateBoundsToParentCoordinates(const gfx::Rect& child_bounds, - gfx::Rect TranslateBoundsToTopLevelCoordinates(const gfx::Rect& child_bounds, - const gfx::Rect& parent_bounds); - -+// Says if the type is kPopup or kMenu. -+bool IsMenuType(ui::PlatformWindowType type); -+ - } // namespace wl - - #endif // UI_OZONE_PLATFORM_WAYLAND_COMMON_WAYLAND_UTIL_H_ -diff --git a/ui/ozone/platform/wayland/host/wayland_popup.cc b/ui/ozone/platform/wayland/host/wayland_popup.cc -new file mode 100644 -index 000000000000..45aac6e51bfc ---- /dev/null -+++ b/ui/ozone/platform/wayland/host/wayland_popup.cc -@@ -0,0 +1,210 @@ -+// 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_popup.h" -+ -+#include "ui/ozone/platform/wayland/common/wayland_util.h" -+#include "ui/ozone/platform/wayland/host/shell_object_factory.h" -+#include "ui/ozone/platform/wayland/host/shell_popup_wrapper.h" -+#include "ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h" -+#include "ui/ozone/platform/wayland/host/wayland_connection.h" -+ -+namespace ui { -+ -+WaylandPopup::WaylandPopup(PlatformWindowDelegate* delegate, -+ WaylandConnection* connection) -+ : WaylandWindow(delegate, connection) {} -+ -+WaylandPopup::~WaylandPopup() = default; -+ -+void WaylandPopup::CreateShellPopup() { -+ if (GetBounds().IsEmpty()) -+ return; -+ -+ // TODO(jkim): Consider how to support DropArrow window on tabstrip. -+ // When it starts dragging, as described the protocol, https://goo.gl/1Mskq3, -+ // the client must have an active implicit grab. If we try to create a popup -+ // window while dragging is executed, it gets 'popup_done' directly from -+ // Wayland compositor and it's destroyed through 'popup_done'. It causes -+ // a crash when aura::Window is destroyed. -+ // https://crbug.com/875164 -+ if (connection()->IsDragInProgress()) { -+ LOG(ERROR) << "Wayland can't create a popup window during dragging."; -+ return; -+ } -+ -+ DCHECK(parent_window() && !shell_popup_); -+ -+ auto bounds_px = AdjustPopupWindowPosition(); -+ -+ ShellObjectFactory factory; -+ shell_popup_ = factory.CreateShellPopupWrapper(connection(), this, bounds_px); -+ if (!shell_popup_) -+ CHECK(false) << "Failed to create Wayland shell popup"; -+ -+ parent_window()->set_child_window(this); -+} -+ -+void WaylandPopup::Show(bool inactive) { -+ set_keyboard_focus(true); -+ -+ if (!shell_popup_) { -+ // When showing a sub-menu after it has been previously shown and hidden, -+ // Wayland sends SetBounds prior to Show, and |bounds_px| takes the pixel -+ // 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. -+ SetBounds(gfx::ScaleToRoundedRect(GetBounds(), 1.0 / ui_scale())); -+ CreateShellPopup(); -+ connection()->ScheduleFlush(); -+ } -+ -+ UpdateBufferScale(false); -+} -+ -+void WaylandPopup::Hide() { -+ if (child_window()) -+ child_window()->Hide(); -+ -+ if (shell_popup_) { -+ parent_window()->set_child_window(nullptr); -+ shell_popup_.reset(); -+ } -+ -+ // Detach buffer from surface in order to completely shutdown popups and -+ // tooltips, and release resources. -+ connection()->buffer_manager_host()->ResetSurfaceContents(GetWidget()); -+} -+ -+bool WaylandPopup::IsVisible() const { -+ return !!shell_popup_; -+} -+ -+bool WaylandPopup::HasCapture() const { -+ // WaylandPopups always have captures. -+ return shell_popup(); -+} -+ -+void WaylandPopup::HandlePopupConfigure(const gfx::Rect& bounds_dip) { -+ DCHECK(shell_popup()); -+ DCHECK(parent_window()); -+ -+ SetBufferScale(parent_window()->buffer_scale(), true); -+ -+ gfx::Rect new_bounds_dip = bounds_dip; -+ -+ // It's not enough to just set new bounds. If it is a menu window, whose -+ // parent is a top level window a.k.a browser window, it can be flipped -+ // vertically along y-axis and have negative values set. Chromium cannot -+ // understand that and starts to position nested menu windows incorrectly. To -+ // fix that, we have to bear in mind that Wayland compositor does not share -+ // global coordinates for any surfaces, and Chromium assumes the top level -+ // window is always located at 0,0 origin. What is more, child windows must -+ // always be positioned relative to parent window local surface coordinates. -+ // Thus, if the menu window is flipped along y-axis by Wayland and its origin -+ // is above the top level parent window, the origin of the top level window -+ // has to be shifted by that value on y-axis so that the origin of the menu -+ // becomes x,0, and events can be handled normally. -+ if (!wl::IsMenuType(parent_window()->type())) { -+ 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. -+ if (new_bounds_dip.y() < 0) { -+ // Move parent bounds along y-axis. -+ parent_bounds.set_y(-(new_bounds_dip.y() * buffer_scale())); -+ new_bounds_dip.set_y(0); -+ } 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. -+ parent_bounds.set_y(0); -+ } -+ parent_window()->SetBounds(parent_bounds); -+ } else { -+ // The nested menu windows are located relative to the parent menu windows. -+ // 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. -+ new_bounds_dip = gfx::ScaleToRoundedRect( -+ wl::TranslateBoundsToTopLevelCoordinates( -+ gfx::ScaleToRoundedRect(new_bounds_dip, buffer_scale()), -+ parent_window()->GetBounds()), -+ 1.0 / buffer_scale()); -+ DCHECK(new_bounds_dip.y() >= 0); -+ } -+ -+ SetBoundsDip(new_bounds_dip); -+} -+ -+void WaylandPopup::OnCloseRequest() { -+ // Before calling OnCloseRequest, the |shell_popup_| must become hidden and -+ // only then call OnCloseRequest(). -+ DCHECK(!shell_popup_); -+ WaylandWindow::OnCloseRequest(); -+} -+ -+bool WaylandPopup::OnInitialize(PlatformWindowInitProperties properties) { -+ if (!wl::IsMenuType(type())) -+ return false; -+ -+ set_parent_window(GetParentWindow(properties.parent_widget)); -+ if (!parent_window()) { -+ LOG(ERROR) << "Failed to get a parent window for this popup"; -+ return false; -+ } -+ // If parent window is known in advanced, we may set the scale early. -+ SetBufferScale(parent_window()->buffer_scale(), false); -+ set_ui_scale(parent_window()->ui_scale()); -+ CreateShellPopup(); -+ return true; -+} -+ -+gfx::Rect WaylandPopup::AdjustPopupWindowPosition() { -+ auto* top_level_parent = wl::IsMenuType(parent_window()->type()) -+ ? parent_window()->parent_window() -+ : parent_window(); -+ DCHECK(top_level_parent); -+ DCHECK(buffer_scale() == top_level_parent->buffer_scale()); -+ DCHECK(ui_scale() == top_level_parent->ui_scale()); -+ -+ // Chromium positions windows in screen coordinates, but Wayland requires them -+ // to be in local surface coordinates a.k.a relative to parent window. -+ const gfx::Rect parent_bounds_dip = -+ gfx::ScaleToRoundedRect(parent_window()->GetBounds(), 1.0 / ui_scale()); -+ gfx::Rect new_bounds_dip = -+ wl::TranslateBoundsToParentCoordinates(GetBounds(), 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 -+ // window becomes larger than the display it is shown on. It's correct when -+ // the window is located on one display and occupies the whole work area, but -+ // as soon as it's moved and there is space on the right side, Chromium -+ // continues positioning the nested menus on the left side relative to the -+ // parent menu (Wayland does not provide clients with global coordinates). -+ // Instead, reposition that window to be on the right side of the parent menu -+ // window and let the compositor decide how to position it if it does not fit -+ // a single display. However, there is one exception - if the window is -+ // maximized, let Chromium position it on the left side as long as the Wayland -+ // compositor may decide to position the nested window on the right side of -+ // the parent menu window, which results in showing it on a second display if -+ // more than one display is used. -+ if (wl::IsMenuType(parent_window()->type()) && -+ parent_window()->parent_window() && -+ (parent_window()->parent_window()->GetPlatformWindowState() != -+ PlatformWindowState::kMaximized)) { -+ auto* top_level_window = parent_window()->parent_window(); -+ DCHECK(top_level_window && !wl::IsMenuType(top_level_window->type())); -+ if (new_bounds_dip.x() <= 0 && top_level_window->GetPlatformWindowState() != -+ PlatformWindowState::kMaximized) { -+ // Position the child menu window on the right side of the parent window -+ // and let the Wayland compositor decide how to do constraint -+ // adjustments. -+ int new_x = parent_bounds_dip.width() - -+ (new_bounds_dip.width() + new_bounds_dip.x()); -+ new_bounds_dip.set_x(new_x); -+ } -+ } -+ return gfx::ScaleToRoundedRect(new_bounds_dip, ui_scale() / buffer_scale()); -+} -+ -+} // namespace ui -diff --git a/ui/ozone/platform/wayland/host/wayland_popup.h b/ui/ozone/platform/wayland/host/wayland_popup.h -new file mode 100644 -index 000000000000..2d45986ba36a ---- /dev/null -+++ b/ui/ozone/platform/wayland/host/wayland_popup.h -@@ -0,0 +1,49 @@ -+// 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_POPUP_H_ -+#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_POPUP_H_ -+ -+#include "ui/ozone/platform/wayland/host/wayland_window.h" -+ -+namespace ui { -+ -+class WaylandConnection; -+class ShellPopupWrapper; -+ -+class WaylandPopup : public WaylandWindow { -+ public: -+ WaylandPopup(PlatformWindowDelegate* delegate, WaylandConnection* connection); -+ ~WaylandPopup() override; -+ -+ ShellPopupWrapper* shell_popup() const { return shell_popup_.get(); } -+ -+ // PlatformWindow -+ void Show(bool inactive) override; -+ void Hide() override; -+ bool IsVisible() const override; -+ bool HasCapture() const override; -+ -+ private: -+ // WaylandWindow overrides: -+ void HandlePopupConfigure(const gfx::Rect& bounds) override; -+ void OnCloseRequest() override; -+ bool OnInitialize(PlatformWindowInitProperties properties) override; -+ -+ // Creates a popup window, which is visible as a menu window. -+ void CreateShellPopup(); -+ -+ // Returns bounds with origin relative to parent window's origin. -+ gfx::Rect AdjustPopupWindowPosition(); -+ -+ // Wrappers around xdg v5 and xdg v6 objects. WaylandPopup doesn't -+ // know anything about the version. -+ std::unique_ptr<ShellPopupWrapper> shell_popup_; -+ -+ DISALLOW_COPY_AND_ASSIGN(WaylandPopup); -+}; -+ -+} // namespace ui -+ -+#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_POPUP_H_ -diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc -index cdc95f904347..045f922a759e 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window.cc -+++ b/ui/ozone/platform/wayland/host/wayland_window.cc -@@ -14,8 +14,6 @@ - #include "ui/events/ozone/events_ozone.h" - #include "ui/gfx/geometry/point_f.h" - #include "ui/ozone/platform/wayland/common/wayland_util.h" --#include "ui/ozone/platform/wayland/host/shell_object_factory.h" --#include "ui/ozone/platform/wayland/host/shell_popup_wrapper.h" - #include "ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h" - #include "ui/ozone/platform/wayland/host/wayland_connection.h" - #include "ui/ozone/platform/wayland/host/wayland_cursor_position.h" -@@ -78,35 +76,6 @@ gfx::AcceleratedWidget WaylandWindow::GetWidget() const { - return surface_.id(); - } - --void WaylandWindow::CreateShellPopup() { -- if (bounds_px_.IsEmpty()) -- return; -- -- // TODO(jkim): Consider how to support DropArrow window on tabstrip. -- // When it starts dragging, as described the protocol, https://goo.gl/1Mskq3, -- // the client must have an active implicit grab. If we try to create a popup -- // window while dragging is executed, it gets 'popup_done' directly from -- // Wayland compositor and it's destroyed through 'popup_done'. It causes -- // a crash when aura::Window is destroyed. -- // https://crbug.com/875164 -- if (connection_->IsDragInProgress()) { -- surface_.reset(); -- LOG(ERROR) << "Wayland can't create a popup window during dragging."; -- return; -- } -- -- DCHECK(parent_window_ && !shell_popup_); -- -- auto bounds_px = AdjustPopupWindowPosition(); -- -- ShellObjectFactory factory; -- shell_popup_ = factory.CreateShellPopupWrapper(connection_, this, bounds_px); -- if (!shell_popup_) -- CHECK(false) << "Failed to create Wayland shell popup"; -- -- parent_window_->set_child_window(this); --} -- - 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. -@@ -156,41 +125,17 @@ void WaylandWindow::SetPointerFocus(bool focus) { - } - - void WaylandWindow::Show(bool inactive) { -- if (!is_tooltip_) // Tooltip windows should not get keyboard focus -- set_keyboard_focus(true); -- -- if (is_tooltip_) { -- CreateAndShowTooltipSubSurface(); -- return; -- } -- -- if (!shell_popup_) { -- // When showing a sub-menu after it has been previously shown and hidden, -- // Wayland sends SetBounds prior to Show, and |bounds_px| takes the pixel -- // 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 / ui_scale_); -- CreateShellPopup(); -- connection_->ScheduleFlush(); -- } -+ DCHECK(is_tooltip_); -+ CreateAndShowTooltipSubSurface(); - - UpdateBufferScale(false); - } - - void WaylandWindow::Hide() { -- if (is_tooltip_) { -- tooltip_subsurface_.reset(); -- } else { -- if (child_window_) -- child_window_->Hide(); -- if (shell_popup_) { -- parent_window_->set_child_window(nullptr); -- shell_popup_.reset(); -- } -- } -+ DCHECK(is_tooltip_); -+ tooltip_subsurface_.reset(); - -- // Detach buffer from surface in order to completely shutdown popups and -+ // Detach buffer from surface in order to completely shutdown menus and - // tooltips, and release resources. - connection_->buffer_manager_host()->ResetSurfaceContents(GetWidget()); - } -@@ -200,7 +145,7 @@ void WaylandWindow::Close() { - } - - bool WaylandWindow::IsVisible() const { -- return !!shell_popup_; -+ return !!tooltip_subsurface_; - } - - void WaylandWindow::PrepareForShutdown() {} -@@ -225,8 +170,8 @@ void WaylandWindow::SetTitle(const base::string16& title) {} - - void WaylandWindow::SetCapture() { - // Wayland does implicit grabs, and doesn't allow for explicit grabs. The -- // exception to that are popups, but we explicitly send events to a -- // parent popup if such exists. -+ // exception to that are menus, but we explicitly send events to a -+ // parent menu if such exists. - } - - void WaylandWindow::ReleaseCapture() { -@@ -234,8 +179,7 @@ void WaylandWindow::ReleaseCapture() { - } - - bool WaylandWindow::HasCapture() const { -- // If WaylandWindow is a popup window, assume it has the capture. -- return shell_popup() ? true : has_implicit_grab_; -+ return has_implicit_grab_; - } - - void WaylandWindow::ToggleFullscreen() {} -@@ -319,14 +263,14 @@ void WaylandWindow::SetWindowIcons(const gfx::ImageSkia& window_icon, - void WaylandWindow::SizeConstraintsChanged() {} - - bool WaylandWindow::CanDispatchEvent(const PlatformEvent& event) { -- // This window is a nested popup window, all the events must be forwarded -- // to the main popup window. -- if (child_window_ && child_window_->shell_popup()) -- return !!shell_popup_.get(); -+ // This window is a nested menu window, all the events must be forwarded -+ // to the main menu window. -+ if (child_window_ && wl::IsMenuType(child_window_->type())) -+ return wl::IsMenuType(type()); - - // If this is a nested menu window with a parent, it mustn't recieve any - // events. -- if (parent_window_ && parent_window_->shell_popup()) -+ if (parent_window_ && wl::IsMenuType(parent_window_->type())) - return false; - - // If another window has capture, return early before checking focus. -@@ -344,7 +288,6 @@ bool WaylandWindow::CanDispatchEvent(const PlatformEvent& event) { - - uint32_t WaylandWindow::DispatchEvent(const PlatformEvent& native_event) { - Event* event = static_cast<Event*>(native_event); -- - if (event->IsLocatedEvent()) { - // Wayland sends locations in DIP so they need to be translated to - // physical pixels. -@@ -355,13 +298,14 @@ uint32_t WaylandWindow::DispatchEvent(const PlatformEvent& native_event) { - } - - // If the window does not have a pointer focus, but received this event, it -- // means the window is a popup window with a child popup window. In this case, -- // the location of the event must be converted from the nested popup to the -- // main popup, which the menu controller needs to properly handle events. -- if (event->IsLocatedEvent() && shell_popup()) { -- // Parent window of the main menu window is not a popup, but rather an -+ // means the window is a menu window with a child menu window. In this case, -+ // the location of the event must be converted from the nested menu to the -+ // main menu, which the menu controller needs to properly handle events. -+ if (event->IsLocatedEvent() && wl::IsMenuType(type())) { -+ // Parent window of the main menu window is not a menu, but rather an - // xdg surface. -- DCHECK(!parent_window_->shell_popup() || !parent_window_->is_tooltip_); -+ DCHECK(!wl::IsMenuType(parent_window_->type()) || -+ !parent_window_->is_tooltip_); - auto* window = - connection_->wayland_window_manager()->GetCurrentFocusedWindow(); - if (window) { -@@ -387,59 +331,10 @@ void WaylandWindow::HandleSurfaceConfigure(int32_t widht, - } - - void WaylandWindow::HandlePopupConfigure(const gfx::Rect& bounds_dip) { -- DCHECK(shell_popup()); -- DCHECK(parent_window_); -- -- SetBufferScale(parent_window_->buffer_scale_, true); -- -- gfx::Rect new_bounds_dip = bounds_dip; -- -- // 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 -- // vertically along y-axis and have negative values set. Chromium cannot -- // understand that and starts to position nested menu windows incorrectly. To -- // fix that, we have to bear in mind that Wayland compositor does not share -- // global coordinates for any surfaces, and Chromium assumes the top level -- // window is always located at 0,0 origin. What is more, child windows must -- // always be positioned relative to parent window local surface coordinates. -- // Thus, if the menu window is flipped along y-axis by Wayland and its origin -- // is above the top level parent window, the origin of the top level window -- // has to be shifted by that value on y-axis so that the origin of the menu -- // becomes x,0, and events can be handled normally. -- if (!parent_window_->shell_popup()) { -- 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. -- if (new_bounds_dip.y() < 0) { -- // Move parent bounds along y-axis. -- parent_bounds.set_y(-(new_bounds_dip.y() * buffer_scale_)); -- new_bounds_dip.set_y(0); -- } 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. -- parent_bounds.set_y(0); -- } -- parent_window_->SetBounds(parent_bounds); -- } else { -- // The nested menu windows are located relative to the parent menu windows. -- // 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. -- new_bounds_dip = gfx::ScaleToRoundedRect( -- wl::TranslateBoundsToTopLevelCoordinates( -- gfx::ScaleToRoundedRect(new_bounds_dip, buffer_scale_), -- parent_window_->GetBounds()), -- 1.0 / buffer_scale_); -- DCHECK(new_bounds_dip.y() >= 0); -- } -- -- SetBoundsDip(new_bounds_dip); -+ NOTREACHED() << "Only shell popups must receive HandlePopupConfigure calls."; - } - - void WaylandWindow::OnCloseRequest() { -- // Before calling OnCloseRequest, the |shell_popup_| must become hidden and -- // only then call OnCloseRequest(). -- DCHECK(!shell_popup_); - delegate_->OnCloseRequest(); - } - -@@ -470,6 +365,7 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) { - DCHECK_EQ(buffer_scale_, 1); - bounds_px_ = properties.bounds; - opacity_ = properties.opacity; -+ type_ = properties.type; - - surface_.reset(wl_compositor_create_surface(connection_->compositor())); - if (!surface_) { -@@ -481,44 +377,18 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) { - - connection_->wayland_window_manager()->AddWindow(GetWidget(), this); - -- ui::PlatformWindowType ui_window_type = properties.type; -- switch (ui_window_type) { -- case ui::PlatformWindowType::kMenu: -- case ui::PlatformWindowType::kPopup: -- parent_window_ = GetParentWindow(properties.parent_widget); -- -- // Popups need to know their scale earlier to position themselves. -- if (!parent_window_) { -- LOG(ERROR) << "Failed to get a parent window for this popup"; -- return false; -- } -- -- 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 -- // parents and pop up when the browser receives a notification. -- CreateShellPopup(); -- break; -- case ui::PlatformWindowType::kTooltip: -- // Tooltips subsurfaces are created on demand, upon ::Show calls. -- is_tooltip_ = true; -- break; -- case ui::PlatformWindowType::kWindow: -- case ui::PlatformWindowType::kBubble: -- case ui::PlatformWindowType::kDrag: -- if (!OnInitialize(std::move(properties))) -- return false; -- break; -- } -+ if (type_ == ui::PlatformWindowType::kTooltip) -+ is_tooltip_ = true; -+ -+ if (!OnInitialize(std::move(properties))) -+ return false; - - connection_->ScheduleFlush(); - - PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); - delegate_->OnAcceleratedWidgetAvailable(GetWidget()); - -- // Will do nothing for popups because they have got their scale above. -+ // Will do nothing for menus because they have got their scale above. - UpdateBufferScale(false); - - MaybeUpdateOpaqueRegion(); -@@ -575,10 +445,10 @@ void WaylandWindow::AddSurfaceListener() { - } - - void WaylandWindow::AddEnteredOutputId(struct wl_output* output) { -- // Wayland does weird things for popups so instead of tracking outputs that -+ // Wayland does weird things for menus so instead of tracking outputs that - // we entered or left, we take that from the parent window and ignore this - // event. -- if (shell_popup()) -+ if (wl::IsMenuType(type())) - return; - - const uint32_t entered_output_id = -@@ -591,10 +461,10 @@ void WaylandWindow::AddEnteredOutputId(struct wl_output* output) { - } - - void WaylandWindow::RemoveEnteredOutputId(struct wl_output* output) { -- // Wayland does weird things for popups so instead of tracking outputs that -+ // Wayland does weird things for menus so instead of tracking outputs that - // we entered or left, we take that from the parent window and ignore this - // event. -- if (shell_popup()) -+ if (wl::IsMenuType(type())) - return; - - const uint32_t left_output_id = -@@ -654,53 +524,6 @@ void WaylandWindow::UpdateCursorPositionFromEvent( - } - } - --gfx::Rect WaylandWindow::AdjustPopupWindowPosition() const { -- auto* parent_window = parent_window_->shell_popup() -- ? parent_window_->parent_window_ -- : 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_dip = -- gfx::ScaleToRoundedRect(parent_window_->GetBounds(), 1.0 / ui_scale_); -- gfx::Rect new_bounds_dip = -- wl::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 -- // window becomes larger than the display it is shown on. It's correct when -- // the window is located on one display and occupies the whole work area, but -- // as soon as it's moved and there is space on the right side, Chromium -- // continues positioning the nested menus on the left side relative to the -- // parent menu (Wayland does not provide clients with global coordinates). -- // Instead, reposition that window to be on the right side of the parent menu -- // window and let the compositor decide how to position it if it does not fit -- // a single display. However, there is one exception - if the window is -- // maximized, let Chromium position it on the left side as long as the Wayland -- // compositor may decide to position the nested window on the right side of -- // the parent menu window, which results in showing it on a second display if -- // more than one display is used. -- if (parent_window_->shell_popup() && parent_window_->parent_window_ && -- (parent_window_->parent_window()->GetPlatformWindowState() != -- PlatformWindowState::kMaximized)) { -- auto* top_level_window = parent_window_->parent_window_; -- DCHECK(top_level_window && !top_level_window->shell_popup()); -- if (new_bounds_dip.x() <= 0 && top_level_window->GetPlatformWindowState() != -- PlatformWindowState::kMaximized) { -- // 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_dip.width() - -- (new_bounds_dip.width() + new_bounds_dip.x()); -- new_bounds_dip.set_x(new_x); -- } -- } -- return gfx::ScaleToRoundedRect(new_bounds_dip, ui_scale_ / buffer_scale_); --} -- - WaylandWindow* WaylandWindow::GetTopLevelWindow() { - return parent_window_ ? parent_window_->GetTopLevelWindow() : this; - } -diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h -index b9ee70d0ecd2..3eca745b38c4 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window.h -+++ b/ui/ozone/platform/wayland/host/wayland_window.h -@@ -30,7 +30,6 @@ namespace ui { - class BitmapCursorOzone; - class OSExchangeData; - class WaylandConnection; --class ShellPopupWrapper; - - class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { - public: -@@ -53,8 +52,10 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { - void UpdateBufferScale(bool update_bounds); - - wl_surface* surface() const { return surface_.get(); } -- ShellPopupWrapper* shell_popup() const { return shell_popup_.get(); } - -+ void set_parent_window(WaylandWindow* parent_window) { -+ parent_window_ = parent_window; -+ } - WaylandWindow* parent_window() const { return parent_window_; } - - gfx::AcceleratedWidget GetWidget() const; -@@ -75,6 +76,7 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { - // Set a child of this window. It is very important in case of nested - // shell_popups as long as they must be destroyed in the back order. - void set_child_window(WaylandWindow* window) { child_window_ = window; } -+ WaylandWindow* child_window() const { return child_window_; } - - // Set whether this window has an implicit grab (often referred to as capture - // in Chrome code). Implicit grabs happen while a pointer is down. -@@ -82,11 +84,15 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { - bool has_implicit_grab() const { return has_implicit_grab_; } - - int32_t buffer_scale() const { return buffer_scale_; } -+ int32_t ui_scale() const { return ui_scale_; } - - const base::flat_set<uint32_t>& entered_outputs_ids() const { - return entered_outputs_ids_; - } - -+ // Returns current type of the window. -+ PlatformWindowType type() const { return type_; } -+ - // PlatformWindow - void Show(bool inactive) override; - void Hide() override; -@@ -131,9 +137,10 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { - bool is_maximized, - bool is_fullscreen, - bool is_activated); -- void HandlePopupConfigure(const gfx::Rect& bounds); -+ virtual void HandlePopupConfigure(const gfx::Rect& bounds); - -- void OnCloseRequest(); -+ // Handles close requests. -+ virtual void OnCloseRequest(); - - // Notifies about drag/drop session events. - virtual void OnDragEnter(const gfx::PointF& point, -@@ -156,23 +163,25 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { - // Sets bounds in dip. - void SetBoundsDip(const gfx::Rect& bounds_dip); - -+ // Gets a parent window for this window. -+ WaylandWindow* GetParentWindow(gfx::AcceleratedWidget parent_widget); -+ -+ // Sets the buffer scale. -+ void SetBufferScale(int32_t scale, bool update_bounds); -+ -+ // Sets the ui scale. -+ void set_ui_scale(int32_t ui_scale) { ui_scale_ = ui_scale; } -+ - private: - FRIEND_TEST_ALL_PREFIXES(WaylandScreenTest, SetBufferScale); - - // Initializes the WaylandWindow with supplied properties. - bool Initialize(PlatformWindowInitProperties properties); - -- void SetBufferScale(int32_t scale, bool update_bounds); -- -- // Creates a popup window, which is visible as a menu window. -- void CreateShellPopup(); - // Creates (if necessary) and show subsurface window, to host - // tooltip's content. - void CreateAndShowTooltipSubSurface(); - -- // Gets a parent window for this window. -- WaylandWindow* GetParentWindow(gfx::AcceleratedWidget parent_widget); -- - // Returns a root parent window. - WaylandWindow* GetRootParentWindow(); - -@@ -184,9 +193,6 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { - - void UpdateCursorPositionFromEvent(std::unique_ptr<Event> event); - -- // Returns bounds with origin relative to parent window's origin. -- gfx::Rect AdjustPopupWindowPosition() const; -- - WaylandWindow* GetTopLevelWindow(); - - // It's important to set opaque region for opaque windows (provides -@@ -214,10 +220,6 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { - wl::Object<wl_surface> surface_; - wl::Object<wl_subsurface> tooltip_subsurface_; - -- // Wrappers around xdg v5 and xdg v6 objects. WaylandWindow doesn't -- // know anything about the version. -- std::unique_ptr<ShellPopupWrapper> shell_popup_; -- - // The current cursor bitmap (immutable). - scoped_refptr<BitmapCursorOzone> bitmap_; - -@@ -253,6 +255,9 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { - // we ask its parent. - base::flat_set<uint32_t> entered_outputs_ids_; - -+ // The type of the current WaylandWindow object. -+ ui::PlatformWindowType type_ = ui::PlatformWindowType::kWindow; -+ - DISALLOW_COPY_AND_ASSIGN(WaylandWindow); - }; - -diff --git a/ui/ozone/platform/wayland/host/wayland_window_factory.cc b/ui/ozone/platform/wayland/host/wayland_window_factory.cc -index 892902e7f845..4c887fa3c1c8 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window_factory.cc -+++ b/ui/ozone/platform/wayland/host/wayland_window_factory.cc -@@ -6,6 +6,7 @@ - - #include <memory> - -+#include "ui/ozone/platform/wayland/host/wayland_popup.h" - #include "ui/ozone/platform/wayland/host/wayland_surface.h" - #include "ui/ozone/platform/wayland/host/wayland_window.h" - -@@ -21,7 +22,7 @@ std::unique_ptr<WaylandWindow> WaylandWindow::Create( - case PlatformWindowType::kMenu: - case PlatformWindowType::kPopup: - // TODO(msisov): Add WaylandPopup. -- window.reset(new WaylandWindow(delegate, connection)); -+ window.reset(new WaylandPopup(delegate, connection)); - break; - case PlatformWindowType::kTooltip: - // TODO(msisov): Add WaylandSubsurface. -diff --git a/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc b/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc -index e85236ce47d7..62b54680e9e7 100644 ---- a/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc -+++ b/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc -@@ -12,10 +12,11 @@ - #include "base/nix/xdg_util.h" - #include "ui/events/event_constants.h" - #include "ui/gfx/geometry/rect.h" -+#include "ui/ozone/platform/wayland/common/wayland_util.h" - #include "ui/ozone/platform/wayland/host/wayland_connection.h" - #include "ui/ozone/platform/wayland/host/wayland_pointer.h" -+#include "ui/ozone/platform/wayland/host/wayland_popup.h" - #include "ui/ozone/platform/wayland/host/wayland_surface.h" --#include "ui/ozone/platform/wayland/host/wayland_window.h" - #include "ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h" - - namespace ui { -@@ -268,38 +269,46 @@ XDGPopupWrapperImpl::~XDGPopupWrapperImpl() = default; - - bool XDGPopupWrapperImpl::Initialize(WaylandConnection* connection, - const gfx::Rect& bounds) { -- if (connection->shell()) -- return InitializeStable(connection, bounds); -- else if (connection->shell_v6()) -- return InitializeV6(connection, bounds); -- NOTREACHED() << "Wrong shell protocol"; -- return false; --} -- --bool XDGPopupWrapperImpl::InitializeStable(WaylandConnection* connection, -- const gfx::Rect& bounds) { -- static const struct xdg_popup_listener xdg_popup_listener = { -- &XDGPopupWrapperImpl::ConfigureStable, -- &XDGPopupWrapperImpl::PopupDoneStable, -- }; -+ if (!connection->shell() && !connection->shell_v6()) { -+ NOTREACHED() << "Wrong shell protocol"; -+ return false; -+ } - -- XDGSurfaceWrapperImpl* parent_xdg_surface; -+ XDGSurfaceWrapperImpl* parent_xdg_surface = nullptr; - // If the parent window is a popup, the surface of that popup must be used as - // a parent. -- if (wayland_window_->parent_window()->shell_popup()) { -- XDGPopupWrapperImpl* popup = reinterpret_cast<XDGPopupWrapperImpl*>( -- wayland_window_->parent_window()->shell_popup()); -+ if (wl::IsMenuType(wayland_window_->parent_window()->type())) { -+ auto* wayland_popup = -+ static_cast<WaylandPopup*>(wayland_window_->parent_window()); -+ XDGPopupWrapperImpl* popup = -+ static_cast<XDGPopupWrapperImpl*>(wayland_popup->shell_popup()); - parent_xdg_surface = popup->xdg_surface(); - } else { - WaylandSurface* wayland_surface = - static_cast<WaylandSurface*>(wayland_window_->parent_window()); -- parent_xdg_surface = reinterpret_cast<XDGSurfaceWrapperImpl*>( -- wayland_surface->shell_surface()); -+ parent_xdg_surface = -+ static_cast<XDGSurfaceWrapperImpl*>(wayland_surface->shell_surface()); - } - -- if (!parent_xdg_surface) -+ if (!xdg_surface_ || !parent_xdg_surface) - return false; - -+ if (connection->shell()) -+ return InitializeStable(connection, bounds, parent_xdg_surface); -+ else if (connection->shell_v6()) -+ return InitializeV6(connection, bounds, parent_xdg_surface); -+ return false; -+} -+ -+bool XDGPopupWrapperImpl::InitializeStable( -+ WaylandConnection* connection, -+ const gfx::Rect& bounds, -+ XDGSurfaceWrapperImpl* parent_xdg_surface) { -+ static const struct xdg_popup_listener xdg_popup_listener = { -+ &XDGPopupWrapperImpl::ConfigureStable, -+ &XDGPopupWrapperImpl::PopupDoneStable, -+ }; -+ - struct xdg_positioner* positioner = CreatePositionerStable( - connection, wayland_window_->parent_window(), bounds); - if (!positioner) -@@ -369,7 +378,7 @@ struct xdg_positioner* XDGPopupWrapperImpl::CreatePositionerStable( - MenuType menu_type = MenuType::TYPE_UNKNOWN; - if (is_right_click_menu) - menu_type = MenuType::TYPE_RIGHT_CLICK; -- else if (parent_window->shell_popup()) -+ else if (wl::IsMenuType(parent_window->type())) - menu_type = MenuType::TYPE_3DOT_CHILD_MENU; - else - menu_type = MenuType::TYPE_3DOT_PARENT_MENU; -@@ -390,33 +399,15 @@ struct xdg_positioner* XDGPopupWrapperImpl::CreatePositionerStable( - return positioner; - } - --bool XDGPopupWrapperImpl::InitializeV6(WaylandConnection* connection, -- const gfx::Rect& bounds) { -+bool XDGPopupWrapperImpl::InitializeV6( -+ WaylandConnection* connection, -+ const gfx::Rect& bounds, -+ XDGSurfaceWrapperImpl* parent_xdg_surface) { - static const struct zxdg_popup_v6_listener zxdg_popup_v6_listener = { - &XDGPopupWrapperImpl::ConfigureV6, - &XDGPopupWrapperImpl::PopupDoneV6, - }; - -- if (!xdg_surface_) -- return false; -- -- XDGSurfaceWrapperImpl* parent_xdg_surface; -- // If the parent window is a popup, the surface of that popup must be used as -- // a parent. -- if (wayland_window_->parent_window()->shell_popup()) { -- XDGPopupWrapperImpl* popup = reinterpret_cast<XDGPopupWrapperImpl*>( -- wayland_window_->parent_window()->shell_popup()); -- parent_xdg_surface = popup->xdg_surface(); -- } else { -- WaylandSurface* wayland_surface = -- static_cast<WaylandSurface*>(wayland_window_->parent_window()); -- parent_xdg_surface = reinterpret_cast<XDGSurfaceWrapperImpl*>( -- wayland_surface->shell_surface()); -- } -- -- if (!parent_xdg_surface) -- return false; -- - zxdg_positioner_v6* positioner = - CreatePositionerV6(connection, wayland_window_->parent_window(), bounds); - if (!positioner) -@@ -488,7 +479,7 @@ zxdg_positioner_v6* XDGPopupWrapperImpl::CreatePositionerV6( - MenuType menu_type = MenuType::TYPE_UNKNOWN; - if (is_right_click_menu) - menu_type = MenuType::TYPE_RIGHT_CLICK; -- else if (parent_window->shell_popup()) -+ else if (wl::IsMenuType(parent_window->type())) - menu_type = MenuType::TYPE_3DOT_CHILD_MENU; - else - menu_type = MenuType::TYPE_3DOT_PARENT_MENU; -diff --git a/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h b/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h -index 2a900818ff6a..c0479cfff7fb 100644 ---- a/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h -+++ b/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h -@@ -27,12 +27,16 @@ class XDGPopupWrapperImpl : public ShellPopupWrapper { - const gfx::Rect& bounds) override; - - private: -- bool InitializeStable(WaylandConnection* connection, const gfx::Rect& bounds); -+ bool InitializeStable(WaylandConnection* connection, -+ const gfx::Rect& bounds, -+ XDGSurfaceWrapperImpl* parent_xdg_surface); - struct xdg_positioner* CreatePositionerStable(WaylandConnection* connection, - WaylandWindow* parent_window, - const gfx::Rect& bounds); - -- bool InitializeV6(WaylandConnection* connection, const gfx::Rect& bounds); -+ bool InitializeV6(WaylandConnection* connection, -+ const gfx::Rect& bounds, -+ XDGSurfaceWrapperImpl* parent_xdg_surface); - struct zxdg_positioner_v6* CreatePositionerV6(WaylandConnection* connection, - WaylandWindow* parent_window, - const gfx::Rect& bounds); --- -2.24.1 - diff --git a/0007-ozone-wayland-Extract-subsurface-from-WaylandWindow.patch b/0007-ozone-wayland-Extract-subsurface-from-WaylandWindow.patch deleted file mode 100644 index 62ceae75d155..000000000000 --- a/0007-ozone-wayland-Extract-subsurface-from-WaylandWindow.patch +++ /dev/null @@ -1,347 +0,0 @@ -From 33a754dd22a0fa37654b569232ffd606aaa5e3b9 Mon Sep 17 00:00:00 2001 -From: Maksim Sisov <msisov@igalia.com> -Date: Wed, 11 Dec 2019 10:04:19 +0000 -Subject: [PATCH 7/9] ozone/wayland: Extract subsurface from WaylandWindow - -This CL does not bring any functional changes, but rather moves -the subsurface methods to WaylandSubsurface. - -Test: ozone_unittests -Bug: 1028919 -Change-Id: I96dbf21267a80022779cd7eebeb56c96a243128b -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1960265 -Commit-Queue: Maksim Sisov <msisov@igalia.com> -Reviewed-by: Michael Spang <spang@chromium.org> -Cr-Commit-Position: refs/heads/master@{#723758} ---- - ui/ozone/platform/wayland/BUILD.gn | 2 + - .../wayland/host/wayland_subsurface.cc | 80 +++++++++++++++++++ - .../wayland/host/wayland_subsurface.h | 37 +++++++++ - .../platform/wayland/host/wayland_window.cc | 63 ++------------- - .../platform/wayland/host/wayland_window.h | 9 +-- - .../wayland/host/wayland_window_factory.cc | 4 +- - 6 files changed, 127 insertions(+), 68 deletions(-) - create mode 100644 ui/ozone/platform/wayland/host/wayland_subsurface.cc - create mode 100644 ui/ozone/platform/wayland/host/wayland_subsurface.h - -diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn -index 4bfe93352f34..f6f21cdb0161 100644 ---- a/ui/ozone/platform/wayland/BUILD.gn -+++ b/ui/ozone/platform/wayland/BUILD.gn -@@ -93,6 +93,8 @@ source_set("wayland") { - "host/wayland_shm.h", - "host/wayland_shm_buffer.cc", - "host/wayland_shm_buffer.h", -+ "host/wayland_subsurface.cc", -+ "host/wayland_subsurface.h", - "host/wayland_surface.cc", - "host/wayland_surface.h", - "host/wayland_touch.cc", -diff --git a/ui/ozone/platform/wayland/host/wayland_subsurface.cc b/ui/ozone/platform/wayland/host/wayland_subsurface.cc -new file mode 100644 -index 000000000000..d261b910fc97 ---- /dev/null -+++ b/ui/ozone/platform/wayland/host/wayland_subsurface.cc -@@ -0,0 +1,80 @@ -+// Copyright 2019 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "ui/ozone/platform/wayland/host/wayland_subsurface.h" -+ -+#include "ui/ozone/platform/wayland/common/wayland_util.h" -+#include "ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h" -+#include "ui/ozone/platform/wayland/host/wayland_connection.h" -+#include "ui/ozone/platform/wayland/host/wayland_window_manager.h" -+ -+namespace ui { -+ -+WaylandSubsurface::WaylandSubsurface(PlatformWindowDelegate* delegate, -+ WaylandConnection* connection) -+ : WaylandWindow(delegate, connection) {} -+ -+WaylandSubsurface::~WaylandSubsurface() = default; -+ -+void WaylandSubsurface::Show(bool inactive) { -+ CreateSubsurface(); -+ UpdateBufferScale(false); -+} -+ -+void WaylandSubsurface::Hide() { -+ subsurface_.reset(); -+ -+ // Detach buffer from surface in order to completely shutdown menus and -+ // tooltips, and release resources. -+ connection()->buffer_manager_host()->ResetSurfaceContents(GetWidget()); -+} -+ -+bool WaylandSubsurface::IsVisible() const { -+ return !!subsurface_; -+} -+ -+void WaylandSubsurface::CreateSubsurface() { -+ // Since Aura does not not provide a reference parent window, needed by -+ // Wayland, we get the current focused window to place and show the tooltips. -+ auto* parent_window = -+ connection()->wayland_window_manager()->GetCurrentFocusedWindow(); -+ -+ // Tooltip creation is an async operation. By the time Aura actually creates -+ // the tooltip, it is possible that the user has already moved the -+ // mouse/pointer out of the window that triggered the tooptip. In this case, -+ // parent_window is NULL. -+ if (!parent_window) -+ return; -+ -+ wl_subcompositor* subcompositor = connection()->subcompositor(); -+ DCHECK(subcompositor); -+ subsurface_.reset(wl_subcompositor_get_subsurface(subcompositor, surface(), -+ parent_window->surface())); -+ -+ // Chromium positions tooltip windows in screen coordinates, but Wayland -+ // requires them to be in local surface coordinates a.k.a relative to parent -+ // window. -+ const auto parent_bounds_dip = -+ gfx::ScaleToRoundedRect(parent_window->GetBounds(), 1.0 / ui_scale()); -+ auto new_bounds_dip = -+ wl::TranslateBoundsToParentCoordinates(GetBounds(), parent_bounds_dip); -+ auto bounds_px = -+ gfx::ScaleToRoundedRect(new_bounds_dip, ui_scale() / buffer_scale()); -+ -+ DCHECK(subsurface_); -+ // Convert position to DIP. -+ wl_subsurface_set_position(subsurface_.get(), bounds_px.x() / buffer_scale(), -+ bounds_px.y() / buffer_scale()); -+ wl_subsurface_set_desync(subsurface_.get()); -+ wl_surface_commit(parent_window->surface()); -+ connection()->ScheduleFlush(); -+} -+ -+bool WaylandSubsurface::OnInitialize(PlatformWindowInitProperties properties) { -+ // TODO(msisov): if the subsurface is not provided with a parent widget, then -+ // it must always use a focused window -+ return true; -+} -+ -+} // namespace ui -diff --git a/ui/ozone/platform/wayland/host/wayland_subsurface.h b/ui/ozone/platform/wayland/host/wayland_subsurface.h -new file mode 100644 -index 000000000000..fd159a7bd465 ---- /dev/null -+++ b/ui/ozone/platform/wayland/host/wayland_subsurface.h -@@ -0,0 +1,37 @@ -+// Copyright 2019 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SUBSURFACE_H_ -+#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SUBSURFACE_H_ -+ -+#include "ui/ozone/platform/wayland/host/wayland_window.h" -+ -+namespace ui { -+ -+class WaylandSubsurface : public WaylandWindow { -+ public: -+ WaylandSubsurface(PlatformWindowDelegate* delegate, -+ WaylandConnection* connection); -+ ~WaylandSubsurface() override; -+ -+ // PlatformWindow overrides: -+ void Show(bool inactive) override; -+ void Hide() override; -+ bool IsVisible() const override; -+ -+ private: -+ // WaylandWindow overrides: -+ bool OnInitialize(PlatformWindowInitProperties properties) override; -+ -+ // Creates (if necessary) and shows a subsurface window. -+ void CreateSubsurface(); -+ -+ wl::Object<wl_subsurface> subsurface_; -+ -+ DISALLOW_COPY_AND_ASSIGN(WaylandSubsurface); -+}; -+ -+} // namespace ui -+ -+#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SUBSURFACE_H_ -diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc -index 045f922a759e..c752ad3c0048 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window.cc -+++ b/ui/ozone/platform/wayland/host/wayland_window.cc -@@ -75,45 +75,6 @@ gfx::AcceleratedWidget WaylandWindow::GetWidget() const { - return gfx::kNullAcceleratedWidget; - return surface_.id(); - } -- --void WaylandWindow::CreateAndShowTooltipSubSurface() { -- // Since Aura does not not provide a reference parent window, needed by -- // Wayland, we get the current focused window to place and show the tooltips. -- auto* parent_window = -- connection_->wayland_window_manager()->GetCurrentFocusedWindow(); -- -- // Tooltip creation is an async operation. By the time Aura actually creates -- // the tooltip, it is possible that the user has already moved the -- // mouse/pointer out of the window that triggered the tooptip. In this case, -- // parent_window is NULL. -- if (!parent_window) -- return; -- -- wl_subcompositor* subcompositor = connection_->subcompositor(); -- DCHECK(subcompositor); -- tooltip_subsurface_.reset(wl_subcompositor_get_subsurface( -- subcompositor, surface_.get(), parent_window->surface())); -- -- // Chromium positions tooltip windows in screen coordinates, but Wayland -- // requires them to be in local surface coordinates aka relative to parent -- // window. -- const auto parent_bounds_dip = -- gfx::ScaleToRoundedRect(parent_window->GetBounds(), 1.0 / ui_scale_); -- auto new_bounds_dip = -- wl::TranslateBoundsToParentCoordinates(bounds_px_, parent_bounds_dip); -- auto bounds_px = -- gfx::ScaleToRoundedRect(new_bounds_dip, ui_scale_ / buffer_scale_); -- -- DCHECK(tooltip_subsurface_); -- // Convert position to DIP. -- wl_subsurface_set_position(tooltip_subsurface_.get(), -- bounds_px.x() / buffer_scale_, -- bounds_px.y() / buffer_scale_); -- wl_subsurface_set_desync(tooltip_subsurface_.get()); -- wl_surface_commit(parent_window->surface()); -- connection_->ScheduleFlush(); --} -- - void WaylandWindow::SetPointerFocus(bool focus) { - has_pointer_focus_ = focus; - -@@ -125,19 +86,11 @@ void WaylandWindow::SetPointerFocus(bool focus) { - } - - void WaylandWindow::Show(bool inactive) { -- DCHECK(is_tooltip_); -- CreateAndShowTooltipSubSurface(); -- -- UpdateBufferScale(false); -+ NOTREACHED(); - } - - void WaylandWindow::Hide() { -- DCHECK(is_tooltip_); -- tooltip_subsurface_.reset(); -- -- // Detach buffer from surface in order to completely shutdown menus and -- // tooltips, and release resources. -- connection_->buffer_manager_host()->ResetSurfaceContents(GetWidget()); -+ NOTREACHED(); - } - - void WaylandWindow::Close() { -@@ -145,7 +98,8 @@ void WaylandWindow::Close() { - } - - bool WaylandWindow::IsVisible() const { -- return !!tooltip_subsurface_; -+ NOTREACHED(); -+ return false; - } - - void WaylandWindow::PrepareForShutdown() {} -@@ -305,7 +259,7 @@ uint32_t WaylandWindow::DispatchEvent(const PlatformEvent& native_event) { - // Parent window of the main menu window is not a menu, but rather an - // xdg surface. - DCHECK(!wl::IsMenuType(parent_window_->type()) || -- !parent_window_->is_tooltip_); -+ parent_window_->type() != PlatformWindowType::kTooltip); - auto* window = - connection_->wayland_window_manager()->GetCurrentFocusedWindow(); - if (window) { -@@ -377,9 +331,6 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) { - - connection_->wayland_window_manager()->AddWindow(GetWidget(), this); - -- if (type_ == ui::PlatformWindowType::kTooltip) -- is_tooltip_ = true; -- - if (!OnInitialize(std::move(properties))) - return false; - -@@ -544,10 +495,6 @@ bool WaylandWindow::IsOpaqueWindow() const { - return opacity_ == ui::PlatformWindowOpacity::kOpaqueWindow; - } - --bool WaylandWindow::OnInitialize(PlatformWindowInitProperties properties) { -- return true; --} -- - // static - void WaylandWindow::Enter(void* data, - struct wl_surface* wl_surface, -diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h -index 3eca745b38c4..08658f1df87c 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window.h -+++ b/ui/ozone/platform/wayland/host/wayland_window.h -@@ -178,10 +178,6 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { - // Initializes the WaylandWindow with supplied properties. - bool Initialize(PlatformWindowInitProperties properties); - -- // Creates (if necessary) and show subsurface window, to host -- // tooltip's content. -- void CreateAndShowTooltipSubSurface(); -- - // Returns a root parent window. - WaylandWindow* GetRootParentWindow(); - -@@ -202,7 +198,7 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { - bool IsOpaqueWindow() const; - - // Additional initialization of derived classes. -- virtual bool OnInitialize(PlatformWindowInitProperties properties); -+ virtual bool OnInitialize(PlatformWindowInitProperties properties) = 0; - - // wl_surface_listener - static void Enter(void* data, -@@ -218,7 +214,6 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { - WaylandWindow* child_window_ = nullptr; - - wl::Object<wl_surface> surface_; -- wl::Object<wl_subsurface> tooltip_subsurface_; - - // The current cursor bitmap (immutable). - scoped_refptr<BitmapCursorOzone> bitmap_; -@@ -243,8 +238,6 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher { - // Stores current opacity of the window. Set on ::Initialize call. - ui::PlatformWindowOpacity opacity_; - -- bool is_tooltip_ = false; -- - // For top level window, stores IDs of outputs that the window is currently - // rendered at. - // -diff --git a/ui/ozone/platform/wayland/host/wayland_window_factory.cc b/ui/ozone/platform/wayland/host/wayland_window_factory.cc -index 4c887fa3c1c8..869c1d0aa1f8 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window_factory.cc -+++ b/ui/ozone/platform/wayland/host/wayland_window_factory.cc -@@ -7,8 +7,8 @@ - #include <memory> - - #include "ui/ozone/platform/wayland/host/wayland_popup.h" -+#include "ui/ozone/platform/wayland/host/wayland_subsurface.h" - #include "ui/ozone/platform/wayland/host/wayland_surface.h" --#include "ui/ozone/platform/wayland/host/wayland_window.h" - - namespace ui { - -@@ -26,7 +26,7 @@ std::unique_ptr<WaylandWindow> WaylandWindow::Create( - break; - case PlatformWindowType::kTooltip: - // TODO(msisov): Add WaylandSubsurface. -- window.reset(new WaylandWindow(delegate, connection)); -+ window.reset(new WaylandSubsurface(delegate, connection)); - break; - case PlatformWindowType::kWindow: - case PlatformWindowType::kBubble: --- -2.24.1 - diff --git a/0008-ozone-wayland-Recreate-ShellSurface-and-ShellPopup-o.patch b/0008-ozone-wayland-Recreate-ShellSurface-and-ShellPopup-o.patch deleted file mode 100644 index a6c9bc9f2714..000000000000 --- a/0008-ozone-wayland-Recreate-ShellSurface-and-ShellPopup-o.patch +++ /dev/null @@ -1,1148 +0,0 @@ -From 8f007d6dd7e450f4661e49a7053ed64e4cafbc1a Mon Sep 17 00:00:00 2001 -From: Maksim Sisov <msisov@igalia.com> -Date: Thu, 12 Dec 2019 13:22:46 +0000 -Subject: [PATCH 8/9] ozone/wayland: Recreate ShellSurface and ShellPopup on - Show calls. - -In Wayland, there is no explicit method for showing surfaces. Instead, -one must create/destroy resources to trigger mapping of the -base wl_surface and show xdg surfaces and xdg popups on a screen. - -Actually, we have already been doing so for WaylandPopups and -WaylandSubsurfaces, but WaylandSurface just ignored that. - -This CL brings the following changes: -1) WaylandSurface: create ShellSurface on Show and destroy on Hide. -If Show fails, tell the delegate to Close the window. Also, restore -min and max size, title and app id on each Show call. -2) WaylandPopup: do no create ShellPopup on Initialize, but rather -wait until Show call comes. -3) Tests: Instead of unretained implementation, use the template -that creates resources and manages their lifetime automatically -so that MockXdgPopup and MockXdgSurface could be destroyed -automatically once the client destroyes the allocated resources. -4) WaylandSubsurface: do not try to Show if the subsurface has already -shown or do not try to Hide if the subsurface has already been -hidden. -5) Also added 3 tests to exercise above changes. - -SetsPropertiesOnShow - -Test: DestroysCreatesSurfaceOnHideShow, DestroysCreatesPopupsOnHideShow -Bug: 578890 -Change-Id: Ifb873eb1b089775e945705b1254ac048eddbb4e8 -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1961201 -Commit-Queue: Maksim Sisov <msisov@igalia.com> -Reviewed-by: Michael Spang <spang@chromium.org> -Cr-Commit-Position: refs/heads/master@{#724184} ---- - .../platform/wayland/host/wayland_popup.cc | 41 +++-- - .../platform/wayland/host/wayland_popup.h | 2 +- - .../wayland/host/wayland_subsurface.cc | 6 + - .../platform/wayland/host/wayland_surface.cc | 78 +++++--- - .../platform/wayland/host/wayland_surface.h | 18 +- - .../host/wayland_window_manager_unittests.cc | 13 +- - .../wayland/host/wayland_window_unittest.cc | 170 +++++++++++++++--- - ui/ozone/platform/wayland/test/mock_surface.h | 18 +- - .../platform/wayland/test/mock_xdg_popup.cc | 10 +- - .../platform/wayland/test/mock_xdg_popup.h | 6 +- - .../platform/wayland/test/mock_xdg_shell.cc | 9 +- - .../platform/wayland/test/mock_xdg_surface.cc | 116 +++++++----- - .../platform/wayland/test/mock_xdg_surface.h | 69 ++++--- - .../platform/wayland/test/wayland_test.cc | 2 + - 14 files changed, 402 insertions(+), 156 deletions(-) - -diff --git a/ui/ozone/platform/wayland/host/wayland_popup.cc b/ui/ozone/platform/wayland/host/wayland_popup.cc -index 45aac6e51bfc..98cadd54555c 100644 ---- a/ui/ozone/platform/wayland/host/wayland_popup.cc -+++ b/ui/ozone/platform/wayland/host/wayland_popup.cc -@@ -18,9 +18,9 @@ WaylandPopup::WaylandPopup(PlatformWindowDelegate* delegate, - - WaylandPopup::~WaylandPopup() = default; - --void WaylandPopup::CreateShellPopup() { -+bool WaylandPopup::CreateShellPopup() { - if (GetBounds().IsEmpty()) -- return; -+ return false; - - // TODO(jkim): Consider how to support DropArrow window on tabstrip. - // When it starts dragging, as described the protocol, https://goo.gl/1Mskq3, -@@ -30,8 +30,8 @@ void WaylandPopup::CreateShellPopup() { - // a crash when aura::Window is destroyed. - // https://crbug.com/875164 - if (connection()->IsDragInProgress()) { -- LOG(ERROR) << "Wayland can't create a popup window during dragging."; -- return; -+ LOG(WARNING) << "Wayland can't create a popup window during dragging."; -+ return false; - } - - DCHECK(parent_window() && !shell_popup_); -@@ -40,30 +40,40 @@ void WaylandPopup::CreateShellPopup() { - - ShellObjectFactory factory; - shell_popup_ = factory.CreateShellPopupWrapper(connection(), this, bounds_px); -- if (!shell_popup_) -- CHECK(false) << "Failed to create Wayland shell popup"; -+ if (!shell_popup_) { -+ LOG(ERROR) << "Failed to create Wayland shell popup"; -+ return false; -+ } - - parent_window()->set_child_window(this); -+ return true; - } - - void WaylandPopup::Show(bool inactive) { -+ if (shell_popup_) -+ return; -+ - set_keyboard_focus(true); - -- if (!shell_popup_) { -- // When showing a sub-menu after it has been previously shown and hidden, -- // Wayland sends SetBounds prior to Show, and |bounds_px| takes the pixel -- // 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. -- SetBounds(gfx::ScaleToRoundedRect(GetBounds(), 1.0 / ui_scale())); -- CreateShellPopup(); -- connection()->ScheduleFlush(); -+ // When showing a sub-menu after it has been previously shown and hidden, -+ // Wayland sends SetBounds prior to Show, and |bounds_px| takes the pixel -+ // 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. -+ SetBounds(gfx::ScaleToRoundedRect(GetBounds(), 1.0 / ui_scale())); -+ if (!CreateShellPopup()) { -+ Close(); -+ return; - } - - UpdateBufferScale(false); -+ connection()->ScheduleFlush(); - } - - void WaylandPopup::Hide() { -+ if (!shell_popup_) -+ return; -+ - if (child_window()) - child_window()->Hide(); - -@@ -155,7 +165,6 @@ bool WaylandPopup::OnInitialize(PlatformWindowInitProperties properties) { - // If parent window is known in advanced, we may set the scale early. - SetBufferScale(parent_window()->buffer_scale(), false); - set_ui_scale(parent_window()->ui_scale()); -- CreateShellPopup(); - return true; - } - -diff --git a/ui/ozone/platform/wayland/host/wayland_popup.h b/ui/ozone/platform/wayland/host/wayland_popup.h -index 2d45986ba36a..7bc48bb29a06 100644 ---- a/ui/ozone/platform/wayland/host/wayland_popup.h -+++ b/ui/ozone/platform/wayland/host/wayland_popup.h -@@ -32,7 +32,7 @@ class WaylandPopup : public WaylandWindow { - bool OnInitialize(PlatformWindowInitProperties properties) override; - - // Creates a popup window, which is visible as a menu window. -- void CreateShellPopup(); -+ bool CreateShellPopup(); - - // Returns bounds with origin relative to parent window's origin. - gfx::Rect AdjustPopupWindowPosition(); -diff --git a/ui/ozone/platform/wayland/host/wayland_subsurface.cc b/ui/ozone/platform/wayland/host/wayland_subsurface.cc -index d261b910fc97..94ca613ecaf1 100644 ---- a/ui/ozone/platform/wayland/host/wayland_subsurface.cc -+++ b/ui/ozone/platform/wayland/host/wayland_subsurface.cc -@@ -18,11 +18,17 @@ WaylandSubsurface::WaylandSubsurface(PlatformWindowDelegate* delegate, - WaylandSubsurface::~WaylandSubsurface() = default; - - void WaylandSubsurface::Show(bool inactive) { -+ if (subsurface_) -+ return; -+ - CreateSubsurface(); - UpdateBufferScale(false); - } - - void WaylandSubsurface::Hide() { -+ if (!subsurface_) -+ return; -+ - subsurface_.reset(); - - // Detach buffer from surface in order to completely shutdown menus and -diff --git a/ui/ozone/platform/wayland/host/wayland_surface.cc b/ui/ozone/platform/wayland/host/wayland_surface.cc -index cfd4349db885..b800a526e64e 100644 ---- a/ui/ozone/platform/wayland/host/wayland_surface.cc -+++ b/ui/ozone/platform/wayland/host/wayland_surface.cc -@@ -10,6 +10,7 @@ - #include "ui/gfx/native_widget_types.h" - #include "ui/ozone/platform/wayland/host/shell_object_factory.h" - #include "ui/ozone/platform/wayland/host/shell_surface_wrapper.h" -+#include "ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h" - #include "ui/ozone/platform/wayland/host/wayland_connection.h" - #include "ui/platform_window/platform_window_handler/wm_drop_handler.h" - -@@ -35,11 +36,18 @@ WaylandSurface::~WaylandSurface() { - } - } - --void WaylandSurface::CreateShellSurface() { -+bool WaylandSurface::CreateShellSurface() { - ShellObjectFactory factory; - shell_surface_ = factory.CreateShellSurfaceWrapper(connection(), this); -- if (!shell_surface_) -- CHECK(false) << "Failed to initialize Wayland shell surface"; -+ if (!shell_surface_) { -+ LOG(ERROR) << "Failed to create a ShellSurface."; -+ return false; -+ } -+ -+ shell_surface_->SetAppId(app_id_); -+ shell_surface_->SetTitle(window_title_); -+ SetSizeConstraints(); -+ return true; - } - - void WaylandSurface::ApplyPendingBounds() { -@@ -77,12 +85,33 @@ void WaylandSurface::StartDrag(const ui::OSExchangeData& data, - } - - void WaylandSurface::Show(bool inactive) { -+ if (shell_surface_) -+ return; -+ -+ if (!CreateShellSurface()) { -+ Close(); -+ return; -+ } -+ - set_keyboard_focus(true); -- // TODO(msisov): recreate |shell_surface_| on show calls. -+ UpdateBufferScale(false); - } - - void WaylandSurface::Hide() { -- // TODO(msisov): destroy |shell_surface_| on hide calls. -+ if (!shell_surface_) -+ return; -+ -+ if (child_window()) { -+ child_window()->Hide(); -+ set_child_window(nullptr); -+ } -+ -+ shell_surface_.reset(); -+ connection()->ScheduleFlush(); -+ -+ // Detach buffer from surface in order to completely shutdown menus and -+ // tooltips, and release resources. -+ connection()->buffer_manager_host()->ResetSurfaceContents(GetWidget()); - } - - bool WaylandSurface::IsVisible() const { -@@ -92,9 +121,15 @@ bool WaylandSurface::IsVisible() const { - } - - void WaylandSurface::SetTitle(const base::string16& title) { -- DCHECK(shell_surface_); -- shell_surface_->SetTitle(title); -- connection()->ScheduleFlush(); -+ if (window_title_ == title) -+ return; -+ -+ window_title_ = title; -+ -+ if (shell_surface_) { -+ shell_surface_->SetTitle(title); -+ connection()->ScheduleFlush(); -+ } - } - - void WaylandSurface::ToggleFullscreen() { -@@ -178,15 +213,9 @@ void WaylandSurface::SizeConstraintsChanged() { - return; - - DCHECK(delegate()); -- auto min_size = delegate()->GetMinimumSizeForWindow(); -- auto max_size = delegate()->GetMaximumSizeForWindow(); -- -- if (min_size.has_value()) -- shell_surface_->SetMinSize(min_size->width(), min_size->height()); -- if (max_size.has_value()) -- shell_surface_->SetMaxSize(max_size->width(), max_size->height()); -- -- connection()->ScheduleFlush(); -+ min_size_ = delegate()->GetMinimumSizeForWindow(); -+ max_size_ = delegate()->GetMaximumSizeForWindow(); -+ SetSizeConstraints(); - } - - void WaylandSurface::HandleSurfaceConfigure(int32_t width, -@@ -315,10 +344,8 @@ void WaylandSurface::OnDragSessionClose(uint32_t dnd_action) { - } - - bool WaylandSurface::OnInitialize(PlatformWindowInitProperties properties) { -- CreateShellSurface(); -- if (shell_surface_ && !properties.wm_class_class.empty()) -- shell_surface_->SetAppId(properties.wm_class_class); -- return !!shell_surface_; -+ app_id_ = properties.wm_class_class; -+ return true; - } - - bool WaylandSurface::IsMinimized() const { -@@ -345,4 +372,13 @@ WmMoveResizeHandler* WaylandSurface::AsWmMoveResizeHandler() { - return static_cast<WmMoveResizeHandler*>(this); - } - -+void WaylandSurface::SetSizeConstraints() { -+ if (min_size_.has_value()) -+ shell_surface_->SetMinSize(min_size_->width(), min_size_->height()); -+ if (max_size_.has_value()) -+ shell_surface_->SetMaxSize(max_size_->width(), max_size_->height()); -+ -+ connection()->ScheduleFlush(); -+} -+ - } // namespace ui -diff --git a/ui/ozone/platform/wayland/host/wayland_surface.h b/ui/ozone/platform/wayland/host/wayland_surface.h -index 0f7204db3c48..677eaca6ef56 100644 ---- a/ui/ozone/platform/wayland/host/wayland_surface.h -+++ b/ui/ozone/platform/wayland/host/wayland_surface.h -@@ -76,10 +76,13 @@ class WaylandSurface : public WaylandWindow, - void MaybeTriggerPendingStateChange(); - - // Creates a surface window, which is visible as a main window. -- void CreateShellSurface(); -+ bool CreateShellSurface(); - - WmMoveResizeHandler* AsWmMoveResizeHandler(); - -+ // Propagates the |min_size_| and |max_size_| to the ShellSurface. -+ void SetSizeConstraints(); -+ - // Wrappers around shell surface. - std::unique_ptr<ShellSurfaceWrapper> shell_surface_; - -@@ -106,6 +109,19 @@ class WaylandSurface : public WaylandWindow, - bool is_active_ = false; - bool is_minimizing_ = false; - -+ // Id of the chromium app passed through -+ // PlatformWindowInitProperties::wm_class_class. This is used by Wayland -+ // compositor to identify the app, unite it's windows into the same stack of -+ // windows and find *.desktop file to set various preferences including icons. -+ std::string app_id_; -+ -+ // Title of the ShellSurface. -+ base::string16 window_title_; -+ -+ // Max and min sizes of the WaylandSurface window. -+ base::Optional<gfx::Size> min_size_; -+ base::Optional<gfx::Size> max_size_; -+ - DISALLOW_COPY_AND_ASSIGN(WaylandSurface); - }; - -diff --git a/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc b/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc -index 64a387723560..a4b1fc7d9436 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc -+++ b/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc -@@ -36,8 +36,11 @@ class WaylandWindowManagerTest : public WaylandTest { - PlatformWindowInitProperties properties; - properties.bounds = bounds; - properties.type = type; -- return WaylandWindow::Create(delegate, connection_.get(), -- std::move(properties)); -+ auto window = WaylandWindow::Create(delegate, connection_.get(), -+ std::move(properties)); -+ if (window) -+ window->Show(false); -+ return window; - } - - WaylandWindowManager* manager_ = nullptr; -@@ -87,6 +90,9 @@ TEST_P(WaylandWindowManagerTest, GetCurrentFocusedWindow) { - - auto window1 = CreateWaylandWindowWithParams(PlatformWindowType::kWindow, - kDefaultBounds, &delegate); -+ // When window is shown, it automatically gets keyboard focus. Reset it. -+ window_->set_keyboard_focus(false); -+ window1->set_keyboard_focus(false); - - Sync(); - -@@ -121,6 +127,9 @@ TEST_P(WaylandWindowManagerTest, GetCurrentKeyboardFocusedWindow) { - - auto window1 = CreateWaylandWindowWithParams(PlatformWindowType::kWindow, - kDefaultBounds, &delegate); -+ // When window is shown, it automatically gets keyboard focus. Reset it. -+ window_->set_keyboard_focus(false); -+ window1->set_keyboard_focus(false); - - Sync(); - -diff --git a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc -index 132f740b0eb1..f56b96690eea 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc -+++ b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc -@@ -128,11 +128,7 @@ class WaylandWindowTest : public WaylandTest { - } - } - -- // Depending on a shell version, xdg_surface_ or xdg_toplevel surface should -- // get the mock calls. This method decided, which surface to use. -- wl::MockXdgSurface* GetXdgSurface() { -- return xdg_surface_->xdg_toplevel(); -- } -+ wl::MockXdgTopLevel* GetXdgToplevel() { return xdg_surface_->xdg_toplevel(); } - - void AddStateToWlArray(uint32_t state, wl_array* states) { - *static_cast<uint32_t*>(wl_array_add(states, sizeof state)) = state; -@@ -162,8 +158,11 @@ class WaylandWindowTest : public WaylandTest { - properties.type = type; - properties.parent_widget = parent_widget; - -- return WaylandWindow::Create(delegate, connection_.get(), -- std::move(properties)); -+ auto window = WaylandWindow::Create(delegate, connection_.get(), -+ std::move(properties)); -+ if (window) -+ window->Show(false); -+ return window; - } - - void InitializeWithSupportedHitTestValues(std::vector<int>* hit_tests) { -@@ -213,7 +212,7 @@ class WaylandWindowTest : public WaylandTest { - }; - - TEST_P(WaylandWindowTest, SetTitle) { -- EXPECT_CALL(*GetXdgSurface(), SetTitle(StrEq("hello"))); -+ EXPECT_CALL(*GetXdgToplevel(), SetTitle(StrEq("hello"))); - window_->SetTitle(base::ASCIIToUTF16("hello")); - } - -@@ -229,7 +228,7 @@ TEST_P(WaylandWindowTest, MaximizeAndRestore) { - - auto active_maximized = MakeStateArray( - {XDG_TOPLEVEL_STATE_ACTIVATED, XDG_TOPLEVEL_STATE_MAXIMIZED}); -- EXPECT_CALL(*GetXdgSurface(), SetMaximized()); -+ EXPECT_CALL(*GetXdgToplevel(), SetMaximized()); - EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, kMaximizedBounds.width(), - kMaximizedBounds.height())); - EXPECT_CALL(delegate_, OnActivationChanged(Eq(true))); -@@ -267,7 +266,7 @@ TEST_P(WaylandWindowTest, MaximizeAndRestore) { - OnWindowStateChanged(Eq(PlatformWindowState::kNormal))); - EXPECT_CALL(delegate_, OnActivationChanged(_)).Times(0); - EXPECT_CALL(delegate_, OnBoundsChanged(kNormalBounds)); -- EXPECT_CALL(*GetXdgSurface(), UnsetMaximized()); -+ EXPECT_CALL(*GetXdgToplevel(), UnsetMaximized()); - window_->Restore(); - // Reinitialize wl_array, which removes previous old states. - auto active = InitializeWlArrayWithActivatedState(); -@@ -283,7 +282,7 @@ TEST_P(WaylandWindowTest, Minimize) { - SendConfigureEvent(0, 0, 1, states.get()); - Sync(); - -- EXPECT_CALL(*GetXdgSurface(), SetMinimized()); -+ EXPECT_CALL(*GetXdgToplevel(), SetMinimized()); - // Wayland compositor doesn't notify clients about minimized state, but rather - // if a window is not activated. Thus, a WaylandWindow marks itself as being - // minimized and as soon as a configuration event with not activated state -@@ -319,7 +318,7 @@ TEST_P(WaylandWindowTest, SetFullscreenAndRestore) { - - AddStateToWlArray(XDG_TOPLEVEL_STATE_FULLSCREEN, states.get()); - -- EXPECT_CALL(*GetXdgSurface(), SetFullscreen()); -+ EXPECT_CALL(*GetXdgToplevel(), SetFullscreen()); - EXPECT_CALL(delegate_, - OnWindowStateChanged(Eq(PlatformWindowState::kFullScreen))); - window_->ToggleFullscreen(); -@@ -330,7 +329,7 @@ TEST_P(WaylandWindowTest, SetFullscreenAndRestore) { - SendConfigureEvent(0, 0, 2, states.get()); - Sync(); - -- EXPECT_CALL(*GetXdgSurface(), UnsetFullscreen()); -+ EXPECT_CALL(*GetXdgToplevel(), UnsetFullscreen()); - EXPECT_CALL(delegate_, - OnWindowStateChanged(Eq(PlatformWindowState::kNormal))); - window_->Restore(); -@@ -347,7 +346,7 @@ TEST_P(WaylandWindowTest, StartWithFullscreen) { - - // The state must not be changed to the fullscreen before the surface is - // activated. -- EXPECT_CALL(*GetXdgSurface(), SetFullscreen()).Times(0); -+ EXPECT_CALL(*GetXdgToplevel(), SetFullscreen()).Times(0); - EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0); - window_->ToggleFullscreen(); - // The state of the window must still be a normal one. -@@ -357,7 +356,7 @@ TEST_P(WaylandWindowTest, StartWithFullscreen) { - - // Once the surface will be activated, the window will automatically trigger - // the state change. -- EXPECT_CALL(*GetXdgSurface(), SetFullscreen()); -+ EXPECT_CALL(*GetXdgToplevel(), SetFullscreen()); - EXPECT_CALL(delegate_, - OnWindowStateChanged(Eq(PlatformWindowState::kFullScreen))); - -@@ -391,7 +390,7 @@ TEST_P(WaylandWindowTest, SetMaximizedFullscreenAndRestore) { - - auto active_maximized = MakeStateArray( - {XDG_TOPLEVEL_STATE_ACTIVATED, XDG_TOPLEVEL_STATE_MAXIMIZED}); -- EXPECT_CALL(*GetXdgSurface(), SetMaximized()); -+ EXPECT_CALL(*GetXdgToplevel(), SetMaximized()); - EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, kMaximizedBounds.width(), - kMaximizedBounds.height())); - EXPECT_CALL(delegate_, OnActivationChanged(Eq(true))); -@@ -404,7 +403,7 @@ TEST_P(WaylandWindowTest, SetMaximizedFullscreenAndRestore) { - Sync(); - VerifyAndClearExpectations(); - -- EXPECT_CALL(*GetXdgSurface(), SetFullscreen()); -+ EXPECT_CALL(*GetXdgToplevel(), SetFullscreen()); - EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, kMaximizedBounds.width(), - kMaximizedBounds.height())); - EXPECT_CALL(delegate_, OnBoundsChanged(_)).Times(0); -@@ -419,8 +418,8 @@ TEST_P(WaylandWindowTest, SetMaximizedFullscreenAndRestore) { - - EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, kNormalBounds.width(), - kNormalBounds.height())); -- EXPECT_CALL(*GetXdgSurface(), UnsetFullscreen()); -- EXPECT_CALL(*GetXdgSurface(), UnsetMaximized()); -+ EXPECT_CALL(*GetXdgToplevel(), UnsetFullscreen()); -+ EXPECT_CALL(*GetXdgToplevel(), UnsetMaximized()); - EXPECT_CALL(delegate_, OnBoundsChanged(kNormalBounds)); - EXPECT_CALL(delegate_, - OnWindowStateChanged(Eq(PlatformWindowState::kNormal))); -@@ -841,7 +840,7 @@ TEST_P(WaylandWindowTest, CanDispatchEventToMenuWindowNested) { - } - - TEST_P(WaylandWindowTest, DispatchWindowMove) { -- EXPECT_CALL(*GetXdgSurface(), Move(_)); -+ EXPECT_CALL(*GetXdgToplevel(), Move(_)); - ui::GetWmMoveResizeHandler(*window_)->DispatchHostWindowDragMovement(HTCAPTION, gfx::Point()); - } - -@@ -855,7 +854,7 @@ TEST_P(WaylandWindowTest, DispatchWindowResize) { - for (const int value : hit_test_values) { - { - uint32_t direction = wl::IdentifyDirection(*(connection_.get()), value); -- EXPECT_CALL(*GetXdgSurface(), Resize(_, Eq(direction))); -+ EXPECT_CALL(*GetXdgToplevel(), Resize(_, Eq(direction))); - wm_move_resize_handler->DispatchHostWindowDragMovement(value, - gfx::Point()); - } -@@ -1092,7 +1091,7 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) { - // shown on another display. - auto active_maximized = MakeStateArray( - {XDG_TOPLEVEL_STATE_ACTIVATED, XDG_TOPLEVEL_STATE_MAXIMIZED}); -- EXPECT_CALL(*GetXdgSurface(), SetMaximized()); -+ EXPECT_CALL(*GetXdgToplevel(), SetMaximized()); - - window_->Maximize(); - SendConfigureEvent(2493, 1413, 1, active_maximized.get()); -@@ -1252,9 +1251,9 @@ TEST_P(WaylandWindowTest, OnSizeConstraintsChanged) { - EXPECT_CALL(delegate_, GetMaximumSizeForWindow()) - .WillOnce(Return(max_size)); - -- EXPECT_CALL(*GetXdgSurface(), SetMinSize(100, 200)) -+ EXPECT_CALL(*GetXdgToplevel(), SetMinSize(100, 200)) - .Times(has_min_size ? 1 : 0); -- EXPECT_CALL(*GetXdgSurface(), SetMaxSize(300, 400)) -+ EXPECT_CALL(*GetXdgToplevel(), SetMaxSize(300, 400)) - .Times(has_max_size ? 1 : 0); - - window_->SizeConstraintsChanged(); -@@ -1265,6 +1264,129 @@ TEST_P(WaylandWindowTest, OnSizeConstraintsChanged) { - } - } - -+TEST_P(WaylandWindowTest, DestroysCreatesSurfaceOnHideShow) { -+ MockPlatformWindowDelegate delegate; -+ auto window = CreateWaylandWindowWithParams( -+ PlatformWindowType::kWindow, gfx::kNullAcceleratedWidget, -+ gfx::Rect(0, 0, 100, 100), &delegate); -+ ASSERT_TRUE(window); -+ -+ Sync(); -+ -+ auto* mock_surface = server_.GetObject<wl::MockSurface>(window->GetWidget()); -+ EXPECT_TRUE(mock_surface->xdg_surface()); -+ EXPECT_TRUE(mock_surface->xdg_surface()->xdg_toplevel()); -+ -+ Sync(); -+ -+ window->Hide(); -+ -+ Sync(); -+ -+ EXPECT_FALSE(mock_surface->xdg_surface()); -+ -+ window->Show(false); -+ -+ Sync(); -+ -+ EXPECT_TRUE(mock_surface->xdg_surface()); -+ EXPECT_TRUE(mock_surface->xdg_surface()->xdg_toplevel()); -+} -+ -+TEST_P(WaylandWindowTest, DestroysCreatesPopupsOnHideShow) { -+ MockPlatformWindowDelegate delegate; -+ auto window = CreateWaylandWindowWithParams( -+ PlatformWindowType::kMenu, window_->GetWidget(), gfx::Rect(0, 0, 50, 50), -+ &delegate); -+ ASSERT_TRUE(window); -+ -+ Sync(); -+ -+ auto* mock_surface = server_.GetObject<wl::MockSurface>(window->GetWidget()); -+ EXPECT_TRUE(mock_surface->xdg_surface()); -+ EXPECT_TRUE(mock_surface->xdg_surface()->xdg_popup()); -+ -+ Sync(); -+ -+ window->Hide(); -+ -+ Sync(); -+ -+ EXPECT_FALSE(mock_surface->xdg_surface()); -+ -+ window->Show(false); -+ -+ Sync(); -+ -+ EXPECT_TRUE(mock_surface->xdg_surface()); -+ EXPECT_TRUE(mock_surface->xdg_surface()->xdg_popup()); -+} -+ -+// Tests that if the window gets hidden and shown again, the title, app id and -+// size constraints remain the same. -+TEST_P(WaylandWindowTest, SetsPropertiesOnShow) { -+ constexpr char kAppId[] = "wayland_test"; -+ const base::string16 kTitle(base::UTF8ToUTF16("WaylandWindowTest")); -+ -+ PlatformWindowInitProperties properties; -+ properties.bounds = gfx::Rect(0, 0, 100, 100); -+ properties.type = PlatformWindowType::kWindow; -+ properties.wm_class_class = kAppId; -+ -+ MockPlatformWindowDelegate delegate; -+ auto window = WaylandWindow::Create(&delegate, connection_.get(), -+ std::move(properties)); -+ DCHECK(window); -+ window->Show(false); -+ -+ Sync(); -+ -+ auto* mock_surface = server_.GetObject<wl::MockSurface>(window->GetWidget()); -+ auto* mock_xdg_toplevel = mock_surface->xdg_surface()->xdg_toplevel(); -+ -+ // Only app id must be set now. -+ EXPECT_EQ(std::string(kAppId), mock_xdg_toplevel->app_id()); -+ EXPECT_TRUE(mock_xdg_toplevel->title().empty()); -+ EXPECT_TRUE(mock_xdg_toplevel->min_size().IsEmpty()); -+ EXPECT_TRUE(mock_xdg_toplevel->max_size().IsEmpty()); -+ -+ // Now, propagate size constraints and title. -+ base::Optional<gfx::Size> min_size(gfx::Size(1, 1)); -+ base::Optional<gfx::Size> max_size(gfx::Size(100, 100)); -+ EXPECT_CALL(delegate, GetMinimumSizeForWindow()).WillOnce(Return(min_size)); -+ EXPECT_CALL(delegate, GetMaximumSizeForWindow()).WillOnce(Return(max_size)); -+ -+ EXPECT_CALL(*mock_xdg_toplevel, -+ SetMinSize(min_size.value().width(), min_size.value().height())); -+ EXPECT_CALL(*mock_xdg_toplevel, -+ SetMaxSize(max_size.value().width(), max_size.value().height())); -+ EXPECT_CALL(*mock_xdg_toplevel, SetTitle(base::UTF16ToUTF8(kTitle))); -+ -+ window->SetTitle(kTitle); -+ window->SizeConstraintsChanged(); -+ -+ Sync(); -+ -+ window->Hide(); -+ -+ Sync(); -+ -+ window->Show(false); -+ -+ Sync(); -+ -+ mock_xdg_toplevel = mock_surface->xdg_surface()->xdg_toplevel(); -+ -+ // We can't mock all those methods above as long as the xdg_toplevel is -+ // created and destroyed on each show and hide call. However, it is the same -+ // WaylandSurface object that cached the values we set and must restore them -+ // on Show(). -+ EXPECT_EQ(mock_xdg_toplevel->min_size(), min_size.value()); -+ EXPECT_EQ(mock_xdg_toplevel->max_size(), max_size.value()); -+ EXPECT_EQ(std::string(kAppId), mock_xdg_toplevel->app_id()); -+ EXPECT_EQ(mock_xdg_toplevel->title(), base::UTF16ToUTF8(kTitle)); -+} -+ - INSTANTIATE_TEST_SUITE_P(XdgVersionStableTest, - WaylandWindowTest, - ::testing::Values(kXdgShellStable)); -diff --git a/ui/ozone/platform/wayland/test/mock_surface.h b/ui/ozone/platform/wayland/test/mock_surface.h -index 27f7a2c09aab..47dc4680d50b 100644 ---- a/ui/ozone/platform/wayland/test/mock_surface.h -+++ b/ui/ozone/platform/wayland/test/mock_surface.h -@@ -42,15 +42,10 @@ class MockSurface : public ServerObject { - MOCK_METHOD4(DamageBuffer, - void(int32_t x, int32_t y, int32_t width, int32_t height)); - -- void set_xdg_surface(std::unique_ptr<MockXdgSurface> xdg_surface) { -- xdg_surface_ = std::move(xdg_surface); -+ void set_xdg_surface(MockXdgSurface* xdg_surface) { -+ xdg_surface_ = xdg_surface; - } -- MockXdgSurface* xdg_surface() const { return xdg_surface_.get(); } -- -- void set_xdg_popup(std::unique_ptr<MockXdgPopup> xdg_popup) { -- xdg_popup_ = std::move(xdg_popup); -- } -- MockXdgPopup* xdg_popup() const { return xdg_popup_.get(); } -+ MockXdgSurface* xdg_surface() const { return xdg_surface_; } - - void set_sub_surface(TestSubSurface* sub_surface) { - sub_surface_ = sub_surface; -@@ -62,17 +57,14 @@ class MockSurface : public ServerObject { - frame_callback_ = callback_resource; - } - -- bool has_role() const { -- return !!xdg_surface_ || !!xdg_popup_ || !!sub_surface_; -- } -+ bool has_role() const { return !!xdg_surface_ || !!sub_surface_; } - - void AttachNewBuffer(wl_resource* buffer_resource, int32_t x, int32_t y); - void ReleasePrevAttachedBuffer(); - void SendFrameCallback(); - - private: -- std::unique_ptr<MockXdgSurface> xdg_surface_; -- std::unique_ptr<MockXdgPopup> xdg_popup_; -+ MockXdgSurface* xdg_surface_ = nullptr; - TestSubSurface* sub_surface_ = nullptr; - - wl_resource* frame_callback_ = nullptr; -diff --git a/ui/ozone/platform/wayland/test/mock_xdg_popup.cc b/ui/ozone/platform/wayland/test/mock_xdg_popup.cc -index ebf449ca3e55..4a92c79edab0 100644 ---- a/ui/ozone/platform/wayland/test/mock_xdg_popup.cc -+++ b/ui/ozone/platform/wayland/test/mock_xdg_popup.cc -@@ -4,6 +4,8 @@ - - #include "ui/ozone/platform/wayland/test/mock_xdg_popup.h" - -+#include "ui/ozone/platform/wayland/test/mock_xdg_surface.h" -+ - namespace wl { - - namespace { -@@ -27,9 +29,11 @@ const struct zxdg_popup_v6_interface kZxdgPopupV6Impl = { - &Grab, // grab - }; - --MockXdgPopup::MockXdgPopup(wl_resource* resource, const void* implementation) -- : ServerObject(resource) { -- SetImplementationUnretained(resource, implementation, this); -+MockXdgPopup::MockXdgPopup(wl_resource* resource, wl_resource* surface) -+ : ServerObject(resource), surface_(surface) { -+ auto* mock_xdg_surface = GetUserDataAs<MockXdgSurface>(surface_); -+ if (mock_xdg_surface) -+ mock_xdg_surface->set_xdg_popup(nullptr); - } - - MockXdgPopup::~MockXdgPopup() {} -diff --git a/ui/ozone/platform/wayland/test/mock_xdg_popup.h b/ui/ozone/platform/wayland/test/mock_xdg_popup.h -index 27b02361d897..61a805130200 100644 ---- a/ui/ozone/platform/wayland/test/mock_xdg_popup.h -+++ b/ui/ozone/platform/wayland/test/mock_xdg_popup.h -@@ -24,7 +24,7 @@ extern const struct zxdg_popup_v6_interface kZxdgPopupV6Impl; - - class MockXdgPopup : public ServerObject { - public: -- MockXdgPopup(wl_resource* resource, const void* implementation); -+ MockXdgPopup(wl_resource* resource, wl_resource* surface); - ~MockXdgPopup() override; - - MOCK_METHOD1(Grab, void(uint32_t serial)); -@@ -42,9 +42,11 @@ class MockXdgPopup : public ServerObject { - } - - private: -- // Position of the popup. Used only with V6. - struct TestPositioner::PopupPosition position_; - -+ // Ground surface for this popup. -+ wl_resource* surface_ = nullptr; -+ - DISALLOW_COPY_AND_ASSIGN(MockXdgPopup); - }; - -diff --git a/ui/ozone/platform/wayland/test/mock_xdg_shell.cc b/ui/ozone/platform/wayland/test/mock_xdg_shell.cc -index 1ba63d431015..cd76626a1245 100644 ---- a/ui/ozone/platform/wayland/test/mock_xdg_shell.cc -+++ b/ui/ozone/platform/wayland/test/mock_xdg_shell.cc -@@ -29,15 +29,16 @@ void GetXdgSurfaceImpl(wl_client* client, - wl_resource_post_error(resource, xdg_error, "surface already has a role"); - return; - } -- wl_resource* xdg_surface_resource = wl_resource_create( -- client, interface, wl_resource_get_version(resource), id); - -+ wl_resource* xdg_surface_resource = -+ CreateResourceWithImpl<::testing::NiceMock<MockXdgSurface>>( -+ client, interface, wl_resource_get_version(resource), implementation, -+ id, surface_resource); - if (!xdg_surface_resource) { - wl_client_post_no_memory(client); - return; - } -- surface->set_xdg_surface( -- std::make_unique<MockXdgSurface>(xdg_surface_resource, implementation)); -+ surface->set_xdg_surface(GetUserDataAs<MockXdgSurface>(xdg_surface_resource)); - } - - void CreatePositioner(wl_client* client, -diff --git a/ui/ozone/platform/wayland/test/mock_xdg_surface.cc b/ui/ozone/platform/wayland/test/mock_xdg_surface.cc -index 35963f84b963..d0bd03add2bd 100644 ---- a/ui/ozone/platform/wayland/test/mock_xdg_surface.cc -+++ b/ui/ozone/platform/wayland/test/mock_xdg_surface.cc -@@ -4,6 +4,7 @@ - - #include <xdg-shell-unstable-v6-server-protocol.h> - -+#include "ui/ozone/platform/wayland/test/mock_surface.h" - #include "ui/ozone/platform/wayland/test/mock_xdg_popup.h" - #include "ui/ozone/platform/wayland/test/mock_xdg_surface.h" - #include "ui/ozone/platform/wayland/test/test_positioner.h" -@@ -11,18 +12,26 @@ - namespace wl { - - void SetTitle(wl_client* client, wl_resource* resource, const char* title) { -- GetUserDataAs<MockXdgSurface>(resource)->SetTitle(title); -+ auto* toplevel = GetUserDataAs<MockXdgTopLevel>(resource); -+ // As it this can be envoked during construction of the XdgSurface, cache the -+ // result so that tests are able to access that information. -+ toplevel->set_title(title); -+ toplevel->SetTitle(toplevel->title()); - } - - void SetAppId(wl_client* client, wl_resource* resource, const char* app_id) { -- GetUserDataAs<MockXdgSurface>(resource)->SetAppId(app_id); -+ auto* toplevel = GetUserDataAs<MockXdgTopLevel>(resource); -+ toplevel->SetAppId(app_id); -+ // As it this can be envoked during construction of the XdgSurface, cache the -+ // result so that tests are able to access that information. -+ toplevel->set_app_id(app_id); - } - - void Move(wl_client* client, - wl_resource* resource, - wl_resource* seat, - uint32_t serial) { -- GetUserDataAs<MockXdgSurface>(resource)->Move(serial); -+ GetUserDataAs<MockXdgTopLevel>(resource)->Move(serial); - } - - void Resize(wl_client* client, -@@ -30,7 +39,7 @@ void Resize(wl_client* client, - wl_resource* seat, - uint32_t serial, - uint32_t edges) { -- GetUserDataAs<MockXdgSurface>(resource)->Resize(serial, edges); -+ GetUserDataAs<MockXdgTopLevel>(resource)->Resize(serial, edges); - } - - void AckConfigure(wl_client* client, wl_resource* resource, uint32_t serial) { -@@ -48,25 +57,47 @@ void SetWindowGeometry(wl_client* client, - } - - void SetMaximized(wl_client* client, wl_resource* resource) { -- GetUserDataAs<MockXdgSurface>(resource)->SetMaximized(); -+ GetUserDataAs<MockXdgTopLevel>(resource)->SetMaximized(); - } - - void UnsetMaximized(wl_client* client, wl_resource* resource) { -- GetUserDataAs<MockXdgSurface>(resource)->UnsetMaximized(); -+ GetUserDataAs<MockXdgTopLevel>(resource)->UnsetMaximized(); - } - - void SetFullscreen(wl_client* client, - wl_resource* resource, - wl_resource* output) { -- GetUserDataAs<MockXdgSurface>(resource)->SetFullscreen(); -+ GetUserDataAs<MockXdgTopLevel>(resource)->SetFullscreen(); - } - - void UnsetFullscreen(wl_client* client, wl_resource* resource) { -- GetUserDataAs<MockXdgSurface>(resource)->UnsetFullscreen(); -+ GetUserDataAs<MockXdgTopLevel>(resource)->UnsetFullscreen(); - } - - void SetMinimized(wl_client* client, wl_resource* resource) { -- GetUserDataAs<MockXdgSurface>(resource)->SetMinimized(); -+ GetUserDataAs<MockXdgTopLevel>(resource)->SetMinimized(); -+} -+ -+void SetMaxSize(wl_client* client, -+ wl_resource* resource, -+ int32_t width, -+ int32_t height) { -+ auto* toplevel = GetUserDataAs<MockXdgTopLevel>(resource); -+ toplevel->SetMaxSize(width, height); -+ // As it this can be envoked during construction of the XdgSurface, cache the -+ // result so that tests are able to access that information. -+ toplevel->set_max_size(gfx::Size(width, height)); -+} -+ -+void SetMinSize(wl_client* client, -+ wl_resource* resource, -+ int32_t width, -+ int32_t height) { -+ auto* toplevel = GetUserDataAs<MockXdgTopLevel>(resource); -+ toplevel->SetMinSize(width, height); -+ // As it this can be envoked during construction of the XdgSurface, cache the -+ // result so that tests are able to access that information. -+ toplevel->set_min_size(gfx::Size(width, height)); - } - - void GetTopLevel(wl_client* client, wl_resource* resource, uint32_t id) { -@@ -120,13 +151,22 @@ void GetXdgPopup(struct wl_client* client, - return; - } - -- wl_resource* xdg_popup_resource = wl_resource_create( -- client, &xdg_popup_interface, wl_resource_get_version(resource), id); -+ wl_resource* xdg_popup_resource = -+ CreateResourceWithImpl<::testing::NiceMock<MockXdgPopup>>( -+ client, &xdg_popup_interface, wl_resource_get_version(resource), -+ &kXdgPopupImpl, id, resource); -+ -+ if (!xdg_popup_resource) { -+ wl_client_post_no_memory(client); -+ return; -+ } -+ -+ auto* mock_xdg_popup = GetUserDataAs<MockXdgPopup>(xdg_popup_resource); -+ DCHECK(mock_xdg_popup); -+ - auto* positioner = GetUserDataAs<TestPositioner>(positioner_resource); - DCHECK(positioner); - -- auto mock_xdg_popup = -- std::make_unique<MockXdgPopup>(xdg_popup_resource, &kXdgPopupImpl); - mock_xdg_popup->set_position(positioner->position()); - if (mock_xdg_popup->size().IsEmpty() || - mock_xdg_popup->anchor_rect().IsEmpty()) { -@@ -135,7 +175,7 @@ void GetXdgPopup(struct wl_client* client, - return; - } - -- mock_xdg_surface->set_xdg_popup(std::move(mock_xdg_popup)); -+ mock_xdg_surface->set_xdg_popup(mock_xdg_popup); - } - - void GetZXdgPopupV6(struct wl_client* client, -@@ -156,13 +196,22 @@ void GetZXdgPopupV6(struct wl_client* client, - return; - } - -- wl_resource* xdg_popup_resource = wl_resource_create( -- client, &zxdg_popup_v6_interface, wl_resource_get_version(resource), id); -+ wl_resource* xdg_popup_resource = -+ CreateResourceWithImpl<::testing::NiceMock<MockXdgPopup>>( -+ client, &zxdg_popup_v6_interface, wl_resource_get_version(resource), -+ &kZxdgPopupV6Impl, id, resource); -+ -+ if (!xdg_popup_resource) { -+ wl_client_post_no_memory(client); -+ return; -+ } -+ -+ auto* mock_xdg_popup = GetUserDataAs<MockXdgPopup>(xdg_popup_resource); -+ DCHECK(mock_xdg_popup); -+ - auto* positioner = GetUserDataAs<TestPositioner>(positioner_resource); - DCHECK(positioner); - -- auto mock_xdg_popup = -- std::make_unique<MockXdgPopup>(xdg_popup_resource, &kZxdgPopupV6Impl); - mock_xdg_popup->set_position(positioner->position()); - if (mock_xdg_popup->size().IsEmpty() || - mock_xdg_popup->anchor_rect().IsEmpty()) { -@@ -171,21 +220,7 @@ void GetZXdgPopupV6(struct wl_client* client, - return; - } - -- mock_xdg_surface->set_xdg_popup(std::move(mock_xdg_popup)); --} -- --void SetMaxSize(wl_client* client, -- wl_resource* resource, -- int32_t width, -- int32_t height) { -- GetUserDataAs<MockXdgSurface>(resource)->SetMaxSize(width, height); --} -- --void SetMinSize(wl_client* client, -- wl_resource* resource, -- int32_t width, -- int32_t height) { -- GetUserDataAs<MockXdgSurface>(resource)->SetMinSize(width, height); -+ mock_xdg_surface->set_xdg_popup(mock_xdg_popup); - } - - const struct xdg_surface_interface kMockXdgSurfaceImpl = { -@@ -238,17 +273,18 @@ const struct zxdg_toplevel_v6_interface kMockZxdgToplevelV6Impl = { - &SetMinimized, // set_minimized - }; - --MockXdgSurface::MockXdgSurface(wl_resource* resource, -- const void* implementation) -- : ServerObject(resource) { -- SetImplementationUnretained(resource, implementation, this); --} -+MockXdgSurface::MockXdgSurface(wl_resource* resource, wl_resource* surface) -+ : ServerObject(resource), surface_(surface) {} - --MockXdgSurface::~MockXdgSurface() {} -+MockXdgSurface::~MockXdgSurface() { -+ auto* mock_surface = GetUserDataAs<MockSurface>(surface_); -+ if (mock_surface) -+ mock_surface->set_xdg_surface(nullptr); -+} - - MockXdgTopLevel::MockXdgTopLevel(wl_resource* resource, - const void* implementation) -- : MockXdgSurface(resource, implementation) { -+ : ServerObject(resource) { - SetImplementationUnretained(resource, implementation, this); - } - -diff --git a/ui/ozone/platform/wayland/test/mock_xdg_surface.h b/ui/ozone/platform/wayland/test/mock_xdg_surface.h -index 20e0f96bdfcb..c41a6ed8fa32 100644 ---- a/ui/ozone/platform/wayland/test/mock_xdg_surface.h -+++ b/ui/ozone/platform/wayland/test/mock_xdg_surface.h -@@ -30,60 +30,71 @@ class MockXdgTopLevel; - // UI. - class MockXdgSurface : public ServerObject { - public: -- MockXdgSurface(wl_resource* resource, const void* implementation); -+ MockXdgSurface(wl_resource* resource, wl_resource* surface); - ~MockXdgSurface() override; - -- // These mock methods are shared between xdg_surface and zxdg_toplevel -- // surface. -- MOCK_METHOD1(SetParent, void(wl_resource* parent)); -- MOCK_METHOD1(SetTitle, void(const char* title)); -- MOCK_METHOD1(SetAppId, void(const char* app_id)); -- MOCK_METHOD1(Move, void(uint32_t serial)); -- MOCK_METHOD2(Resize, void(uint32_t serial, uint32_t edges)); - MOCK_METHOD1(AckConfigure, void(uint32_t serial)); - MOCK_METHOD4(SetWindowGeometry, - void(int32_t x, int32_t y, int32_t width, int32_t height)); -- MOCK_METHOD0(SetMaximized, void()); -- MOCK_METHOD0(UnsetMaximized, void()); -- MOCK_METHOD0(SetFullscreen, void()); -- MOCK_METHOD0(UnsetFullscreen, void()); -- MOCK_METHOD0(SetMinimized, void()); -- -- // These methods are for zxdg_toplevel only. -- MOCK_METHOD2(SetMaxSize, void(int32_t width, int32_t height)); -- MOCK_METHOD2(SetMinSize, void(int32_t width, int32_t height)); - - void set_xdg_toplevel(std::unique_ptr<MockXdgTopLevel> xdg_toplevel) { - xdg_toplevel_ = std::move(xdg_toplevel); - } - MockXdgTopLevel* xdg_toplevel() const { return xdg_toplevel_.get(); } - -- void set_xdg_popup(std::unique_ptr<MockXdgPopup> xdg_popup) { -- xdg_popup_ = std::move(xdg_popup); -- } -- MockXdgPopup* xdg_popup() const { return xdg_popup_.get(); } -+ void set_xdg_popup(MockXdgPopup* xdg_popup) { xdg_popup_ = xdg_popup; } -+ MockXdgPopup* xdg_popup() const { return xdg_popup_; } - - private: -- // Used when xdg v6 is used. -+ // Has either toplevel role.. - std::unique_ptr<MockXdgTopLevel> xdg_toplevel_; -+ // Or popup role. -+ MockXdgPopup* xdg_popup_ = nullptr; - -- std::unique_ptr<MockXdgPopup> xdg_popup_; -+ // MockSurface that is the ground for this xdg_surface. -+ wl_resource* surface_ = nullptr; - - DISALLOW_COPY_AND_ASSIGN(MockXdgSurface); - }; - - // Manage zxdg_toplevel for providing desktop UI. --class MockXdgTopLevel : public MockXdgSurface { -+class MockXdgTopLevel : public ServerObject { - public: -- explicit MockXdgTopLevel(wl_resource* resource, const void* implementation); -+ MockXdgTopLevel(wl_resource* resource, const void* implementation); - ~MockXdgTopLevel() override; - -- // TODO(msisov): mock other zxdg_toplevel specific methods once -- // implementation -- // is done. example: MOCK_METHOD2(SetMaxSize, void(int32_t width, int32_t -- // height()); -+ MOCK_METHOD1(SetParent, void(wl_resource* parent)); -+ MOCK_METHOD1(SetTitle, void(const std::string& title)); -+ MOCK_METHOD1(SetAppId, void(const char* app_id)); -+ MOCK_METHOD1(Move, void(uint32_t serial)); -+ MOCK_METHOD2(Resize, void(uint32_t serial, uint32_t edges)); -+ MOCK_METHOD0(SetMaximized, void()); -+ MOCK_METHOD0(UnsetMaximized, void()); -+ MOCK_METHOD0(SetFullscreen, void()); -+ MOCK_METHOD0(UnsetFullscreen, void()); -+ MOCK_METHOD0(SetMinimized, void()); -+ MOCK_METHOD2(SetMaxSize, void(int32_t width, int32_t height)); -+ MOCK_METHOD2(SetMinSize, void(int32_t width, int32_t height)); -+ -+ const std::string& app_id() const { return app_id_; } -+ void set_app_id(const char* app_id) { app_id_ = std::string(app_id); } -+ -+ std::string title() const { return title_; } -+ void set_title(const char* title) { title_ = std::string(title); } -+ -+ const gfx::Size& min_size() const { return min_size_; } -+ void set_min_size(const gfx::Size& min_size) { min_size_ = min_size; } -+ -+ const gfx::Size& max_size() const { return max_size_; } -+ void set_max_size(const gfx::Size& max_size) { max_size_ = max_size; } - - private: -+ gfx::Size min_size_; -+ gfx::Size max_size_; -+ -+ std::string title_; -+ std::string app_id_; -+ - DISALLOW_COPY_AND_ASSIGN(MockXdgTopLevel); - }; - -diff --git a/ui/ozone/platform/wayland/test/wayland_test.cc b/ui/ozone/platform/wayland/test/wayland_test.cc -index 2543981d8c38..2866ab6a07f8 100644 ---- a/ui/ozone/platform/wayland/test/wayland_test.cc -+++ b/ui/ozone/platform/wayland/test/wayland_test.cc -@@ -55,6 +55,8 @@ void WaylandTest::SetUp() { - std::move(properties)); - ASSERT_NE(widget_, gfx::kNullAcceleratedWidget); - -+ window_->Show(false); -+ - // Wait for the client to flush all pending requests from initialization. - base::RunLoop().RunUntilIdle(); - --- -2.24.1 - diff --git a/0009-ozone-wayland-window-state-change-must-be-synchronou.patch b/0009-ozone-wayland-window-state-change-must-be-synchronou.patch deleted file mode 100644 index 1386e82e4e62..000000000000 --- a/0009-ozone-wayland-window-state-change-must-be-synchronou.patch +++ /dev/null @@ -1,665 +0,0 @@ -From f70d9e1475b402cc70ff0b4539c26ff86ef1116c Mon Sep 17 00:00:00 2001 -From: Maksim Sisov <msisov@igalia.com> -Date: Tue, 7 Jan 2020 18:17:05 +0000 -Subject: [PATCH 9/9] ozone/wayland: window state change must be synchronous. - -This CL fixes two issues: - -1) After we changed to only create ShellSurfaces after Show calls, starting the -browser with maximized or fullscreen modes broke. That is, in Wayland, it -is required to assign a role to wl_surface and make higher level objects like -xdg_surface and xdg_toplevel that are used by desktop xdg shell. - -State manipulation can only be done through those higher level objects and -we must defer setting state to maximized/fullscreen until they are created. - -2) Also, this CL changes the intermidiate result of state changes: now, all of -them are considered synchronous and if Wayland decides to change the state -to something else, the state will be overriden and OnWindowStateChange will -be called. Otherwise, if it was the client, who changed the state, no -notification is sent. - -Test: StartMaximized, StartWithFullscreen, CompositorSideChanges -Bug: 1033525 - -Change-Id: I89728297d572d62db59f2d3b1628f2d735dbd4b0 -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1965031 -Reviewed-by: Michael Spang <spang@chromium.org> -Commit-Queue: Maksim Sisov <msisov@igalia.com> -Cr-Commit-Position: refs/heads/master@{#728996} ---- - .../platform/wayland/host/wayland_surface.cc | 173 ++++++-------- - .../platform/wayland/host/wayland_surface.h | 17 +- - .../wayland/host/wayland_window_unittest.cc | 212 +++++++++++++++--- - 3 files changed, 249 insertions(+), 153 deletions(-) - -diff --git a/ui/ozone/platform/wayland/host/wayland_surface.cc b/ui/ozone/platform/wayland/host/wayland_surface.cc -index b800a526e64e..c90e499fc796 100644 ---- a/ui/ozone/platform/wayland/host/wayland_surface.cc -+++ b/ui/ozone/platform/wayland/host/wayland_surface.cc -@@ -19,8 +19,7 @@ namespace ui { - WaylandSurface::WaylandSurface(PlatformWindowDelegate* delegate, - WaylandConnection* connection) - : WaylandWindow(delegate, connection), -- state_(PlatformWindowState::kNormal), -- pending_state_(PlatformWindowState::kUnknown) { -+ state_(PlatformWindowState::kNormal) { - // Set a class property key, which allows |this| to be used for interactive - // events, e.g. move or resize. - SetWmMoveResizeHandler(this, AsWmMoveResizeHandler()); -@@ -47,6 +46,7 @@ bool WaylandSurface::CreateShellSurface() { - shell_surface_->SetAppId(app_id_); - shell_surface_->SetTitle(window_title_); - SetSizeConstraints(); -+ TriggerStateChanges(); - return true; - } - -@@ -117,7 +117,7 @@ void WaylandSurface::Hide() { - bool WaylandSurface::IsVisible() const { - // X and Windows return true if the window is minimized. For consistency, do - // the same. -- return !!shell_surface_ || IsMinimized(); -+ return !!shell_surface_ || state_ == PlatformWindowState::kMinimized; - } - - void WaylandSurface::SetTitle(const base::string16& title) { -@@ -133,74 +133,36 @@ void WaylandSurface::SetTitle(const base::string16& title) { - } - - void WaylandSurface::ToggleFullscreen() { -- DCHECK(shell_surface_); -- -- // There are some cases, when Chromium triggers a fullscreen state change -- // before the surface is activated. In such cases, Wayland may ignore state -- // changes and such flags as --kiosk or --start-fullscreen will be ignored. -- // To overcome this, set a pending state, and once the surface is activated, -- // trigger the change. -- if (!is_active_) { -- DCHECK(!IsFullscreen()); -- pending_state_ = PlatformWindowState::kFullScreen; -- return; -- } -- - // TODO(msisov, tonikitoo): add multiscreen support. As the documentation says -- // if shell_surface_set_fullscreen() is not provided with wl_output, it's up -+ // if xdg_toplevel_set_fullscreen() is not provided with wl_output, it's up - // to the compositor to choose which display will be used to map this surface. -- if (!IsFullscreen()) { -- // Fullscreen state changes have to be handled manually and then checked -- // against configuration events, which come from a compositor. The reason -- // of manually changing the |state_| is that the compositor answers about -- // state changes asynchronously, which leads to a wrong return value in -- // DesktopWindowTreeHostPlatform::IsFullscreen, for example, and media -- // files can never be set to fullscreen. -- state_ = PlatformWindowState::kFullScreen; -- shell_surface_->SetFullscreen(); -+ -+ // We must track the previous state to correctly say our state as long as it -+ // can be the maximized instead of normal one. -+ PlatformWindowState new_state = PlatformWindowState::kUnknown; -+ if (state_ == PlatformWindowState::kFullScreen) { -+ if (previous_state_ == PlatformWindowState::kMaximized) -+ new_state = previous_state_; -+ else -+ new_state = PlatformWindowState::kNormal; - } else { -- // Check the comment above. If it's not handled synchronously, media files -- // may not leave the fullscreen mode. -- state_ = PlatformWindowState::kUnknown; -- shell_surface_->UnSetFullscreen(); -+ new_state = PlatformWindowState::kFullScreen; - } - -- connection()->ScheduleFlush(); -+ SetWindowState(new_state); - } - - void WaylandSurface::Maximize() { -- DCHECK(shell_surface_); -- -- if (IsFullscreen()) -- ToggleFullscreen(); -- -- shell_surface_->SetMaximized(); -- connection()->ScheduleFlush(); -+ SetWindowState(PlatformWindowState::kMaximized); - } - - void WaylandSurface::Minimize() { -- DCHECK(shell_surface_); -- DCHECK(!is_minimizing_); -- // Wayland doesn't explicitly say if a window is minimized. Instead, it -- // notifies that the window is not activated. But there are many cases, when -- // the window is not minimized and deactivated. In order to properly record -- // the minimized state, mark this window as being minimized. And as soon as a -- // configuration event comes, check if the window has been deactivated and has -- // |is_minimizing_| set. -- is_minimizing_ = true; -- shell_surface_->SetMinimized(); -- connection()->ScheduleFlush(); -+ SetWindowState(PlatformWindowState::kMinimized); - } - - void WaylandSurface::Restore() { - DCHECK(shell_surface_); -- -- // Unfullscreen the window if it is fullscreen. -- if (IsFullscreen()) -- ToggleFullscreen(); -- -- shell_surface_->UnSetMaximized(); -- connection()->ScheduleFlush(); -+ SetWindowState(PlatformWindowState::kNormal); - } - - PlatformWindowState WaylandSurface::GetPlatformWindowState() const { -@@ -223,34 +185,21 @@ void WaylandSurface::HandleSurfaceConfigure(int32_t width, - bool is_maximized, - bool is_fullscreen, - bool is_activated) { -- // Propagate the window state information to the client. -+ // Store the old state to propagte state changes if Wayland decides to change -+ // the state to something else. - PlatformWindowState old_state = state_; -- -- // Ensure that manually handled state changes to fullscreen correspond to the -- // configuration events from a compositor. -- DCHECK_EQ(is_fullscreen, IsFullscreen()); -- -- // There are two cases, which must be handled for the minimized state. -- // The first one is the case, when the surface goes into the minimized state -- // (check comment in WaylandSurface::Minimize), and the second case is when -- // the surface still has been minimized, but another configuration event with -- // !is_activated comes. For this, check if the WaylandSurface has been -- // minimized before and !is_activated is sent. -- if ((is_minimizing_ || IsMinimized()) && !is_activated) { -- is_minimizing_ = false; -+ if (state_ == PlatformWindowState::kMinimized && !is_activated) { - state_ = PlatformWindowState::kMinimized; - } else if (is_fullscreen) { -- // To ensure the |delegate()| is notified about state changes to fullscreen, -- // assume the old_state is UNKNOWN (check comment in ToggleFullscreen). -- old_state = PlatformWindowState::kUnknown; -- DCHECK(state_ == PlatformWindowState::kFullScreen); -+ state_ = PlatformWindowState::kFullScreen; - } else if (is_maximized) { - state_ = PlatformWindowState::kMaximized; - } else { - state_ = PlatformWindowState::kNormal; - } -+ - const bool state_changed = old_state != state_; -- const bool is_normal = !IsFullscreen() && !IsMaximized(); -+ const bool is_normal = state_ == PlatformWindowState::kNormal; - - // Update state before notifying delegate. - const bool did_active_change = is_active_ != is_activated; -@@ -281,28 +230,17 @@ void WaylandSurface::HandleSurfaceConfigure(int32_t width, - 1.0 / buffer_scale())); - } - -- if (state_changed) { -- // The |restored_bounds_| are used when the window gets back to normal -- // state after it went maximized or fullscreen. So we reset these if the -- // window has just become normal and store the current bounds if it is -- // either going out of normal state or simply changes the state and we don't -- // have any meaningful value stored. -- if (is_normal) { -- SetRestoredBoundsInPixels({}); -- } else if (old_state == PlatformWindowState::kNormal || -- GetRestoredBoundsInPixels().IsEmpty()) { -- SetRestoredBoundsInPixels(GetBounds()); -- } -+ // Store the restored bounds of current state differs from the normal state. -+ // It can be client or compositor side change from normal to something else. -+ // Thus, we must store previous bounds to restore later. -+ SetOrResetRestoredBounds(); -+ ApplyPendingBounds(); - -+ if (state_changed) - delegate()->OnWindowStateChanged(state_); -- } -- -- ApplyPendingBounds(); - - if (did_active_change) - delegate()->OnActivationChanged(is_active_); -- -- MaybeTriggerPendingStateChange(); - } - - void WaylandSurface::OnDragEnter(const gfx::PointF& point, -@@ -348,24 +286,34 @@ bool WaylandSurface::OnInitialize(PlatformWindowInitProperties properties) { - return true; - } - --bool WaylandSurface::IsMinimized() const { -- return state_ == PlatformWindowState::kMinimized; --} -+void WaylandSurface::TriggerStateChanges() { -+ if (!shell_surface_) -+ return; - --bool WaylandSurface::IsMaximized() const { -- return state_ == PlatformWindowState::kMaximized; --} -+ if (state_ == PlatformWindowState::kFullScreen) -+ shell_surface_->SetFullscreen(); -+ else -+ shell_surface_->UnSetFullscreen(); -+ -+ // Call UnSetMaximized only if current state is normal. Otherwise, if the -+ // current state is fullscreen and the previous is maximized, calling -+ // UnSetMaximized may result in wrong restored window position that clients -+ // are not allowed to know about. -+ if (state_ == PlatformWindowState::kMaximized) -+ shell_surface_->SetMaximized(); -+ else if (state_ == PlatformWindowState::kNormal) -+ shell_surface_->UnSetMaximized(); -+ -+ if (state_ == PlatformWindowState::kMinimized) -+ shell_surface_->SetMinimized(); - --bool WaylandSurface::IsFullscreen() const { -- return state_ == PlatformWindowState::kFullScreen; -+ connection()->ScheduleFlush(); - } - --void WaylandSurface::MaybeTriggerPendingStateChange() { -- if (pending_state_ == PlatformWindowState::kUnknown || !is_active_) -- return; -- DCHECK_EQ(pending_state_, PlatformWindowState::kFullScreen); -- pending_state_ = PlatformWindowState::kUnknown; -- ToggleFullscreen(); -+void WaylandSurface::SetWindowState(PlatformWindowState state) { -+ previous_state_ = state_; -+ state_ = state; -+ TriggerStateChanges(); - } - - WmMoveResizeHandler* WaylandSurface::AsWmMoveResizeHandler() { -@@ -381,4 +329,17 @@ void WaylandSurface::SetSizeConstraints() { - connection()->ScheduleFlush(); - } - -+void WaylandSurface::SetOrResetRestoredBounds() { -+ // The |restored_bounds_| are used when the window gets back to normal -+ // state after it went maximized or fullscreen. So we reset these if the -+ // window has just become normal and store the current bounds if it is -+ // either going out of normal state or simply changes the state and we don't -+ // have any meaningful value stored. -+ if (GetPlatformWindowState() == PlatformWindowState::kNormal) { -+ SetRestoredBoundsInPixels({}); -+ } else if (GetRestoredBoundsInPixels().IsEmpty()) { -+ SetRestoredBoundsInPixels(GetBounds()); -+ } -+} -+ - } // namespace ui -diff --git a/ui/ozone/platform/wayland/host/wayland_surface.h b/ui/ozone/platform/wayland/host/wayland_surface.h -index 677eaca6ef56..ceda32d24a7c 100644 ---- a/ui/ozone/platform/wayland/host/wayland_surface.h -+++ b/ui/ozone/platform/wayland/host/wayland_surface.h -@@ -69,11 +69,8 @@ class WaylandSurface : public WaylandWindow, - void OnDragSessionClose(uint32_t dnd_action) override; - bool OnInitialize(PlatformWindowInitProperties properties) override; - -- bool IsMinimized() const; -- bool IsMaximized() const; -- bool IsFullscreen() const; -- -- void MaybeTriggerPendingStateChange(); -+ void TriggerStateChanges(); -+ void SetWindowState(PlatformWindowState state); - - // Creates a surface window, which is visible as a main window. - bool CreateShellSurface(); -@@ -83,6 +80,8 @@ class WaylandSurface : public WaylandWindow, - // Propagates the |min_size_| and |max_size_| to the ShellSurface. - void SetSizeConstraints(); - -+ void SetOrResetRestoredBounds(); -+ - // Wrappers around shell surface. - std::unique_ptr<ShellSurfaceWrapper> shell_surface_; - -@@ -100,14 +99,12 @@ class WaylandSurface : public WaylandWindow, - // handler that receives DIP from Wayland. - gfx::Rect pending_bounds_dip_; - -- // Stores current states of the window. -+ // Contains the current state of the window. - PlatformWindowState state_; -- // Stores a pending state of the window, which is used before the surface is -- // activated. -- PlatformWindowState pending_state_; -+ // Contains the previous state of the window. -+ PlatformWindowState previous_state_; - - bool is_active_ = false; -- bool is_minimizing_ = false; - - // Id of the chromium app passed through - // PlatformWindowInitProperties::wm_class_class. This is used by Wayland -diff --git a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc -index f56b96690eea..c72d27edff66 100644 ---- a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc -+++ b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc -@@ -233,8 +233,7 @@ TEST_P(WaylandWindowTest, MaximizeAndRestore) { - kMaximizedBounds.height())); - EXPECT_CALL(delegate_, OnActivationChanged(Eq(true))); - EXPECT_CALL(delegate_, OnBoundsChanged(kMaximizedBounds)); -- EXPECT_CALL(delegate_, -- OnWindowStateChanged(Eq(PlatformWindowState::kMaximized))); -+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0); - window_->Maximize(); - SendConfigureEvent(kMaximizedBounds.width(), kMaximizedBounds.height(), 1, - active_maximized.get()); -@@ -262,8 +261,7 @@ TEST_P(WaylandWindowTest, MaximizeAndRestore) { - - EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, kNormalBounds.width(), - kNormalBounds.height())); -- EXPECT_CALL(delegate_, -- OnWindowStateChanged(Eq(PlatformWindowState::kNormal))); -+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0); - EXPECT_CALL(delegate_, OnActivationChanged(_)).Times(0); - EXPECT_CALL(delegate_, OnBoundsChanged(kNormalBounds)); - EXPECT_CALL(*GetXdgToplevel(), UnsetMaximized()); -@@ -283,19 +281,21 @@ TEST_P(WaylandWindowTest, Minimize) { - Sync(); - - EXPECT_CALL(*GetXdgToplevel(), SetMinimized()); -- // Wayland compositor doesn't notify clients about minimized state, but rather -- // if a window is not activated. Thus, a WaylandWindow marks itself as being -- // minimized and as soon as a configuration event with not activated state -- // comes, its state is changed to minimized. This EXPECT_CALL ensures this -- // behaviour. -- EXPECT_CALL(delegate_, -- OnWindowStateChanged(Eq(PlatformWindowState::kMinimized))); -+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0); - window_->Minimize(); -+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kMinimized); -+ - // Reinitialize wl_array, which removes previous old states. - states = ScopedWlArray(); - SendConfigureEvent(0, 0, 2, states.get()); - Sync(); - -+ // Wayland compositor doesn't notify clients about minimized state, but rather -+ // if a window is not activated. Thus, a WaylandSurface marks itself as being -+ // minimized and and sets state to minimized. Thus, the state mustn't change -+ // after the configuration event is sent. -+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kMinimized); -+ - // Send one additional empty configuration event (which means the surface is - // not maximized, fullscreen or activated) to ensure, WaylandWindow stays in - // the same minimized state and doesn't notify its delegate. -@@ -319,8 +319,7 @@ TEST_P(WaylandWindowTest, SetFullscreenAndRestore) { - AddStateToWlArray(XDG_TOPLEVEL_STATE_FULLSCREEN, states.get()); - - EXPECT_CALL(*GetXdgToplevel(), SetFullscreen()); -- EXPECT_CALL(delegate_, -- OnWindowStateChanged(Eq(PlatformWindowState::kFullScreen))); -+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0); - window_->ToggleFullscreen(); - // Make sure than WaylandWindow manually handles fullscreen states. Check the - // comment in the WaylandWindow::ToggleFullscreen. -@@ -330,51 +329,181 @@ TEST_P(WaylandWindowTest, SetFullscreenAndRestore) { - Sync(); - - EXPECT_CALL(*GetXdgToplevel(), UnsetFullscreen()); -- EXPECT_CALL(delegate_, -- OnWindowStateChanged(Eq(PlatformWindowState::kNormal))); -+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0); - window_->Restore(); -- EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kUnknown); -+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kNormal); - // Reinitialize wl_array, which removes previous old states. - states = InitializeWlArrayWithActivatedState(); - SendConfigureEvent(0, 0, 3, states.get()); - Sync(); -+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kNormal); - } - - TEST_P(WaylandWindowTest, StartWithFullscreen) { -+ MockPlatformWindowDelegate delegate; -+ PlatformWindowInitProperties properties; -+ properties.bounds = gfx::Rect(0, 0, 100, 100); -+ properties.type = PlatformWindowType::kWindow; -+ // We need to create a window avoid calling Show() on it as it is what upper -+ // views layer does - when Widget initialize DesktopWindowTreeHost, the Show() -+ // is called later down the road, but Maximize may be called earlier. We -+ // cannot process them and set a pending state instead, because ShellSurface -+ // is not created by that moment. -+ auto window = WaylandWindow::Create(&delegate, connection_.get(), -+ std::move(properties)); -+ -+ Sync(); -+ -+ // Make sure the window is initialized to normal state from the beginning. -+ EXPECT_EQ(PlatformWindowState::kNormal, window->GetPlatformWindowState()); -+ -+ // The state must not be changed to the fullscreen before the surface is -+ // activated. -+ auto* mock_surface = server_.GetObject<wl::MockSurface>(window->GetWidget()); -+ EXPECT_FALSE(mock_surface->xdg_surface()); -+ EXPECT_CALL(delegate, OnWindowStateChanged(_)).Times(0); -+ window->ToggleFullscreen(); -+ // The state of the window must already be fullscreen one. -+ EXPECT_EQ(window->GetPlatformWindowState(), PlatformWindowState::kFullScreen); -+ -+ Sync(); -+ -+ // We mustn't receive any state changes if that does not differ from the last -+ // state. -+ EXPECT_CALL(delegate, OnWindowStateChanged(_)).Times(0); -+ -+ // Activate the surface. -+ ScopedWlArray states = InitializeWlArrayWithActivatedState(); -+ AddStateToWlArray(XDG_TOPLEVEL_STATE_FULLSCREEN, states.get()); -+ SendConfigureEvent(0, 0, 1, states.get()); -+ -+ Sync(); -+ -+ // It must be still the same state. -+ EXPECT_EQ(window->GetPlatformWindowState(), PlatformWindowState::kFullScreen); -+} -+ -+TEST_P(WaylandWindowTest, StartMaximized) { -+ MockPlatformWindowDelegate delegate; -+ PlatformWindowInitProperties properties; -+ properties.bounds = gfx::Rect(0, 0, 100, 100); -+ properties.type = PlatformWindowType::kWindow; -+ // We need to create a window avoid calling Show() on it as it is what upper -+ // views layer does - when Widget initialize DesktopWindowTreeHost, the Show() -+ // is called later down the road, but Maximize may be called earlier. We -+ // cannot process them and set a pending state instead, because ShellSurface -+ // is not created by that moment. -+ auto window = WaylandWindow::Create(&delegate, connection_.get(), -+ std::move(properties)); -+ -+ Sync(); -+ - // Make sure the window is initialized to normal state from the beginning. - EXPECT_EQ(PlatformWindowState::kNormal, window_->GetPlatformWindowState()); - - // The state must not be changed to the fullscreen before the surface is - // activated. -- EXPECT_CALL(*GetXdgToplevel(), SetFullscreen()).Times(0); -+ auto* mock_surface = server_.GetObject<wl::MockSurface>(window->GetWidget()); -+ EXPECT_FALSE(mock_surface->xdg_surface()); - EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0); -- window_->ToggleFullscreen(); -- // The state of the window must still be a normal one. -- EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kNormal); -+ -+ window_->Maximize(); -+ // The state of the window must already be fullscreen one. -+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kMaximized); - - Sync(); - -- // Once the surface will be activated, the window will automatically trigger -- // the state change. -- EXPECT_CALL(*GetXdgToplevel(), SetFullscreen()); -- EXPECT_CALL(delegate_, -- OnWindowStateChanged(Eq(PlatformWindowState::kFullScreen))); -+ // Once the surface will be activated, the window state mustn't be changed -+ // and retain the same. -+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0); -+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kMaximized); - - // Activate the surface. - ScopedWlArray states = InitializeWlArrayWithActivatedState(); -+ AddStateToWlArray(XDG_TOPLEVEL_STATE_MAXIMIZED, states.get()); - SendConfigureEvent(0, 0, 1, states.get()); - - Sync(); - -- // The wayland window manually handles the fullscreen state changes, and it -- // must change to a fullscreen before the state change is confirmed by the -- // wayland. See comment in the WaylandWindow::ToggleFullscreen. -- EXPECT_EQ(window_->GetPlatformWindowState(), -- PlatformWindowState::kFullScreen); -+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kMaximized); -+} - -- AddStateToWlArray(XDG_TOPLEVEL_STATE_FULLSCREEN, states.get()); -+TEST_P(WaylandWindowTest, CompositorSideStateChanges) { -+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kNormal); -+ auto normal_bounds = window_->GetBounds(); -+ -+ ScopedWlArray states = InitializeWlArrayWithActivatedState(); -+ AddStateToWlArray(XDG_TOPLEVEL_STATE_MAXIMIZED, states.get()); -+ SendConfigureEvent(2000, 2000, 1, states.get()); -+ -+ EXPECT_CALL(delegate_, -+ OnWindowStateChanged(Eq(PlatformWindowState::kMaximized))) -+ .Times(1); -+ EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, 2000, 2000)); -+ -+ Sync(); -+ -+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kMaximized); -+ -+ // Unmaximize -+ states = InitializeWlArrayWithActivatedState(); - SendConfigureEvent(0, 0, 2, states.get()); - -+ EXPECT_CALL(delegate_, OnWindowStateChanged(Eq(PlatformWindowState::kNormal))) -+ .Times(1); -+ EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, normal_bounds.width(), -+ normal_bounds.height())); -+ -+ // Now, set to fullscreen. -+ AddStateToWlArray(XDG_TOPLEVEL_STATE_FULLSCREEN, states.get()); -+ SendConfigureEvent(2005, 2005, 3, states.get()); -+ EXPECT_CALL(delegate_, -+ OnWindowStateChanged(Eq(PlatformWindowState::kFullScreen))) -+ .Times(1); -+ EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, 2005, 2005)); -+ -+ Sync(); -+ -+ // Unfullscreen -+ states = InitializeWlArrayWithActivatedState(); -+ SendConfigureEvent(0, 0, 4, states.get()); -+ -+ EXPECT_CALL(delegate_, OnWindowStateChanged(Eq(PlatformWindowState::kNormal))) -+ .Times(1); -+ EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, normal_bounds.width(), -+ normal_bounds.height())); -+ -+ Sync(); -+ -+ // Now, maximize, fullscreen and restore. -+ states = InitializeWlArrayWithActivatedState(); -+ AddStateToWlArray(XDG_TOPLEVEL_STATE_MAXIMIZED, states.get()); -+ SendConfigureEvent(2000, 2000, 1, states.get()); -+ -+ EXPECT_CALL(delegate_, -+ OnWindowStateChanged(Eq(PlatformWindowState::kMaximized))) -+ .Times(1); -+ EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, 2000, 2000)); -+ -+ Sync(); -+ -+ AddStateToWlArray(XDG_TOPLEVEL_STATE_FULLSCREEN, states.get()); -+ SendConfigureEvent(2005, 2005, 1, states.get()); -+ -+ EXPECT_CALL(delegate_, -+ OnWindowStateChanged(Eq(PlatformWindowState::kFullScreen))) -+ .Times(1); -+ EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, 2005, 2005)); -+ -+ // Restore -+ states = InitializeWlArrayWithActivatedState(); -+ SendConfigureEvent(0, 0, 4, states.get()); -+ -+ EXPECT_CALL(delegate_, OnWindowStateChanged(Eq(PlatformWindowState::kNormal))) -+ .Times(1); -+ EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, normal_bounds.width(), -+ normal_bounds.height())); -+ - Sync(); - } - -@@ -395,25 +524,33 @@ TEST_P(WaylandWindowTest, SetMaximizedFullscreenAndRestore) { - kMaximizedBounds.height())); - EXPECT_CALL(delegate_, OnActivationChanged(Eq(true))); - EXPECT_CALL(delegate_, OnBoundsChanged(kMaximizedBounds)); -- EXPECT_CALL(delegate_, -- OnWindowStateChanged(Eq(PlatformWindowState::kMaximized))); -+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0); - window_->Maximize(); -+ // State changes are synchronous. -+ EXPECT_EQ(PlatformWindowState::kMaximized, window_->GetPlatformWindowState()); - SendConfigureEvent(kMaximizedBounds.width(), kMaximizedBounds.height(), 2, - active_maximized.get()); - Sync(); -+ // Verify that the state has not been changed. -+ EXPECT_EQ(PlatformWindowState::kMaximized, window_->GetPlatformWindowState()); - VerifyAndClearExpectations(); - - EXPECT_CALL(*GetXdgToplevel(), SetFullscreen()); - EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, kMaximizedBounds.width(), - kMaximizedBounds.height())); - EXPECT_CALL(delegate_, OnBoundsChanged(_)).Times(0); -- EXPECT_CALL(delegate_, -- OnWindowStateChanged(Eq(PlatformWindowState::kFullScreen))); -+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0); - window_->ToggleFullscreen(); -+ // State changes are synchronous. -+ EXPECT_EQ(PlatformWindowState::kFullScreen, -+ window_->GetPlatformWindowState()); - AddStateToWlArray(XDG_TOPLEVEL_STATE_FULLSCREEN, active_maximized.get()); - SendConfigureEvent(kMaximizedBounds.width(), kMaximizedBounds.height(), 3, - active_maximized.get()); - Sync(); -+ // Verify that the state has not been changed. -+ EXPECT_EQ(PlatformWindowState::kFullScreen, -+ window_->GetPlatformWindowState()); - VerifyAndClearExpectations(); - - EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, kNormalBounds.width(), -@@ -421,13 +558,14 @@ TEST_P(WaylandWindowTest, SetMaximizedFullscreenAndRestore) { - EXPECT_CALL(*GetXdgToplevel(), UnsetFullscreen()); - EXPECT_CALL(*GetXdgToplevel(), UnsetMaximized()); - EXPECT_CALL(delegate_, OnBoundsChanged(kNormalBounds)); -- EXPECT_CALL(delegate_, -- OnWindowStateChanged(Eq(PlatformWindowState::kNormal))); -+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0); - window_->Restore(); -+ EXPECT_EQ(PlatformWindowState::kNormal, window_->GetPlatformWindowState()); - // Reinitialize wl_array, which removes previous old states. - auto active = InitializeWlArrayWithActivatedState(); - SendConfigureEvent(0, 0, 4, active.get()); - Sync(); -+ EXPECT_EQ(PlatformWindowState::kNormal, window_->GetPlatformWindowState()); - } - - TEST_P(WaylandWindowTest, RestoreBoundsAfterMaximize) { --- -2.24.1 - @@ -5,7 +5,7 @@ # Contributor: Daniel J Griffiths <ghost1227@archlinux.us> pkgname=chromium-beta-ozone -pkgver=80.0.3987.42 +pkgver=80.0.3987.87 pkgrel=1 _launcher_ver=6 pkgdesc="Chromium built with patches for wayland support via Ozone (beta channel)" @@ -14,13 +14,14 @@ url="https://www.chromium.org/Home" options=(debug !strip) license=('BSD') depends=('gtk3' 'nss' 'alsa-lib' 'xdg-utils' 'libxss' 'libcups' 'libgcrypt' - 'ttf-font' 'systemd' 'dbus' 'libpulse' 'pciutils' 'json-glib' 'libva' + 'ttf-liberation' 'systemd' 'dbus' 'libpulse' 'pciutils' 'json-glib' 'desktop-file-utils' 'hicolor-icon-theme') provides=('chromium') conflicts=('chromium') makedepends=('python' 'python2' 'gperf' 'yasm' 'mesa' 'ninja' 'nodejs' 'git' - 'clang' 'lld' 'gn' 'java-runtime-headless') + 'pipewire' 'clang' 'lld' 'gn' 'java-runtime-headless') optdepends=('pepper-flash: support for Flash content' + 'pipewire: WebRTC desktop sharing under Wayland' 'kdialog: needed for file dialogs in KDE' 'org.freedesktop.secrets: password storage backend on GNOME / Xfce' 'kwallet: for storing passwords in KWallet on KDE desktops') @@ -28,21 +29,31 @@ install=chromium.install source=(https://commondatastorage.googleapis.com/chromium-browser-official/chromium-$pkgver.tar.xz chromium-launcher-$_launcher_ver.tar.gz::https://github.com/foutrelis/chromium-launcher/archive/v$_launcher_ver.tar.gz 0001-Add-missing-algorithm-header-in-bitmap_cursor_factor.patch - 0001-cros-search-service-Include-cmath-for-std-pow.patch - 0001-BookmarkModelMerger-Move-RemoteTreeNode-declaration-.patch - chromium-system-icu.patch - chromium-system-zlib.patch - fix-spammy-unique-font-matching-log.patch + cros-search-service-Include-cmath-for-std-pow.patch + move-RemoteTreeNode-declaration.patch + sync-enable-USSPasswords-by-default.patch + fix-shim-header-generation-when-unbundling-ICU.patch + fix-building-with-system-zlib.patch + remove-verbose-logging-in-local-unique-font-matching.patch + fix-building-with-unbundled-libxml.patch + fix-browser-frame-view-not-getting-a-relayout.patch + rename-Relayout-in-DesktopWindowTreeHostPlatform.patch + rebuild-Linux-frame-button-cache-when-activation.patch chromium-widevine.patch chromium-skia-harmony.patch) -sha256sums=('160c02ed00d45a074246c8984144a35b092102e9b9a31e2bc9c2dad49f297945' +sha256sums=('f51f6fca5d9abbef855aa6b5bf427410c6e96ae58b64a7d45f843868cfb0ac8e' '04917e3cd4307d8e31bfb0027a5dce6d086edb10ff8a716024fbb8bb0c7dccf1' '716c28bed9f6e9c32e3617e125c1b04806700aef691763923cd4ed14b8d23279' - '4c892f046ab10df609aa39d9985248d368c77306783a64d335ff713dabad60b0' - 'a44ed59db5258221ee187dc2501040e5ebfc5c1353ac98d4313ac6a12ae32d1f' - 'e73cc2ee8d3ea35aab18c478d76fdfc68ca4463e1e10306fa1e738c03b3f26b5' - 'eb67eda4945a89c3b90473fa8dc20637511ca4dcb58879a8ed6bf403700ca9c8' - '6fbffe59b886195b92c9a55137cef83021c16593f49714acb20023633e3ebb19' + '0a8d1af2a3734b5f99ea8462940e332db4acee7130fe436ad3e4b7ad133e5ae5' + '21f631851cdcb347f40793485b168cb5d0da65ae26ae39ba58d624c66197d0a5' + '08ef82476780e0864b5bf7f20eb19db320e73b9a5d4f595351e12e97dda8746f' + 'e477aa48a11ca4d53927f66a9593567fcd053325fb38af30ac3508465f1dd1f6' + '18276e65c68a0c328601b12fefb7e8bfc632346f34b87e64944c9de8c95c5cfa' + '5bc775c0ece84d67855f51b30eadcf96fa8163b416d2036e9f9ba19072f54dfe' + 'e530d1b39504c2ab247e16f1602359c484e9e8be4ef6d4824d68b14d29a7f60b' + '5db225565336a3d9b9e9f341281680433c0b7bb343dff2698b2acffd86585cbe' + 'ae3bf107834bd8eda9a3ec7899fe35fde62e6111062e5def7d24bf49b53db3db' + '46f7fc9768730c460b27681ccf3dc2685c7e1fd22d70d3a82d9e57e3389bb014' '709e2fddba3c1f2ed4deb3a239fc0479bfa50c46e054e7f32db4fb1365fed070' '771292942c0901092a402cc60ee883877a99fb804cb54d568c8c6c94565a48e1') @@ -57,10 +68,10 @@ declare -gA _system_libs=( [icu]=icu [libdrm]= [libjpeg]=libjpeg - #[libpng]=libpng # https://crbug.com/752403#c10 - #[libvpx]=libvpx # https://github.com/webmproject/libvpx/commit/5a0242ba5c + #[libpng]=libpng # https://crbug.com/752403#c10 + [libvpx]=libvpx [libwebp]=libwebp - # [libxml]=libxml2 + [libxml]=libxml2 [libxslt]=libxslt [opus]=opus [re2]=re2 @@ -100,19 +111,36 @@ prepare() { sed -i -e 's/\<xmlMalloc\>/malloc/' -e 's/\<xmlFree\>/free/' \ third_party/blink/renderer/core/xml/*.cc \ third_party/blink/renderer/core/xml/parser/xml_document_parser.cc \ - third_party/libxml/chromium/libxml_utils.cc + third_party/libxml/chromium/*.cc # build fixes patch -Np1 -i ../0001-Add-missing-algorithm-header-in-bitmap_cursor_factor.patch - patch -Np1 -i ../0001-cros-search-service-Include-cmath-for-std-pow.patch - patch -Np1 -i ../0001-BookmarkModelMerger-Move-RemoteTreeNode-declaration-.patch - # Fixes from Gentoo - patch -Np1 -i ../chromium-system-icu.patch - patch -Np1 -i ../chromium-system-zlib.patch + # https://crbug.com/957519 + patch -Np1 -i ../cros-search-service-Include-cmath-for-std-pow.patch + patch -Np1 -i ../move-RemoteTreeNode-declaration.patch + + # https://crbug.com/1027929 + patch -Np1 -i ../sync-enable-USSPasswords-by-default.patch + + # https://crbug.com/989153 + patch -Np1 -i ../fix-shim-header-generation-when-unbundling-ICU.patch + + # https://crbug.com/977964 + patch -Np1 -i ../fix-building-with-system-zlib.patch # https://crbug.com/1005508 - # patch -Np1 -i ../fix-spammy-unique-font-matching-log.patch + patch -Np1 -i ../remove-verbose-logging-in-local-unique-font-matching.patch + + # https://crbug.com/1043042 + patch -Np1 -i ../fix-building-with-unbundled-libxml.patch + + # https://crbug.com/1046122 + patch -Np1 -i ../fix-browser-frame-view-not-getting-a-relayout.patch + + # https://crbug.com/1049258 + patch -Np1 -i ../rename-Relayout-in-DesktopWindowTreeHostPlatform.patch + patch -Np1 -i ../rebuild-Linux-frame-button-cache-when-activation.patch # Load bundled Widevine CDM if available (see chromium-widevine in the AUR) # M79 is supposed to download it as a component but it doesn't seem to work @@ -163,6 +191,7 @@ build() { 'fieldtrial_testing_like_official_build=true' 'ffmpeg_branding="Chrome"' 'proprietary_codecs=true' + 'rtc_use_pipewire=true' 'link_pulseaudio=true' 'use_gnome_keyring=false' 'use_sysroot=false' diff --git a/chromium-system-icu.patch b/chromium-system-icu.patch deleted file mode 100644 index 1f848d7ee2be..000000000000 --- a/chromium-system-icu.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff --git a/build/linux/unbundle/icu.gn b/build/linux/unbundle/icu.gn -index 4450e40..9ca36dd 100644 ---- a/build/linux/unbundle/icu.gn -+++ b/build/linux/unbundle/icu.gn -@@ -96,6 +96,7 @@ shim_headers("icui18n_shim") { - "unicode/fpositer.h", - "unicode/gender.h", - "unicode/gregocal.h", -+ "unicode/listformatter.h", - "unicode/measfmt.h", - "unicode/measunit.h", - "unicode/measure.h", -@@ -178,7 +179,6 @@ shim_headers("icuuc_shim") { - "unicode/icudataver.h", - "unicode/icuplug.h", - "unicode/idna.h", -- "unicode/listformatter.h", - "unicode/localpointer.h", - "unicode/locdspnm.h", - "unicode/locid.h", diff --git a/chromium-system-zlib.patch b/chromium-system-zlib.patch deleted file mode 100644 index 951a2adb196a..000000000000 --- a/chromium-system-zlib.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/third_party/perfetto/gn/BUILD.gn b/third_party/perfetto/gn/BUILD.gn -index 3bc618a..e0ddf6d 100644 ---- a/third_party/perfetto/gn/BUILD.gn -+++ b/third_party/perfetto/gn/BUILD.gn -@@ -244,7 +244,7 @@ if (enable_perfetto_trace_processor || perfetto_build_standalone || - "//buildtools:zlib", - ] - } else { -- public_configs = [ "//third_party/zlib:zlib_config" ] -+ public_configs = [ "//third_party/zlib:system_zlib" ] - public_deps = [ - "//third_party/zlib", - ] diff --git a/0001-cros-search-service-Include-cmath-for-std-pow.patch b/cros-search-service-Include-cmath-for-std-pow.patch index 5c620a79edf6..410b968d0fe6 100644 --- a/0001-cros-search-service-Include-cmath-for-std-pow.patch +++ b/cros-search-service-Include-cmath-for-std-pow.patch @@ -22,7 +22,7 @@ Cr-Commit-Position: refs/heads/master@{#723499} 1 file changed, 1 insertion(+) diff --git a/chrome/common/string_matching/fuzzy_tokenized_string_match.cc b/chrome/common/string_matching/fuzzy_tokenized_string_match.cc -index 8351fa701e4d..884ef638c61c 100644 +index 8351fa701e4..884ef638c61 100644 --- a/chrome/common/string_matching/fuzzy_tokenized_string_match.cc +++ b/chrome/common/string_matching/fuzzy_tokenized_string_match.cc @@ -5,6 +5,7 @@ @@ -33,6 +33,3 @@ index 8351fa701e4d..884ef638c61c 100644 #include <iterator> #include "base/i18n/case_conversion.h" --- -2.24.1 - diff --git a/fix-browser-frame-view-not-getting-a-relayout.patch b/fix-browser-frame-view-not-getting-a-relayout.patch new file mode 100644 index 000000000000..fbdd026ff10f --- /dev/null +++ b/fix-browser-frame-view-not-getting-a-relayout.patch @@ -0,0 +1,38 @@ +From c73968d63c456d4aaf55c5cd439b42403a3bbeb1 Mon Sep 17 00:00:00 2001 +From: Tom Anderson <thomasanderson@chromium.org> +Date: Mon, 3 Feb 2020 19:53:50 +0000 +Subject: [PATCH] Fix browser frame view not getting a relayout after a state + change + +views::NonClientView has 2 things: a views::NonClientFrameView and a +views::ClientView. We were previously only invalidating the layout on +the ClientView after a state change. This was causing the browser +frame to paint as if it were still maximized after restoring from +a maximized state on Linux. Invalidating the layout of the frame view +fixes the issue. + +BUG=1046122 +R=sky + +Change-Id: I7da525efe1f436564ffffb410afe294e901e5d89 +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2033759 +Reviewed-by: Scott Violet <sky@chromium.org> +Commit-Queue: Thomas Anderson <thomasanderson@chromium.org> +Cr-Commit-Position: refs/heads/master@{#737890} +--- + .../widget/desktop_aura/desktop_window_tree_host_platform.cc | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc +index 9abbce89586..6c00d49eb3f 100644 +--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc ++++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc +@@ -717,6 +717,8 @@ void DesktopWindowTreeHostPlatform::Relayout() { + NonClientView* non_client_view = widget->non_client_view(); + // non_client_view may be NULL, especially during creation. + if (non_client_view) { ++ if (non_client_view->frame_view()) ++ non_client_view->frame_view()->InvalidateLayout(); + non_client_view->client_view()->InvalidateLayout(); + non_client_view->InvalidateLayout(); + } diff --git a/fix-building-with-system-zlib.patch b/fix-building-with-system-zlib.patch new file mode 100644 index 000000000000..d488ac20fe13 --- /dev/null +++ b/fix-building-with-system-zlib.patch @@ -0,0 +1,32 @@ +From cda86e34ddadba5f08dea764881bbb6c8ec01e8a Mon Sep 17 00:00:00 2001 +From: Stephan Hartmann <stha09@googlemail.com> +Date: Sat, 25 Jan 2020 02:00:43 +0000 +Subject: [PATCH] Fix building with system zlib + +Add zlib_config target because perfetto depends on it. + +Bug: 977964 +Change-Id: I2aac5c3704f1274f932a61264d1c26a05f2db55e +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2019035 +Reviewed-by: Thomas Anderson <thomasanderson@chromium.org> +Commit-Queue: Thomas Anderson <thomasanderson@chromium.org> +Cr-Commit-Position: refs/heads/master@{#735201} +--- + build/linux/unbundle/zlib.gn | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/build/linux/unbundle/zlib.gn b/build/linux/unbundle/zlib.gn +index 1fdd472f35e..97d6aebe6d5 100644 +--- a/build/linux/unbundle/zlib.gn ++++ b/build/linux/unbundle/zlib.gn +@@ -13,6 +13,10 @@ config("system_zlib") { + defines = [ "USE_SYSTEM_ZLIB=1" ] + } + ++config("zlib_config") { ++ configs = [ ":system_zlib" ] ++} ++ + source_set("zlib") { + deps = [ ":zlib_shim" ] + libs = [ "z" ] diff --git a/fix-building-with-unbundled-libxml.patch b/fix-building-with-unbundled-libxml.patch new file mode 100644 index 000000000000..7b934376e6e4 --- /dev/null +++ b/fix-building-with-unbundled-libxml.patch @@ -0,0 +1,127 @@ +From d3afade220ddb307e16a6dd4f2b0ec88b2af91e7 Mon Sep 17 00:00:00 2001 +From: Stephan Hartmann <stha09@googlemail.com> +Date: Tue, 28 Jan 2020 18:16:54 +0000 +Subject: [PATCH] Fix building with unbundled libxml + +Add new targets to libxml.gn that were added in + https://chromium-review.googlesource.com/c/chromium/src/+/1894877 +Adjust includes to use system libxml headers too + +Bug: 1043042 +Change-Id: I948c063e212e49b9e7f42fed2b8bf7f4af042ca7 +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2007110 +Reviewed-by: Robert Sesek <rsesek@chromium.org> +Reviewed-by: Daniel Cheng <dcheng@chromium.org> +Reviewed-by: Nico Weber <thakis@chromium.org> +Commit-Queue: Robert Sesek <rsesek@chromium.org> +Cr-Commit-Position: refs/heads/master@{#735957} +--- + build/linux/unbundle/libxml.gn | 41 ++++++++++++++++++++-- + third_party/libxml/chromium/libxml_utils.h | 4 +-- + third_party/libxml/chromium/xml_reader.cc | 3 +- + third_party/libxml/chromium/xml_writer.cc | 3 +- + 4 files changed, 45 insertions(+), 6 deletions(-) + +diff --git a/build/linux/unbundle/libxml.gn b/build/linux/unbundle/libxml.gn +index c481bd3547b..3587881eea8 100644 +--- a/build/linux/unbundle/libxml.gn ++++ b/build/linux/unbundle/libxml.gn +@@ -8,11 +8,48 @@ pkg_config("system_libxml") { + packages = [ "libxml-2.0" ] + } + +-static_library("libxml") { ++source_set("libxml") { ++ public_configs = [ ":system_libxml" ] ++} ++ ++static_library("libxml_utils") { ++ # Do not expand this visibility list without first consulting with the ++ # Security Team. ++ visibility = [ ++ ":xml_reader", ++ ":xml_writer", ++ "//base/test:test_support", ++ "//services/data_decoder:xml_parser_fuzzer", ++ ] + sources = [ + "chromium/libxml_utils.cc", + "chromium/libxml_utils.h", + ] +- + public_configs = [ ":system_libxml" ] + } ++ ++static_library("xml_reader") { ++ # Do not expand this visibility list without first consulting with the ++ # Security Team. ++ visibility = [ ++ "//base/test:test_support", ++ "//components/policy/core/common:unit_tests", ++ "//services/data_decoder:*", ++ "//tools/traffic_annotation/auditor:auditor_sources", ++ ] ++ sources = [ ++ "chromium/xml_reader.cc", ++ "chromium/xml_reader.h", ++ ] ++ deps = [ ":libxml_utils" ] ++} ++ ++static_library("xml_writer") { ++ # The XmlWriter is considered safe to use from any target. ++ visibility = [ "*" ] ++ sources = [ ++ "chromium/xml_writer.cc", ++ "chromium/xml_writer.h", ++ ] ++ deps = [ ":libxml_utils" ] ++} +diff --git a/third_party/libxml/chromium/libxml_utils.h b/third_party/libxml/chromium/libxml_utils.h +index ff969fab540..8b2383f9c8b 100644 +--- a/third_party/libxml/chromium/libxml_utils.h ++++ b/third_party/libxml/chromium/libxml_utils.h +@@ -5,9 +5,9 @@ + #ifndef THIRD_PARTY_LIBXML_CHROMIUM_LIBXML_UTILS_H_ + #define THIRD_PARTY_LIBXML_CHROMIUM_LIBXML_UTILS_H_ + +-#include <string> ++#include <libxml/xmlreader.h> + +-#include "third_party/libxml/src/include/libxml/xmlreader.h" ++#include <string> + + // libxml uses a global error function pointer for reporting errors. + // A ScopedXmlErrorFunc object lets you change the global error pointer +diff --git a/third_party/libxml/chromium/xml_reader.cc b/third_party/libxml/chromium/xml_reader.cc +index 92464f4cbcc..899ccefb7c8 100644 +--- a/third_party/libxml/chromium/xml_reader.cc ++++ b/third_party/libxml/chromium/xml_reader.cc +@@ -4,10 +4,11 @@ + + #include "third_party/libxml/chromium/xml_reader.h" + ++#include <libxml/xmlreader.h> ++ + #include <vector> + + #include "third_party/libxml/chromium/libxml_utils.h" +-#include "third_party/libxml/src/include/libxml/xmlreader.h" + + using internal::XmlStringToStdString; + +diff --git a/third_party/libxml/chromium/xml_writer.cc b/third_party/libxml/chromium/xml_writer.cc +index 51fce8ebeb1..7c58031fe2d 100644 +--- a/third_party/libxml/chromium/xml_writer.cc ++++ b/third_party/libxml/chromium/xml_writer.cc +@@ -4,8 +4,9 @@ + + #include "third_party/libxml/chromium/xml_writer.h" + ++#include <libxml/xmlwriter.h> ++ + #include "third_party/libxml/chromium/libxml_utils.h" +-#include "third_party/libxml/src/include/libxml/xmlwriter.h" + + XmlWriter::XmlWriter() : writer_(nullptr), buffer_(nullptr) {} + diff --git a/fix-shim-header-generation-when-unbundling-ICU.patch b/fix-shim-header-generation-when-unbundling-ICU.patch new file mode 100644 index 000000000000..04f1ecd3bced --- /dev/null +++ b/fix-shim-header-generation-when-unbundling-ICU.patch @@ -0,0 +1,50 @@ +From dcad5af090528018599277dc5d7e160fb6b2d68e Mon Sep 17 00:00:00 2001 +From: Stephan Hartmann <stha09@googlemail.com> +Date: Wed, 15 Jan 2020 20:26:40 +0000 +Subject: [PATCH] Fix shim header generation when unbundling ICU + +listformatter.h was moved from icuuc to icui18n + +Bug: 989153 +Change-Id: I9fcb56f6d5af7787f34ea99b737e2ed8fe741c84 +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2000142 +Reviewed-by: Lei Zhang <thestig@chromium.org> +Commit-Queue: Lei Zhang <thestig@chromium.org> +Cr-Commit-Position: refs/heads/master@{#732114} +--- + AUTHORS | 1 + + build/linux/unbundle/icu.gn | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/AUTHORS b/AUTHORS +index 7523e483aae..1618fddc633 100644 +--- a/AUTHORS ++++ b/AUTHORS +@@ -891,6 +891,7 @@ Soren Dreijer <dreijerbit@gmail.com> + Sreerenj Balachandran <sreerenj.balachandran@intel.com> + Srirama Chandra Sekhar Mogali <srirama.m@samsung.com> + Staphany Park <stapark008@gmail.com> ++Stephan Hartmann <stha09@googlemail.com> + Stephen Searles <stephen.searles@gmail.com> + Steve Sanders <steve@zanderz.com> + Steven Pennington <spenn@engr.uvic.ca> +diff --git a/build/linux/unbundle/icu.gn b/build/linux/unbundle/icu.gn +index 923bd7f5ac3..e77bc43db87 100644 +--- a/build/linux/unbundle/icu.gn ++++ b/build/linux/unbundle/icu.gn +@@ -92,6 +92,7 @@ shim_headers("icui18n_shim") { + "unicode/fpositer.h", + "unicode/gender.h", + "unicode/gregocal.h", ++ "unicode/listformatter.h", + "unicode/measfmt.h", + "unicode/measunit.h", + "unicode/measure.h", +@@ -174,7 +175,6 @@ shim_headers("icuuc_shim") { + "unicode/icudataver.h", + "unicode/icuplug.h", + "unicode/idna.h", +- "unicode/listformatter.h", + "unicode/localpointer.h", + "unicode/locdspnm.h", + "unicode/locid.h", diff --git a/fix-spammy-unique-font-matching-log.patch b/fix-spammy-unique-font-matching-log.patch deleted file mode 100644 index 9321a98a7254..000000000000 --- a/fix-spammy-unique-font-matching-log.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/content/child/child_process_sandbox_support_impl_linux.cc b/content/child/child_process_sandbox_support_impl_linux.cc -index 0a57543eb5..fe2ee491a2 100644 ---- a/content/child/child_process_sandbox_support_impl_linux.cc -+++ b/content/child/child_process_sandbox_support_impl_linux.cc -@@ -78,8 +78,6 @@ void WebSandboxSupportLinux::MatchFontByPostscriptNameOrFullFontName( - std::string family_name; - if (!font_loader_->MatchFontByPostscriptNameOrFullFontName(font_unique_name, - &font_identity)) { -- LOG(ERROR) << "FontService unique font name matching request did not " -- "receive a response."; - return; - } - diff --git a/libstdc-do-not-assume-unique_ptr-has-ostream-operator.patch b/libstdc-do-not-assume-unique_ptr-has-ostream-operator.patch deleted file mode 100644 index 2a2cad0db4ae..000000000000 --- a/libstdc-do-not-assume-unique_ptr-has-ostream-operator.patch +++ /dev/null @@ -1,36 +0,0 @@ -From aeed4d1f15ce84a17ea0bc219e258dc4982b2368 Mon Sep 17 00:00:00 2001 -From: Jose Dapena Paz <jose.dapena@lge.com> -Date: Fri, 26 Apr 2019 20:07:05 +0000 -Subject: [PATCH] libstdc++: do not assume unique_ptr has ostream operator -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -CompositorFrameReportingController is using DCHECK_NE to compare -several unique_ptr. This is valid in libc++, but on libstdc++ unique_ptr -does not have an ostream operator. - -Change-Id: I9f23ef17f02b9e107694ba493f6f8f3caf5cac4d -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1584292 -Reviewed-by: Sunny Sachanandani <sunnyps@chromium.org> -Commit-Queue: José Dapena Paz <jose.dapena@lge.com> -Cr-Commit-Position: refs/heads/master@{#654570} ---- - cc/scheduler/compositor_frame_reporting_controller.cc | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/cc/scheduler/compositor_frame_reporting_controller.cc b/cc/scheduler/compositor_frame_reporting_controller.cc -index f1587ed158..1b17021fd2 100644 ---- a/cc/scheduler/compositor_frame_reporting_controller.cc -+++ b/cc/scheduler/compositor_frame_reporting_controller.cc -@@ -31,8 +31,8 @@ void CompositorFrameReportingController::WillBeginImplFrame() { - - void CompositorFrameReportingController::WillBeginMainFrame() { - DCHECK(reporters_[PipelineStage::kBeginImplFrame]); -- DCHECK_NE(reporters_[PipelineStage::kBeginMainFrame], -- reporters_[PipelineStage::kBeginImplFrame]); -+ DCHECK(reporters_[PipelineStage::kBeginMainFrame] != -+ reporters_[PipelineStage::kBeginImplFrame]); - reporters_[PipelineStage::kBeginImplFrame]->StartStage( - "SendBeginMainFrameToCommit"); - AdvanceReporterStage(PipelineStage::kBeginImplFrame, diff --git a/0001-BookmarkModelMerger-Move-RemoteTreeNode-declaration-.patch b/move-RemoteTreeNode-declaration.patch index ba57aca99be3..50fc78cdb47a 100644 --- a/0001-BookmarkModelMerger-Move-RemoteTreeNode-declaration-.patch +++ b/move-RemoteTreeNode-declaration.patch @@ -58,7 +58,7 @@ Cr-Commit-Position: refs/heads/master@{#725070} 2 files changed, 80 insertions(+), 57 deletions(-) diff --git a/components/sync_bookmarks/bookmark_model_merger.cc b/components/sync_bookmarks/bookmark_model_merger.cc -index eae153eff953..579848ee664e 100644 +index eae153eff95..579848ee664 100644 --- a/components/sync_bookmarks/bookmark_model_merger.cc +++ b/components/sync_bookmarks/bookmark_model_merger.cc @@ -5,7 +5,6 @@ @@ -170,7 +170,7 @@ index eae153eff953..579848ee664e 100644 // static BookmarkModelMerger::RemoteTreeNode diff --git a/components/sync_bookmarks/bookmark_model_merger.h b/components/sync_bookmarks/bookmark_model_merger.h -index 9b592000dc59..bf0783ecf8ee 100644 +index 9b592000dc5..bf0783ecf8e 100644 --- a/components/sync_bookmarks/bookmark_model_merger.h +++ b/components/sync_bookmarks/bookmark_model_merger.h @@ -5,6 +5,7 @@ @@ -235,6 +235,3 @@ index 9b592000dc59..bf0783ecf8ee 100644 // A forest composed of multiple trees where the root of each tree represents // a permanent node, keyed by server-defined unique tag of the root. --- -2.24.1 - diff --git a/rebuild-Linux-frame-button-cache-when-activation.patch b/rebuild-Linux-frame-button-cache-when-activation.patch new file mode 100644 index 000000000000..40764b3ba7ab --- /dev/null +++ b/rebuild-Linux-frame-button-cache-when-activation.patch @@ -0,0 +1,62 @@ +From d10f885b9327399be9348b780967ebd6b7f2c4bc Mon Sep 17 00:00:00 2001 +From: Tom Anderson <thomasanderson@chromium.org> +Date: Fri, 7 Feb 2020 22:44:54 +0000 +Subject: [PATCH] Rebuild Linux frame button cache when activation state + changes + +This fixes an issue where the frame buttons would always render in an +inactive state on Linux (see repro steps in bug 1049258). + +Bug: 1049258 +R=sky +CC=pkasting + +Change-Id: Ic5af33199003e1d1cdf6cedf506e32388ea11fa9 +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2044538 +Auto-Submit: Thomas Anderson <thomasanderson@chromium.org> +Commit-Queue: Scott Violet <sky@chromium.org> +Reviewed-by: Scott Violet <sky@chromium.org> +Cr-Commit-Position: refs/heads/master@{#739585} +--- + .../ui/views/frame/desktop_linux_browser_frame_view.cc | 6 +++--- + .../desktop_aura/desktop_window_tree_host_platform.cc | 3 +++ + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/chrome/browser/ui/views/frame/desktop_linux_browser_frame_view.cc b/chrome/browser/ui/views/frame/desktop_linux_browser_frame_view.cc +index 954e776057f..4f579955675 100644 +--- a/chrome/browser/ui/views/frame/desktop_linux_browser_frame_view.cc ++++ b/chrome/browser/ui/views/frame/desktop_linux_browser_frame_view.cc +@@ -22,13 +22,13 @@ DesktopLinuxBrowserFrameView::DesktopLinuxBrowserFrameView( + : OpaqueBrowserFrameView(frame, browser_view, layout), + nav_button_provider_(std::move(nav_button_provider)) {} + +-DesktopLinuxBrowserFrameView::~DesktopLinuxBrowserFrameView() {} ++DesktopLinuxBrowserFrameView::~DesktopLinuxBrowserFrameView() = default; + + void DesktopLinuxBrowserFrameView::Layout() { + // Calling MaybeUpdateCachedFrameButtonImages() from Layout() is sufficient to + // catch all cases that could update the appearance, since +- // DesktopWindowTreeHostPlatform::OnWindowStateChanged() does a layout any +- // time any properties change. ++ // DesktopWindowTreeHostPlatform::On{Window,Activation}StateChanged() does a ++ // layout any time the maximized and activation state changes, respectively. + MaybeUpdateCachedFrameButtonImages(); + OpaqueBrowserFrameView::Layout(); + } +diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc +index 9c695d8e5b1..9662f19aa90 100644 +--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc ++++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc +@@ -677,9 +677,12 @@ void DesktopWindowTreeHostPlatform::OnCloseRequest() { + } + + void DesktopWindowTreeHostPlatform::OnActivationChanged(bool active) { ++ if (is_active_ == active) ++ return; + is_active_ = active; + aura::WindowTreeHostPlatform::OnActivationChanged(active); + desktop_native_widget_aura_->HandleActivationChanged(active); ++ ScheduleRelayout(); + } + + base::Optional<gfx::Size> diff --git a/remove-verbose-logging-in-local-unique-font-matching.patch b/remove-verbose-logging-in-local-unique-font-matching.patch new file mode 100644 index 000000000000..a88286181017 --- /dev/null +++ b/remove-verbose-logging-in-local-unique-font-matching.patch @@ -0,0 +1,33 @@ +From 8500a125e9fba8bb84d185542155747ee7157ff8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dominik=20R=C3=B6ttsches?= <drott@chromium.org> +Date: Tue, 28 Jan 2020 13:48:07 +0000 +Subject: [PATCH] Remove verbose logging in local unique font matching on Linux +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fixed: 1005508 +Change-Id: I97f5340c6d1881798ba51effc4a9e5c07de12e52 +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2023552 +Commit-Queue: Dominik Röttsches <drott@chromium.org> +Commit-Queue: Kentaro Hara <haraken@chromium.org> +Auto-Submit: Dominik Röttsches <drott@chromium.org> +Reviewed-by: Kentaro Hara <haraken@chromium.org> +Cr-Commit-Position: refs/heads/master@{#735854} +--- + content/child/child_process_sandbox_support_impl_linux.cc | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/content/child/child_process_sandbox_support_impl_linux.cc b/content/child/child_process_sandbox_support_impl_linux.cc +index 693ead7f7a5..c97c8fa197b 100644 +--- a/content/child/child_process_sandbox_support_impl_linux.cc ++++ b/content/child/child_process_sandbox_support_impl_linux.cc +@@ -76,8 +76,6 @@ bool WebSandboxSupportLinux::MatchFontByPostscriptNameOrFullFontName( + std::string family_name; + if (!font_loader_->MatchFontByPostscriptNameOrFullFontName(font_unique_name, + &font_identity)) { +- LOG(ERROR) << "FontService unique font name matching request did not " +- "receive a response."; + return false; + } + diff --git a/rename-Relayout-in-DesktopWindowTreeHostPlatform.patch b/rename-Relayout-in-DesktopWindowTreeHostPlatform.patch new file mode 100644 index 000000000000..eda3cbdbaaf3 --- /dev/null +++ b/rename-Relayout-in-DesktopWindowTreeHostPlatform.patch @@ -0,0 +1,64 @@ +From 5a2cd2409c7d65c019ad9f4595a4e85315857ac4 Mon Sep 17 00:00:00 2001 +From: Tom Anderson <thomasanderson@chromium.org> +Date: Mon, 3 Feb 2020 23:18:46 +0000 +Subject: [PATCH] Rename Relayout() in DesktopWindowTreeHostPlatform to + ScheduleRelayout() + +R=sky + +Bug: None +Change-Id: I680cafd25935e59a280e3b2baac754d3d5f13a35 +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2036553 +Auto-Submit: Thomas Anderson <thomasanderson@chromium.org> +Reviewed-by: Scott Violet <sky@chromium.org> +Commit-Queue: Thomas Anderson <thomasanderson@chromium.org> +Cr-Commit-Position: refs/heads/master@{#737974} +--- + .../desktop_aura/desktop_window_tree_host_platform.cc | 6 +++--- + .../widget/desktop_aura/desktop_window_tree_host_platform.h | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc +index 6c00d49eb3f..9c695d8e5b1 100644 +--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc ++++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc +@@ -556,7 +556,7 @@ void DesktopWindowTreeHostPlatform::SetFullscreen(bool fullscreen) { + DCHECK_EQ(fullscreen, IsFullscreen()); + + if (IsFullscreen() == fullscreen) +- Relayout(); ++ ScheduleRelayout(); + // Else: the widget will be relaid out either when the window bounds change + // or when |platform_window|'s fullscreen state changes. + } +@@ -669,7 +669,7 @@ void DesktopWindowTreeHostPlatform::OnWindowStateChanged( + // Now that we have different window properties, we may need to relayout the + // window. (The windows code doesn't need this because their window change is + // synchronous.) +- Relayout(); ++ ScheduleRelayout(); + } + + void DesktopWindowTreeHostPlatform::OnCloseRequest() { +@@ -712,7 +712,7 @@ gfx::Rect DesktopWindowTreeHostPlatform::ToPixelRect( + return gfx::ToEnclosingRect(rect_in_pixels); + } + +-void DesktopWindowTreeHostPlatform::Relayout() { ++void DesktopWindowTreeHostPlatform::ScheduleRelayout() { + Widget* widget = native_widget_delegate_->AsWidget(); + NonClientView* non_client_view = widget->non_client_view(); + // non_client_view may be NULL, especially during creation. +diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h +index 89beb8d2245..75a401e02a7 100644 +--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h ++++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h +@@ -129,7 +129,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostPlatform + gfx::Rect ToPixelRect(const gfx::Rect& rect_in_dip) const; + + private: +- void Relayout(); ++ void ScheduleRelayout(); + + Widget* GetWidget(); + const Widget* GetWidget() const; diff --git a/sync-enable-USSPasswords-by-default.patch b/sync-enable-USSPasswords-by-default.patch new file mode 100644 index 000000000000..7f3a7005a66c --- /dev/null +++ b/sync-enable-USSPasswords-by-default.patch @@ -0,0 +1,28 @@ +From eb997db5527c01fd12c321a6abc52b7cff882e50 Mon Sep 17 00:00:00 2001 +From: Mohamed Amir Yosef <mamir@chromium.org> +Date: Thu, 9 Jan 2020 21:22:19 +0000 +Subject: [PATCH] [Sync] Enable USSPasswords by default + +Change-Id: I021cd952d7a2917a8fb7203cabdac612251193df +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1963804 +Auto-Submit: Mohamed Amir Yosef <mamir@chromium.org> +Reviewed-by: Mikel Astiz <mastiz@chromium.org> +Commit-Queue: Mohamed Amir Yosef <mamir@chromium.org> +Cr-Commit-Position: refs/heads/master@{#729902} +--- + components/sync/driver/sync_driver_switches.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/components/sync/driver/sync_driver_switches.cc b/components/sync/driver/sync_driver_switches.cc +index ddff8b91419..999384aa68a 100644 +--- a/components/sync/driver/sync_driver_switches.cc ++++ b/components/sync/driver/sync_driver_switches.cc +@@ -55,7 +55,7 @@ const base::Feature kStopSyncInPausedState{"StopSyncInPausedState", + + // Enable USS implementation of Passwords datatype. + const base::Feature kSyncUSSPasswords{"SyncUSSPasswords", +- base::FEATURE_DISABLED_BY_DEFAULT}; ++ base::FEATURE_ENABLED_BY_DEFAULT}; + + // Enable USS implementation of Nigori datatype. + const base::Feature kSyncUSSNigori{"SyncUSSNigori", |