mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Windows] Move DWM composition status to Windows proc table for mocking (flutter/engine#49397)
The `FlutterWindowsView` needs the `DwmIsCompositionEnabled` win32 API to check whether it should block presents until the v-blank to prevent screen tearing. Currently, the view used the `FlutterWindow` to allow mocking this win32 API. However, the window is a complex type with lots of other responsibilities. The `WindowsProcTable` is the new preferred type for mocking win32 API. Part of https://github.com/flutter/flutter/issues/140626 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
parent
e18aa559bd
commit
ed5f58647f
@ -372,18 +372,6 @@ ui::AXPlatformNodeWin* FlutterWindow::GetAlert() {
|
||||
return alert_node_.get();
|
||||
}
|
||||
|
||||
bool FlutterWindow::NeedsVSync() const {
|
||||
// If the Desktop Window Manager composition is enabled,
|
||||
// the system itself synchronizes with v-sync.
|
||||
// See: https://learn.microsoft.com/windows/win32/dwm/composition-ovw
|
||||
BOOL composition_enabled;
|
||||
if (SUCCEEDED(::DwmIsCompositionEnabled(&composition_enabled))) {
|
||||
return !composition_enabled;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FlutterWindow::OnWindowStateEvent(WindowStateEvent event) {
|
||||
switch (event) {
|
||||
case WindowStateEvent::kShow:
|
||||
|
||||
@ -193,9 +193,6 @@ class FlutterWindow : public KeyboardManager::WindowDelegate,
|
||||
// |WindowBindingHandler|
|
||||
virtual ui::AXPlatformNodeWin* GetAlert() override;
|
||||
|
||||
// |WindowBindingHandler|
|
||||
virtual bool NeedsVSync() const override;
|
||||
|
||||
// Called to obtain a pointer to the fragment root delegate.
|
||||
virtual ui::AXFragmentRootDelegateWin* GetAxFragmentRootDelegate();
|
||||
|
||||
|
||||
@ -82,8 +82,8 @@ FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(
|
||||
width, height, engine_ptr->windows_proc_table());
|
||||
|
||||
auto engine = std::unique_ptr<flutter::FlutterWindowsEngine>(engine_ptr);
|
||||
auto view =
|
||||
std::make_unique<flutter::FlutterWindowsView>(std::move(window_wrapper));
|
||||
auto view = std::make_unique<flutter::FlutterWindowsView>(
|
||||
std::move(window_wrapper), engine_ptr->windows_proc_table());
|
||||
auto controller = std::make_unique<flutter::FlutterWindowsViewController>(
|
||||
std::move(engine), std::move(view));
|
||||
|
||||
|
||||
@ -40,8 +40,7 @@ bool SurfaceWillUpdate(size_t cur_width,
|
||||
|
||||
/// Update the surface's swap interval to block until the v-blank iff
|
||||
/// the system compositor is disabled.
|
||||
void UpdateVsync(const FlutterWindowsEngine& engine,
|
||||
const WindowBindingHandler& window) {
|
||||
void UpdateVsync(const FlutterWindowsEngine& engine, bool needs_vsync) {
|
||||
AngleSurfaceManager* surface_manager = engine.surface_manager();
|
||||
if (!surface_manager) {
|
||||
return;
|
||||
@ -52,7 +51,6 @@ void UpdateVsync(const FlutterWindowsEngine& engine,
|
||||
// the raster thread. If the engine is initializing, the raster thread doesn't
|
||||
// exist yet and the render surface can be made current on the platform
|
||||
// thread.
|
||||
auto needs_vsync = window.NeedsVSync();
|
||||
if (engine.running()) {
|
||||
engine.PostRasterThreadTask([surface_manager, needs_vsync]() {
|
||||
surface_manager->SetVSyncEnabled(needs_vsync);
|
||||
@ -72,7 +70,13 @@ void UpdateVsync(const FlutterWindowsEngine& engine,
|
||||
} // namespace
|
||||
|
||||
FlutterWindowsView::FlutterWindowsView(
|
||||
std::unique_ptr<WindowBindingHandler> window_binding) {
|
||||
std::unique_ptr<WindowBindingHandler> window_binding,
|
||||
std::shared_ptr<WindowsProcTable> windows_proc_table)
|
||||
: windows_proc_table_(std::move(windows_proc_table)) {
|
||||
if (windows_proc_table_ == nullptr) {
|
||||
windows_proc_table_ = std::make_shared<WindowsProcTable>();
|
||||
}
|
||||
|
||||
// Take the binding handler, and give it a pointer back to self.
|
||||
binding_handler_ = std::move(window_binding);
|
||||
binding_handler_->SetView(this);
|
||||
@ -114,7 +118,7 @@ void FlutterWindowsView::OnEmptyFrameGenerated() {
|
||||
// resize_status_ is set to kDone.
|
||||
engine_->surface_manager()->ResizeSurface(
|
||||
GetWindowHandle(), resize_target_width_, resize_target_height_,
|
||||
binding_handler_->NeedsVSync());
|
||||
NeedsVsync());
|
||||
resize_status_ = ResizeState::kFrameGenerated;
|
||||
}
|
||||
|
||||
@ -130,7 +134,7 @@ bool FlutterWindowsView::OnFrameGenerated(size_t width, size_t height) {
|
||||
// Platform thread is blocked for the entire duration until the
|
||||
// resize_status_ is set to kDone.
|
||||
engine_->surface_manager()->ResizeSurface(GetWindowHandle(), width, height,
|
||||
binding_handler_->NeedsVSync());
|
||||
NeedsVsync());
|
||||
resize_status_ = ResizeState::kFrameGenerated;
|
||||
return true;
|
||||
}
|
||||
@ -638,7 +642,7 @@ void FlutterWindowsView::CreateRenderSurface() {
|
||||
engine_->surface_manager()->CreateSurface(GetWindowHandle(), bounds.width,
|
||||
bounds.height);
|
||||
|
||||
UpdateVsync(*engine_, *binding_handler_);
|
||||
UpdateVsync(*engine_, NeedsVsync());
|
||||
|
||||
resize_target_width_ = bounds.width;
|
||||
resize_target_height_ = bounds.height;
|
||||
@ -706,7 +710,7 @@ void FlutterWindowsView::UpdateSemanticsEnabled(bool enabled) {
|
||||
}
|
||||
|
||||
void FlutterWindowsView::OnDwmCompositionChanged() {
|
||||
UpdateVsync(*engine_, *binding_handler_);
|
||||
UpdateVsync(*engine_, NeedsVsync());
|
||||
}
|
||||
|
||||
void FlutterWindowsView::OnWindowStateEvent(HWND hwnd, WindowStateEvent event) {
|
||||
@ -715,4 +719,11 @@ void FlutterWindowsView::OnWindowStateEvent(HWND hwnd, WindowStateEvent event) {
|
||||
}
|
||||
}
|
||||
|
||||
bool FlutterWindowsView::NeedsVsync() const {
|
||||
// If the Desktop Window Manager composition is enabled,
|
||||
// the system itself synchronizes with vsync.
|
||||
// See: https://learn.microsoft.com/windows/win32/dwm/composition-ovw
|
||||
return !windows_proc_table_->DwmIsCompositionEnabled();
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include "flutter/shell/platform/windows/window_binding_handler.h"
|
||||
#include "flutter/shell/platform/windows/window_binding_handler_delegate.h"
|
||||
#include "flutter/shell/platform/windows/window_state.h"
|
||||
#include "flutter/shell/platform/windows/windows_proc_table.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
@ -35,7 +36,9 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate {
|
||||
//
|
||||
// In order for object to render Flutter content the SetEngine method must be
|
||||
// called with a valid FlutterWindowsEngine instance.
|
||||
FlutterWindowsView(std::unique_ptr<WindowBindingHandler> window_binding);
|
||||
FlutterWindowsView(
|
||||
std::unique_ptr<WindowBindingHandler> window_binding,
|
||||
std::shared_ptr<WindowsProcTable> windows_proc_table = nullptr);
|
||||
|
||||
virtual ~FlutterWindowsView();
|
||||
|
||||
@ -365,9 +368,16 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate {
|
||||
void SendPointerEventWithData(const FlutterPointerEvent& event_data,
|
||||
PointerState* state);
|
||||
|
||||
// If true, rendering to the window should synchronize with the vsync
|
||||
// to prevent screen tearing.
|
||||
bool NeedsVsync() const;
|
||||
|
||||
// The engine associated with this view.
|
||||
FlutterWindowsEngine* engine_ = nullptr;
|
||||
|
||||
// Mocks win32 APIs.
|
||||
std::shared_ptr<WindowsProcTable> windows_proc_table_;
|
||||
|
||||
// Keeps track of pointer states in relation to the window.
|
||||
std::unordered_map<int32_t, std::unique_ptr<PointerState>> pointer_states_;
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "flutter/shell/platform/windows/testing/engine_modifier.h"
|
||||
#include "flutter/shell/platform/windows/testing/mock_angle_surface_manager.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 "gmock/gmock.h"
|
||||
@ -814,18 +815,20 @@ TEST(FlutterWindowsViewTest, WindowResizeTests) {
|
||||
|
||||
auto window_binding_handler =
|
||||
std::make_unique<NiceMock<MockWindowBindingHandler>>();
|
||||
auto windows_proc_table = std::make_shared<MockWindowsProcTable>();
|
||||
std::unique_ptr<MockAngleSurfaceManager> surface_manager =
|
||||
std::make_unique<MockAngleSurfaceManager>();
|
||||
|
||||
EXPECT_CALL(*window_binding_handler.get(), NeedsVSync)
|
||||
.WillOnce(Return(false));
|
||||
EXPECT_CALL(*windows_proc_table.get(), DwmIsCompositionEnabled)
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(
|
||||
*surface_manager.get(),
|
||||
ResizeSurface(_, /*width=*/500, /*height=*/500, /*enable_vsync=*/false))
|
||||
.Times(1);
|
||||
EXPECT_CALL(*surface_manager.get(), DestroySurface).Times(1);
|
||||
|
||||
FlutterWindowsView view(std::move(window_binding_handler));
|
||||
FlutterWindowsView view(std::move(window_binding_handler),
|
||||
std::move(windows_proc_table));
|
||||
modifier.SetSurfaceManager(std::move(surface_manager));
|
||||
view.SetEngine(engine.get());
|
||||
|
||||
@ -861,18 +864,20 @@ TEST(FlutterWindowsViewTest, TestEmptyFrameResizes) {
|
||||
|
||||
auto window_binding_handler =
|
||||
std::make_unique<NiceMock<MockWindowBindingHandler>>();
|
||||
auto windows_proc_table = std::make_shared<MockWindowsProcTable>();
|
||||
std::unique_ptr<MockAngleSurfaceManager> surface_manager =
|
||||
std::make_unique<MockAngleSurfaceManager>();
|
||||
|
||||
EXPECT_CALL(*window_binding_handler.get(), NeedsVSync)
|
||||
.WillOnce(Return(false));
|
||||
EXPECT_CALL(*windows_proc_table.get(), DwmIsCompositionEnabled)
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(
|
||||
*surface_manager.get(),
|
||||
ResizeSurface(_, /*width=*/500, /*height=*/500, /*enable_vsync=*/false))
|
||||
.Times(1);
|
||||
EXPECT_CALL(*surface_manager.get(), DestroySurface).Times(1);
|
||||
|
||||
FlutterWindowsView view(std::move(window_binding_handler));
|
||||
FlutterWindowsView view(std::move(window_binding_handler),
|
||||
std::move(windows_proc_table));
|
||||
modifier.SetSurfaceManager(std::move(surface_manager));
|
||||
view.SetEngine(engine.get());
|
||||
|
||||
@ -1254,17 +1259,19 @@ TEST(FlutterWindowsViewTest, DisablesVSyncAtStartup) {
|
||||
std::make_unique<MockFlutterWindowsEngine>();
|
||||
auto window_binding_handler =
|
||||
std::make_unique<NiceMock<MockWindowBindingHandler>>();
|
||||
auto windows_proc_table = std::make_shared<MockWindowsProcTable>();
|
||||
std::unique_ptr<MockAngleSurfaceManager> surface_manager =
|
||||
std::make_unique<MockAngleSurfaceManager>();
|
||||
|
||||
EXPECT_CALL(*engine.get(), running).WillRepeatedly(Return(false));
|
||||
EXPECT_CALL(*engine.get(), PostRasterThreadTask).Times(0);
|
||||
|
||||
EXPECT_CALL(*window_binding_handler.get(), NeedsVSync)
|
||||
.WillOnce(Return(false));
|
||||
EXPECT_CALL(*windows_proc_table.get(), DwmIsCompositionEnabled)
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EngineModifier modifier(engine.get());
|
||||
FlutterWindowsView view(std::move(window_binding_handler));
|
||||
FlutterWindowsView view(std::move(window_binding_handler),
|
||||
std::move(windows_proc_table));
|
||||
|
||||
InSequence s;
|
||||
EXPECT_CALL(*surface_manager.get(), CreateSurface(_, _, _))
|
||||
@ -1289,15 +1296,18 @@ TEST(FlutterWindowsViewTest, EnablesVSyncAtStartup) {
|
||||
std::make_unique<MockFlutterWindowsEngine>();
|
||||
auto window_binding_handler =
|
||||
std::make_unique<NiceMock<MockWindowBindingHandler>>();
|
||||
auto windows_proc_table = std::make_shared<MockWindowsProcTable>();
|
||||
std::unique_ptr<MockAngleSurfaceManager> surface_manager =
|
||||
std::make_unique<MockAngleSurfaceManager>();
|
||||
|
||||
EXPECT_CALL(*engine.get(), running).WillRepeatedly(Return(false));
|
||||
EXPECT_CALL(*engine.get(), PostRasterThreadTask).Times(0);
|
||||
EXPECT_CALL(*window_binding_handler.get(), NeedsVSync).WillOnce(Return(true));
|
||||
EXPECT_CALL(*windows_proc_table.get(), DwmIsCompositionEnabled)
|
||||
.WillOnce(Return(false));
|
||||
|
||||
EngineModifier modifier(engine.get());
|
||||
FlutterWindowsView view(std::move(window_binding_handler));
|
||||
FlutterWindowsView view(std::move(window_binding_handler),
|
||||
std::move(windows_proc_table));
|
||||
|
||||
InSequence s;
|
||||
EXPECT_CALL(*surface_manager.get(), CreateSurface(_, _, _))
|
||||
@ -1322,14 +1332,17 @@ TEST(FlutterWindowsViewTest, DisablesVSyncAfterStartup) {
|
||||
std::make_unique<MockFlutterWindowsEngine>();
|
||||
auto window_binding_handler =
|
||||
std::make_unique<NiceMock<MockWindowBindingHandler>>();
|
||||
auto windows_proc_table = std::make_shared<MockWindowsProcTable>();
|
||||
std::unique_ptr<MockAngleSurfaceManager> surface_manager =
|
||||
std::make_unique<MockAngleSurfaceManager>();
|
||||
|
||||
EXPECT_CALL(*engine.get(), running).WillRepeatedly(Return(true));
|
||||
EXPECT_CALL(*window_binding_handler.get(), NeedsVSync).WillOnce(Return(true));
|
||||
EXPECT_CALL(*windows_proc_table.get(), DwmIsCompositionEnabled)
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EngineModifier modifier(engine.get());
|
||||
FlutterWindowsView view(std::move(window_binding_handler));
|
||||
FlutterWindowsView view(std::move(window_binding_handler),
|
||||
std::move(windows_proc_table));
|
||||
|
||||
InSequence s;
|
||||
EXPECT_CALL(*surface_manager.get(), CreateSurface(_, _, _))
|
||||
@ -1340,7 +1353,7 @@ TEST(FlutterWindowsViewTest, DisablesVSyncAfterStartup) {
|
||||
callback();
|
||||
return true;
|
||||
});
|
||||
EXPECT_CALL(*surface_manager.get(), SetVSyncEnabled(true)).Times(1);
|
||||
EXPECT_CALL(*surface_manager.get(), SetVSyncEnabled(false)).Times(1);
|
||||
EXPECT_CALL(*surface_manager.get(), ClearCurrent).Times(0);
|
||||
|
||||
EXPECT_CALL(*engine.get(), Stop).Times(1);
|
||||
@ -1359,15 +1372,18 @@ TEST(FlutterWindowsViewTest, EnablesVSyncAfterStartup) {
|
||||
std::make_unique<MockFlutterWindowsEngine>();
|
||||
auto window_binding_handler =
|
||||
std::make_unique<NiceMock<MockWindowBindingHandler>>();
|
||||
auto windows_proc_table = std::make_shared<MockWindowsProcTable>();
|
||||
std::unique_ptr<MockAngleSurfaceManager> surface_manager =
|
||||
std::make_unique<MockAngleSurfaceManager>();
|
||||
|
||||
EXPECT_CALL(*engine.get(), running).WillRepeatedly(Return(true));
|
||||
|
||||
EXPECT_CALL(*window_binding_handler.get(), NeedsVSync).WillOnce(Return(true));
|
||||
EXPECT_CALL(*windows_proc_table.get(), DwmIsCompositionEnabled)
|
||||
.WillOnce(Return(false));
|
||||
|
||||
EngineModifier modifier(engine.get());
|
||||
FlutterWindowsView view(std::move(window_binding_handler));
|
||||
FlutterWindowsView view(std::move(window_binding_handler),
|
||||
std::move(windows_proc_table));
|
||||
|
||||
InSequence s;
|
||||
EXPECT_CALL(*surface_manager.get(), CreateSurface(_, _, _))
|
||||
@ -1398,6 +1414,7 @@ TEST(FlutterWindowsViewTest, UpdatesVSyncOnDwmUpdates) {
|
||||
std::make_unique<MockFlutterWindowsEngine>();
|
||||
auto window_binding_handler =
|
||||
std::make_unique<NiceMock<MockWindowBindingHandler>>();
|
||||
auto windows_proc_table = std::make_shared<MockWindowsProcTable>();
|
||||
std::unique_ptr<MockAngleSurfaceManager> surface_manager =
|
||||
std::make_unique<MockAngleSurfaceManager>();
|
||||
|
||||
@ -1409,14 +1426,15 @@ TEST(FlutterWindowsViewTest, UpdatesVSyncOnDwmUpdates) {
|
||||
return true;
|
||||
});
|
||||
|
||||
EXPECT_CALL(*window_binding_handler.get(), NeedsVSync)
|
||||
.WillOnce(Return(true))
|
||||
.WillOnce(Return(false));
|
||||
EXPECT_CALL(*windows_proc_table.get(), DwmIsCompositionEnabled)
|
||||
.WillOnce(Return(false))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(*surface_manager.get(), ClearCurrent).Times(0);
|
||||
|
||||
EngineModifier modifier(engine.get());
|
||||
FlutterWindowsView view(std::move(window_binding_handler));
|
||||
FlutterWindowsView view(std::move(window_binding_handler),
|
||||
std::move(windows_proc_table));
|
||||
|
||||
InSequence s;
|
||||
EXPECT_CALL(*surface_manager.get(), SetVSyncEnabled(true)).Times(1);
|
||||
|
||||
@ -40,7 +40,6 @@ class MockWindowBindingHandler : public WindowBindingHandler {
|
||||
MOCK_METHOD(PointerLocation, GetPrimaryPointerLocation, (), (override));
|
||||
MOCK_METHOD(AlertPlatformNodeDelegate*, GetAlertDelegate, (), (override));
|
||||
MOCK_METHOD(ui::AXPlatformNodeWin*, GetAlert, (), (override));
|
||||
MOCK_METHOD(bool, NeedsVSync, (), (const override));
|
||||
|
||||
private:
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(MockWindowBindingHandler);
|
||||
|
||||
@ -21,14 +21,16 @@ class MockWindowsProcTable : public WindowsProcTable {
|
||||
MOCK_METHOD(BOOL,
|
||||
GetPointerType,
|
||||
(UINT32 pointer_id, POINTER_INPUT_TYPE* pointer_type),
|
||||
(override));
|
||||
(const, override));
|
||||
|
||||
MOCK_METHOD(LRESULT,
|
||||
GetThreadPreferredUILanguages,
|
||||
(DWORD, PULONG, PZZWSTR, PULONG),
|
||||
(const, override));
|
||||
|
||||
MOCK_METHOD(bool, GetHighContrastEnabled, (), (override));
|
||||
MOCK_METHOD(bool, GetHighContrastEnabled, (), (const, override));
|
||||
|
||||
MOCK_METHOD(bool, DwmIsCompositionEnabled, (), (const, override));
|
||||
|
||||
private:
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(MockWindowsProcTable);
|
||||
|
||||
@ -96,10 +96,6 @@ class WindowBindingHandler {
|
||||
|
||||
// Retrieve the alert node.
|
||||
virtual ui::AXPlatformNodeWin* GetAlert() = 0;
|
||||
|
||||
// If true, rendering to the window should synchronize with the vsync
|
||||
// to prevent screen tearing.
|
||||
virtual bool NeedsVSync() const = 0;
|
||||
};
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
@ -4,6 +4,9 @@
|
||||
|
||||
#include "flutter/shell/platform/windows/windows_proc_table.h"
|
||||
|
||||
#include <WinUser.h>
|
||||
#include <dwmapi.h>
|
||||
|
||||
namespace flutter {
|
||||
|
||||
WindowsProcTable::WindowsProcTable() {
|
||||
@ -17,7 +20,7 @@ WindowsProcTable::~WindowsProcTable() {
|
||||
}
|
||||
|
||||
BOOL WindowsProcTable::GetPointerType(UINT32 pointer_id,
|
||||
POINTER_INPUT_TYPE* pointer_type) {
|
||||
POINTER_INPUT_TYPE* pointer_type) const {
|
||||
if (!get_pointer_type_.has_value()) {
|
||||
return FALSE;
|
||||
}
|
||||
@ -32,7 +35,7 @@ LRESULT WindowsProcTable::GetThreadPreferredUILanguages(DWORD flags,
|
||||
return ::GetThreadPreferredUILanguages(flags, count, languages, length);
|
||||
}
|
||||
|
||||
bool WindowsProcTable::GetHighContrastEnabled() {
|
||||
bool WindowsProcTable::GetHighContrastEnabled() const {
|
||||
HIGHCONTRAST high_contrast = {.cbSize = sizeof(HIGHCONTRAST)};
|
||||
if (!::SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(HIGHCONTRAST),
|
||||
&high_contrast, 0)) {
|
||||
@ -42,4 +45,13 @@ bool WindowsProcTable::GetHighContrastEnabled() {
|
||||
return high_contrast.dwFlags & HCF_HIGHCONTRASTON;
|
||||
}
|
||||
|
||||
bool WindowsProcTable::DwmIsCompositionEnabled() const {
|
||||
BOOL composition_enabled;
|
||||
if (SUCCEEDED(::DwmIsCompositionEnabled(&composition_enabled))) {
|
||||
return composition_enabled;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
@ -24,11 +24,12 @@ class WindowsProcTable {
|
||||
// Used to react differently to touch or pen inputs. Returns false on failure.
|
||||
// Available on Windows 8 and newer, otherwise returns false.
|
||||
virtual BOOL GetPointerType(UINT32 pointer_id,
|
||||
POINTER_INPUT_TYPE* pointer_type);
|
||||
POINTER_INPUT_TYPE* pointer_type) const;
|
||||
|
||||
// Get the preferred languages for the thread, and optionally the process,
|
||||
// and system, in that order, depending on the flags.
|
||||
// See
|
||||
//
|
||||
// See:
|
||||
// https://learn.microsoft.com/windows/win32/api/winnls/nf-winnls-getthreadpreferreduilanguages
|
||||
virtual LRESULT GetThreadPreferredUILanguages(DWORD flags,
|
||||
PULONG count,
|
||||
@ -38,9 +39,16 @@ class WindowsProcTable {
|
||||
// Get whether high contrast is enabled.
|
||||
//
|
||||
// Available on Windows 8 and newer, otherwise returns false.
|
||||
// See
|
||||
//
|
||||
// See:
|
||||
// https://learn.microsoft.com/windows/win32/winauto/high-contrast-parameter
|
||||
virtual bool GetHighContrastEnabled();
|
||||
virtual bool GetHighContrastEnabled() const;
|
||||
|
||||
// Get whether the system compositor, DWM, is enabled.
|
||||
//
|
||||
// See:
|
||||
// https://learn.microsoft.com/windows/win32/api/dwmapi/nf-dwmapi-dwmiscompositionenabled
|
||||
virtual bool DwmIsCompositionEnabled() const;
|
||||
|
||||
private:
|
||||
using GetPointerType_ = BOOL __stdcall(UINT32 pointerId,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user