Found while testing crates/color/src/swatch.rs:94-101 (value_name)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* Show file and message dialogs without blocking the frame
A blocking rfd dialog inside the egui frame runs AppKit's modal loop; a
file dragged from Finder and held over the window then re-enters winit's
handler and aborts the app. Dialogs now go through craft-dialogs: a
command without a path asks with a continuation and returns, the host
shows the dialog at the end of the frame, and the continuation runs with
the answer on a later frame, in the document it was asked for. Commands
given a path stay synchronous. The replace-file question is a message
box from the same queue. Quit and Close wait for a Save As dialog's
answer. clippy.toml disallows rfd::FileDialog and rfd::MessageDialog.
* Raise the open file panel when File > Open is chosen again
* Repin craft-dialogs to the craft-libs PR head
* Queue dialogs asked by different code or documents; hold answers behind newer dialogs
Two asks for the same file dialog were treated as one, so Place for one
document and then Choose Image, or Place again for another document, ran
the first ask's action. An ask is now skipped (and the open panel
raised) only when the same code asked for the same dialog for the same
document. An answer that would replace an egui dialog opened since the
asking (an unsaved-changes question, Preferences) waits until it closes;
Quit counts it as pending.
* Repin craft-dialogs to the craft-libs PR head
* Allow the file dialogs' existence checks in the file guard
* Repin craft-dialogs to storytold/craft-libs main
* Honor CARGO_BUILD_TARGET in FreeBSD packaging for aarch64 release builds
The shared release workflow cross-compiles FreeBSD aarch64 in an x86_64 VM and sets
CARGO_BUILD_TARGET. package.sh ignored it: it built for the host, read binaries from
target/release, took the arch from uname -m (amd64 in the VM), and ran the cross-built
designcraft-cli --version on the host.
Take the arch from the target, build and read binaries from the target's directory, and skip
the host-side --version run when cross-compiling. Unset CARGO_BUILD_TARGET keeps the old behavior.
* Pick FreeBSD archive arch from CARGO_BUILD_TARGET with a release_arch helper
Follow soundcraft's pattern: native builds use uname -m, aarch64-unknown-freebsd and
x86_64-unknown-freebsd map to their arch, and any other target exits 2. The --version check
runs only when the archive arch matches the host arch.
The policy check now reads the compiled AppSearch and RegLocator rows for the
remembered-folder properties (registry root, key, value name and type for both
scopes) and runs the DIR, FOLDER, PATH and legacy exe actions in sequence order
against seeded values, so their precedence and the preset-folder guard cannot
regress. It also replays the wizard folder actions in sequence order (a
remembered folder beats the new-install default, a typed folder beats both) and
requires the machine restore action between the scope page and costing.
The pre-signing check matched any folder named Program Files, so it rejected
a valid MSI when Windows resolves Program Files elsewhere, accepted the 64-bit
root for an x86 package and accepted a different app name. Build the expected
folder from the package architecture's resolved root and the policy name.
The PDF exporter called Cache::get twice for every text frame it drew.
Each call rebuilds the cache signature of the whole story, which looks up
every frame of the story with Document::find (a linear walk over all
spreads), and the anchored-frame placements walk them again. For a story
threaded through many frames this is O(frames^2 x items) per export.
The document doesn't change during an export, so the exporter now keeps
the composition it got for each (story, page) and reuses it. The cache
still decides what to compose; the output is byte-identical.
Add examples/pdf_export.rs to designcraft-cli: File > Export PDF through
a headless session on the `designcraft-cli perf` stress document (200
pages, 1M characters in 40 threaded stories, 500 placed images). The
stress document generator moves unchanged from src/perf.rs to a small
library module (src/stress.rs) that the binary and the example share.
Ryzen 16 threads, Linux, 12 runs each, interleaved:
main median 3485 ms, min 3427 ms
patched median 2016 ms, min 1656 ms (-42 % median, -52 % min)
The exported PDF is byte-identical (12,075,744 bytes).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Real msiexec runs (per-user and all-users, silent and wizard) found two defects
that the metadata fixtures cannot see:
- "Only for me" published ALLUSERS=2, so FindRelatedProducts treated the run as
per-machine and skipped the existing per-user copy. An interactive upgrade
left two registered products and uninstall left files behind. The page now
leaves ALLUSERS unset for a per-user choice.
- Windows Installer resolves Program Files once, for the context it started in,
so choosing "Everyone" in the wizard installed into the user profile with a
machine-wide registration. The wizard now sets the new-install folder itself
after the choice (Program Files, Program Files (x86) for 32-bit, or the
per-user Programs folder). Silent installs are unchanged.
check-install-policy.ps1 now fails if either regresses.
* fix(ui): font menus grow back after a search with no matches
Every combo box is craft_ui::ComboBox (craft-libs pinned at 62bb0e1d), whose
menu follows its contents' height while open (egui#5225); clippy.toml bans
egui::ComboBox.
The Font menu splits into a header (search field, filters) and a list
(font_menu_header, font_menu_list). Font fields show it in a
craft_ui::combo::Menu and the style dialogs' Font Family combo boxes in
ComboBox::show_ui_with_header, so only the rows scroll and the search field
stays in place. The blank and Parent's Font rows sit in the header, above
the search.
* chore(deps): craft-libs 60d60d48 (dropdown fixes)
* chore(deps): craft-libs 4d7b82f7 (dropdown fixes)
* chore(deps): craft-libs 92d392cf (#387 merged)
* chore(xtask): pdf-deps expects craft-libs 92d392cf
Auto-Collapse Iconic Panels is off by default, so a flyout closes only from its icon or
another icon. The setting is saved under a new key, so preferences saved with the old
default start with it off, and Preferences > Interface > Panels shows it.
Split files share test helpers through pub(super)/pub(crate) test modules. The guard read only `mod` and `pub mod` as a test module, so it scanned their fixtures as production code. `attr.contains("test")` also matched `#[cfg(not(test))]`, so such a module was skipped; it is scanned now.