fix(pen): eraser lag/stuck-red/reliability; zoom glitch-reject; native input diag
All checks were successful
CI / Windows build (push) Successful in 17m58s
All checks were successful
CI / Windows build (push) Successful in 17m58s
Eraser (regression from the preview I added):
- LAG: the preview did setState on every hover/erase-move (rebuilding the whole
canvas) and recomputed perfect_freehand getStroke per overlapped stroke per
frame. Now the cursor is a ValueNotifier driving the preview layer's repaint
directly (no canvas rebuild), and the highlight is a plain polyline of the
point-runs inside the radius (no getStroke).
- STUCK RED ("一直红着"): the cursor was never cleared. Preview is now
active-erase-only and cleared on pen up/cancel.
- "选中了的笔画也不见得能删掉": radius was strokeWidth*2 (tiny) so a pass removed
~2 points and the stroke survived. Now a decisive fixed 0.02 (page-width
fraction). The highlight traces exactly the point-run that splitStrokeByCircle
removes, so what turns red is what gets deleted.
Zoom: replace the per-frame scale CLAMP with glitch REJECTION — drop a frame
demanding an implausible per-frame scale jump (>1.4x or <0.71x; a real pinch is
≲1.15x/frame). A dropped frame catches up the next frame (absolute tracking), so
no lag, but the Windows multi-touch spike never shows. Pairs with the existing
pointer-count re-baseline.
Native diagnostic: ObservePenMessage now counts WM_POINTER* / PT_PEN / legacy
mouse messages it sees and emits them on the channel; PenInputService exposes
`debugSummary` and the overlay shows `native ptr=… pen=… mouse=… msg=0x…`. This
will tell us on-device whether WM_POINTER ever reaches the observer (→ buttons
recoverable) or Flutter is on a non-pointer path (→ not).
Dart: analyze clean, 66/66 tests, linux build green. Native compiles on CI.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -94,6 +94,19 @@ class PenInputService {
|
||||
bool get isActive => _active;
|
||||
bool _active = false;
|
||||
|
||||
// Native-side diagnostics (see windows/runner/pen_channel.cpp): how many
|
||||
// WM_POINTER / PT_PEN / legacy-mouse messages the observer has seen. Lets the
|
||||
// on-device overlay tell us WHICH layer is failing for buttons/tilt.
|
||||
int _diagPtr = 0;
|
||||
int _diagPen = 0;
|
||||
int _diagMouse = 0;
|
||||
int _diagMsg = 0;
|
||||
|
||||
/// One-line native readout for the diagnostic overlay.
|
||||
String get debugSummary => _active
|
||||
? 'native ptr=$_diagPtr pen=$_diagPen mouse=$_diagMouse msg=0x${_diagMsg.toRadixString(16)}'
|
||||
: 'native: channel silent (no events)';
|
||||
|
||||
/// Begins listening to the native channel. Idempotent; safe on any platform
|
||||
/// (no-ops where the channel has no handler).
|
||||
void start() {
|
||||
@@ -123,6 +136,10 @@ class PenInputService {
|
||||
tiltX: (event['tiltX'] as num?)?.toDouble() ?? 0.0,
|
||||
tiltY: (event['tiltY'] as num?)?.toDouble() ?? 0.0,
|
||||
);
|
||||
_diagPtr = (event['diagPtr'] as num?)?.toInt() ?? _diagPtr;
|
||||
_diagPen = (event['diagPen'] as num?)?.toInt() ?? _diagPen;
|
||||
_diagMouse = (event['diagMouse'] as num?)?.toInt() ?? _diagMouse;
|
||||
_diagMsg = (event['diagMsg'] as num?)?.toInt() ?? _diagMsg;
|
||||
_active = true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user