Skip to content

fix(ui-egui): Save picture never writes over an existing file (#158) - #177

Merged
DWAA1660 merged 3 commits into
AlienTechSoftware:mainfrom
DWAA1660:fix/save-picture-unique-name
Nov 12, 2026
Merged

DWAA1660 merged 3 commits into
AlienTechSoftware:mainfrom
DWAA1660:fix/save-picture-unique-name

Conversation

@DWAA1660

Copy link
Copy Markdown
Collaborator

What and why

Fixes #158. inkpad::Pad::save_plain (Draw › Save picture) always wrote ink-picture.svg beside the page with fs::write, silently replacing any file already there: an earlier export kept on purpose, or an unrelated file with that name.

It now writes to the first free name of ink-picture.svg, ink-picture-2.svg, ink-picture-3.svg, … (up to 10,000, then it reports an error). Each candidate is opened with OpenOptions::create_new, so a taken name is refused atomically and never written over. app.ink_export_plain already reports the returned path ("Saved the drawing as a picture: …"), so the user sees which file was made.

This picks the issue's "generate a unique snapshot name" option. A Save As dialog could be added later, but would be a larger UI change.

How it was checked

  • inkpad::tests::ink_is_written_beside_the_page_and_comes_back_as_strokes, extended: with an owner's file already at ink-picture.svg, Save picture writes ink-picture-2.svg and leaves the owner's bytes unchanged. A third save writes ink-picture-3.svg.
  • The UI test that clicks Save picture on a fresh page still finds ink-picture.svg.
  • cargo test -p notecraft-ui-egui: all pass (302 unit, 200 UI)
  • cargo fmt --all -- --check, cargo clippy -p notecraft-ui-egui --all-targets -- -D warnings: clean

🤖 Generated with Claude Code

Draw > Save picture always wrote `ink-picture.svg`, replacing whatever
was there: a picture saved earlier and kept, or another file of the
owner's under that name (AlienTechSoftware#158). It now writes the first free name of
`ink-picture.svg`, `ink-picture-2.svg`, ... and opens it with
`create_new`, so a taken name is never written over. The window already
says where the picture went.

Fixes AlienTechSoftware#158

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@DWAA1660

Copy link
Copy Markdown
Collaborator Author

Audit finding: this changes Save picture from the browser's virtual std::fs::write to std::fs::OpenOptions::create_new, but the browser shim does not implement OpenOptions.

Checked .github/web-build/web.diff and patches.yaml: the virtual fs re-exports native fs items and supplies its own read/write/File implementations; there is no OpenOptions override. A probe using the actual shim with its patched File implementation produces:

virtual fs read: Ok("virtual ink")
OpenOptions::new().write(true).create_new(true).open(virtual_path): NotFound
patched virtual File::open succeeds: true

On wasm the inherited native OpenOptions cannot write the virtual notebook, so the new export path will fail. Please provide a virtual exclusive-create operation (with a matching browser test) or isolate the native implementation behind a platform boundary. Holding this PR out of the merge batch for this browser regression.

@DWAA1660
DWAA1660 merged commit 759fd14 into AlienTechSoftware:main Nov 12, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Save picture silently overwrites an existing ink-picture.svg without a destination or overwrite check

1 participant