feat(windows): disable pen tap / press-hold visual feedback
On pen-down the OS drew the "Windows Ink" tap ripple / press-and-hold ring under the nib — ugly and laggy-looking while writing. Set the tablet input service's MicrosoftTabletPenServiceProperty on both the top-level window and the Flutter child (where WM_POINTER lands) with the disable flags (PENTAPFEEDBACK, PRESSANDHOLD, PENBARRELFEEDBACK, TOUCHUIFORCEON/OFF, FLICKS) so the pen draws instantly with no OS animation. Native-only change (windows/runner/flutter_window.cpp); built by CI.
This commit is contained in:
@@ -29,6 +29,32 @@ LRESULT CALLBACK FlutterChildSubclassProc(HWND hwnd, UINT message,
|
|||||||
return DefSubclassProc(hwnd, message, wparam, lparam);
|
return DefSubclassProc(hwnd, message, wparam, lparam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Turn off the OS-drawn pen visual feedback (the "Windows Ink" tap ripple, the
|
||||||
|
// press-and-hold right-click ring, barrel feedback, and flicks) so the pen
|
||||||
|
// draws instantly with no ugly OS animation under the nib. The tablet input
|
||||||
|
// service reads these flags from a window property; set it on whichever window
|
||||||
|
// receives the pointer input. Flag values are from the Windows pen/tablet docs
|
||||||
|
// (not declared in the public SDK headers).
|
||||||
|
void DisablePenVisualFeedback(HWND hwnd) {
|
||||||
|
if (!hwnd) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
constexpr ULONG_PTR kDisablePressAndHold = 0x00000001;
|
||||||
|
constexpr ULONG_PTR kDisablePenTapFeedback = 0x00000008;
|
||||||
|
constexpr ULONG_PTR kDisablePenBarrelFeedback = 0x00000010;
|
||||||
|
constexpr ULONG_PTR kDisableTouchUIForceOn = 0x00000100;
|
||||||
|
constexpr ULONG_PTR kDisableTouchUIForceOff = 0x00000200;
|
||||||
|
constexpr ULONG_PTR kDisableFlicks = 0x00010000;
|
||||||
|
const ULONG_PTR flags = kDisablePressAndHold | kDisablePenTapFeedback |
|
||||||
|
kDisablePenBarrelFeedback | kDisableTouchUIForceOn |
|
||||||
|
kDisableTouchUIForceOff | kDisableFlicks;
|
||||||
|
const ATOM atom = ::GlobalAddAtomW(L"MicrosoftTabletPenServiceProperty");
|
||||||
|
if (atom != 0) {
|
||||||
|
::SetPropW(hwnd, MAKEINTATOM(atom), reinterpret_cast<HANDLE>(flags));
|
||||||
|
::GlobalDeleteAtom(atom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
FlutterWindow::FlutterWindow(const flutter::DartProject& project)
|
FlutterWindow::FlutterWindow(const flutter::DartProject& project)
|
||||||
@@ -64,6 +90,11 @@ bool FlutterWindow::OnCreate() {
|
|||||||
SetWindowSubclass(flutter_child, FlutterChildSubclassProc, kPenSubclassId, 0);
|
SetWindowSubclass(flutter_child, FlutterChildSubclassProc, kPenSubclassId, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Kill the OS pen tap/press-and-hold visual feedback on both the top-level
|
||||||
|
// window and the Flutter child (the one that actually gets the pointer input).
|
||||||
|
DisablePenVisualFeedback(GetHandle());
|
||||||
|
DisablePenVisualFeedback(flutter_child);
|
||||||
|
|
||||||
flutter_controller_->engine()->SetNextFrameCallback([&]() {
|
flutter_controller_->engine()->SetNextFrameCallback([&]() {
|
||||||
this->Show();
|
this->Show();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user