Commit ab465aaf authored by John Pham's avatar John Pham Committed by Commit Bot

Resize the host when text scaling on windows changes.

If the text scale change delta is too small (e.g. 100% to 105% compared to 100% to 150%), Windows only sends a text scale change message. If the delta is large (e.g. 100% to 150%), Windows sends a text scale and window resize message.

Here's the new behavior: https://i.imgur.com/PAjwJSt.gif

Bug: 1087626
Change-Id: I5b6d86a6219d3e27128a5b221d401bcf001443ff
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2223123
Commit-Queue: John Pham <johnp@microsoft.com>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Cr-Commit-Position: refs/heads/master@{#775284}
parent 78c32d09
......@@ -109,7 +109,7 @@ AuraTestHelper* AuraTestHelper::GetInstance() {
void AuraTestHelper::SetUp() {
display::Screen* screen = display::Screen::GetScreen();
gfx::Size host_size(screen ? screen->GetPrimaryDisplay().GetSizeInPixel()
: gfx::Size(800, 600));
: kDefaultHostSize);
test_screen_.reset(TestScreen::Create(host_size));
// TODO(pkasting): Seems like we should either always set the screen instance,
// or not create the screen/host if the test already has one; it doesn't make
......@@ -198,6 +198,8 @@ client::CaptureClient* AuraTestHelper::GetCaptureClient() {
return capture_client_.get();
}
constexpr gfx::Size AuraTestHelper::kDefaultHostSize;
Env* AuraTestHelper::GetEnv() {
if (env_)
return env_.get();
......
......@@ -67,6 +67,8 @@ class AuraTestHelper {
virtual client::FocusClient* GetFocusClient();
virtual client::CaptureClient* GetCaptureClient();
static constexpr gfx::Size kDefaultHostSize{800, 600};
Env* GetEnv();
protected:
......
......@@ -70,12 +70,14 @@ WindowTreeHost* TestScreen::CreateHostForPrimaryDisplay() {
return host_;
}
void TestScreen::SetDeviceScaleFactor(float device_scale_factor) {
void TestScreen::SetDeviceScaleFactor(float device_scale_factor,
bool resize_host) {
display::Display display(GetPrimaryDisplay());
gfx::Rect bounds_in_pixel(display.GetSizeInPixel());
display.SetScaleAndBounds(device_scale_factor, bounds_in_pixel);
display_list().UpdateDisplay(display);
host_->OnHostResizedInPixels(bounds_in_pixel.size());
if (resize_host)
host_->OnHostResizedInPixels(bounds_in_pixel.size());
}
void TestScreen::SetColorSpace(const gfx::ColorSpace& color_space,
......
......@@ -33,7 +33,7 @@ class TestScreen : public display::ScreenBase, public WindowObserver {
WindowTreeHost* CreateHostForPrimaryDisplay();
void SetDeviceScaleFactor(float device_scale_fator);
void SetDeviceScaleFactor(float device_scale_factor, bool resize_host = true);
void SetColorSpace(
const gfx::ColorSpace& color_space,
float sdr_white_level = gfx::ColorSpace::kDefaultSDRWhiteLevel);
......
......@@ -504,13 +504,18 @@ void WindowTreeHost::OnHostLostWindowCapture() {
void WindowTreeHost::OnDisplayMetricsChanged(const display::Display& display,
uint32_t metrics) {
if (metrics & DisplayObserver::DISPLAY_METRIC_COLOR_SPACE) {
display::Screen* screen = display::Screen::GetScreen();
if (compositor_ &&
display.id() == screen->GetDisplayNearestView(window()).id()) {
compositor_->SetDisplayColorSpaces(display.color_spaces());
}
}
if (metrics & DisplayObserver::DISPLAY_METRIC_COLOR_SPACE && compositor_ &&
display.id() == GetDisplayId())
compositor_->SetDisplayColorSpaces(display.color_spaces());
// Chrome OS is handled in WindowTreeHostManager::OnDisplayMetricsChanged.
// Chrome OS requires additional handling for the bounds that we do not need to
// do for other OSes.
#if !defined(OS_CHROMEOS)
if (metrics & DISPLAY_METRIC_DEVICE_SCALE_FACTOR &&
display.id() == GetDisplayId())
OnHostResizedInPixels(GetBoundsInPixels().size());
#endif
}
gfx::Rect WindowTreeHost::GetTransformedRootWindowBoundsInPixels(
......
......@@ -21,7 +21,9 @@ namespace aura {
using WindowTreeHostTest = test::AuraTestBase;
TEST_F(WindowTreeHostTest, DPIWindowSize) {
gfx::Rect starting_bounds(0, 0, 800, 600);
constexpr gfx::Rect starting_bounds(
aura::test::AuraTestHelper::kDefaultHostSize);
EXPECT_EQ(starting_bounds.size(), host()->compositor()->size());
EXPECT_EQ(starting_bounds, host()->GetBoundsInPixels());
EXPECT_EQ(starting_bounds, root_window()->bounds());
......@@ -113,6 +115,30 @@ TEST_F(WindowTreeHostTest, HoldPointerMovesOnChildResizing) {
}
#endif
#if !defined(OS_CHROMEOS)
// Tests if scale factor changes take effect. Previously a scale factor change
// wouldn't take effect without a bounds change. For context see
// https://crbug.com/1087626
TEST_F(WindowTreeHostTest, ShouldHandleTextScale) {
constexpr gfx::Rect starting_bounds(
aura::test::AuraTestHelper::kDefaultHostSize);
auto asserter = [&](float test_scale_factor) {
test_screen()->SetDeviceScaleFactor(test_scale_factor, false);
EXPECT_EQ(starting_bounds, host()->GetBoundsInPixels());
// Size should be rounded up after scaling.
EXPECT_EQ(
gfx::ScaleToEnclosingRect(starting_bounds, 1.0f / test_scale_factor),
root_window()->bounds());
EXPECT_EQ(test_scale_factor, host()->device_scale_factor());
};
asserter(1.0f);
asserter(1.05f);
asserter(1.5f);
}
#endif
TEST_F(WindowTreeHostTest, NoRewritesPostIME) {
ui::test::TestEventRewriter event_rewriter;
host()->AddEventRewriter(&event_rewriter);
......
......@@ -184,23 +184,6 @@ Widget::MoveLoopResult DesktopWindowTreeHostLinux::RunMoveLoop(
escape_behavior);
}
void DesktopWindowTreeHostLinux::OnDisplayMetricsChanged(
const display::Display& display,
uint32_t changed_metrics) {
aura::WindowTreeHost::OnDisplayMetricsChanged(display, changed_metrics);
if ((changed_metrics & DISPLAY_METRIC_DEVICE_SCALE_FACTOR) &&
display::Screen::GetScreen()->GetDisplayNearestWindow(window()).id() ==
display.id()) {
// When the scale factor changes, also pretend that a resize
// occurred so that the window layout will be refreshed and a
// compositor redraw will be scheduled. This is weird, but works.
// TODO(thomasanderson): Figure out a more direct way of doing
// this.
OnHostResizedInPixels(GetBoundsInPixels().size());
}
}
void DesktopWindowTreeHostLinux::DispatchEvent(ui::Event* event) {
// The input can be disabled and the widget marked as non-active in case of
// opened file-dialogs.
......
......@@ -92,10 +92,6 @@ class VIEWS_EXPORT DesktopWindowTreeHostLinux
friend class DesktopWindowTreeHostX11Test;
FRIEND_TEST_ALL_PREFIXES(DesktopWindowTreeHostLinuxTest, HitTest);
// Overridden from display::DisplayObserver via aura::WindowTreeHost:
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) override;
// DesktopWindowTreeHostPlatform overrides:
void AddAdditionalInitProperties(
const Widget::InitParams& params,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment