diff options
Diffstat (limited to 'chromium-ozone-scale.patch')
-rw-r--r-- | chromium-ozone-scale.patch | 1541 |
1 files changed, 0 insertions, 1541 deletions
diff --git a/chromium-ozone-scale.patch b/chromium-ozone-scale.patch deleted file mode 100644 index 2291787d3d76..000000000000 --- a/chromium-ozone-scale.patch +++ /dev/null @@ -1,1541 +0,0 @@ -commit f2f7f4d81479a69a34ed9227eceb9eb8b6f6ceac -Author: Alexander Dunaev <adunaev@igalia.com> -Date: Fri May 3 17:12:15 2019 +0000 - - [ozone/wayland] Fixed some issues related to scaling on HiDPI screens. - - There are two independent scale factors that were not used properly, which - caused incorrect scaling behaviour on HiDPI screens. - - The first scale factor is property of the window manager (Wayland); it is - integral and expected to be used as scale of buffers that back the window - surface (see wl_surface_set_buffer_scale). This value is provided by - the window manager, and neither user nor browser can affect it directly. - I will refer to this value as 'platform scale'. - - The second scale factor defines how much the browser UI should be scaled. - This value is real (floating point), and it can be set via the aforementioned - --force-device-scale-factor command line flag. The default base scale is - equal to the platform scale, which results in UI that looks more or less - the same size as other applications. This scale is set in display::Display, - and I will refer to it as 'UI scale'. - - So here is what this CL fixes. - - 1. The platform scale had been forwarded to the UI scale with no regard to - the forcing flag, which caused issue 910797 (the flag did not have any - effect). - 2. The platform scale had not been used to scale the backing buffers, which - caused the issue 929871 (blurry contents of windows on HDPI screens). - 3. The coordinate-aware events (mouse and touch) and window sizing logic - were not aware of the buffer scaling. - 4. Both parameters had been named 'device scale factors' which was confusing. - - There are some issues that will be fixed in consequent CLs. The forced - device scale factor is not propagated properly through display::Display. - For fixing that, https://crbug.com/950313 is filed. - - Bug: 910797 - Change-Id: I51a95e7218306295e3ab1f90d4b088b8bee93951 - Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1472617 - Reviewed-by: Sadrul Chowdhury <sadrul@chromium.org> - Reviewed-by: Ahmed Fakhry <afakhry@chromium.org> - Reviewed-by: Bret Sepulveda <bsep@chromium.org> - Reviewed-by: Maksim Sisov <msisov@igalia.com> - Reviewed-by: Malay Keshav <malaykeshav@chromium.org> - Reviewed-by: Dominick Ng <dominickn@chromium.org> - Reviewed-by: Robert Kroeger <rjkroege@chromium.org> - Commit-Queue: Alexander Dunaev <adunaev@igalia.com> - Auto-Submit: Alexander Dunaev <adunaev@igalia.com> - Cr-Commit-Position: refs/heads/master@{#656423} - -diff --git a/content/browser/renderer_host/browser_compositor_view_mac.mm b/content/browser/renderer_host/browser_compositor_view_mac.mm -index 0817b4eca4f4..07b3e1a6fab8 100644 ---- a/content/browser/renderer_host/browser_compositor_view_mac.mm -+++ b/content/browser/renderer_host/browser_compositor_view_mac.mm -@@ -166,7 +166,7 @@ void BrowserCompositorMac::UpdateSurfaceFromChild( - const viz::LocalSurfaceIdAllocation& child_local_surface_id_allocation) { - if (dfh_local_surface_id_allocator_.UpdateFromChild( - child_local_surface_id_allocation)) { -- dfh_display_.set_device_scale_factor(new_device_scale_factor); -+ dfh_display_.SetDeviceScaleFactor(new_device_scale_factor); - dfh_size_dip_ = gfx::ConvertSizeToDIP(dfh_display_.device_scale_factor(), - new_size_in_pixels); - dfh_size_pixels_ = new_size_in_pixels; -@@ -400,7 +400,7 @@ void BrowserCompositorMac::SetParentUiLayer(ui::Layer* new_parent_ui_layer) { - - bool BrowserCompositorMac::ForceNewSurfaceForTesting() { - display::Display new_display(dfh_display_); -- new_display.set_device_scale_factor(new_display.device_scale_factor() * 2.0f); -+ new_display.SetDeviceScaleFactor(new_display.device_scale_factor() * 2.0f); - return UpdateSurfaceFromNSView(dfh_size_dip_, new_display); - } - -diff --git a/content/common/cursors/webcursor_unittest.cc b/content/common/cursors/webcursor_unittest.cc -index d5454d35332c..855aff061cb5 100644 ---- a/content/common/cursors/webcursor_unittest.cc -+++ b/content/common/cursors/webcursor_unittest.cc -@@ -258,7 +258,7 @@ TEST(WebCursorTest, AlphaConversion) { - #if defined(USE_AURA) - TEST(WebCursorTest, CursorScaleFactor) { - display::Display display; -- display.set_device_scale_factor(80.2f); -+ display.SetDeviceScaleFactor(4.2f); - - CursorInfo info; - info.type = WebCursorInfo::kTypeCustom; -@@ -325,7 +325,7 @@ namespace { - - void ScaleCursor(float scale_factor, int hotspot_x, int hotspot_y) { - display::Display display; -- display.set_device_scale_factor(scale_factor); -+ display.SetDeviceScaleFactor(scale_factor); - - CursorInfo info; - info.type = WebCursorInfo::kTypeCustom; -diff --git a/ui/android/display_android_manager.cc b/ui/android/display_android_manager.cc -index 7352daa7127f..746680acbc55 100644 ---- a/ui/android/display_android_manager.cc -+++ b/ui/android/display_android_manager.cc -@@ -69,6 +69,30 @@ Display DisplayAndroidManager::GetDisplayMatching( - return GetPrimaryDisplay(); - } - -+void DisplayAndroidManager::DoUpdateDisplay(display::Display* display, -+ gfx::Size size_in_pixels, -+ float dipScale, -+ int rotationDegrees, -+ int bitsPerPixel, -+ int bitsPerComponent, -+ bool isWideColorGamut) { -+ if (!Display::HasForceDeviceScaleFactor()) -+ display->SetDeviceScaleFactor(dipScale); -+ if (!Display::HasForceDisplayColorProfile()) { -+ if (isWideColorGamut) { -+ display->set_color_space(gfx::ColorSpace::CreateDisplayP3D65()); -+ } else { -+ display->set_color_space(gfx::ColorSpace::CreateSRGB()); -+ } -+ } -+ -+ display->set_size_in_pixels(size_in_pixels); -+ display->SetRotationAsDegree(rotationDegrees); -+ display->set_color_depth(bitsPerPixel); -+ display->set_depth_per_component(bitsPerComponent); -+ display->set_is_monochrome(bitsPerComponent == 0); -+} -+ - // Methods called from Java - - void DisplayAndroidManager::UpdateDisplay( -diff --git a/ui/aura/window_tree_host.cc b/ui/aura/window_tree_host.cc -index 08ffa5e729bf..5c6b9c5dc01a 100644 ---- a/ui/aura/window_tree_host.cc -+++ b/ui/aura/window_tree_host.cc -@@ -28,7 +28,6 @@ - #include "ui/compositor/compositor_switches.h" - #include "ui/compositor/dip_util.h" - #include "ui/compositor/layer.h" --#include "ui/display/display.h" - #include "ui/display/screen.h" - #include "ui/events/keycodes/dom/dom_code.h" - #include "ui/gfx/geometry/insets.h" -@@ -114,9 +113,7 @@ WindowTreeHost* WindowTreeHost::GetForAcceleratedWidget( - } - - void WindowTreeHost::InitHost() { -- display::Display display = -- display::Screen::GetScreen()->GetDisplayNearestWindow(window()); -- device_scale_factor_ = display.device_scale_factor(); -+ device_scale_factor_ = GetDisplay().device_scale_factor(); - - UpdateRootWindowSizeInPixels(); - InitCompositor(); -@@ -283,7 +280,7 @@ ui::EventSink* WindowTreeHost::GetEventSink() { - } - - int64_t WindowTreeHost::GetDisplayId() { -- return display::Screen::GetScreen()->GetDisplayNearestWindow(window()).id(); -+ return GetDisplay().id(); - } - - void WindowTreeHost::Show() { -@@ -356,8 +353,11 @@ WindowTreeHost::WindowTreeHost(std::unique_ptr<Window> window) - if (!window_) - window_ = new Window(nullptr); - display::Screen::GetScreen()->AddObserver(this); -- auto display = display::Screen::GetScreen()->GetDisplayNearestWindow(window_); -- device_scale_factor_ = display.device_scale_factor(); -+ device_scale_factor_ = GetDisplay().device_scale_factor(); -+} -+ -+display::Display WindowTreeHost::GetDisplay() const { -+ return display::Screen::GetScreen()->GetDisplayNearestWindow(window_); - } - - void WindowTreeHost::IntializeDeviceScaleFactor(float device_scale_factor) { -@@ -384,7 +384,7 @@ void WindowTreeHost::DestroyDispatcher() { - // ~Window, but by that time any calls to virtual methods overriden here (such - // as GetRootWindow()) result in Window's implementation. By destroying here - // we ensure GetRootWindow() still returns this. -- //window()->RemoveOrDestroyChildren(); -+ // window()->RemoveOrDestroyChildren(); - } - - void WindowTreeHost::CreateCompositor( -@@ -425,8 +425,7 @@ void WindowTreeHost::InitCompositor() { - window()->GetLocalSurfaceIdAllocation()); - compositor_->SetRootLayer(window()->layer()); - -- display::Display display = -- display::Screen::GetScreen()->GetDisplayNearestWindow(window()); -+ display::Display display = GetDisplay(); - compositor_->SetDisplayColorSpace(display.color_space()); - } - -@@ -450,9 +449,7 @@ void WindowTreeHost::OnHostResizedInPixels( - const viz::LocalSurfaceIdAllocation& new_local_surface_id_allocation) { - // TODO(jonross) Unify all OnHostResizedInPixels to have both - // viz::LocalSurfaceId and allocation time as optional parameters. -- display::Display display = -- display::Screen::GetScreen()->GetDisplayNearestWindow(window()); -- device_scale_factor_ = display.device_scale_factor(); -+ device_scale_factor_ = GetDisplay().device_scale_factor(); - UpdateRootWindowSizeInPixels(); - - // Allocate a new LocalSurfaceId for the new state. -@@ -479,8 +476,7 @@ void WindowTreeHost::OnHostWorkspaceChanged() { - void WindowTreeHost::OnHostDisplayChanged() { - if (!compositor_) - return; -- display::Display display = -- display::Screen::GetScreen()->GetDisplayNearestWindow(window()); -+ display::Display display = GetDisplay(); - compositor_->SetDisplayColorSpace(display.color_space()); - } - -@@ -529,11 +525,8 @@ void WindowTreeHost::MoveCursorToInternal(const gfx::Point& root_location, - last_cursor_request_position_in_host_ = host_location; - MoveCursorToScreenLocationInPixels(host_location); - client::CursorClient* cursor_client = client::GetCursorClient(window()); -- if (cursor_client) { -- const display::Display& display = -- display::Screen::GetScreen()->GetDisplayNearestWindow(window()); -- cursor_client->SetDisplay(display); -- } -+ if (cursor_client) -+ cursor_client->SetDisplay(GetDisplay()); - dispatcher()->OnCursorMovedToRootLocation(root_location); - } - -diff --git a/ui/aura/window_tree_host.h b/ui/aura/window_tree_host.h -index 7730ef6a58a7..4629aa61f9d7 100644 ---- a/ui/aura/window_tree_host.h -+++ b/ui/aura/window_tree_host.h -@@ -24,6 +24,7 @@ - #include "ui/base/cursor/cursor.h" - #include "ui/base/ime/input_method_delegate.h" - #include "ui/compositor/compositor_observer.h" -+#include "ui/display/display.h" - #include "ui/display/display_observer.h" - #include "ui/events/event_source.h" - #include "ui/events/platform_event.h" -@@ -34,7 +35,7 @@ class Point; - class Rect; - class Size; - class Transform; --} -+} // namespace gfx - - namespace ui { - class Compositor; -@@ -43,7 +44,7 @@ class EventSink; - class InputMethod; - class ViewProp; - struct PlatformWindowInitProperties; --} -+} // namespace ui - - namespace aura { - -@@ -254,6 +255,9 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate, - - explicit WindowTreeHost(std::unique_ptr<Window> window = nullptr); - -+ // Gets the display that this window tree host resides at. -+ display::Display GetDisplay() const; -+ - // Set the cached display device scale factor. This should only be called - // during subclass initialization, when the value is needed before InitHost(). - void IntializeDeviceScaleFactor(float device_scale_factor); -diff --git a/ui/aura/window_tree_host_platform.cc b/ui/aura/window_tree_host_platform.cc -index 99159327dd48..d839420eb361 100644 ---- a/ui/aura/window_tree_host_platform.cc -+++ b/ui/aura/window_tree_host_platform.cc -@@ -272,7 +272,6 @@ void WindowTreeHostPlatform::OnAcceleratedWidgetDestroyed() { - widget_ = gfx::kNullAcceleratedWidget; - } - --void WindowTreeHostPlatform::OnActivationChanged(bool active) { --} -+void WindowTreeHostPlatform::OnActivationChanged(bool active) {} - - } // namespace aura -diff --git a/ui/display/display.cc b/ui/display/display.cc -index 68a5b3a9cc2d..187af470dedf 100644 ---- a/ui/display/display.cc -+++ b/ui/display/display.cc -@@ -230,6 +230,12 @@ Display Display::GetDefaultDisplay() { - return Display(kDefaultDisplayId, gfx::Rect(0, 0, 1920, 1080)); - } - -+void Display::SetDeviceScaleFactor(float scale) { -+ if (HasForceDeviceScaleFactor()) -+ return; -+ device_scale_factor_ = scale; -+} -+ - int Display::RotationAsDegree() const { - switch (rotation_) { - case ROTATE_0: -diff --git a/ui/display/display.h b/ui/display/display.h -index 53f3e95c8243..5e316dfec472 100644 ---- a/ui/display/display.h -+++ b/ui/display/display.h -@@ -148,12 +148,12 @@ class DISPLAY_EXPORT Display final { - const gfx::Rect& work_area() const { return work_area_; } - void set_work_area(const gfx::Rect& work_area) { work_area_ = work_area; } - -- // Output device's pixel scale factor. This specifies how much the -- // UI should be scaled when the actual output has more pixels than -- // standard displays (which is around 100~120dpi.) The potential return -- // values depend on each platforms. -+ // Pixel scale factor. This specifies how much the UI should be scaled when -+ // rendering on the actual output. This is needed when the latter has more -+ // pixels than standard displays (which is around 100~120dpi). The potential -+ // return values depend on each platforms. - float device_scale_factor() const { return device_scale_factor_; } -- void set_device_scale_factor(float scale) { device_scale_factor_ = scale; } -+ void SetDeviceScaleFactor(float scale); - - Rotation rotation() const { return rotation_; } - void set_rotation(Rotation rotation) { rotation_ = rotation; } -@@ -178,7 +178,7 @@ class DISPLAY_EXPORT Display final { - gfx::Insets GetWorkAreaInsets() const; - - // Sets the device scale factor and display bounds in pixel. This -- // updates the work are using the same insets between old bounds and -+ // updates the work area using the same insets between old bounds and - // work area. - void SetScaleAndBounds(float device_scale_factor, - const gfx::Rect& bounds_in_pixel); -@@ -187,7 +187,7 @@ class DISPLAY_EXPORT Display final { - // between old bounds and work area. - void SetSize(const gfx::Size& size_in_pixel); - -- // Computes and updates the display's work are using -+ // Computes and updates the display's work area using - // |work_area_insets| and the bounds. - void UpdateWorkAreaFromInsets(const gfx::Insets& work_area_insets); - -@@ -234,9 +234,7 @@ class DISPLAY_EXPORT Display final { - - // The number of bits per pixel. Used by media query APIs. - int color_depth() const { return color_depth_; } -- void set_color_depth(int color_depth) { -- color_depth_ = color_depth; -- } -+ void set_color_depth(int color_depth) { color_depth_ = color_depth; } - - // The number of bits per color component (all color components are assumed to - // have the same number of bits). Used by media query APIs. -diff --git a/ui/display/display_change_notifier_unittest.cc b/ui/display/display_change_notifier_unittest.cc -index af69515cba98..346892980c7a 100644 ---- a/ui/display/display_change_notifier_unittest.cc -+++ b/ui/display/display_change_notifier_unittest.cc -@@ -412,9 +412,9 @@ TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_DSF) { - - std::vector<Display> old_displays, new_displays; - old_displays.push_back(Display(1)); -- old_displays[0].set_device_scale_factor(1.f); -+ old_displays[0].SetDeviceScaleFactor(1.f); - new_displays.push_back(Display(1)); -- new_displays[0].set_device_scale_factor(2.f); -+ new_displays[0].SetDeviceScaleFactor(2.f); - - change_notifier.NotifyDisplaysChanged(old_displays, new_displays); - EXPECT_EQ(1, observer.display_changed()); -@@ -436,8 +436,8 @@ TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_Multi_Displays) { - new_displays.push_back(Display(2)); - new_displays.push_back(Display(3)); - -- old_displays[0].set_device_scale_factor(1.f); -- new_displays[0].set_device_scale_factor(2.f); -+ old_displays[0].SetDeviceScaleFactor(1.f); -+ new_displays[0].SetDeviceScaleFactor(2.f); - - old_displays[1].set_bounds(gfx::Rect(0, 0, 200, 200)); - new_displays[1].set_bounds(gfx::Rect(0, 0, 400, 400)); -@@ -456,11 +456,11 @@ TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_Multi_Metrics) { - - std::vector<Display> old_displays, new_displays; - old_displays.push_back(Display(1, gfx::Rect(0, 0, 200, 200))); -- old_displays[0].set_device_scale_factor(1.f); -+ old_displays[0].SetDeviceScaleFactor(1.f); - old_displays[0].SetRotationAsDegree(0); - - new_displays.push_back(Display(1, gfx::Rect(100, 100, 200, 200))); -- new_displays[0].set_device_scale_factor(2.f); -+ new_displays[0].SetDeviceScaleFactor(2.f); - new_displays[0].SetRotationAsDegree(90); - - change_notifier.NotifyDisplaysChanged(old_displays, new_displays); -diff --git a/ui/display/display_list.cc b/ui/display/display_list.cc -index 9edacb7399ea..cb4867a56ca3 100644 ---- a/ui/display/display_list.cc -+++ b/ui/display/display_list.cc -@@ -90,7 +90,7 @@ uint32_t DisplayList::UpdateDisplay(const Display& display, Type type) { - changed_values |= DisplayObserver::DISPLAY_METRIC_ROTATION; - } - if (local_display->device_scale_factor() != display.device_scale_factor()) { -- local_display->set_device_scale_factor(display.device_scale_factor()); -+ local_display->SetDeviceScaleFactor(display.device_scale_factor()); - changed_values |= DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR; - } - if (local_display->color_space() != display.color_space()) { -diff --git a/ui/display/ios/screen_ios.mm b/ui/display/ios/screen_ios.mm -index cb3c47b282b5..7f26be4d24c3 100644 ---- a/ui/display/ios/screen_ios.mm -+++ b/ui/display/ios/screen_ios.mm -@@ -17,7 +17,7 @@ class ScreenIos : public ScreenBase { - UIScreen* mainScreen = [UIScreen mainScreen]; - CHECK(mainScreen); - Display display(0, gfx::Rect(mainScreen.bounds)); -- display.set_device_scale_factor([mainScreen scale]); -+ display.SetDeviceScaleFactor([mainScreen scale]); - ProcessDisplayChanged(display, true /* is_primary */); - } - -diff --git a/ui/display/mac/screen_mac.mm b/ui/display/mac/screen_mac.mm -index 96f17137071a..79a7e39b05e2 100644 ---- a/ui/display/mac/screen_mac.mm -+++ b/ui/display/mac/screen_mac.mm -@@ -78,7 +78,7 @@ Display BuildDisplayForScreen(NSScreen* screen) { - CGFloat scale = [screen backingScaleFactor]; - if (Display::HasForceDeviceScaleFactor()) - scale = Display::GetForcedDeviceScaleFactor(); -- display.set_device_scale_factor(scale); -+ display.SetDeviceScaleFactor(scale); - - // Compute the color profile. - gfx::ICCProfile icc_profile; -diff --git a/ui/display/mojo/display_struct_traits.cc b/ui/display/mojo/display_struct_traits.cc -index 2603edefcccc..6bfba6a47650 100644 ---- a/ui/display/mojo/display_struct_traits.cc -+++ b/ui/display/mojo/display_struct_traits.cc -@@ -126,7 +126,7 @@ bool StructTraits<display::mojom::DisplayDataView, display::Display>::Read( - if (!data.ReadWorkArea(&out->work_area_)) - return false; - -- out->set_device_scale_factor(data.device_scale_factor()); -+ out->SetDeviceScaleFactor(data.device_scale_factor()); - - if (!data.ReadRotation(&out->rotation_)) - return false; -diff --git a/ui/display/mojo/display_struct_traits_unittest.cc b/ui/display/mojo/display_struct_traits_unittest.cc -index 32a460e93949..83b860a7b5e1 100644 ---- a/ui/display/mojo/display_struct_traits_unittest.cc -+++ b/ui/display/mojo/display_struct_traits_unittest.cc -@@ -131,7 +131,7 @@ TEST(DisplayStructTraitsTest, SetAllDisplayValues) { - - Display input(246345234, bounds); - input.set_work_area(work_area); -- input.set_device_scale_factor(2.0f); -+ input.SetDeviceScaleFactor(2.0f); - input.set_rotation(Display::ROTATE_270); - input.set_touch_support(Display::TouchSupport::AVAILABLE); - input.set_accelerometer_support(Display::AccelerometerSupport::UNAVAILABLE); -diff --git a/ui/display/win/screen_win.cc b/ui/display/win/screen_win.cc -index cb17d76dd94f..9701116b9e79 100644 ---- a/ui/display/win/screen_win.cc -+++ b/ui/display/win/screen_win.cc -@@ -172,7 +172,7 @@ Display CreateDisplayFromDisplayInfo(const DisplayInfo& display_info, - bool hdr_enabled) { - Display display(display_info.id()); - float scale_factor = display_info.device_scale_factor(); -- display.set_device_scale_factor(scale_factor); -+ display.SetDeviceScaleFactor(scale_factor); - display.set_work_area( - gfx::ScaleToEnclosingRect(display_info.screen_work_rect(), - 1.0f / scale_factor)); -diff --git a/ui/display/win/screen_win_display.cc b/ui/display/win/screen_win_display.cc -index 5a000b563015..cdb36ccf29c1 100644 ---- a/ui/display/win/screen_win_display.cc -+++ b/ui/display/win/screen_win_display.cc -@@ -14,7 +14,7 @@ namespace { - Display CreateDisplayFromDisplayInfo(const DisplayInfo& display_info) { - Display display(display_info.id()); - float scale_factor = display_info.device_scale_factor(); -- display.set_device_scale_factor(scale_factor); -+ display.SetDeviceScaleFactor(scale_factor); - display.set_work_area( - gfx::ScaleToEnclosingRect(display_info.screen_work_rect(), - 1.0f / scale_factor)); -diff --git a/ui/ozone/platform/scenic/scenic_screen.cc b/ui/ozone/platform/scenic/scenic_screen.cc -index e7658c5cf277..a504ad649046 100644 ---- a/ui/ozone/platform/scenic/scenic_screen.cc -+++ b/ui/ozone/platform/scenic/scenic_screen.cc -@@ -55,7 +55,7 @@ void ScenicScreen::OnWindowMetrics(int32_t window_id, - }); - DCHECK(display_it != displays_.end()); - -- display_it->set_device_scale_factor(device_pixel_ratio); -+ display_it->SetDeviceScaleFactor(device_pixel_ratio); - for (auto& observer : observers_) { - observer.OnDisplayMetricsChanged( - *display_it, -diff --git a/ui/ozone/platform/wayland/wayland_connection.cc b/ui/ozone/platform/wayland/wayland_connection.cc -index e7095507a83d..76c075cea38d 100644 ---- a/ui/ozone/platform/wayland/wayland_connection.cc -+++ b/ui/ozone/platform/wayland/wayland_connection.cc -@@ -160,6 +160,16 @@ WaylandWindow* WaylandConnection::GetCurrentKeyboardFocusedWindow() { - return nullptr; - } - -+std::vector<WaylandWindow*> WaylandConnection::GetWindowsOnDisplay( -+ uint32_t display_id) { -+ std::vector<WaylandWindow*> result; -+ for (auto entry : window_map_) { -+ if (entry.second->GetEnteredOutputsIds().count(display_id) > 0) -+ result.push_back(entry.second); -+ } -+ return result; -+} -+ - void WaylandConnection::AddWindow(gfx::AcceleratedWidget widget, - WaylandWindow* window) { - window_map_[widget] = window; -diff --git a/ui/ozone/platform/wayland/wayland_connection.h b/ui/ozone/platform/wayland/wayland_connection.h -index c7da42b930dd..575b5fbf4b05 100644 ---- a/ui/ozone/platform/wayland/wayland_connection.h -+++ b/ui/ozone/platform/wayland/wayland_connection.h -@@ -99,6 +99,9 @@ class WaylandConnection : public PlatformEventSource, - WaylandWindow* GetWindowWithLargestBounds(); - WaylandWindow* GetCurrentFocusedWindow(); - WaylandWindow* GetCurrentKeyboardFocusedWindow(); -+ // TODO(adunaev) remove this in favor of targeted subscription of windows to -+ // their displays. -+ std::vector<WaylandWindow*> GetWindowsOnDisplay(uint32_t display_id); - void AddWindow(gfx::AcceleratedWidget widget, WaylandWindow* window); - void RemoveWindow(gfx::AcceleratedWidget widget); - -@@ -220,7 +223,7 @@ class WaylandConnection : public PlatformEventSource, - // xdg_shell_listener - static void Ping(void* data, xdg_shell* shell, uint32_t serial); - -- std::map<gfx::AcceleratedWidget, WaylandWindow*> window_map_; -+ base::flat_map<gfx::AcceleratedWidget, WaylandWindow*> window_map_; - - wl::Object<wl_display> display_; - wl::Object<wl_registry> registry_; -diff --git a/ui/ozone/platform/wayland/wayland_output.cc b/ui/ozone/platform/wayland/wayland_output.cc -index 91cdf2c43bf5..719f251a31b9 100644 ---- a/ui/ozone/platform/wayland/wayland_output.cc -+++ b/ui/ozone/platform/wayland/wayland_output.cc -@@ -11,14 +11,10 @@ - - namespace ui { - --namespace { --constexpr float kDefaultScaleFactor = 1.0f; --} -- - WaylandOutput::WaylandOutput(const uint32_t output_id, wl_output* output) - : output_id_(output_id), - output_(output), -- device_scale_factor_(kDefaultScaleFactor), -+ scale_factor_(kDefaultScaleFactor), - rect_in_physical_pixels_(gfx::Rect()) {} - - WaylandOutput::~WaylandOutput() = default; -@@ -36,7 +32,7 @@ void WaylandOutput::Initialize(Delegate* delegate) { - void WaylandOutput::TriggerDelegateNotification() const { - DCHECK(!rect_in_physical_pixels_.IsEmpty()); - delegate_->OnOutputHandleMetrics(output_id_, rect_in_physical_pixels_, -- device_scale_factor_); -+ scale_factor_); - } - - // static -@@ -80,7 +76,7 @@ void WaylandOutput::OutputHandleScale(void* data, - int32_t factor) { - WaylandOutput* wayland_output = static_cast<WaylandOutput*>(data); - if (wayland_output) -- wayland_output->device_scale_factor_ = factor; -+ wayland_output->scale_factor_ = factor; - } - - } // namespace ui -diff --git a/ui/ozone/platform/wayland/wayland_output.h b/ui/ozone/platform/wayland/wayland_output.h -index 41a4d3959bb3..15d15672711f 100644 ---- a/ui/ozone/platform/wayland/wayland_output.h -+++ b/ui/ozone/platform/wayland/wayland_output.h -@@ -36,12 +36,15 @@ class WaylandOutput { - - uint32_t output_id() const { return output_id_; } - bool has_output(wl_output* output) const { return output_.get() == output; } -+ int32_t scale_factor() const { return scale_factor_; } - - // Tells if the output has already received physical screen dimensions in the - // global compositor space. - bool is_ready() const { return !rect_in_physical_pixels_.IsEmpty(); } - - private: -+ static constexpr int32_t kDefaultScaleFactor = 1; -+ - // Callback functions used for setting geometric properties of the output - // and available modes. - static void OutputHandleGeometry(void* data, -@@ -54,7 +57,6 @@ class WaylandOutput { - const char* make, - const char* model, - int32_t output_transform); -- - static void OutputHandleMode(void* data, - wl_output* wl_output, - uint32_t flags, -@@ -68,7 +70,7 @@ class WaylandOutput { - - const uint32_t output_id_ = 0; - wl::Object<wl_output> output_; -- float device_scale_factor_; -+ int32_t scale_factor_ = kDefaultScaleFactor; - gfx::Rect rect_in_physical_pixels_; - - Delegate* delegate_ = nullptr; -diff --git a/ui/ozone/platform/wayland/wayland_output_manager.cc b/ui/ozone/platform/wayland/wayland_output_manager.cc -index 992d0c309333..34e1a9ef3a65 100644 ---- a/ui/ozone/platform/wayland/wayland_output_manager.cc -+++ b/ui/ozone/platform/wayland/wayland_output_manager.cc -@@ -24,10 +24,7 @@ void WaylandOutputManager::AddWaylandOutput(const uint32_t output_id, - // Make sure an output with |output_id| has not been added yet. It's very - // unlikely to happen, unless a compositor has a bug in the numeric names - // representation of global objects. -- auto output_it = std::find_if(output_list_.begin(), output_list_.end(), -- [output_id](const auto& output) { -- return output->output_id() == output_id; -- }); -+ auto output_it = GetOutputItById(output_id); - DCHECK(output_it == output_list_.end()); - auto wayland_output = std::make_unique<WaylandOutput>(output_id, output); - WaylandOutput* wayland_output_ptr = wayland_output.get(); -@@ -42,10 +39,7 @@ void WaylandOutputManager::AddWaylandOutput(const uint32_t output_id, - } - - void WaylandOutputManager::RemoveWaylandOutput(const uint32_t output_id) { -- auto output_it = std::find_if(output_list_.begin(), output_list_.end(), -- [output_id](const auto& output) { -- return output->output_id() == output_id; -- }); -+ auto output_it = GetOutputItById(output_id); - - // Check the comment in the WaylandConnetion::GlobalRemove. - if (output_it == output_list_.end()) -@@ -87,6 +81,13 @@ uint32_t WaylandOutputManager::GetIdForOutput(wl_output* output) const { - return output_it->get()->output_id(); - } - -+WaylandOutput* WaylandOutputManager::GetOutput(uint32_t id) const { -+ auto output_it = GetOutputItById(id); -+ // This is unlikely to happen, but better to be explicit here. -+ DCHECK(output_it != output_list_.end()); -+ return output_it->get(); -+} -+ - void WaylandOutputManager::OnWaylandOutputAdded(uint32_t output_id) { - if (wayland_screen_) - wayland_screen_->OnOutputAdded(output_id); -@@ -105,4 +106,11 @@ void WaylandOutputManager::OnOutputHandleMetrics(uint32_t output_id, - scale_factor); - } - -+WaylandOutputManager::OutputList::const_iterator -+WaylandOutputManager::GetOutputItById(uint32_t id) const { -+ return std::find_if( -+ output_list_.begin(), output_list_.end(), -+ [id](const auto& item) { return item->output_id() == id; }); -+} -+ - } // namespace ui -diff --git a/ui/ozone/platform/wayland/wayland_output_manager.h b/ui/ozone/platform/wayland/wayland_output_manager.h -index cae7097d4b12..133d7a1256b5 100644 ---- a/ui/ozone/platform/wayland/wayland_output_manager.h -+++ b/ui/ozone/platform/wayland/wayland_output_manager.h -@@ -39,6 +39,9 @@ class WaylandOutputManager : public WaylandOutput::Delegate { - WaylandConnection* connection); - - uint32_t GetIdForOutput(wl_output* output) const; -+ WaylandOutput* GetOutput(uint32_t id) const; -+ -+ WaylandScreen* wayland_screen() const { return wayland_screen_.get(); } - - private: - void OnWaylandOutputAdded(uint32_t output_id); -@@ -49,7 +52,11 @@ class WaylandOutputManager : public WaylandOutput::Delegate { - const gfx::Rect& new_bounds, - int32_t scale_factor) override; - -- std::vector<std::unique_ptr<WaylandOutput>> output_list_; -+ using OutputList = std::vector<std::unique_ptr<WaylandOutput>>; -+ -+ OutputList::const_iterator GetOutputItById(uint32_t id) const; -+ -+ OutputList output_list_; - - // Non-owned wayland screen instance. - base::WeakPtr<WaylandScreen> wayland_screen_; -diff --git a/ui/ozone/platform/wayland/wayland_screen.cc b/ui/ozone/platform/wayland/wayland_screen.cc -index 19fb4050b2c0..6b77b8758440 100644 ---- a/ui/ozone/platform/wayland/wayland_screen.cc -+++ b/ui/ozone/platform/wayland/wayland_screen.cc -@@ -23,14 +23,12 @@ WaylandScreen::WaylandScreen(WaylandConnection* connection) - WaylandScreen::~WaylandScreen() = default; - - void WaylandScreen::OnOutputAdded(uint32_t output_id) { -- display::Display new_display(output_id); -- display_list_.AddDisplay(std::move(new_display), -+ display_list_.AddDisplay(display::Display(output_id), - display::DisplayList::Type::NOT_PRIMARY); - } - - void WaylandScreen::OnOutputRemoved(uint32_t output_id) { -- display::Display primary_display = GetPrimaryDisplay(); -- if (primary_display.id() == output_id) { -+ if (output_id == GetPrimaryDisplay().id()) { - // First, set a new primary display as required by the |display_list_|. It's - // safe to set any of the displays to be a primary one. Once the output is - // completely removed, Wayland updates geometry of other displays. And a -@@ -49,9 +47,9 @@ void WaylandScreen::OnOutputRemoved(uint32_t output_id) { - - void WaylandScreen::OnOutputMetricsChanged(uint32_t output_id, - const gfx::Rect& new_bounds, -- float device_pixel_ratio) { -+ int32_t output_scale) { - display::Display changed_display(output_id); -- changed_display.set_device_scale_factor(device_pixel_ratio); -+ changed_display.SetDeviceScaleFactor(output_scale); - changed_display.set_bounds(new_bounds); - changed_display.set_work_area(new_bounds); - -@@ -81,6 +79,9 @@ void WaylandScreen::OnOutputMetricsChanged(uint32_t output_id, - display_list_.UpdateDisplay( - changed_display, is_primary ? display::DisplayList::Type::PRIMARY - : display::DisplayList::Type::NOT_PRIMARY); -+ -+ for (auto* window : connection_->GetWindowsOnDisplay(output_id)) -+ window->UpdateBufferScale(true); - } - - base::WeakPtr<WaylandScreen> WaylandScreen::GetWeakPtr() { -@@ -99,13 +100,14 @@ display::Display WaylandScreen::GetPrimaryDisplay() const { - - display::Display WaylandScreen::GetDisplayForAcceleratedWidget( - gfx::AcceleratedWidget widget) const { -- auto* wayland_window = connection_->GetWindow(widget); -+ auto* window = connection_->GetWindow(widget); - // A window might be destroyed by this time on shutting down the browser. -- if (!wayland_window) -+ if (!window) - return GetPrimaryDisplay(); - -- const std::set<uint32_t> entered_outputs_ids = -- wayland_window->GetEnteredOutputsIds(); -+ const auto* parent_window = window->parent_window(); -+ -+ const std::set<uint32_t> entered_outputs_ids = window->GetEnteredOutputsIds(); - // 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 -@@ -114,14 +116,19 @@ display::Display WaylandScreen::GetDisplayForAcceleratedWidget( - // events immediately, which can result in empty container of entered ids - // (check comments in WaylandWindow::RemoveEnteredOutputId). In this case, - // it's also safe to return the primary display. -- if (entered_outputs_ids.empty()) -+ // A child window will most probably enter the same display than its parent -+ // so we return the parent's display if there is a parent. -+ if (entered_outputs_ids.empty()) { -+ if (parent_window) -+ return GetDisplayForAcceleratedWidget(parent_window->GetWidget()); - return GetPrimaryDisplay(); -+ } - - DCHECK(!display_list_.displays().empty()); - - // A widget can be located on two or more displays. It would be better if the -- // most in pixels occupied display was returned, but it's impossible to do in -- // Wayland. Thus, return the one, which was the very first used. -+ // most in DIP occupied display was returned, but it's impossible to do so in -+ // Wayland. Thus, return the one that was used the earliest. - for (const auto& display : display_list_.displays()) { - if (display.id() == *entered_outputs_ids.begin()) - return display; -diff --git a/ui/ozone/platform/wayland/wayland_screen.h b/ui/ozone/platform/wayland/wayland_screen.h -index 480957bf024d..e1974458e272 100644 ---- a/ui/ozone/platform/wayland/wayland_screen.h -+++ b/ui/ozone/platform/wayland/wayland_screen.h -@@ -29,7 +29,7 @@ class WaylandScreen : public PlatformScreen { - void OnOutputRemoved(uint32_t output_id); - void OnOutputMetricsChanged(uint32_t output_id, - const gfx::Rect& bounds, -- float device_pixel_ratio); -+ int32_t output_scale); - - base::WeakPtr<WaylandScreen> GetWeakPtr(); - -diff --git a/ui/ozone/platform/wayland/wayland_screen_unittest.cc b/ui/ozone/platform/wayland/wayland_screen_unittest.cc -index bd2a30c58589..7a0d45fa47ea 100644 ---- a/ui/ozone/platform/wayland/wayland_screen_unittest.cc -+++ b/ui/ozone/platform/wayland/wayland_screen_unittest.cc -@@ -224,9 +224,8 @@ TEST_P(WaylandScreenTest, OutputPropertyChanges) { - EXPECT_EQ(observer.GetAndClearChangedMetrics(), changed_values); - EXPECT_EQ(observer.GetDisplay().bounds(), new_rect); - -- const float new_scale_value = 2.0f; -- wl_output_send_scale(output_->resource(), new_scale_value); -- wl_output_send_done(output_->resource()); -+ const int32_t new_scale_value = 2; -+ output_->SetScale(new_scale_value); - - Sync(); - -@@ -581,6 +580,23 @@ TEST_P(WaylandScreenTest, GetCursorScreenPoint) { - EXPECT_EQ(gfx::Point(1912, 1071), platform_screen_->GetCursorScreenPoint()); - } - -+// Checks that the surface that backs the window receives new scale of the -+// output that it is in. -+TEST_P(WaylandScreenTest, SetBufferScale) { -+ // Place the window onto the output. -+ 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); -+ -+ Sync(); -+ -+ EXPECT_EQ(window_->buffer_scale(), kNewScale); -+} -+ - INSTANTIATE_TEST_CASE_P(XdgVersionV5Test, - WaylandScreenTest, - ::testing::Values(kXdgShellV5)); -diff --git a/ui/ozone/platform/wayland/wayland_test.cc b/ui/ozone/platform/wayland/wayland_test.cc -index c15bc87efa15..43f4b0dcff12 100644 ---- a/ui/ozone/platform/wayland/wayland_test.cc -+++ b/ui/ozone/platform/wayland/wayland_test.cc -@@ -6,6 +6,8 @@ - - #include "base/run_loop.h" - #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" -+#include "ui/ozone/platform/wayland/host/wayland_output_manager.h" -+#include "ui/ozone/platform/wayland/host/wayland_screen.h" - #include "ui/platform_window/platform_window_init_properties.h" - - #if BUILDFLAG(USE_XKBCOMMON) -@@ -37,6 +39,8 @@ WaylandTest::~WaylandTest() {} - void WaylandTest::SetUp() { - ASSERT_TRUE(server_.Start(GetParam())); - ASSERT_TRUE(connection_->Initialize()); -+ screen_ = connection_->wayland_output_manager()->CreateWaylandScreen( -+ connection_.get()); - EXPECT_CALL(delegate_, OnAcceleratedWidgetAvailable(_)) - .WillOnce(SaveArg<0>(&widget_)); - PlatformWindowInitProperties properties; -diff --git a/ui/ozone/platform/wayland/wayland_test.h b/ui/ozone/platform/wayland/wayland_test.h -index 7c2109062ca1..580dc57f01cc 100644 ---- a/ui/ozone/platform/wayland/wayland_test.h -+++ b/ui/ozone/platform/wayland/wayland_test.h -@@ -20,6 +20,8 @@ - - namespace ui { - -+class WaylandScreen; -+ - const uint32_t kXdgShellV5 = 5; - const uint32_t kXdgShellV6 = 6; - -@@ -46,6 +48,7 @@ class WaylandTest : public ::testing::TestWithParam<uint32_t> { - MockPlatformWindowDelegate delegate_; - std::unique_ptr<WaylandConnectionProxy> connection_proxy_; - std::unique_ptr<WaylandConnection> connection_; -+ std::unique_ptr<WaylandScreen> screen_; - std::unique_ptr<WaylandWindow> window_; - gfx::AcceleratedWidget widget_ = gfx::kNullAcceleratedWidget; - -diff --git a/ui/ozone/platform/wayland/wayland_touch.cc b/ui/ozone/platform/wayland/wayland_touch.cc -index d30bc7342d99..c293681a4391 100644 ---- a/ui/ozone/platform/wayland/wayland_touch.cc -+++ b/ui/ozone/platform/wayland/wayland_touch.cc -@@ -72,7 +72,9 @@ void WaylandTouch::Down(void* data, - WaylandTouch* touch = static_cast<WaylandTouch*>(data); - DCHECK(touch); - touch->connection_->set_serial(serial); -- WaylandWindow::FromSurface(surface)->set_touch_focus(true); -+ auto* window = WaylandWindow::FromSurface(surface); -+ DCHECK(window); -+ window->set_touch_focus(true); - - // Make sure this touch point wasn't present before. - if (touch->current_points_.find(id) != touch->current_points_.end()) { -diff --git a/ui/ozone/platform/wayland/wayland_window.cc b/ui/ozone/platform/wayland/wayland_window.cc -index 7b658951a403..5689ce0e9470 100644 ---- a/ui/ozone/platform/wayland/wayland_window.cc -+++ b/ui/ozone/platform/wayland/wayland_window.cc -@@ -123,7 +123,11 @@ WaylandWindow* WaylandWindow::FromSurface(wl_surface* surface) { - bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) { - DCHECK(xdg_shell_objects_factory_); - -- bounds_ = properties.bounds; -+ // 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())); -@@ -131,16 +135,21 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) { - LOG(ERROR) << "Failed to create wl_surface"; - return false; - } -- wl_surface_set_user_data(surface_.get(), this); -+ -+ wl_surface_set_user_data(surface(), this); -+ - AddSurfaceListener(); - MaybeUpdateOpaqueRegion(); - -- ui::PlatformWindowType ui_window_type = properties.type; -- switch (ui_window_type) { -+ switch (properties.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. -+ DCHECK(parent_window_); -+ SetBufferScale(parent_window_->buffer_scale_, false); -+ - // 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. -@@ -161,9 +170,34 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) { - PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); - delegate_->OnAcceleratedWidgetAvailable(GetWidget()); - -+ // Will do nothing for popups because they have got their scale above. -+ UpdateBufferScale(false); -+ - return true; - } - -+void WaylandWindow::UpdateBufferScale(bool update_bounds) { -+ DCHECK(connection_->wayland_output_manager()); -+ const auto* screen = connection_->wayland_output_manager()->wayland_screen(); -+ DCHECK(screen); -+ const auto widget = GetWidget(); -+ -+ 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(); -+ } else { -+ // This is the main window that is fully set up so we can ask which display -+ // we are at currently. -+ current_display_ = screen->GetDisplayForAcceleratedWidget(widget); -+ new_scale = connection_->wayland_output_manager() -+ ->GetOutput(current_display_.id()) -+ ->scale_factor(); -+ } -+ SetBufferScale(new_scale, update_bounds); -+} -+ - gfx::AcceleratedWidget WaylandWindow::GetWidget() const { - if (!surface_) - return gfx::kNullAcceleratedWidget; -@@ -175,7 +209,7 @@ std::set<uint32_t> WaylandWindow::GetEnteredOutputsIds() const { - } - - void WaylandWindow::CreateXdgPopup() { -- if (bounds_.IsEmpty()) -+ if (bounds_px_.IsEmpty()) - return; - - // TODO(jkim): Consider how to support DropArrow window on tabstrip. -@@ -193,11 +227,11 @@ void WaylandWindow::CreateXdgPopup() { - - DCHECK(parent_window_ && !xdg_popup_); - -- auto bounds = AdjustPopupWindowPosition(); -+ auto bounds_px = AdjustPopupWindowPosition(); - - xdg_popup_ = xdg_shell_objects_factory_->CreateXDGPopup(connection_, this); -- if (!xdg_popup_ || -- !xdg_popup_->Initialize(connection_, surface(), parent_window_, bounds)) { -+ if (!xdg_popup_ || !xdg_popup_->Initialize(connection_, surface(), -+ parent_window_, bounds_px)) { - CHECK(false) << "Failed to create xdg_popup"; - } - -@@ -234,22 +268,24 @@ void WaylandWindow::CreateAndShowTooltipSubSurface() { - } - - DCHECK(tooltip_subsurface_); -- wl_subsurface_set_position(tooltip_subsurface_.get(), bounds_.x(), -- bounds_.y()); -+ // 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::ApplyPendingBounds() { -- if (pending_bounds_.IsEmpty()) -+ if (pending_bounds_dip_.IsEmpty()) - return; - DCHECK(xdg_surface_); - -- SetBounds(pending_bounds_); -- xdg_surface_->SetWindowGeometry(bounds_); -+ SetBoundsDip(pending_bounds_dip_); -+ xdg_surface_->SetWindowGeometry(pending_bounds_dip_); - xdg_surface_->AckConfigure(); -- pending_bounds_ = gfx::Rect(); -+ pending_bounds_dip_ = gfx::Rect(); - connection_->ScheduleFlush(); - } - -@@ -289,9 +325,16 @@ void WaylandWindow::Show() { - } - - if (!xdg_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 / buffer_scale_); - CreateXdgPopup(); - connection_->ScheduleFlush(); - } -+ UpdateBufferScale(false); - } - - void WaylandWindow::Hide() { -@@ -321,20 +364,26 @@ void WaylandWindow::Close() { - - void WaylandWindow::PrepareForShutdown() {} - --void WaylandWindow::SetBounds(const gfx::Rect& bounds) { -- if (bounds == bounds_) -+void WaylandWindow::SetBounds(const gfx::Rect& bounds_px) { -+ // TODO(adunaev): figure out if this return is legitimate, see -+ // https://crbug.com/958314 -+ // The X11 implementation says that even if the pixel bounds -+ // didn't change, we still need to forward this call to the delegate, and that -+ // the device scale factor may have changed which effectively changes the -+ // bounds. Perhaps we need to do the same here. -+ if (bounds_px_ == bounds_px) - return; -- bounds_ = bounds; -+ 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); -+ delegate_->OnBoundsChanged(bounds_px_); - } - - gfx::Rect WaylandWindow::GetBounds() { -- return bounds_; -+ return bounds_px_; - } - - void WaylandWindow::SetTitle(const base::string16& title) { -@@ -461,12 +510,12 @@ PlatformImeController* WaylandWindow::GetPlatformImeController() { - return nullptr; - } - --void WaylandWindow::SetRestoredBoundsInPixels(const gfx::Rect& bounds) { -- restored_bounds_ = bounds; -+void WaylandWindow::SetRestoredBoundsInPixels(const gfx::Rect& bounds_px) { -+ restored_bounds_px_ = bounds_px; - } - - gfx::Rect WaylandWindow::GetRestoredBoundsInPixels() const { -- return restored_bounds_; -+ return restored_bounds_px_; - } - - bool WaylandWindow::CanDispatchEvent(const PlatformEvent& event) { -@@ -497,6 +546,10 @@ uint32_t WaylandWindow::DispatchEvent(const PlatformEvent& native_event) { - Event* event = static_cast<Event*>(native_event); - - if (event->IsLocatedEvent()) { -+ // Located events come in output scale and need to be translated to -+ // physical pixels. -+ event->AsLocatedEvent()->set_location_f(gfx::ScalePoint( -+ event->AsLocatedEvent()->location_f(), buffer_scale_, buffer_scale_)); - auto copied_event = Event::Clone(*event); - UpdateCursorPositionFromEvent(std::move(copied_event)); - } -@@ -578,11 +631,12 @@ void WaylandWindow::HandleSurfaceConfigure(int32_t width, - // explicitly set the bounds to the current desired ones or the previous - // bounds. - if (width > 1 && height > 1) { -- pending_bounds_ = gfx::Rect(0, 0, width, height); -+ pending_bounds_dip_ = gfx::Rect(0, 0, width, height); - } else if (is_normal) { -- pending_bounds_.set_size(restored_bounds_.IsEmpty() -- ? GetBounds().size() -- : restored_bounds_.size()); -+ pending_bounds_dip_.set_size(gfx::ScaleToRoundedSize( -+ restored_bounds_px_.IsEmpty() ? GetBounds().size() -+ : restored_bounds_px_.size(), -+ 1.0 / buffer_scale_)); - } - - if (state_changed) { -@@ -594,8 +648,8 @@ void WaylandWindow::HandleSurfaceConfigure(int32_t width, - if (is_normal) { - SetRestoredBoundsInPixels({}); - } else if (old_state == PlatformWindowState::PLATFORM_WINDOW_STATE_NORMAL || -- restored_bounds_.IsEmpty()) { -- SetRestoredBoundsInPixels(bounds_); -+ restored_bounds_px_.IsEmpty()) { -+ SetRestoredBoundsInPixels(bounds_px_); - } - - delegate_->OnWindowStateChanged(state_); -@@ -604,12 +658,18 @@ void WaylandWindow::HandleSurfaceConfigure(int32_t width, - if (did_active_change) - delegate_->OnActivationChanged(is_active_); - -+ UpdateBufferScale(true); -+ - MaybeTriggerPendingStateChange(); - } - --void WaylandWindow::HandlePopupConfigure(const gfx::Rect& bounds) { -+void WaylandWindow::HandlePopupConfigure(const gfx::Rect& bounds_dip) { - DCHECK(xdg_popup()); -- gfx::Rect new_bounds = bounds; -+ 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 -@@ -627,10 +687,10 @@ void WaylandWindow::HandlePopupConfigure(const gfx::Rect& bounds) { - gfx::Rect parent_bounds = parent_window_->GetBounds(); - // The menu window is flipped along y-axis and have x,-y origin. Shift the - // parent top level window instead. -- if (new_bounds.y() < 0) { -+ if (new_bounds_dip.y() < 0) { - // Move parent bounds along y-axis. -- parent_bounds.set_y(-(new_bounds.y())); -- new_bounds.set_y(0); -+ 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. -@@ -642,11 +702,16 @@ void WaylandWindow::HandlePopupConfigure(const gfx::Rect& bounds) { - // Thus, the location must be translated to be relative to the top level - // window, which automatically becomes the same as relative to an origin of - // a display. -- new_bounds = TranslateBoundsToTopLevelCoordinates( -- new_bounds, parent_window_->GetBounds()); -- DCHECK(new_bounds.y() >= 0); -+ new_bounds_dip = gfx::ScaleToRoundedRect( -+ TranslateBoundsToTopLevelCoordinates( -+ gfx::ScaleToRoundedRect(new_bounds_dip, buffer_scale_), -+ parent_window_->GetBounds()), -+ 1.0 / buffer_scale_); -+ DCHECK(new_bounds_dip.y() >= 0); - } -- SetBounds(new_bounds); -+ -+ // Finally, the menu bounds must be converted to physical pixels. -+ SetBoundsDip(new_bounds_dip); - } - - void WaylandWindow::OnCloseRequest() { -@@ -694,6 +759,26 @@ void WaylandWindow::OnDragSessionClose(uint32_t dnd_action) { - connection_->ResetPointerFlags(); - } - -+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); -+ -+ if (new_scale == buffer_scale_) -+ return; -+ -+ auto old_scale = buffer_scale_; -+ buffer_scale_ = new_scale; -+ if (update_bounds) -+ SetBoundsDip(gfx::ScaleToRoundedRect(bounds_px_, 1.0 / old_scale)); -+ -+ DCHECK(surface()); -+ wl_surface_set_buffer_scale(surface(), buffer_scale_); -+ connection_->ScheduleFlush(); -+} -+ - bool WaylandWindow::IsMinimized() const { - return state_ == PlatformWindowState::PLATFORM_WINDOW_STATE_MINIMIZED; - } -@@ -749,14 +834,28 @@ void WaylandWindow::AddSurfaceListener() { - } - - void WaylandWindow::AddEnteredOutputId(struct wl_output* output) { -+ // Wayland does weird things for popups so instead of tracking outputs that -+ // we entered or left, we take that from the parent window and ignore this -+ // event. -+ if (xdg_popup()) -+ return; -+ - const uint32_t entered_output_id = - connection_->wayland_output_manager()->GetIdForOutput(output); - DCHECK_NE(entered_output_id, 0u); - auto result = entered_outputs_ids_.insert(entered_output_id); - DCHECK(result.first != entered_outputs_ids_.end()); -+ -+ UpdateBufferScale(true); - } - - void WaylandWindow::RemoveEnteredOutputId(struct wl_output* output) { -+ // Wayland does weird things for popups so instead of tracking outputs that -+ // we entered or left, we take that from the parent window and ignore this -+ // event. -+ if (xdg_popup()) -+ return; -+ - const uint32_t left_output_id = - connection_->wayland_output_manager()->GetIdForOutput(output); - auto entered_output_id_it = entered_outputs_ids_.find(left_output_id); -@@ -766,8 +865,11 @@ void WaylandWindow::RemoveEnteredOutputId(struct wl_output* output) { - // displays in a single output mode results in leave events, but the surface - // might not have received enter event before. Thus, remove the id of left - // output only if it was stored before. -- if (entered_output_id_it != entered_outputs_ids_.end()) -+ if (entered_output_id_it != entered_outputs_ids_.end()) { - entered_outputs_ids_.erase(entered_output_id_it); -+ } -+ -+ UpdateBufferScale(true); - } - - void WaylandWindow::UpdateCursorPositionFromEvent( -@@ -816,11 +918,15 @@ gfx::Rect WaylandWindow::AdjustPopupWindowPosition() const { - ? parent_window_->parent_window_ - : parent_window_; - DCHECK(parent_window); -+ DCHECK(buffer_scale_ == parent_window->buffer_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 = parent_window_->GetBounds(); -+ const gfx::Rect parent_bounds_px = -+ gfx::ScaleToRoundedRect(parent_window_->GetBounds(), 1.0 / buffer_scale_); -+ - gfx::Rect new_bounds = -- TranslateBoundsToParentCoordinates(bounds_, parent_bounds); -+ TranslateBoundsToParentCoordinates(bounds_px_, parent_bounds_px); - - // 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 -@@ -844,7 +950,8 @@ gfx::Rect WaylandWindow::AdjustPopupWindowPosition() const { - // Position the child menu window on the right side of the parent window - // and let the Wayland compositor decide how to do constraint - // adjustements. -- int new_x = parent_bounds.width() - (new_bounds.width() + new_bounds.x()); -+ int new_x = -+ parent_bounds_px.width() - (new_bounds.width() + new_bounds.x()); - new_bounds.set_x(new_x); - } - } -@@ -861,7 +968,7 @@ void WaylandWindow::MaybeUpdateOpaqueRegion() { - - wl::Object<wl_region> region( - wl_compositor_create_region(connection_->compositor())); -- wl_region_add(region.get(), 0, 0, bounds_.width(), bounds_.height()); -+ wl_region_add(region.get(), 0, 0, bounds_px_.width(), bounds_px_.height()); - wl_surface_set_opaque_region(surface(), region.get()); - - connection_->ScheduleFlush(); -diff --git a/ui/ozone/platform/wayland/wayland_window.h b/ui/ozone/platform/wayland/wayland_window.h -index 4c7271d19d94..25632cbd5f31 100644 ---- a/ui/ozone/platform/wayland/wayland_window.h -+++ b/ui/ozone/platform/wayland/wayland_window.h -@@ -10,6 +10,7 @@ - - #include "base/callback.h" - #include "base/memory/ref_counted.h" -+#include "ui/display/display.h" - #include "ui/events/platform/platform_event_dispatcher.h" - #include "ui/gfx/geometry/rect.h" - #include "ui/gfx/native_widget_types.h" -@@ -50,10 +51,19 @@ class WaylandWindow : public PlatformWindow, - - bool Initialize(PlatformWindowInitProperties properties); - -+ // Updates the surface buffer scale of the window. Top level windows take -+ // scale according to 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). -+ void UpdateBufferScale(bool update_bounds); -+ - wl_surface* surface() const { return surface_.get(); } - XDGSurfaceWrapper* xdg_surface() const { return xdg_surface_.get(); } - XDGPopupWrapper* xdg_popup() const { return xdg_popup_.get(); } - -+ WaylandWindow* parent_window() const { return parent_window_; } -+ - gfx::AcceleratedWidget GetWidget() const; - - // Returns the list of wl_outputs aka displays, which this window occupies. -@@ -88,6 +98,8 @@ class WaylandWindow : public PlatformWindow, - void set_has_implicit_grab(bool value) { has_implicit_grab_ = value; } - bool has_implicit_grab() const { return has_implicit_grab_; } - -+ int32_t buffer_scale() const { return buffer_scale_; } -+ - bool is_active() const { return is_active_; } - - // WmMoveResizeHandler -@@ -128,6 +140,10 @@ 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 -+ // |XDGSurfaceWrapperV5::Configure| 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, -@@ -146,6 +162,9 @@ class WaylandWindow : public PlatformWindow, - void OnDragSessionClose(uint32_t dnd_action); - - private: -+ void SetBoundsDip(const gfx::Rect& bounds_dip); -+ void SetBufferScale(int32_t scale, bool update_bounds); -+ - bool IsMinimized() const; - bool IsMaximized() const; - bool IsFullscreen() const; -@@ -213,14 +232,28 @@ class WaylandWindow : public PlatformWindow, - - base::OnceCallback<void(int)> drag_closed_callback_; - -- gfx::Rect bounds_; -- gfx::Rect pending_bounds_; -+ // These bounds attributes below have suffices that indicate uints used. -+ // Values measured in physical pixels are used in calls to PlatformWindow -+ // and PlatformWindowDelegate that work with physical pixels. -+ // -+ // Current bounds of the window. -+ gfx::Rect bounds_px_; -+ // 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. -+ gfx::Rect pending_bounds_dip_; - // The bounds of the window before it went maximized or fullscreen. -- gfx::Rect restored_bounds_; -+ gfx::Rect restored_bounds_px_; -+ -+ display::Display current_display_; -+ - bool has_pointer_focus_ = false; - bool has_keyboard_focus_ = false; - bool has_touch_focus_ = false; - bool has_implicit_grab_ = false; -+ int32_t buffer_scale_ = 1; - - // Stores current states of the window. - ui::PlatformWindowState state_; -@@ -236,7 +269,14 @@ class WaylandWindow : public PlatformWindow, - - bool is_tooltip_ = false; - -- // Stores the list of entered outputs that the window is currently in. -+ // For top level window, stores the list of entered outputs that the window -+ // is currently in. -+ // -+ // For a popup, not used. Wayland 'repositions' sub-menus to wrong outputs -+ // (by sending them leave and enter events) when sub-menus are hidden and -+ // shown again so their list of entered outputs becomes meaningless after -+ // they have been hidden at least once. To determine which output the popup -+ // belongs to, refer to its parent. - std::set<uint32_t> entered_outputs_ids_; - - DISALLOW_COPY_AND_ASSIGN(WaylandWindow); -diff --git a/ui/ozone/platform/wayland/xdg_popup_wrapper_v6.cc b/ui/ozone/platform/wayland/xdg_popup_wrapper_v6.cc -index 38b274f5d7bd..fce77bb6a99c 100644 ---- a/ui/ozone/platform/wayland/xdg_popup_wrapper_v6.cc -+++ b/ui/ozone/platform/wayland/xdg_popup_wrapper_v6.cc -@@ -165,6 +165,8 @@ gfx::Rect GetAnchorRect(MenuType menu_type, - break; - } - -+ if (anchor_rect.width() == 0) -+ anchor_rect.set_width(1); - return anchor_rect; - } - -@@ -255,8 +257,10 @@ zxdg_positioner_v6* XDGPopupWrapperV6::CreatePositioner( - menu_type = MenuType::TYPE_3DOT_PARENT_MENU; - - // Place anchor to the end of the possible position. -- gfx::Rect anchor_rect = -- GetAnchorRect(menu_type, bounds, parent_window->GetBounds()); -+ gfx::Rect anchor_rect = GetAnchorRect( -+ menu_type, bounds, -+ gfx::ScaleToRoundedRect(parent_window->GetBounds(), -+ 1.0 / parent_window->buffer_scale())); - - zxdg_positioner_v6_set_anchor_rect(positioner, anchor_rect.x(), - anchor_rect.y(), anchor_rect.width(), -@@ -282,11 +286,10 @@ void XDGPopupWrapperV6::Configure(void* data, - // Wayland requires doing so in respect to parent window's origin. To properly - // place windows, the bounds are translated and adjusted according to the - // Wayland compositor needs during WaylandWindow::CreateXdgPopup call. -- gfx::Rect new_bounds(x, y, width, height); - WaylandWindow* window = - static_cast<XDGPopupWrapperV6*>(data)->wayland_window_; - DCHECK(window); -- window->HandlePopupConfigure(new_bounds); -+ window->HandlePopupConfigure({x, y, width, height}); - } - - // static -diff --git a/ui/views/controls/menu/submenu_view.cc b/ui/views/controls/menu/submenu_view.cc -index 0796aec67623..e9b1c39edb27 100644 ---- a/ui/views/controls/menu/submenu_view.cc -+++ b/ui/views/controls/menu/submenu_view.cc -@@ -167,16 +167,16 @@ gfx::Size SubmenuView::CalculatePreferredSize() const { - const MenuItemView* menu = static_cast<const MenuItemView*>(child); - const MenuItemView::MenuItemDimensions& dimensions = - menu->GetDimensions(); -- max_simple_width = std::max( -- max_simple_width, dimensions.standard_width); -+ max_simple_width = std::max(max_simple_width, dimensions.standard_width); - max_minor_text_width_ = - std::max(max_minor_text_width_, dimensions.minor_text_width); -- max_complex_width = std::max(max_complex_width, -- dimensions.standard_width + dimensions.children_width); -+ max_complex_width = -+ std::max(max_complex_width, -+ dimensions.standard_width + dimensions.children_width); - touchable_minimum_width = dimensions.standard_width; - } else { -- max_complex_width = std::max(max_complex_width, -- child->GetPreferredSize().width()); -+ max_complex_width = -+ std::max(max_complex_width, child->GetPreferredSize().width()); - } - } - if (max_minor_text_width_ > 0) -@@ -184,10 +184,10 @@ gfx::Size SubmenuView::CalculatePreferredSize() const { - - // Finish calculating our optimum width. - gfx::Insets insets = GetInsets(); -- int width = std::max(max_complex_width, -- std::max(max_simple_width + max_minor_text_width_ + -- insets.width(), -- minimum_preferred_width_ - 2 * insets.width())); -+ int width = std::max( -+ max_complex_width, -+ std::max(max_simple_width + max_minor_text_width_ + insets.width(), -+ minimum_preferred_width_ - 2 * insets.width())); - - if (GetMenuItem()->GetMenuController() && - GetMenuItem()->GetMenuController()->use_touchable_layout()) { -@@ -318,8 +318,8 @@ bool SubmenuView::OnMouseWheel(const ui::MouseWheelEvent& e) { - if (GetMenuItemAt(first_vis_index)->y() == vis_bounds.y()) - first_vis_index++; - } -- ScrollRectToVisible(gfx::Rect(gfx::Point(0, scroll_target), -- vis_bounds.size())); -+ ScrollRectToVisible( -+ gfx::Rect(gfx::Point(0, scroll_target), vis_bounds.size())); - vis_bounds = GetVisibleBounds(); - } - -diff --git a/ui/views/widget/desktop_aura/desktop_screen_ozone.cc b/ui/views/widget/desktop_aura/desktop_screen_ozone.cc -index 6dd57cd74545..be4ea972005a 100644 ---- a/ui/views/widget/desktop_aura/desktop_screen_ozone.cc -+++ b/ui/views/widget/desktop_aura/desktop_screen_ozone.cc -@@ -41,7 +41,7 @@ void DesktopScreenOzone::OnHostDisplaysReady( - display::Display display(display_snapshot->display_id()); - display.set_bounds(gfx::Rect(scaled_size)); - display.set_work_area(display.bounds()); -- display.set_device_scale_factor(device_scale_factor); -+ display.SetDeviceScaleFactor(device_scale_factor); - - ProcessDisplayChanged(display, true /* is_primary */); - } -diff --git a/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc b/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc -index 86834c46d1be..92ee9f82f46f 100644 ---- a/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc -+++ b/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc -@@ -468,25 +468,25 @@ TEST_F(DesktopScreenX11Test, DeviceScaleFactorChange) { - NotifyDisplaysChanged(displays); - ResetDisplayChanges(); - -- displays[0].set_device_scale_factor(2.5f); -+ displays[0].SetDeviceScaleFactor(2.5f); - NotifyDisplaysChanged(displays); - EXPECT_EQ(1u, changed_display_.size()); - EXPECT_EQ(2.5f, gfx::GetFontRenderParamsDeviceScaleFactor()); - -- displays[1].set_device_scale_factor(2.5f); -+ displays[1].SetDeviceScaleFactor(2.5f); - NotifyDisplaysChanged(displays); - EXPECT_EQ(2u, changed_display_.size()); - -- displays[0].set_device_scale_factor(2.5f); -+ displays[0].SetDeviceScaleFactor(2.5f); - NotifyDisplaysChanged(displays); - EXPECT_EQ(2u, changed_display_.size()); - -- displays[1].set_device_scale_factor(2.5f); -+ displays[1].SetDeviceScaleFactor(2.5f); - NotifyDisplaysChanged(displays); - EXPECT_EQ(2u, changed_display_.size()); - -- displays[0].set_device_scale_factor(1.f); -- displays[1].set_device_scale_factor(1.f); -+ displays[0].SetDeviceScaleFactor(1.f); -+ displays[1].SetDeviceScaleFactor(1.f); - NotifyDisplaysChanged(displays); - EXPECT_EQ(4u, changed_display_.size()); - EXPECT_EQ(1.f, gfx::GetFontRenderParamsDeviceScaleFactor()); |