fix: Surface pen pressure, zoom glitches, sticky notes, selection UX
All checks were successful
CI / Windows build (push) Successful in 8m19s

Wire Win32 pressure into Dart, tighten pinch guards, use geometric shape
strokes, expand the ink palette, and replace scratch-link split view with
an on-page sticky that shares the sidecar repo.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-05 19:52:15 +08:00
parent 198da00ecd
commit 4a6fe7d05e
16 changed files with 621 additions and 171 deletions

View File

@@ -99,6 +99,11 @@ class SidecarRepository {
Timer? _timer;
bool _disposed = false;
/// How many editors currently hold this repo. [open] reuses an existing
/// instance and bumps the count; [dispose] only tears down at zero so a
/// split-view / sticky overlay cannot clobber the PDF editor's sidecar.
int _retainCount = 1;
/// Tail of the in-flight write chain. Writes are serialized through this so a
/// debounce-timer write and a concurrent lifecycle [flush] can't race on the
/// same `.tmp`/rename (which would throw on the loser). Each write always
@@ -107,14 +112,23 @@ class SidecarRepository {
/// Open (or create) the repository for [sourceFilePath]. Reads the existing
/// sidecar if present (falling back to its `.bak`), else starts empty.
///
/// Reuses an already-open repo for the same path (retain-counted) so a
/// scratchpad overlay / split view cannot race the PDF editor with a second
/// in-memory snapshot that would overwrite scratchpad ink on flush.
static Future<SidecarRepository> open(
String sourceFilePath, {
String? docType,
Duration debounce = const Duration(milliseconds: 800),
}) async {
final existing = SidecarRepositoryRegistry.forPath(sourceFilePath);
if (existing != null && !existing._disposed) {
existing._retainCount++;
return existing;
}
final file = File('$sourceFilePath$kSidecarSuffix');
final existing = await SidecarStore.read(file);
final sidecar = existing ??
final loaded = await SidecarStore.read(file);
final sidecar = loaded ??
BadnoteSidecar(
sourceFile: _basename(sourceFilePath),
docType: docType,
@@ -313,6 +327,11 @@ class SidecarRepository {
/// Cancel pending timers. Call [flush] first to persist pending writes.
void dispose() {
if (_disposed) return;
if (_retainCount > 1) {
_retainCount--;
return;
}
_disposed = true;
_timer?.cancel();
_timer = null;