diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc index a54bfdde7a6ca..4e598483af322 100644 --- a/ash/test/ash_test_helper.cc +++ b/ash/test/ash_test_helper.cc @@ -250,6 +250,8 @@ void AshTestHelper::TearDown() { command_line_.reset(); + display::Display::ResetForceDeviceScaleFactorForTesting(); + // WindowManager owns the CaptureController for mus/mash. CHECK(config_ != Config::CLASSIC || !::wm::CaptureController::Get()); } diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc index b8655a1b2382a..353f722daf98b 100644 --- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc @@ -50,6 +50,7 @@ class ArcAccessibilityHelperBridgeTest : public testing::Test { void AddPostTargetHandler(ui::EventHandler* handler) override {} void RemovePostTargetHandler(ui::EventHandler* handler) override {} bool IsTabletModeWindowManagerEnabled() const override { return false; } + double GetDefaultDeviceScaleFactor() const override { return 1.0; } DISALLOW_COPY_AND_ASSIGN(FakeWMHelper); }; diff --git a/components/exo/display.cc b/components/exo/display.cc index 6bf7395a08a99..f77bdfa2c2d9d 100644 --- a/components/exo/display.cc +++ b/components/exo/display.cc @@ -183,7 +183,8 @@ std::unique_ptr Display::CreatePopupShellSurface( std::unique_ptr Display::CreateRemoteShellSurface( Surface* surface, - int container) { + int container, + bool scale_by_defult_device_scale_factor) { TRACE_EVENT2("exo", "Display::CreateRemoteShellSurface", "surface", surface->AsTracedValue(), "container", container); @@ -195,9 +196,14 @@ std::unique_ptr Display::CreateRemoteShellSurface( // Remote shell surfaces in system modal container cannot be minimized. bool can_minimize = container != ash::kShellWindowId_SystemModalContainer; - return base::MakeUnique( + std::unique_ptr shell_surface(base::MakeUnique( surface, nullptr, ShellSurface::BoundsMode::CLIENT, gfx::Point(), - true /* activatable */, can_minimize, container); + true /* activatable */, can_minimize, container)); + if (scale_by_defult_device_scale_factor) { + shell_surface->SetScale( + WMHelper::GetInstance()->GetDefaultDeviceScaleFactor()); + } + return shell_surface; } std::unique_ptr Display::CreateSubSurface(Surface* surface, diff --git a/components/exo/display.h b/components/exo/display.h index e115d200017b8..154fd96636aa2 100644 --- a/components/exo/display.h +++ b/components/exo/display.h @@ -80,7 +80,8 @@ class Display { // Creates a remote shell surface for an existing surface using |container|. std::unique_ptr CreateRemoteShellSurface( Surface* surface, - int container); + int container, + bool scale_by_default_device_scale_factor); // Creates a sub-surface for an existing surface. The sub-surface will be // a child of |parent|. diff --git a/components/exo/display_unittest.cc b/components/exo/display_unittest.cc index 68aca8980e405..b1c50a3e56bde 100644 --- a/components/exo/display_unittest.cc +++ b/components/exo/display_unittest.cc @@ -150,13 +150,15 @@ TEST_F(DisplayTest, CreateRemoteShellSurface) { // Create a remote shell surface for surface1. std::unique_ptr shell_surface1 = display->CreateRemoteShellSurface( - surface1.get(), ash::kShellWindowId_SystemModalContainer); + surface1.get(), ash::kShellWindowId_SystemModalContainer, + true /* scale_by_default_scale_factor */); EXPECT_TRUE(shell_surface1); // Create a remote shell surface for surface2. std::unique_ptr shell_surface2 = - display->CreateRemoteShellSurface(surface2.get(), - ash::kShellWindowId_DefaultContainer); + display->CreateRemoteShellSurface( + surface2.get(), ash::kShellWindowId_DefaultContainer, + false /* scale_by_default_scale_factor */); EXPECT_TRUE(shell_surface2); } diff --git a/components/exo/shell_surface_unittest.cc b/components/exo/shell_surface_unittest.cc index 4081a6aa5bcdc..2d0f4361140ba 100644 --- a/components/exo/shell_surface_unittest.cc +++ b/components/exo/shell_surface_unittest.cc @@ -33,6 +33,7 @@ #include "ui/compositor/compositor.h" #include "ui/compositor/layer.h" #include "ui/display/display.h" +#include "ui/display/manager/display_manager.h" #include "ui/display/screen.h" #include "ui/events/test/event_generator.h" #include "ui/views/widget/widget.h" @@ -85,9 +86,13 @@ class ShellSurfaceBoundsModeTest } std::unique_ptr CreateDefaultShellSurface(Surface* surface) { - return base::MakeUnique(surface, nullptr, GetParam(), - gfx::Point(), true, false, - ash::kShellWindowId_DefaultContainer); + if (IsClientBoundsMode()) { + return Display().CreateRemoteShellSurface( + surface, ash::kShellWindowId_DefaultContainer, + true /* scale_by_default_scale_factor */); + } else { + return Display().CreateShellSurface(surface); + } } private: @@ -376,20 +381,73 @@ TEST_F(ShellSurfaceTest, SetGeometry) { shell_surface->host_window()->bounds().ToString()); } -TEST_F(ShellSurfaceTest, SetScale) { +TEST_P(ShellSurfaceBoundsModeTest, DefaultDeviceScaleFactorForcedScaleFactor) { + double scale = 1.5; + display::Display::SetForceDeviceScaleFactor(scale); + + int64_t display_id = display::Screen::GetScreen()->GetPrimaryDisplay().id(); + display::Display::SetInternalDisplayId(display_id); + gfx::Size buffer_size(64, 64); std::unique_ptr buffer( new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); std::unique_ptr surface(new Surface); - std::unique_ptr shell_surface(new ShellSurface(surface.get())); + std::unique_ptr shell_surface( + CreateDefaultShellSurface(surface.get())); + surface->Attach(buffer.get()); + surface->Commit(); + gfx::Transform transform; + if (IsClientBoundsMode()) + transform.Scale(1.0 / scale, 1.0 / scale); + + EXPECT_EQ( + transform.ToString(), + shell_surface->host_window()->layer()->GetTargetTransform().ToString()); +} + +TEST_P(ShellSurfaceBoundsModeTest, DefaultDeviceScaleFactorFromDisplayManager) { + int64_t display_id = display::Screen::GetScreen()->GetPrimaryDisplay().id(); + display::Display::SetInternalDisplayId(display_id); + gfx::Size size(1920, 1080); + + display::DisplayManager* display_manager = + ash::Shell::Get()->display_manager(); + + double scale = 1.25; + scoped_refptr mode( + new display::ManagedDisplayMode(size, 60.f, false /* overscan */, + true /*native*/, 1.0, scale)); + mode->set_is_default(true); + + display::ManagedDisplayInfo::ManagedDisplayModeList mode_list; + mode_list.push_back(mode); + + display::ManagedDisplayInfo native_display_info(display_id, "test", false); + native_display_info.SetManagedDisplayModes(mode_list); + + native_display_info.SetBounds(gfx::Rect(size)); + native_display_info.set_device_scale_factor(scale); + + std::vector display_info_list; + display_info_list.push_back(native_display_info); + + display_manager->OnNativeDisplaysChanged(display_info_list); + display_manager->UpdateInternalManagedDisplayModeListForTest(); + + gfx::Size buffer_size(64, 64); + std::unique_ptr buffer( + new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); + std::unique_ptr surface(new Surface); + std::unique_ptr shell_surface( + CreateDefaultShellSurface(surface.get())); - double scale = 1.5; - shell_surface->SetScale(scale); surface->Attach(buffer.get()); surface->Commit(); gfx::Transform transform; - transform.Scale(1.0 / scale, 1.0 / scale); + if (IsClientBoundsMode()) + transform.Scale(1.0 / scale, 1.0 / scale); + EXPECT_EQ( transform.ToString(), shell_surface->host_window()->layer()->GetTargetTransform().ToString()); diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc index c42e332f50267..8c483b3d5a5b0 100644 --- a/components/exo/wayland/server.cc +++ b/components/exo/wayland/server.cc @@ -2280,6 +2280,17 @@ class WaylandRemoteShell : public WMHelper::TabletModeObserver, ? ZCR_REMOTE_SHELL_V1_LAYOUT_MODE_TABLET : ZCR_REMOTE_SHELL_V1_LAYOUT_MODE_WINDOWED; + if (wl_resource_get_version(remote_shell_resource_) >= 8) { + float scale_factor = + WMHelper::GetInstance()->GetDefaultDeviceScaleFactor(); + // Send using 16.16 fixed point. + const int kDecimalBits = 16; + int32_t fixed_scale = + static_cast(scale_factor * (1 << kDecimalBits)); + zcr_remote_shell_v1_send_default_device_scale_factor( + remote_shell_resource_, fixed_scale); + } + SendDisplayMetrics(); SendActivated(helper->GetActiveWindow(), nullptr); } @@ -2294,9 +2305,12 @@ class WaylandRemoteShell : public WMHelper::TabletModeObserver, return wl_resource_get_version(remote_shell_resource_) >= 5; } - std::unique_ptr CreateShellSurface(Surface* surface, - int container) { - return display_->CreateRemoteShellSurface(surface, container); + std::unique_ptr CreateShellSurface( + Surface* surface, + int container, + bool scale_by_default_device_scale_factor) { + return display_->CreateRemoteShellSurface( + surface, container, scale_by_default_device_scale_factor); } std::unique_ptr CreateNotificationSurface( @@ -2541,8 +2555,11 @@ void remote_shell_get_remote_surface(wl_client* client, wl_resource* surface, uint32_t container) { WaylandRemoteShell* shell = GetUserDataAs(resource); + bool scale_by_default_scale_factor = wl_resource_get_version(resource) >= 8; + std::unique_ptr shell_surface = shell->CreateShellSurface( - GetUserDataAs(surface), RemoteSurfaceContainer(container)); + GetUserDataAs(surface), RemoteSurfaceContainer(container), + scale_by_default_scale_factor); if (!shell_surface) { wl_resource_post_error(resource, ZCR_REMOTE_SHELL_V1_ERROR_ROLE, "surface has already been assigned a role"); @@ -2602,7 +2619,7 @@ const struct zcr_remote_shell_v1_interface remote_shell_implementation = { remote_shell_destroy, remote_shell_get_remote_surface, remote_shell_get_notification_surface}; -const uint32_t remote_shell_version = 7; +const uint32_t remote_shell_version = 8; void bind_remote_shell(wl_client* client, void* data, diff --git a/components/exo/wm_helper.h b/components/exo/wm_helper.h index 025d9f4979ce5..69d72cf9342ec 100644 --- a/components/exo/wm_helper.h +++ b/components/exo/wm_helper.h @@ -131,6 +131,7 @@ class WMHelper : public aura::client::DragDropDelegate { virtual void AddPostTargetHandler(ui::EventHandler* handler) = 0; virtual void RemovePostTargetHandler(ui::EventHandler* handler) = 0; virtual bool IsTabletModeWindowManagerEnabled() const = 0; + virtual double GetDefaultDeviceScaleFactor() const = 0; // Overridden from aura::client::DragDropDelegate: void OnDragEntered(const ui::DropTargetEvent& event) override; diff --git a/components/exo/wm_helper_ash.cc b/components/exo/wm_helper_ash.cc index 1d4caa1bc6868..3a6cd897df4bb 100644 --- a/components/exo/wm_helper_ash.cc +++ b/components/exo/wm_helper_ash.cc @@ -112,6 +112,26 @@ bool WMHelperAsh::IsTabletModeWindowManagerEnabled() const { ->IsTabletModeWindowManagerEnabled(); } +double WMHelperAsh::GetDefaultDeviceScaleFactor() const { + if (!display::Display::HasInternalDisplay()) + return 1.0; + + if (display::Display::HasForceDeviceScaleFactor()) + return display::Display::GetForcedDeviceScaleFactor(); + + display::DisplayManager* display_manager = + ash::Shell::Get()->display_manager(); + const display::ManagedDisplayInfo& display_info = + display_manager->GetDisplayInfo(display::Display::InternalDisplayId()); + for (auto& mode : display_info.display_modes()) { + if (mode->is_default()) + return mode->device_scale_factor(); + } + + NOTREACHED(); + return 1.0f; +} + void WMHelperAsh::OnWindowActivated( wm::ActivationChangeObserver::ActivationReason reason, aura::Window* gained_active, diff --git a/components/exo/wm_helper_ash.h b/components/exo/wm_helper_ash.h index f557484a83664..4a951b7f143fc 100644 --- a/components/exo/wm_helper_ash.h +++ b/components/exo/wm_helper_ash.h @@ -42,6 +42,7 @@ class WMHelperAsh : public WMHelper, void AddPostTargetHandler(ui::EventHandler* handler) override; void RemovePostTargetHandler(ui::EventHandler* handler) override; bool IsTabletModeWindowManagerEnabled() const override; + double GetDefaultDeviceScaleFactor() const override; // Overridden from wm::ActivationChangeObserver: void OnWindowActivated(wm::ActivationChangeObserver::ActivationReason reason, diff --git a/components/exo/wm_helper_mus.cc b/components/exo/wm_helper_mus.cc index 8f8e8c2edeb18..678e2a81298b8 100644 --- a/components/exo/wm_helper_mus.cc +++ b/components/exo/wm_helper_mus.cc @@ -95,6 +95,11 @@ bool WMHelperMus::IsTabletModeWindowManagerEnabled() const { return false; } +double WMHelperMus::GetDefaultDeviceScaleFactor() const { + NOTIMPLEMENTED(); + return 1.0; +} + void WMHelperMus::OnActiveFocusClientChanged( aura::client::FocusClient* focus_client, aura::Window* focus_client_root) { diff --git a/components/exo/wm_helper_mus.h b/components/exo/wm_helper_mus.h index 820db7a929c0a..f883c12c0e8c5 100644 --- a/components/exo/wm_helper_mus.h +++ b/components/exo/wm_helper_mus.h @@ -41,6 +41,7 @@ class WMHelperMus : public WMHelper, void AddPostTargetHandler(ui::EventHandler* handler) override; void RemovePostTargetHandler(ui::EventHandler* handler) override; bool IsTabletModeWindowManagerEnabled() const override; + double GetDefaultDeviceScaleFactor() const override; // Overridden from aura::FocusSynchronizerObserver: void OnActiveFocusClientChanged(aura::client::FocusClient* focus_client, diff --git a/third_party/wayland-protocols/include/protocol/remote-shell-unstable-v1-client-protocol.h b/third_party/wayland-protocols/include/protocol/remote-shell-unstable-v1-client-protocol.h index 30bc9017cb88e..df883d0de1cfb 100644 --- a/third_party/wayland-protocols/include/protocol/remote-shell-unstable-v1-client-protocol.h +++ b/third_party/wayland-protocols/include/protocol/remote-shell-unstable-v1-client-protocol.h @@ -293,6 +293,16 @@ struct zcr_remote_shell_v1_listener { void (*configure)(void *data, struct zcr_remote_shell_v1 *zcr_remote_shell_v1, uint32_t layout_mode); + /** + * initialize scale configuration + * + * Sends the default device scale factor. + * @param scale DP to pixels ratio, in 16.16 fixed point format + * @since 8 + */ + void (*default_device_scale_factor)(void *data, + struct zcr_remote_shell_v1 *zcr_remote_shell_v1, + int32_t scale); }; /** @@ -326,6 +336,10 @@ zcr_remote_shell_v1_add_listener(struct zcr_remote_shell_v1 *zcr_remote_shell_v1 * @ingroup iface_zcr_remote_shell_v1 */ #define ZCR_REMOTE_SHELL_V1_CONFIGURE_SINCE_VERSION 5 +/** + * @ingroup iface_zcr_remote_shell_v1 + */ +#define ZCR_REMOTE_SHELL_V1_DEFAULT_DEVICE_SCALE_FACTOR_SINCE_VERSION 8 /** * @ingroup iface_zcr_remote_shell_v1 @@ -471,14 +485,14 @@ enum zcr_remote_surface_v1_orientation { * The type of the window. */ enum zcr_remote_surface_v1_window_type { - /** - * normal app window - */ - ZCR_REMOTE_SURFACE_V1_WINDOW_TYPE_NORMAL = 1, - /** - * window is treated as systemui - */ - ZCR_REMOTE_SURFACE_V1_WINDOW_TYPE_SYSTEM_UI = 2, + /** + * normal app window + */ + ZCR_REMOTE_SURFACE_V1_WINDOW_TYPE_NORMAL = 1, + /** + * window is treated as systemui + */ + ZCR_REMOTE_SURFACE_V1_WINDOW_TYPE_SYSTEM_UI = 2, }; #endif /* ZCR_REMOTE_SURFACE_V1_WINDOW_TYPE_ENUM */ @@ -1144,11 +1158,11 @@ zcr_remote_surface_v1_set_orientation(struct zcr_remote_surface_v1 *zcr_remote_s * Set the type of window. This is only a hint to the compositor and the * compositor is free to ignore it. */ -static inline void zcr_remote_surface_v1_set_window_type( - struct zcr_remote_surface_v1* zcr_remote_surface_v1, - uint32_t type) { - wl_proxy_marshal((struct wl_proxy*)zcr_remote_surface_v1, - ZCR_REMOTE_SURFACE_V1_SET_WINDOW_TYPE, type); +static inline void +zcr_remote_surface_v1_set_window_type(struct zcr_remote_surface_v1 *zcr_remote_surface_v1, uint32_t type) +{ + wl_proxy_marshal((struct wl_proxy *) zcr_remote_surface_v1, + ZCR_REMOTE_SURFACE_V1_SET_WINDOW_TYPE, type); } #define ZCR_NOTIFICATION_SURFACE_V1_DESTROY 0 diff --git a/third_party/wayland-protocols/include/protocol/remote-shell-unstable-v1-server-protocol.h b/third_party/wayland-protocols/include/protocol/remote-shell-unstable-v1-server-protocol.h index eff65db9dcf58..08b09e51c58e5 100644 --- a/third_party/wayland-protocols/include/protocol/remote-shell-unstable-v1-server-protocol.h +++ b/third_party/wayland-protocols/include/protocol/remote-shell-unstable-v1-server-protocol.h @@ -283,6 +283,7 @@ struct zcr_remote_shell_v1_interface { #define ZCR_REMOTE_SHELL_V1_CONFIGURATION_CHANGED 1 #define ZCR_REMOTE_SHELL_V1_WORKSPACE 2 #define ZCR_REMOTE_SHELL_V1_CONFIGURE 3 +#define ZCR_REMOTE_SHELL_V1_DEFAULT_DEVICE_SCALE_FACTOR 4 /** * @ingroup iface_zcr_remote_shell_v1 @@ -300,6 +301,10 @@ struct zcr_remote_shell_v1_interface { * @ingroup iface_zcr_remote_shell_v1 */ #define ZCR_REMOTE_SHELL_V1_CONFIGURE_SINCE_VERSION 5 +/** + * @ingroup iface_zcr_remote_shell_v1 + */ +#define ZCR_REMOTE_SHELL_V1_DEFAULT_DEVICE_SCALE_FACTOR_SINCE_VERSION 8 /** * @ingroup iface_zcr_remote_shell_v1 @@ -359,6 +364,18 @@ zcr_remote_shell_v1_send_configure(struct wl_resource *resource_, uint32_t layou wl_resource_post_event(resource_, ZCR_REMOTE_SHELL_V1_CONFIGURE, layout_mode); } +/** + * @ingroup iface_zcr_remote_shell_v1 + * Sends an default_device_scale_factor event to the client owning the resource. + * @param resource_ The client's resource + * @param scale DP to pixels ratio, in 16.16 fixed point format + */ +static inline void +zcr_remote_shell_v1_send_default_device_scale_factor(struct wl_resource *resource_, int32_t scale) +{ + wl_resource_post_event(resource_, ZCR_REMOTE_SHELL_V1_DEFAULT_DEVICE_SCALE_FACTOR, scale); +} + #ifndef ZCR_REMOTE_SURFACE_V1_SYSTEMUI_VISIBILITY_STATE_ENUM #define ZCR_REMOTE_SURFACE_V1_SYSTEMUI_VISIBILITY_STATE_ENUM /** @@ -412,14 +429,14 @@ enum zcr_remote_surface_v1_orientation { * The type of the window. */ enum zcr_remote_surface_v1_window_type { - /** - * normal app window - */ - ZCR_REMOTE_SURFACE_V1_WINDOW_TYPE_NORMAL = 1, - /** - * window is treated as systemui - */ - ZCR_REMOTE_SURFACE_V1_WINDOW_TYPE_SYSTEM_UI = 2, + /** + * normal app window + */ + ZCR_REMOTE_SURFACE_V1_WINDOW_TYPE_NORMAL = 1, + /** + * window is treated as systemui + */ + ZCR_REMOTE_SURFACE_V1_WINDOW_TYPE_SYSTEM_UI = 2, }; #endif /* ZCR_REMOTE_SURFACE_V1_WINDOW_TYPE_ENUM */ @@ -761,17 +778,17 @@ struct zcr_remote_surface_v1_interface { void (*set_orientation)(struct wl_client *client, struct wl_resource *resource, int32_t orientation); - /** - * set the type of the window - * - * Set the type of window. This is only a hint to the compositor - * and the compositor is free to ignore it. - * @param type type of the window - * @since 7 - */ - void (*set_window_type)(struct wl_client* client, - struct wl_resource* resource, - uint32_t type); + /** + * set the type of the window + * + * Set the type of window. This is only a hint to the compositor + * and the compositor is free to ignore it. + * @param type type of the window + * @since 7 + */ + void (*set_window_type)(struct wl_client *client, + struct wl_resource *resource, + uint32_t type); }; #define ZCR_REMOTE_SURFACE_V1_CLOSE 0 diff --git a/third_party/wayland-protocols/protocol/remote-shell-protocol.c b/third_party/wayland-protocols/protocol/remote-shell-protocol.c index bd8c64464a84b..2cefcaffba195 100644 --- a/third_party/wayland-protocols/protocol/remote-shell-protocol.c +++ b/third_party/wayland-protocols/protocol/remote-shell-protocol.c @@ -66,12 +66,13 @@ static const struct wl_message zcr_remote_shell_v1_events[] = { { "configuration_changed", "iiifiiiiu", types + 0 }, { "workspace", "5uuiiiiiiiiifu", types + 0 }, { "configure", "5u", types + 0 }, + { "default_device_scale_factor", "8i", types + 0 }, }; WL_EXPORT const struct wl_interface zcr_remote_shell_v1_interface = { - "zcr_remote_shell_v1", 7, + "zcr_remote_shell_v1", 8, 3, zcr_remote_shell_v1_requests, - 4, zcr_remote_shell_v1_events, + 5, zcr_remote_shell_v1_events, }; static const struct wl_message zcr_remote_surface_v1_requests[] = { diff --git a/third_party/wayland-protocols/unstable/remote-shell/remote-shell-unstable-v1.xml b/third_party/wayland-protocols/unstable/remote-shell/remote-shell-unstable-v1.xml index 738eb73a692b6..3fa25840f1cf6 100644 --- a/third_party/wayland-protocols/unstable/remote-shell/remote-shell-unstable-v1.xml +++ b/third_party/wayland-protocols/unstable/remote-shell/remote-shell-unstable-v1.xml @@ -38,7 +38,7 @@ reset. - + The global interface that allows clients to turn a wl_surface into a "real window" which is remotely managed but can be stacked, activated @@ -169,6 +169,15 @@ + + + + + + Sends the default device scale factor. + + +