mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Windows] Refactor high contrast mode detection (flutter/engine#47314)
This refactors how high contrast is implemented on Windows: 1. Added a test to verify accessibility features are updated when a view is created. This prevents staleness issues as the Windows embedder isn't notified of accessibility changes while in headless mode. 1. Moved high contrast mode detection to `WindowsProcTable` from `FlutterWindow` to remove engine to view to window plumbing. 1. `FlutterWindow` and `FlutterWindowsEngine` now share their `WindowsProcTable` (which is used for mocking and polyfilling win32 APIs) to reduce redundant dynamic loading. This pull request contains no functional changes. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
parent
912c891a1d
commit
f06b89215e
@ -119,7 +119,7 @@ static uint64_t ConvertWinButtonToFlutterButton(UINT button) {
|
||||
FlutterWindow::FlutterWindow(
|
||||
int width,
|
||||
int height,
|
||||
std::unique_ptr<WindowsProcTable> windows_proc_table,
|
||||
std::shared_ptr<WindowsProcTable> windows_proc_table,
|
||||
std::unique_ptr<TextInputManager> text_input_manager)
|
||||
: binding_handler_delegate_(nullptr),
|
||||
touch_id_generator_(kMinTouchDeviceId, kMaxTouchDeviceId),
|
||||
@ -356,12 +356,7 @@ PointerLocation FlutterWindow::GetPrimaryPointerLocation() {
|
||||
}
|
||||
|
||||
void FlutterWindow::OnThemeChange() {
|
||||
binding_handler_delegate_->UpdateHighContrastEnabled(
|
||||
GetHighContrastEnabled());
|
||||
}
|
||||
|
||||
void FlutterWindow::SendInitialAccessibilityFeatures() {
|
||||
OnThemeChange();
|
||||
binding_handler_delegate_->OnHighContrastChanged();
|
||||
}
|
||||
|
||||
ui::AXFragmentRootDelegateWin* FlutterWindow::GetAxFragmentRootDelegate() {
|
||||
@ -950,19 +945,6 @@ float FlutterWindow::GetScrollOffsetMultiplier() {
|
||||
return scroll_offset_multiplier_;
|
||||
}
|
||||
|
||||
bool FlutterWindow::GetHighContrastEnabled() {
|
||||
HIGHCONTRAST high_contrast = {.cbSize = sizeof(HIGHCONTRAST)};
|
||||
// API call is only supported on Windows 8+
|
||||
if (SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(HIGHCONTRAST),
|
||||
&high_contrast, 0)) {
|
||||
return high_contrast.dwFlags & HCF_HIGHCONTRASTON;
|
||||
} else {
|
||||
FML_LOG(INFO) << "Failed to get status of high contrast feature,"
|
||||
<< "support only for Windows 8 + ";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT FlutterWindow::Win32DefWindowProc(HWND hWnd,
|
||||
UINT Msg,
|
||||
WPARAM wParam,
|
||||
|
||||
@ -38,7 +38,7 @@ class FlutterWindow : public KeyboardManager::WindowDelegate,
|
||||
// Create flutter Window for use as child window
|
||||
FlutterWindow(int width,
|
||||
int height,
|
||||
std::unique_ptr<WindowsProcTable> windows_proc_table = nullptr,
|
||||
std::shared_ptr<WindowsProcTable> windows_proc_table = nullptr,
|
||||
std::unique_ptr<TextInputManager> text_input_manager = nullptr);
|
||||
|
||||
virtual ~FlutterWindow();
|
||||
@ -189,9 +189,6 @@ class FlutterWindow : public KeyboardManager::WindowDelegate,
|
||||
// Called when a theme change message is issued.
|
||||
virtual void OnThemeChange();
|
||||
|
||||
// |WindowBindingHandler|
|
||||
virtual void SendInitialAccessibilityFeatures() override;
|
||||
|
||||
// |WindowBindingHandler|
|
||||
virtual AlertPlatformNodeDelegate* GetAlertDelegate() override;
|
||||
|
||||
@ -281,9 +278,6 @@ class FlutterWindow : public KeyboardManager::WindowDelegate,
|
||||
// Returns the current pixel per scroll tick value.
|
||||
virtual float GetScrollOffsetMultiplier();
|
||||
|
||||
// Check if the high contrast feature is enabled on the OS
|
||||
virtual bool GetHighContrastEnabled();
|
||||
|
||||
// Delegate to a alert_node_ used to set the announcement text.
|
||||
std::unique_ptr<AlertPlatformNodeDelegate> alert_delegate_;
|
||||
|
||||
@ -381,7 +375,7 @@ class FlutterWindow : public KeyboardManager::WindowDelegate,
|
||||
|
||||
// Abstracts Windows APIs that may not be available on all supported versions
|
||||
// of Windows.
|
||||
std::unique_ptr<WindowsProcTable> windows_proc_table_;
|
||||
std::shared_ptr<WindowsProcTable> windows_proc_table_;
|
||||
|
||||
// Manages IME state.
|
||||
std::unique_ptr<TextInputManager> text_input_manager_;
|
||||
|
||||
@ -64,7 +64,6 @@ class MockFlutterWindow : public FlutterWindow {
|
||||
(override));
|
||||
MOCK_METHOD(void, OnSetCursor, (), (override));
|
||||
MOCK_METHOD(float, GetScrollOffsetMultiplier, (), (override));
|
||||
MOCK_METHOD(bool, GetHighContrastEnabled, (), (override));
|
||||
MOCK_METHOD(float, GetDpiScale, (), (override));
|
||||
MOCK_METHOD(bool, IsVisible, (), (override));
|
||||
MOCK_METHOD(void, UpdateCursorRect, (const Rect&), (override));
|
||||
@ -290,8 +289,7 @@ TEST(FlutterWindowTest, OnThemeChange) {
|
||||
MockWindowBindingHandlerDelegate delegate;
|
||||
win32window.SetView(&delegate);
|
||||
|
||||
ON_CALL(win32window, GetHighContrastEnabled()).WillByDefault(Return(true));
|
||||
EXPECT_CALL(delegate, UpdateHighContrastEnabled(true)).Times(1);
|
||||
EXPECT_CALL(delegate, OnHighContrastChanged).Times(1);
|
||||
|
||||
win32window.InjectWindowMessage(WM_THEMECHANGED, 0, 0);
|
||||
}
|
||||
@ -305,17 +303,6 @@ TEST(FlutterWindowTest, AccessibilityNodeWithoutView) {
|
||||
EXPECT_EQ(win32window.GetNativeViewAccessible(), nullptr);
|
||||
}
|
||||
|
||||
TEST(FlutterWindowTest, InitialAccessibilityFeatures) {
|
||||
MockFlutterWindow win32window;
|
||||
MockWindowBindingHandlerDelegate delegate;
|
||||
win32window.SetView(&delegate);
|
||||
|
||||
ON_CALL(win32window, GetHighContrastEnabled()).WillByDefault(Return(true));
|
||||
EXPECT_CALL(delegate, UpdateHighContrastEnabled(true)).Times(1);
|
||||
|
||||
win32window.SendInitialAccessibilityFeatures();
|
||||
}
|
||||
|
||||
// Ensure that announcing the alert propagates the message to the alert node.
|
||||
// Different screen readers use different properties for alerts.
|
||||
TEST(FlutterWindowTest, AlertNode) {
|
||||
|
||||
@ -76,11 +76,12 @@ FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(
|
||||
int width,
|
||||
int height,
|
||||
FlutterDesktopEngineRef engine_ref) {
|
||||
flutter::FlutterWindowsEngine* engine_ptr = EngineFromHandle(engine_ref);
|
||||
std::unique_ptr<flutter::WindowBindingHandler> window_wrapper =
|
||||
std::make_unique<flutter::FlutterWindow>(width, height);
|
||||
std::make_unique<flutter::FlutterWindow>(
|
||||
width, height, engine_ptr->windows_proc_table());
|
||||
|
||||
auto engine = std::unique_ptr<flutter::FlutterWindowsEngine>(
|
||||
EngineFromHandle(engine_ref));
|
||||
auto engine = std::unique_ptr<flutter::FlutterWindowsEngine>(engine_ptr);
|
||||
auto view =
|
||||
std::make_unique<flutter::FlutterWindowsView>(std::move(window_wrapper));
|
||||
auto controller = std::make_unique<flutter::FlutterWindowsViewController>(
|
||||
@ -96,7 +97,11 @@ FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(
|
||||
|
||||
// Must happen after engine is running.
|
||||
controller->view()->SendInitialBounds();
|
||||
controller->view()->SendInitialAccessibilityFeatures();
|
||||
|
||||
// The Windows embedder listens to accessibility updates using the
|
||||
// view's HWND. The embedder's accessibility features may be stale if
|
||||
// the app was in headless mode.
|
||||
controller->engine()->UpdateAccessibilityFeatures();
|
||||
|
||||
return HandleForViewController(controller.release());
|
||||
}
|
||||
|
||||
@ -157,10 +157,17 @@ FlutterLocale CovertToFlutterLocale(const LanguageInfo& info) {
|
||||
|
||||
} // namespace
|
||||
|
||||
FlutterWindowsEngine::FlutterWindowsEngine(const FlutterProjectBundle& project)
|
||||
FlutterWindowsEngine::FlutterWindowsEngine(
|
||||
const FlutterProjectBundle& project,
|
||||
std::shared_ptr<WindowsProcTable> windows_proc_table)
|
||||
: project_(std::make_unique<FlutterProjectBundle>(project)),
|
||||
windows_proc_table_(std::move(windows_proc_table)),
|
||||
aot_data_(nullptr, nullptr),
|
||||
lifecycle_manager_(std::make_unique<WindowsLifecycleManager>(this)) {
|
||||
if (windows_proc_table_ == nullptr) {
|
||||
windows_proc_table_ = std::make_shared<WindowsProcTable>();
|
||||
}
|
||||
|
||||
embedder_api_.struct_size = sizeof(FlutterEngineProcTable);
|
||||
FlutterEngineGetProcAddresses(&embedder_api_);
|
||||
|
||||
@ -569,8 +576,7 @@ void FlutterWindowsEngine::HandlePlatformMessage(
|
||||
|
||||
auto message = ConvertToDesktopMessage(*engine_message);
|
||||
|
||||
message_dispatcher_->HandleMessage(
|
||||
message, [this] {}, [this] {});
|
||||
message_dispatcher_->HandleMessage(message, [this] {}, [this] {});
|
||||
}
|
||||
|
||||
void FlutterWindowsEngine::ReloadSystemFonts() {
|
||||
@ -605,7 +611,7 @@ void FlutterWindowsEngine::SetLifecycleState(flutter::AppLifecycleState state) {
|
||||
|
||||
void FlutterWindowsEngine::SendSystemLocales() {
|
||||
std::vector<LanguageInfo> languages =
|
||||
GetPreferredLanguageInfo(windows_proc_table_);
|
||||
GetPreferredLanguageInfo(*windows_proc_table_);
|
||||
std::vector<FlutterLocale> flutter_locales;
|
||||
flutter_locales.reserve(languages.size());
|
||||
for (const auto& info : languages) {
|
||||
@ -737,34 +743,27 @@ std::string FlutterWindowsEngine::GetExecutableName() const {
|
||||
return "Flutter";
|
||||
}
|
||||
|
||||
void FlutterWindowsEngine::UpdateAccessibilityFeatures(
|
||||
FlutterAccessibilityFeature flags) {
|
||||
embedder_api_.UpdateAccessibilityFeatures(engine_, flags);
|
||||
void FlutterWindowsEngine::UpdateAccessibilityFeatures() {
|
||||
UpdateHighContrastMode();
|
||||
}
|
||||
|
||||
void FlutterWindowsEngine::UpdateHighContrastEnabled(bool enabled) {
|
||||
high_contrast_enabled_ = enabled;
|
||||
int flags = EnabledAccessibilityFeatures();
|
||||
if (enabled) {
|
||||
flags |=
|
||||
FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast;
|
||||
} else {
|
||||
flags &=
|
||||
~FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast;
|
||||
}
|
||||
UpdateAccessibilityFeatures(static_cast<FlutterAccessibilityFeature>(flags));
|
||||
settings_plugin_->UpdateHighContrastMode(enabled);
|
||||
void FlutterWindowsEngine::UpdateHighContrastMode() {
|
||||
high_contrast_enabled_ = windows_proc_table_->GetHighContrastEnabled();
|
||||
|
||||
SendAccessibilityFeatures();
|
||||
settings_plugin_->UpdateHighContrastMode(high_contrast_enabled_);
|
||||
}
|
||||
|
||||
int FlutterWindowsEngine::EnabledAccessibilityFeatures() const {
|
||||
void FlutterWindowsEngine::SendAccessibilityFeatures() {
|
||||
int flags = 0;
|
||||
if (high_contrast_enabled()) {
|
||||
|
||||
if (high_contrast_enabled_) {
|
||||
flags |=
|
||||
FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast;
|
||||
}
|
||||
// As more accessibility features are enabled for Windows,
|
||||
// the corresponding checks and flags should be added here.
|
||||
return flags;
|
||||
|
||||
embedder_api_.UpdateAccessibilityFeatures(
|
||||
engine_, static_cast<FlutterAccessibilityFeature>(flags));
|
||||
}
|
||||
|
||||
void FlutterWindowsEngine::HandleAccessibilityMessage(
|
||||
|
||||
@ -78,7 +78,9 @@ static void WindowsPlatformThreadPrioritySetter(
|
||||
class FlutterWindowsEngine {
|
||||
public:
|
||||
// Creates a new Flutter engine object configured to run |project|.
|
||||
explicit FlutterWindowsEngine(const FlutterProjectBundle& project);
|
||||
FlutterWindowsEngine(
|
||||
const FlutterProjectBundle& project,
|
||||
std::shared_ptr<WindowsProcTable> windows_proc_table = nullptr);
|
||||
|
||||
virtual ~FlutterWindowsEngine();
|
||||
|
||||
@ -215,11 +217,11 @@ class FlutterWindowsEngine {
|
||||
// Returns true if the semantics tree is enabled.
|
||||
bool semantics_enabled() const { return semantics_enabled_; }
|
||||
|
||||
// Update the high contrast feature state.
|
||||
void UpdateHighContrastEnabled(bool enabled);
|
||||
// Refresh accessibility features and send them to the engine.
|
||||
void UpdateAccessibilityFeatures();
|
||||
|
||||
// Returns the flags for all currently enabled accessibility features
|
||||
int EnabledAccessibilityFeatures() const;
|
||||
// Refresh high contrast accessibility mode and notify the engine.
|
||||
void UpdateHighContrastMode();
|
||||
|
||||
// Returns true if the high contrast feature is enabled.
|
||||
bool high_contrast_enabled() const { return high_contrast_enabled_; }
|
||||
@ -240,9 +242,6 @@ class FlutterWindowsEngine {
|
||||
// Returns the executable name for this process or "Flutter" if unknown.
|
||||
std::string GetExecutableName() const;
|
||||
|
||||
// Updates accessibility, e.g. switch to high contrast mode
|
||||
void UpdateAccessibilityFeatures(FlutterAccessibilityFeature flags);
|
||||
|
||||
// Called when the application quits in response to a quit request.
|
||||
void OnQuit(std::optional<HWND> hwnd,
|
||||
std::optional<WPARAM> wparam,
|
||||
@ -274,6 +273,10 @@ class FlutterWindowsEngine {
|
||||
return lifecycle_manager_.get();
|
||||
}
|
||||
|
||||
std::shared_ptr<WindowsProcTable> windows_proc_table() {
|
||||
return windows_proc_table_;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Creates the keyboard key handler.
|
||||
//
|
||||
@ -320,6 +323,9 @@ class FlutterWindowsEngine {
|
||||
// Calling this method again resets the keyboard state.
|
||||
void InitializeKeyboard();
|
||||
|
||||
// Send the currently enabled accessibility features to the engine.
|
||||
void SendAccessibilityFeatures();
|
||||
|
||||
void HandleAccessibilityMessage(FlutterDesktopMessengerRef messenger,
|
||||
const FlutterDesktopMessage* message);
|
||||
|
||||
@ -414,7 +420,7 @@ class FlutterWindowsEngine {
|
||||
// Handler for top level window messages.
|
||||
std::unique_ptr<WindowsLifecycleManager> lifecycle_manager_;
|
||||
|
||||
WindowsProcTable windows_proc_table_;
|
||||
std::shared_ptr<WindowsProcTable> windows_proc_table_;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(FlutterWindowsEngine);
|
||||
};
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "flutter/shell/platform/windows/testing/engine_modifier.h"
|
||||
#include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
|
||||
#include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
|
||||
#include "flutter/shell/platform/windows/testing/mock_windows_proc_table.h"
|
||||
#include "flutter/shell/platform/windows/testing/test_keyboard.h"
|
||||
#include "flutter/shell/platform/windows/testing/windows_test.h"
|
||||
#include "flutter/third_party/accessibility/ax/platform/ax_platform_node_win.h"
|
||||
@ -25,6 +26,8 @@
|
||||
namespace flutter {
|
||||
namespace testing {
|
||||
|
||||
using ::testing::Return;
|
||||
|
||||
class FlutterWindowsEngineTest : public WindowsTest {};
|
||||
|
||||
TEST_F(FlutterWindowsEngineTest, RunDoesExpectedInitialization) {
|
||||
@ -558,29 +561,41 @@ TEST_F(FlutterWindowsEngineTest, GetExecutableName) {
|
||||
// Ensure that after setting or resetting the high contrast feature,
|
||||
// the corresponding status flag can be retrieved from the engine.
|
||||
TEST_F(FlutterWindowsEngineTest, UpdateHighContrastFeature) {
|
||||
auto windows_proc_table = std::make_shared<MockWindowsProcTable>();
|
||||
EXPECT_CALL(*windows_proc_table, GetHighContrastEnabled)
|
||||
.WillOnce(Return(true))
|
||||
.WillOnce(Return(false));
|
||||
|
||||
FlutterWindowsEngineBuilder builder{GetContext()};
|
||||
builder.SetWindowsProcTable(windows_proc_table);
|
||||
std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
|
||||
EngineModifier modifier(engine.get());
|
||||
|
||||
bool called = false;
|
||||
std::optional<FlutterAccessibilityFeature> engine_flags;
|
||||
modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
|
||||
UpdateAccessibilityFeatures, ([&called](auto engine, auto flags) {
|
||||
called = true;
|
||||
UpdateAccessibilityFeatures, ([&engine_flags](auto engine, auto flags) {
|
||||
engine_flags = flags;
|
||||
return kSuccess;
|
||||
}));
|
||||
|
||||
engine->UpdateHighContrastEnabled(true);
|
||||
EXPECT_TRUE(
|
||||
engine->EnabledAccessibilityFeatures() &
|
||||
FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast);
|
||||
EXPECT_TRUE(engine->high_contrast_enabled());
|
||||
EXPECT_TRUE(called);
|
||||
// 1: High contrast is enabled.
|
||||
engine->UpdateHighContrastMode();
|
||||
|
||||
engine->UpdateHighContrastEnabled(false);
|
||||
EXPECT_FALSE(
|
||||
engine->EnabledAccessibilityFeatures() &
|
||||
EXPECT_TRUE(engine->high_contrast_enabled());
|
||||
EXPECT_TRUE(engine_flags.has_value());
|
||||
EXPECT_TRUE(
|
||||
engine_flags.value() &
|
||||
FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast);
|
||||
|
||||
// 2: High contrast is disabled.
|
||||
engine_flags.reset();
|
||||
engine->UpdateHighContrastMode();
|
||||
|
||||
EXPECT_FALSE(engine->high_contrast_enabled());
|
||||
EXPECT_TRUE(engine_flags.has_value());
|
||||
EXPECT_FALSE(
|
||||
engine_flags.value() &
|
||||
FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast);
|
||||
}
|
||||
|
||||
TEST_F(FlutterWindowsEngineTest, PostRasterThreadTask) {
|
||||
|
||||
@ -10,6 +10,8 @@
|
||||
|
||||
#include "flutter/fml/synchronization/count_down_latch.h"
|
||||
#include "flutter/fml/synchronization/waitable_event.h"
|
||||
#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
|
||||
#include "flutter/shell/platform/windows/testing/engine_modifier.h"
|
||||
#include "flutter/shell/platform/windows/testing/windows_test.h"
|
||||
#include "flutter/shell/platform/windows/testing/windows_test_config_builder.h"
|
||||
#include "flutter/shell/platform/windows/testing/windows_test_context.h"
|
||||
@ -99,6 +101,27 @@ TEST_F(WindowsTest, LaunchHeadlessEngine) {
|
||||
ASSERT_TRUE(FlutterDesktopEngineRun(engine.get(), nullptr));
|
||||
}
|
||||
|
||||
// Verify that accessibility features are initialized when a view is created.
|
||||
TEST_F(WindowsTest, LaunchRefreshesAccessibility) {
|
||||
auto& context = GetContext();
|
||||
WindowsConfigBuilder builder(context);
|
||||
EnginePtr engine{builder.InitializeEngine()};
|
||||
EngineModifier modifier{
|
||||
reinterpret_cast<FlutterWindowsEngine*>(engine.get())};
|
||||
|
||||
auto called = false;
|
||||
modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
|
||||
UpdateAccessibilityFeatures, ([&called](auto engine, auto flags) {
|
||||
called = true;
|
||||
return kSuccess;
|
||||
}));
|
||||
|
||||
ViewControllerPtr controller{
|
||||
FlutterDesktopViewControllerCreate(0, 0, engine.release())};
|
||||
|
||||
ASSERT_TRUE(called);
|
||||
}
|
||||
|
||||
// Verify that engine fails to launch when a conflicting entrypoint in
|
||||
// FlutterDesktopEngineProperties.dart_entrypoint and the
|
||||
// FlutterDesktopEngineRun parameter.
|
||||
|
||||
@ -613,12 +613,8 @@ void FlutterWindowsView::DestroyRenderSurface() {
|
||||
}
|
||||
}
|
||||
|
||||
void FlutterWindowsView::SendInitialAccessibilityFeatures() {
|
||||
binding_handler_->SendInitialAccessibilityFeatures();
|
||||
}
|
||||
|
||||
void FlutterWindowsView::UpdateHighContrastEnabled(bool enabled) {
|
||||
engine_->UpdateHighContrastEnabled(enabled);
|
||||
void FlutterWindowsView::OnHighContrastChanged() {
|
||||
engine_->UpdateHighContrastMode();
|
||||
}
|
||||
|
||||
WindowsRenderTarget* FlutterWindowsView::GetRenderTarget() const {
|
||||
|
||||
@ -82,14 +82,11 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate,
|
||||
// Send initial bounds to embedder. Must occur after engine has initialized.
|
||||
void SendInitialBounds();
|
||||
|
||||
// Send the initial accessibility features to the window
|
||||
void SendInitialAccessibilityFeatures();
|
||||
|
||||
// Set the text of the alert, and create it if it does not yet exist.
|
||||
void AnnounceAlert(const std::wstring& text);
|
||||
|
||||
// |WindowBindingHandlerDelegate|
|
||||
void UpdateHighContrastEnabled(bool enabled) override;
|
||||
void OnHighContrastChanged() override;
|
||||
|
||||
// Returns the frame buffer id for the engine to render to.
|
||||
uint32_t GetFrameBufferId(size_t width, size_t height);
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/shell/platform/windows/windows_proc_table.h"
|
||||
|
||||
namespace flutter {
|
||||
namespace testing {
|
||||
@ -14,8 +15,9 @@ class TestFlutterWindowsEngine : public FlutterWindowsEngine {
|
||||
TestFlutterWindowsEngine(
|
||||
const FlutterProjectBundle& project,
|
||||
KeyboardKeyEmbedderHandler::GetKeyStateHandler get_key_state,
|
||||
KeyboardKeyEmbedderHandler::MapVirtualKeyToScanCode map_vk_to_scan)
|
||||
: FlutterWindowsEngine(project),
|
||||
KeyboardKeyEmbedderHandler::MapVirtualKeyToScanCode map_vk_to_scan,
|
||||
std::shared_ptr<WindowsProcTable> windows_proc_table = nullptr)
|
||||
: FlutterWindowsEngine(project, std::move(windows_proc_table)),
|
||||
get_key_state_(std::move(get_key_state)),
|
||||
map_vk_to_scan_(std::move(map_vk_to_scan)) {}
|
||||
|
||||
@ -74,6 +76,11 @@ void FlutterWindowsEngineBuilder::SetCreateKeyboardHandlerCallbacks(
|
||||
map_vk_to_scan_ = std::move(map_vk_to_scan);
|
||||
}
|
||||
|
||||
void FlutterWindowsEngineBuilder::SetWindowsProcTable(
|
||||
std::shared_ptr<WindowsProcTable> windows_proc_table) {
|
||||
windows_proc_table_ = std::move(windows_proc_table);
|
||||
}
|
||||
|
||||
std::unique_ptr<FlutterWindowsEngine> FlutterWindowsEngineBuilder::Build() {
|
||||
std::vector<const char*> dart_args;
|
||||
dart_args.reserve(dart_entrypoint_arguments_.size());
|
||||
@ -93,8 +100,8 @@ std::unique_ptr<FlutterWindowsEngine> FlutterWindowsEngineBuilder::Build() {
|
||||
FlutterProjectBundle project(properties_);
|
||||
project.SetSwitches(switches_);
|
||||
|
||||
return std::make_unique<TestFlutterWindowsEngine>(project, get_key_state_,
|
||||
map_vk_to_scan_);
|
||||
return std::make_unique<TestFlutterWindowsEngine>(
|
||||
project, get_key_state_, map_vk_to_scan_, std::move(windows_proc_table_));
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
@ -31,6 +31,9 @@ class FlutterWindowsEngineBuilder {
|
||||
|
||||
void SetSwitches(std::vector<std::string> switches);
|
||||
|
||||
void SetWindowsProcTable(
|
||||
std::shared_ptr<WindowsProcTable> windows_proc_table);
|
||||
|
||||
std::unique_ptr<FlutterWindowsEngine> Build();
|
||||
|
||||
private:
|
||||
@ -41,6 +44,7 @@ class FlutterWindowsEngineBuilder {
|
||||
std::vector<std::string> switches_;
|
||||
KeyboardKeyEmbedderHandler::GetKeyStateHandler get_key_state_;
|
||||
KeyboardKeyEmbedderHandler::MapVirtualKeyToScanCode map_vk_to_scan_;
|
||||
std::shared_ptr<WindowsProcTable> windows_proc_table_;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(FlutterWindowsEngineBuilder);
|
||||
};
|
||||
|
||||
@ -38,7 +38,6 @@ class MockWindowBindingHandler : public WindowBindingHandler {
|
||||
(const void* allocation, size_t row_bytes, size_t height),
|
||||
(override));
|
||||
MOCK_METHOD(PointerLocation, GetPrimaryPointerLocation, (), (override));
|
||||
MOCK_METHOD(void, SendInitialAccessibilityFeatures, (), (override));
|
||||
MOCK_METHOD(AlertPlatformNodeDelegate*, GetAlertDelegate, (), (override));
|
||||
MOCK_METHOD(ui::AXPlatformNodeWin*, GetAlert, (), (override));
|
||||
MOCK_METHOD(bool, NeedsVSync, (), (override));
|
||||
|
||||
@ -68,7 +68,7 @@ class MockWindowBindingHandlerDelegate : public WindowBindingHandlerDelegate {
|
||||
(double, double, double, double, int, FlutterPointerDeviceKind, int32_t),
|
||||
(override));
|
||||
MOCK_METHOD(void, OnScrollInertiaCancel, (int32_t), (override));
|
||||
MOCK_METHOD(void, UpdateHighContrastEnabled, (bool enabled), (override));
|
||||
MOCK_METHOD(void, OnHighContrastChanged, (), (override));
|
||||
|
||||
MOCK_METHOD(ui::AXFragmentRootDelegateWin*,
|
||||
GetAxFragmentRootDelegate,
|
||||
|
||||
@ -28,6 +28,8 @@ class MockWindowsProcTable : public WindowsProcTable {
|
||||
(DWORD, PULONG, PZZWSTR, PULONG),
|
||||
(const, override));
|
||||
|
||||
MOCK_METHOD(bool, GetHighContrastEnabled, (), (override));
|
||||
|
||||
private:
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(MockWindowsProcTable);
|
||||
};
|
||||
|
||||
@ -98,9 +98,6 @@ class WindowBindingHandler {
|
||||
// coordinates.
|
||||
virtual PointerLocation GetPrimaryPointerLocation() = 0;
|
||||
|
||||
// Called to set the initial state of accessibility features
|
||||
virtual void SendInitialAccessibilityFeatures() = 0;
|
||||
|
||||
// Retrieve the delegate for the alert.
|
||||
virtual AlertPlatformNodeDelegate* GetAlertDelegate() = 0;
|
||||
|
||||
|
||||
@ -136,8 +136,8 @@ class WindowBindingHandlerDelegate {
|
||||
// Returns the root view accessibility node, or nullptr if none.
|
||||
virtual gfx::NativeViewAccessible GetNativeViewAccessible() = 0;
|
||||
|
||||
// Update the status of the high contrast feature
|
||||
virtual void UpdateHighContrastEnabled(bool enabled) = 0;
|
||||
// Update the status of the high contrast feature.
|
||||
virtual void OnHighContrastChanged() = 0;
|
||||
|
||||
// Obtain a pointer to the fragment root delegate.
|
||||
// This is required by UIA in order to obtain the fragment root that
|
||||
|
||||
@ -32,4 +32,14 @@ LRESULT WindowsProcTable::GetThreadPreferredUILanguages(DWORD flags,
|
||||
return ::GetThreadPreferredUILanguages(flags, count, languages, length);
|
||||
}
|
||||
|
||||
bool WindowsProcTable::GetHighContrastEnabled() {
|
||||
HIGHCONTRAST high_contrast = {.cbSize = sizeof(HIGHCONTRAST)};
|
||||
if (!::SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(HIGHCONTRAST),
|
||||
&high_contrast, 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return high_contrast.dwFlags & HCF_HIGHCONTRASTON;
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
@ -22,7 +22,7 @@ class WindowsProcTable {
|
||||
// Retrieves the pointer type for a specified pointer.
|
||||
//
|
||||
// Used to react differently to touch or pen inputs. Returns false on failure.
|
||||
// Available in Windows 8 and newer, otherwise returns false.
|
||||
// Available on Windows 8 and newer, otherwise returns false.
|
||||
virtual BOOL GetPointerType(UINT32 pointer_id,
|
||||
POINTER_INPUT_TYPE* pointer_type);
|
||||
|
||||
@ -35,6 +35,13 @@ class WindowsProcTable {
|
||||
PZZWSTR languages,
|
||||
PULONG length) const;
|
||||
|
||||
// Get whether high contrast is enabled.
|
||||
//
|
||||
// Available on Windows 8 and newer, otherwise returns false.
|
||||
// See
|
||||
// https://learn.microsoft.com/windows/win32/winauto/high-contrast-parameter
|
||||
virtual bool GetHighContrastEnabled();
|
||||
|
||||
private:
|
||||
using GetPointerType_ = BOOL __stdcall(UINT32 pointerId,
|
||||
POINTER_INPUT_TYPE* pointerType);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user