diff options
author | Daniel Playfair Cal | 2019-08-09 01:26:09 +1000 |
---|---|---|
committer | Daniel Playfair Cal | 2019-08-09 01:26:09 +1000 |
commit | aaa1f9a6be7a5f2883388b44fda07ecdf6263065 (patch) | |
tree | 70dc72948b8d1a618ff5af19d5c0e0309fa77d24 /0009-Fixed-positioning-and-sizes-of-menus-when-the-scale-.patch | |
parent | fc6ed6aa0254db2ff86daaba0b5aba2368872f0c (diff) | |
download | aur-aaa1f9a6be7a5f2883388b44fda07ecdf6263065.tar.gz |
More patches to fix freezes
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-.patch | 315 |
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 + |