From e9e9202783fb8e56222f6746c046033802fd2df5 Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Tue, 30 Nov 2021 16:26:02 -0800 Subject: [PATCH] Eliminate hardcoded scale factor in a11y scroll When performing an accessibilty scroll, the default scroll distance is kSmallScrollIncrement (40 pixels). This value is then multiplied by the system scale factor, as set in the display settings drop-down in the Windows system settings. When we imported the AX tree from Chromium, we hard-coded the system scale factor to 1.0 due to a fair amount of abstraction of the scale factor lookup in their code. This fills it back in. Issue: https://github.com/flutter/flutter/issues/78798 --- ci/licenses_golden/licenses_flutter | 3 + third_party/accessibility/BUILD.gn | 1 + third_party/accessibility/ax/BUILD.gn | 1 + .../ax/platform/ax_platform_node_win.cc | 6 +- third_party/accessibility/base/BUILD.gn | 2 + third_party/accessibility/base/win/display.cc | 59 +++++++++++++++++++ third_party/accessibility/base/win/display.h | 23 ++++++++ .../base/win/display_unittest.cc | 32 ++++++++++ 8 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 third_party/accessibility/base/win/display.cc create mode 100644 third_party/accessibility/base/win/display.h create mode 100644 third_party/accessibility/base/win/display_unittest.cc diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 9fc5b5dc5c51f..4308d1df37ab4 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -2390,6 +2390,9 @@ ORIGIN: ../../../flutter/third_party/accessibility/base/win/atl_module.h + ../.. TYPE: LicenseType.bsd FILE: ../../../flutter/third_party/accessibility/base/auto_reset.h FILE: ../../../flutter/third_party/accessibility/base/win/atl_module.h +FILE: ../../../flutter/third_party/accessibility/base/win/display.cc +FILE: ../../../flutter/third_party/accessibility/base/win/display.h +FILE: ../../../flutter/third_party/accessibility/base/win/display_unittest.cc FILE: ../../../flutter/third_party/accessibility/base/win/enum_variant.cc FILE: ../../../flutter/third_party/accessibility/base/win/enum_variant.h FILE: ../../../flutter/third_party/accessibility/base/win/enum_variant_unittest.cc diff --git a/third_party/accessibility/BUILD.gn b/third_party/accessibility/BUILD.gn index 1295f7aed3412..469849c8196da 100644 --- a/third_party/accessibility/BUILD.gn +++ b/third_party/accessibility/BUILD.gn @@ -81,6 +81,7 @@ if (enable_unittests) { "ax/platform/ax_platform_node_win_unittest.cc", "base/win/dispatch_stub.cc", "base/win/dispatch_stub.h", + "base/win/display_unittest.cc", "base/win/scoped_bstr_unittest.cc", "base/win/scoped_safearray_unittest.cc", "base/win/scoped_variant_unittest.cc", diff --git a/third_party/accessibility/ax/BUILD.gn b/third_party/accessibility/ax/BUILD.gn index 3c234b72344a7..ef38c51dee33e 100644 --- a/third_party/accessibility/ax/BUILD.gn +++ b/third_party/accessibility/ax/BUILD.gn @@ -99,6 +99,7 @@ source_set("ax") { ] libs = [ "oleacc.lib", + "shcore.lib", "uiautomationcore.lib", ] } diff --git a/third_party/accessibility/ax/platform/ax_platform_node_win.cc b/third_party/accessibility/ax/platform/ax_platform_node_win.cc index 43a3f482410ca..f56c0a3737270 100644 --- a/third_party/accessibility/ax/platform/ax_platform_node_win.cc +++ b/third_party/accessibility/ax/platform/ax_platform_node_win.cc @@ -31,10 +31,12 @@ #include "ax_fragment_root_win.h" #include "ax_platform_node_delegate.h" #include "ax_platform_node_delegate_utils_win.h" +#include "shellscalingapi.h" #include "uia_registrar_win.h" #include "base/logging.h" #include "base/win/atl_module.h" +#include "base/win/display.h" #include "gfx/geometry/rect_conversions.h" // From ax.constants.mojom @@ -476,9 +478,7 @@ gfx::Vector2d AXPlatformNodeWin::CalculateUIAScrollPoint( const HWND hwnd = GetDelegate()->GetTargetForNativeAccessibilityEvent(); BASE_DCHECK(hwnd); - // TODO(gw280): https://github.com/flutter/flutter/issues/78798 - // Support scale factors - const float scale_factor = 1.0f; + const float scale_factor = base::win::GetScaleFactorForHWND(hwnd); const int small_change = base::ClampRound(kSmallScrollIncrement * scale_factor); diff --git a/third_party/accessibility/base/BUILD.gn b/third_party/accessibility/base/BUILD.gn index d3f76b72a8add..c630ba7391b59 100644 --- a/third_party/accessibility/base/BUILD.gn +++ b/third_party/accessibility/base/BUILD.gn @@ -26,6 +26,8 @@ source_set("base") { sources += [ "win/atl.h", "win/atl_module.h", + "win/display.cc", + "win/display.h", "win/enum_variant.cc", "win/enum_variant.h", "win/scoped_bstr.cc", diff --git a/third_party/accessibility/base/win/display.cc b/third_party/accessibility/base/win/display.cc new file mode 100644 index 0000000000000..64024e125e642 --- /dev/null +++ b/third_party/accessibility/base/win/display.cc @@ -0,0 +1,59 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/win/display.h" + +namespace base { +namespace win { + +float GetScaleFactorForHWND(HWND hwnd) { + HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + DEVICE_SCALE_FACTOR scale_factor = DEVICE_SCALE_FACTOR_INVALID; + if (SUCCEEDED(GetScaleFactorForMonitor(monitor, &scale_factor))) { + return ScaleFactorToFloat(scale_factor); + } + return 1.0f; +} + +float ScaleFactorToFloat(DEVICE_SCALE_FACTOR scale_factor) { + switch (scale_factor) { + case SCALE_100_PERCENT: + return 1.0f; + case SCALE_120_PERCENT: + return 1.2f; + case SCALE_125_PERCENT: + return 1.25f; + case SCALE_140_PERCENT: + return 1.4f; + case SCALE_150_PERCENT: + return 1.5f; + case SCALE_160_PERCENT: + return 1.6f; + case SCALE_175_PERCENT: + return 1.75f; + case SCALE_180_PERCENT: + return 1.8f; + case SCALE_200_PERCENT: + return 2.0f; + case SCALE_225_PERCENT: + return 2.25f; + case SCALE_250_PERCENT: + return 2.5f; + case SCALE_300_PERCENT: + return 3.0f; + case SCALE_350_PERCENT: + return 3.5f; + case SCALE_400_PERCENT: + return 4.0f; + case SCALE_450_PERCENT: + return 4.5f; + case SCALE_500_PERCENT: + return 5.0f; + default: + return 1.0f; + } +} + +} // namespace win +} // namespace base diff --git a/third_party/accessibility/base/win/display.h b/third_party/accessibility/base/win/display.h new file mode 100644 index 0000000000000..f8f5026a92ec2 --- /dev/null +++ b/third_party/accessibility/base/win/display.h @@ -0,0 +1,23 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_WIN_DISPLAY_H_ +#define BASE_WIN_DISPLAY_H_ + +#include + +#include + +#include "base/base_export.h" + +namespace base { +namespace win { + +float GetScaleFactorForHWND(HWND hwnd); +float ScaleFactorToFloat(DEVICE_SCALE_FACTOR scale_factor); + +} // namespace win +} // namespace base + +#endif // BASE_WIN_DISPLAY_H_ diff --git a/third_party/accessibility/base/win/display_unittest.cc b/third_party/accessibility/base/win/display_unittest.cc new file mode 100644 index 0000000000000..95286dc400de5 --- /dev/null +++ b/third_party/accessibility/base/win/display_unittest.cc @@ -0,0 +1,32 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/win/display.h" + +#include "gtest/gtest.h" + +namespace base { +namespace win { + +TEST(Display, ScaleFactorToFloat) { + EXPECT_EQ(ScaleFactorToFloat(SCALE_100_PERCENT), 1.00f); + EXPECT_EQ(ScaleFactorToFloat(SCALE_120_PERCENT), 1.20f); + EXPECT_EQ(ScaleFactorToFloat(SCALE_125_PERCENT), 1.25f); + EXPECT_EQ(ScaleFactorToFloat(SCALE_140_PERCENT), 1.40f); + EXPECT_EQ(ScaleFactorToFloat(SCALE_150_PERCENT), 1.50f); + EXPECT_EQ(ScaleFactorToFloat(SCALE_160_PERCENT), 1.60f); + EXPECT_EQ(ScaleFactorToFloat(SCALE_175_PERCENT), 1.75f); + EXPECT_EQ(ScaleFactorToFloat(SCALE_180_PERCENT), 1.80f); + EXPECT_EQ(ScaleFactorToFloat(SCALE_200_PERCENT), 2.00f); + EXPECT_EQ(ScaleFactorToFloat(SCALE_225_PERCENT), 2.25f); + EXPECT_EQ(ScaleFactorToFloat(SCALE_250_PERCENT), 2.50f); + EXPECT_EQ(ScaleFactorToFloat(SCALE_350_PERCENT), 3.50f); + EXPECT_EQ(ScaleFactorToFloat(SCALE_400_PERCENT), 4.00f); + EXPECT_EQ(ScaleFactorToFloat(SCALE_450_PERCENT), 4.50f); + EXPECT_EQ(ScaleFactorToFloat(SCALE_500_PERCENT), 5.00f); + EXPECT_EQ(ScaleFactorToFloat(DEVICE_SCALE_FACTOR_INVALID), 1.0f); +} + +} // namespace win +} // namespace base