summarylogtreecommitdiffstats
path: root/0009-Fixed-positioning-and-sizes-of-menus-when-the-scale-.patch
diff options
context:
space:
mode:
Diffstat (limited to '0009-Fixed-positioning-and-sizes-of-menus-when-the-scale-.patch')
-rw-r--r--0009-Fixed-positioning-and-sizes-of-menus-when-the-scale-.patch315
1 files changed, 315 insertions, 0 deletions
diff --git a/0009-Fixed-positioning-and-sizes-of-menus-when-the-scale-.patch b/0009-Fixed-positioning-and-sizes-of-menus-when-the-scale-.patch
new file mode 100644
index 000000000000..2e153cf2ff0c
--- /dev/null
+++ b/0009-Fixed-positioning-and-sizes-of-menus-when-the-scale-.patch
@@ -0,0 +1,315 @@
+From 6077336fd2b3a5402ef07e980ebcd46106d8074e Mon Sep 17 00:00:00 2001
+From: Alexander Dunaev <adunaev@igalia.com>
+Date: Wed, 17 Jul 2019 05:26:49 +0000
+Subject: [PATCH 09/11] Fixed positioning and sizes of menus when the scale
+ factor is forced.
+
+When --force-device-scale-factor command line flag is present, the UI scale
+is replaced with the value passed with the flag, which should be taken into
+account when positioning and sizing the menus.
+
+R=msisov@igalia.com, rjkroege@chromium.org
+
+Bug: 910797
+Change-Id: I7880472c29fdaa33e20e2a896e48f922c20680ac
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1692578
+Auto-Submit: Alexander Dunaev <adunaev@igalia.com>
+Reviewed-by: Maksim Sisov <msisov@igalia.com>
+Reviewed-by: Robert Kroeger <rjkroege@chromium.org>
+Commit-Queue: Maksim Sisov <msisov@igalia.com>
+Cr-Commit-Position: refs/heads/master@{#678151}
+---
+ .../wayland/host/wayland_connection.cc | 2 +-
+ .../platform/wayland/host/wayland_screen.cc | 2 +-
+ .../wayland/host/wayland_screen_unittest.cc | 38 +++++++++++++--
+ .../platform/wayland/host/wayland_window.cc | 46 ++++++++++---------
+ .../platform/wayland/host/wayland_window.h | 37 +++++++++------
+ 5 files changed, 81 insertions(+), 44 deletions(-)
+
+diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc
+index 72617b5f37a3..a949baf5a934 100644
+--- a/ui/ozone/platform/wayland/host/wayland_connection.cc
++++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
+@@ -164,7 +164,7 @@ std::vector<WaylandWindow*> WaylandConnection::GetWindowsOnOutput(
+ uint32_t output_id) {
+ std::vector<WaylandWindow*> result;
+ for (auto entry : window_map_) {
+- if (entry.second->GetEnteredOutputsIds().count(output_id) > 0)
++ if (entry.second->entered_outputs_ids().count(output_id) > 0)
+ result.push_back(entry.second);
+ }
+ return result;
+diff --git a/ui/ozone/platform/wayland/host/wayland_screen.cc b/ui/ozone/platform/wayland/host/wayland_screen.cc
+index 694c13f4e4d2..ef372ad794d3 100644
+--- a/ui/ozone/platform/wayland/host/wayland_screen.cc
++++ b/ui/ozone/platform/wayland/host/wayland_screen.cc
+@@ -107,7 +107,7 @@ display::Display WaylandScreen::GetDisplayForAcceleratedWidget(
+ return GetPrimaryDisplay();
+
+ const auto* parent_window = window->parent_window();
+- const std::set<uint32_t> entered_outputs_ids = window->GetEnteredOutputsIds();
++ const auto entered_outputs_ids = window->entered_outputs_ids();
+ // Although spec says a surface receives enter/leave surface events on
+ // create/move/resize actions, this might be called right after a window is
+ // created, but it has not been configured by a Wayland compositor and it has
+diff --git a/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc b/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc
+index f93ac20d51e0..0a18b8366cae 100644
+--- a/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc
++++ b/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc
+@@ -5,8 +5,11 @@
+ #include <wayland-server.h>
+ #include <memory>
+
++#include "base/strings/stringprintf.h"
++#include "base/test/scoped_command_line.h"
+ #include "testing/gtest/include/gtest/gtest.h"
+ #include "ui/display/display_observer.h"
++#include "ui/display/display_switches.h"
+ #include "ui/ozone/platform/wayland/host/wayland_connection.h"
+ #include "ui/ozone/platform/wayland/host/wayland_output_manager.h"
+ #include "ui/ozone/platform/wayland/host/wayland_screen.h"
+@@ -586,14 +589,39 @@ TEST_P(WaylandScreenTest, SetBufferScale) {
+ wl_surface_send_enter(surface_->resource(), output_->resource());
+
+ // Change the scale of the output. Windows looking into that output must get
+- // the new scale and update scale of their buffers.
+- const int32_t kNewScale = 3;
+- EXPECT_CALL(*surface_, SetBufferScale(kNewScale));
+- output_->SetScale(kNewScale);
++ // the new scale and update scale of their buffers. The default UI scale
++ // equals the output scale.
++ const int32_t kTripleScale = 3;
++ EXPECT_CALL(*surface_, SetBufferScale(kTripleScale));
++ output_->SetScale(kTripleScale);
+
+ Sync();
+
+- EXPECT_EQ(window_->buffer_scale(), kNewScale);
++ EXPECT_EQ(window_->buffer_scale(), kTripleScale);
++ EXPECT_EQ(window_->ui_scale_, kTripleScale);
++
++ // Now simulate the --force-device-scale-factor=1.5
++ const float kForcedUIScale = 1.5;
++ base::test::ScopedCommandLine command_line;
++ command_line.GetProcessCommandLine()->AppendSwitchASCII(
++ switches::kForceDeviceScaleFactor,
++ base::StringPrintf("%.1f", kForcedUIScale));
++ display::Display::ResetForceDeviceScaleFactorForTesting();
++
++ // Change the scale of the output again. Windows must update scale of
++ // their buffers but the UI scale must get the forced value.
++ const int32_t kDoubleScale = 2;
++ // Question ourselves before questioning others!
++ EXPECT_NE(kForcedUIScale, kDoubleScale);
++ EXPECT_CALL(*surface_, SetBufferScale(kDoubleScale));
++ output_->SetScale(kDoubleScale);
++
++ Sync();
++
++ EXPECT_EQ(window_->buffer_scale(), kDoubleScale);
++ EXPECT_EQ(window_->ui_scale_, kForcedUIScale);
++
++ display::Display::ResetForceDeviceScaleFactorForTesting();
+ }
+
+ INSTANTIATE_TEST_SUITE_P(XdgVersionV5Test,
+diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc
+index eb79b91892f9..9afed0cc87fb 100644
+--- a/ui/ozone/platform/wayland/host/wayland_window.cc
++++ b/ui/ozone/platform/wayland/host/wayland_window.cc
+@@ -147,6 +147,7 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) {
+ // Popups need to know their scale earlier to position themselves.
+ DCHECK(parent_window_);
+ SetBufferScale(parent_window_->buffer_scale_, false);
++ ui_scale_ = parent_window_->ui_scale_;
+
+ // TODO(msisov, jkim): Handle notification windows, which are marked
+ // as popup windows as well. Those are the windows that do not have
+@@ -184,15 +185,19 @@ void WaylandWindow::UpdateBufferScale(bool update_bounds) {
+ int32_t new_scale = 0;
+ if (parent_window_) {
+ new_scale = parent_window_->buffer_scale_;
+- } else if (widget == gfx::kNullAcceleratedWidget) {
+- new_scale = screen->GetPrimaryDisplay().device_scale_factor();
++ ui_scale_ = parent_window_->ui_scale_;
+ } else {
+- // This is the main window that is fully set up so we can ask which display
+- // we are at currently.
+- new_scale =
+- connection_->wayland_output_manager()
+- ->GetOutput(screen->GetDisplayForAcceleratedWidget(widget).id())
+- ->scale_factor();
++ const auto display = (widget == gfx::kNullAcceleratedWidget)
++ ? screen->GetPrimaryDisplay()
++ : screen->GetDisplayForAcceleratedWidget(widget);
++ new_scale = connection_->wayland_output_manager()
++ ->GetOutput(display.id())
++ ->scale_factor();
++
++ if (display::Display::HasForceDeviceScaleFactor())
++ ui_scale_ = display::Display::GetForcedDeviceScaleFactor();
++ else
++ ui_scale_ = display.device_scale_factor();
+ }
+ SetBufferScale(new_scale, update_bounds);
+ }
+@@ -203,10 +208,6 @@ gfx::AcceleratedWidget WaylandWindow::GetWidget() const {
+ return surface_.id();
+ }
+
+-std::set<uint32_t> WaylandWindow::GetEnteredOutputsIds() const {
+- return entered_outputs_ids_;
+-}
+-
+ void WaylandWindow::CreateXdgPopup() {
+ if (bounds_px_.IsEmpty())
+ return;
+@@ -333,7 +334,7 @@ void WaylandWindow::Show() {
+ // bounds. This makes a difference against the normal flow when the
+ // window is created (see |Initialize|). To equalize things, rescale
+ // |bounds_px_| to DIP. It will be adjusted while creating the popup.
+- bounds_px_ = gfx::ScaleToRoundedRect(bounds_px_, 1.0 / buffer_scale_);
++ bounds_px_ = gfx::ScaleToRoundedRect(bounds_px_, 1.0 / ui_scale_);
+ CreateXdgPopup();
+ connection_->ScheduleFlush();
+ }
+@@ -916,13 +917,14 @@ gfx::Rect WaylandWindow::AdjustPopupWindowPosition() const {
+ : parent_window_;
+ DCHECK(parent_window);
+ DCHECK(buffer_scale_ == parent_window->buffer_scale_);
++ DCHECK(ui_scale_ == parent_window->ui_scale_);
+
+ // Chromium positions windows in screen coordinates, but Wayland requires them
+ // to be in local surface coordinates aka relative to parent window.
+- const gfx::Rect parent_bounds_px =
+- gfx::ScaleToRoundedRect(parent_window_->GetBounds(), 1.0 / buffer_scale_);
+- gfx::Rect new_bounds =
+- TranslateBoundsToParentCoordinates(bounds_px_, parent_bounds_px);
++ const gfx::Rect parent_bounds_dip =
++ gfx::ScaleToRoundedRect(parent_window_->GetBounds(), 1.0 / ui_scale_);
++ gfx::Rect new_bounds_dip =
++ TranslateBoundsToParentCoordinates(bounds_px_, parent_bounds_dip);
+
+ // Chromium may decide to position nested menu windows on the left side
+ // instead of the right side of parent menu windows when the size of the
+@@ -942,16 +944,16 @@ gfx::Rect WaylandWindow::AdjustPopupWindowPosition() const {
+ !parent_window_->parent_window_->IsMaximized()) {
+ auto* top_level_window = parent_window_->parent_window_;
+ DCHECK(top_level_window && !top_level_window->xdg_popup());
+- if (new_bounds.x() <= 0 && !top_level_window->IsMaximized()) {
++ if (new_bounds_dip.x() <= 0 && !top_level_window->IsMaximized()) {
+ // Position the child menu window on the right side of the parent window
+ // and let the Wayland compositor decide how to do constraint
+ // adjustements.
+- int new_x =
+- parent_bounds_px.width() - (new_bounds.width() + new_bounds.x());
+- new_bounds.set_x(new_x);
++ int new_x = parent_bounds_dip.width() -
++ (new_bounds_dip.width() + new_bounds_dip.x());
++ new_bounds_dip.set_x(new_x);
+ }
+ }
+- return new_bounds;
++ return gfx::ScaleToRoundedRect(new_bounds_dip, ui_scale_ / buffer_scale_);
+ }
+
+ WaylandWindow* WaylandWindow::GetTopLevelWindow() {
+diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h
+index 8fcf28fde934..d21e5f48e8ff 100644
+--- a/ui/ozone/platform/wayland/host/wayland_window.h
++++ b/ui/ozone/platform/wayland/host/wayland_window.h
+@@ -10,6 +10,8 @@
+ #include <vector>
+
+ #include "base/callback.h"
++#include "base/containers/flat_set.h"
++#include "base/gtest_prod_util.h"
+ #include "base/memory/ref_counted.h"
+ #include "ui/events/platform/platform_event_dispatcher.h"
+ #include "ui/gfx/geometry/rect.h"
+@@ -52,10 +54,10 @@ class WaylandWindow : public PlatformWindow,
+ bool Initialize(PlatformWindowInitProperties properties);
+
+ // Updates the surface buffer scale of the window. Top level windows take
+- // scale according to the scale of their current display or the primary one if
+- // their widget is not yet created, children inherit scale from their parent.
+- // The method recalculates window bounds appropriately if asked to do so
+- // (this is not needed upon window initialization).
++ // scale from the output attached to either their current display or the
++ // primary one if their widget is not yet created, children inherit scale from
++ // their parent. The method recalculates window bounds appropriately if asked
++ // to do so (this is not needed upon window initialization).
+ void UpdateBufferScale(bool update_bounds);
+
+ wl_surface* surface() const { return surface_.get(); }
+@@ -66,13 +68,6 @@ class WaylandWindow : public PlatformWindow,
+
+ gfx::AcceleratedWidget GetWidget() const;
+
+- // Returns the list of wl_outputs aka displays, which this window occupies.
+- // The window can be shown on one or more displays at the same time. An empty
+- // vector can also be returned if the window is not configured on the
+- // compositor side or it has been moved due to unplug action (check the
+- // comment in RemoveEnteredOutputId).
+- std::set<uint32_t> GetEnteredOutputsIds() const;
+-
+ // Apply the bounds specified in the most recent configure event. This should
+ // be called after processing all pending events in the wayland connection.
+ void ApplyPendingBounds();
+@@ -102,6 +97,10 @@ class WaylandWindow : public PlatformWindow,
+
+ bool is_active() const { return is_active_; }
+
++ const base::flat_set<uint32_t>& entered_outputs_ids() const {
++ return entered_outputs_ids_;
++ }
++
+ // WmMoveResizeHandler
+ void DispatchHostWindowDragMovement(
+ int hittest,
+@@ -162,6 +161,8 @@ class WaylandWindow : public PlatformWindow,
+ void OnDragSessionClose(uint32_t dnd_action);
+
+ private:
++ FRIEND_TEST_ALL_PREFIXES(WaylandScreenTest, SetBufferScale);
++
+ void SetBoundsDip(const gfx::Rect& bounds_dip);
+ void SetBufferScale(int32_t scale, bool update_bounds);
+
+@@ -252,7 +253,13 @@ class WaylandWindow : public PlatformWindow,
+ bool has_keyboard_focus_ = false;
+ bool has_touch_focus_ = false;
+ bool has_implicit_grab_ = false;
++ // Wayland's scale factor for the output that this window currently belongs
++ // to.
+ int32_t buffer_scale_ = 1;
++ // The UI scale may be forced through the command line, which means that it
++ // replaces the default value that is equal to the natural device scale.
++ // We need it to place and size the menus properly.
++ float ui_scale_ = 1.0;
+
+ // Stores current states of the window.
+ ui::PlatformWindowState state_;
+@@ -268,15 +275,15 @@ class WaylandWindow : public PlatformWindow,
+
+ bool is_tooltip_ = false;
+
+- // For top level window, stores the list of entered outputs that the window
+- // is currently in.
++ // For top level window, stores IDs of outputs that the window is currently
++ // rendered at.
+ //
+ // Not used by popups. When sub-menus are hidden and shown again, Wayland
+- // 'repositions' sub-menus to wrong outputs by sending them leave and enter
++ // 'repositions' them to wrong outputs by sending them leave and enter
+ // events so their list of entered outputs becomes meaningless after they have
+ // been hidden at least once. To determine which output the popup belongs to,
+ // we ask its parent.
+- std::set<uint32_t> entered_outputs_ids_;
++ base::flat_set<uint32_t> entered_outputs_ids_;
+
+ DISALLOW_COPY_AND_ASSIGN(WaylandWindow);
+ };
+--
+2.22.0
+