Commit Graph
274 Commits
Author SHA1 Message Date
aiongg b749251694 Merge pull request #1478 from Hamza0101/fix/cli-argument-handling
cli: the three argument bugs photocraft#7071 lists are live here too
2026-11-03 17:01:34 -05:00
aiongg 65c4db30e1 Apply review fixes
- apps/designcraft-cli/src/main.rs
2026-11-03 21:48:08 +00:00
aiongg 61ed22140a Apply review fixes
- apps/designcraft-cli/src/main.rs
2026-11-03 19:41:27 +00:00
aiongg 35a7410481 Merge pull request #2192 2026-11-03 19:07:42 +00:00
Hamza 54df0d21b3 Merge remote-tracking branch 'origin/main' into fix/cli-argument-handling
# Conflicts:
#	apps/designcraft-cli/src/main.rs
#	apps/designcraft-cli/tests/it/cli.rs
2026-11-03 13:50:15 +05:00
Brandon Thomas 1bca5db25b Merge pull request #1792 from marcoarnulfo/feat/thumbnailer
Linux: file managers show a .designcraft file's first page through a freedesktop thumbnailer (#1782)
2026-11-02 23:24:25 -05:00
Brandon Thomas 3a40dc7577 Merge pull request #2158 from Silvertree2010/fix/2116-graphics-fallback-marks-a-workin
Keep the graphics backend when the window closes before its first frame
2026-11-02 23:23:50 -05:00
JonRC 41c59708eb cli: script --export prints the export's warnings, as run does (#2191)
The script command threw away the result of each export, so a PDF with
a drop shadow came out with nothing on stderr, while run --export
printed "warning: 1 object(s) with soft effects ... exported as images".
Each warning an export returns now goes to stderr as "warning: ...".
The JSON report on stdout is unchanged.
2026-11-03 01:05:17 -03:00
FredApps fc47f3156e Merge current main into fix/gnome-window-decorations 2026-11-02 19:10:33 +01:00
NetterSilverandClaude Opus 5.5 a207f13f73 Keep the graphics backend when the window closes before its first frame
Fixes #2116

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 15:47:11 +01:00
Hamza 133e9098e8 cli: validate-pdf's help names --standard
`validate_pdf` accepts `--standard x4|x1a`, and both its own usage string and the
module docs say so, but the line in the global `USAGE` left it off -- and that
line is exactly what `validate-pdf --help` slices out. So the option was
documented everywhere except the one place a user would look (noted in review).

`subcommand_help_names_the_options_that_subcommand_takes` asserts it, checks the
parser and the help agree by refusing an unknown standard, and does the same for
`run --cmd` and `mcp --automation-read-root` so this is about subcommand help
rather than one line.
2026-11-02 17:39:55 +05:00
Hamza 4c9e5277f7 cli: subcommand help is for subcommands that exist
`<sub> --help` answered about that subcommand without first asking whether the
subcommand was one, so `designcraft-cli typo --help` printed the whole usage and
succeeded. `typo` on its own was an error and `typo --help` was not, which is
backwards: a script checking the exit status carried straight past a misspelled
command (noted in review).

`is_subcommand` reads the names out of `USAGE` rather than listing them again,
so one added to the usage text cannot be missing here, and `usage_for` now uses
the same line parser instead of its own copy. An unknown name falls through to
the dispatch and fails there, as it already did without `--help`.

Measured over every name the usage lists -- run, commands, describe, script,
app, mcp, perf, bench, validate-pdf, links -- each still answers on stdout and
exits 0, while `typo` and `nonsense` exit 1. The test asserts both halves, so
the check cannot quietly become a block on subcommand help.
2026-11-02 16:00:15 +05:00
aiongg cc3c70d4be Windows: keep the custom title bar window borderless (#2139)
winit 0.30 gives an undecorated window WS_CAPTION and WS_BORDER; on some systems the compositor
reserves that frame, so the content is drawn offset (black bars at the top and left) while the
pointer keeps the client coordinates. A per-frame guard strips the styles again after every
winit flag change and keeps a maximized window clear of the taskbar. Fixes #1295.
2026-11-01 20:39:44 -05:00
NetterSilverandClaude Opus 5.5 52232fc2c7 Read PDF/X output intent and Info as parsed objects in validate-pdf
Fixes #2050

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:47:33 +01:00
MarekSpodBiedry 759ab3ba7c Separate the CJK commands from Insert Math Expression in the Type menu (#2043) 2026-10-30 16:39:22 +01:00
Dylan M. Taylor 15d13dde20 Update prompt shows the app icon and accent color instead of a letter (#2023)
UPDATE_APP (native builds; craft-update is a native-only dependency) carries our 128 px icon and accent (#7bb51c, its colour in ArtCraft Launcher). The updater, the self-update
helper and craft-update's startup prompt all get them through crate::UPDATE_APP; the
prompt draws the icon, the accent and "by ArtCraft" (craft-update's default developer).

craft-update is pinned to storytold/craft-libs main at 1065653e7 (#434).
Clippy fixes for Rust 1.99 in untouched code (same logic):
- crates/engine/src/cmd/export/text_tests.rs
- crates/pdf/src/gradient_inks.rs
2026-10-30 01:28:06 -04:00
Marco Arnulfo 8e8865bba1 thumbnail: refuse an output that names the input document (#1782)
designcraft-cli thumbnail a.designcraft a.designcraft replaced the
document with PNG bytes. The output is now refused before anything is
read or written when it is the input by the same path, through a
symlink, or on Unix as a hard link (same device and inode).
2026-10-30 03:08:39 +01:00
Marco Arnulfo ec059c042b Linux: file managers show a .designcraft file's first page through a freedesktop thumbnailer (#1782) 2026-10-30 03:00:29 +01:00
Hamza f11f5f3b11 cli: a missing value is found before anything runs
Review caught a consequence of the previous commit. Standing the order check
aside so a missing value could be reported meant the value was reported
later -- after the exports before it had already been written. `run --export
first.png --scale --export second.png` wrote first.png and only then failed,
so an invocation that fails could overwrite a file that was already there.

`values_present` checks every option that takes a value before the order
check and before any export, so the line is refused as a whole. The test
writes a file at the export path first and asserts its bytes are unchanged.
2026-10-29 13:51:49 +05:00
aiongg 855d606325 Show file and message dialogs without blocking the frame (fixes macOS crash) (#1961)
* 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
2026-10-28 17:13:45 -04:00
Hamza 434e269691 cli: the three argument bugs photocraft#7071 lists are live here too
- An option took the next token whatever it was, so `--export --scale` wrote a
  file called `--scale` in the working directory. A token that cannot be a
  value is refused, and where the value is a path the message offers the
  shell's own way out (`./-name`). A negative number can still be a value, and
  `-inf`/`-nan` still reach the check that reports them.
- An argument that is not UTF-8 panicked inside `std::env::args`. It is a
  usage error now, named, since such a path cannot reach the engine anyway.
- `<sub> --help` was read as an unknown option by every parser but `script`'s.
  It answers from the usage block, on stdout, and nothing else happens.

Rebased onto the post-split main, where the fix had to grow one part. Upstream
has since added a check that an export option sits before its `--export`, and
it consumed the following token whatever it was, so `--scale --export out.png`
was reported as the *order* of the options -- advice to move an option that is
already where it belongs -- when what is wrong is that `--scale` has no value.
That check now skips a value only where the next token can be one, and stands
aside entirely when a value is missing so the value error speaks. Its own test,
`run_export_options_come_before_their_export`, still passes.

The CLI's tests moved to tests/it/cli.rs, so the test additions went there.
2026-10-28 18:34:12 +05:00
Dylan M. Taylor 251dabb2b5 Refactor designcraft-cli for strict Clippy checks 2026-10-28 11:39:26 +00:00
NetterSilverandClaude Opus 5.5 1db1635a88 Ask the composition cache once per story and page in PDF export
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>
2026-10-27 16:47:25 +01:00
aiongg ab48df68c8 refactor(designcraft): move the tests module of gpu.rs to gpu/tests.rs 2026-10-26 18:18:14 +00:00
aiongg 3fc0bf83fd Merge branch 'keymap-adoption' into keymap-shortcuts-dialog
# Conflicts:
#	Cargo.toml
#	xtask/src/pdf_deps.rs
2026-10-26 02:06:51 +00:00
aiongg 23173b9065 Merge remote-tracking branch 'upstream/main' into keymap-adoption
# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	xtask/src/pdf_deps.rs
2026-10-26 02:06:25 +00:00
aiongg c6444a0471 A command's other shortcuts run while the macOS menu bar holds its first 2026-10-26 01:39:22 +00:00
aiongg d28271b489 Merge branch 'keymap-adoption' into keymap-shortcuts-dialog
# Conflicts:
#	Cargo.lock
#	Cargo.toml
2026-10-26 01:16:37 +00:00
aiongg 1a52593d0d Merge remote-tracking branch 'upstream/main' into keymap-adoption
# Conflicts:
#	Cargo.toml
2026-10-26 01:15:41 +00:00
aiongg c856db68f1 Merge branch 'print-color' into print-color-x1a
# Conflicts:
#	Cargo.toml
2026-10-26 01:11:11 +00:00
aiongg 240dbcf731 Merge remote-tracking branch 'upstream/main' into print-color
# Conflicts:
#	Cargo.toml
#	crates/idml/src/export.rs
2026-10-26 01:10:39 +00:00
Daniel 699ba7d6ed Merge latest upstream main and resolve GNOME Wayland control conflicts 2026-10-26 00:02:02 +01:00
aiongg 074db00079 Merge print-color into print-color-x1a
Brings in #1374 with upstream main merged (egui 0.37, craft-libs at
storytold/craft-libs e3b9e239).

Conflicts:
- Cargo.toml: print-color's pins (storytold/craft-libs e3b9e239 for
  craft-pdf, craft-prepress, krilla and the hayro crates; winit and egui
  patches), with craft-prepress keeping the `flatten` feature.
- xtask/src/pdf_deps.rs: print-color's REPO/REV.
- Cargo.lock: print-color's, relocked with cargo metadata; adds only
  craft-prepress and linesweeper.
- crates/pdf/src/export.rs: main's optional-content registration and
  add_form_fields helper; the helper leaves form fields and media out of
  PDF/X-1a with a warning.
- crates/engine/src/cmd/export.rs: the X-1a parameter docs plus main's
  `created`; the X-1a flatten and shadow-mask path on top of main's
  PDF/A-2b-only rasterize_layered.

Also: x1a_tests builds FlattenTotals through Default, since the struct is
non_exhaustive at e3b9e239.
2026-10-25 19:55:21 +00:00
aiongg 65c387732d Merge upstream/main into print-color
PDF/X and CMYK groups keep this branch's approach: krilla's serialize
settings (pdfx::print_settings) write the CMYK page and transparency
groups, the GTS_PDFX output intent and the PDF/X Info and XMP entries.
make_pdfx4 adds only the XMP dates, so main's title argument and its
output-intent, Info and pdfxid XMP edits are dropped, and both
cmyk_group_spaces calls after writer.finish() (Export PDF, Print
Booklet) stay removed. Main's new parts are kept: file_info_metadata
(also for Print Booklet, on top of the print settings), optional content
registration and layer errors, add_form_fields, and pdfx's fonts module.
Main's metadata panic test calls the two-argument make_pdfx4.

craft-libs and the krilla patch are pinned to storytold/craft-libs
e3b9e239; Cargo.lock is main's, relocked without updates.
2026-10-25 19:47:27 +00:00
aiongg 77c718aa68 Merge keymap-adoption (#1298, on main) into keymap-shortcuts-dialog
craft-keymap with the dialog comes from storytold/craft-libs main e3b9e239. egui 0.37's
shaper owns bidi, so the dialog's labels go to it in logical order: rtl::visual_text and the
dialog's visual hook are gone. ForeignSet keeps the dropped-entry count through its builder.
2026-10-25 19:39:58 +00:00
aiongg 073ac98694 Merge upstream main into keymap-adoption; pin craft-libs to main e3b9e239
Main's shortcut dispatch (shortcut_key, used for keys forwarded from floating panel windows)
becomes the keymap's: shortcuts and forwarded_shortcuts both take their presses through the
key dispatcher and run them once the input is released. craft-keymap comes from
storytold/craft-libs, ForeignSet is built through its constructor, and the panel shortcut test
asks the docking layout which panel shows.
2026-10-25 19:36:33 +00:00
Dylan M. Taylor d607c068b1 feat: startup update prompt modal and direct self-updating
The update flow (check at start or on request, the startup prompt, the self-update worker) is craft-update's Updater; the app only supplies the suite, its close path and its status window. The check at start is opt-in for the desktop app, and the Windows update helper runs before argument parsing.

Ref: storytold/craft-libs#319
2026-10-25 15:02:26 -04:00
aiongg 5c99863f12 Merge remote-tracking branch 'upstream/main' into docking-trial
# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	apps/designcraft/src/main.rs
2026-10-25 18:18:36 +00:00
aiongg 02cb2876d2 Merge upstream main into docking-trial
Main's File Info PDF metadata gets craft-pdf's modified field (None, as before), and the
Notes panel ids use Id::unique (egui 0.37).
2026-10-25 17:52:22 +00:00
skylar taylor-barrick bd4b9dd1d2 egui-037: reconcile shared window integration with main 2026-10-25 18:34:10 +01:00
aiongg 1da1f7028b Merge designcraft#1810 (egui 0.37) into docking-trial; pin craft-libs to main a0916808 2026-10-25 17:16:25 +00:00
aiongg 56f15a600d Merge upstream main into docking-trial; pin craft-libs to main 5bbe9f62 2026-10-25 16:25:57 +00:00
Brandon Thomas a8b8b3eb62 Merge pull request #1779 from dotCooCoo/fix/automation-roots-tests-on-windows
MCP: the several-roots tests expect Windows paths without the \\?\ prefix
2026-10-25 12:25:47 -04:00
aiongg fec0897a5d Application bar: use craft-window's shared title bar (#1811)
* UI: the application bar uses craft-window's title bar

DesignCraft's title-bar code moved to craft-libs as craft_window::title_bar.
The application bar calls it instead of its own copy, and the macOS shell
takes sync_movable from it. Differences: a drag on an in-window panel lying
over the bar no longer moves the window, full screen ignores the bar's drag
and double-click, and floating panels in their own windows keep their own
movable flag.

* UI: craft-window from craft-libs main

* UI: the application bar ignores the title bar's response
2026-10-25 12:06:36 -04:00
skylartaylor 8a6ed75d41 egui037: reconcile current DesignCraft main and qualify CI 2026-10-25 03:38:13 +01:00
skylartaylor a2db858e7d egui037: Port DesignCraft to egui 0.37
Pin the final egui, winit and shared UI revisions and reconcile current main.
Preserve document-epoch input and screenshot boundaries, host action ordering,
and Windows path regression coverage. Add click/End batch characterization.

Validation: all nine Linux CI stages pass (3230 tests, zero failures); Windows
CI and bounded native editing workflows pass on the same production source.
2026-10-25 00:52:21 +02:00
skylar taylor-barrick 9fc02f8f7b Merge contributor branch codex/placed-graphic-layer-overrides (PR #1647) into main
Conflict resolutions:
- crates/pdf/src/export.rs: keep main's `graphic(.., hidden)` signature from
  #1241 and report retained graphic-layer overrides that drawing cannot apply.
- docs/gaps.md: keep main's change list and add the graphic-layer entry.
2026-10-24 15:30:03 -06:00
aiongg b3be40ed08 Merge remote-tracking branch 'upstream/main' into docking-trial
# Conflicts:
#	Cargo.toml
2026-10-24 18:46:43 +00:00
dotCooCoo bab76dcd11 MCP: the several-roots CLI test keeps a share path a share path
The test removed only the \\?\ prefix from the folder it resolved, so a
temporary folder on a network share became the relative path
UNC\server\share\... . It now removes the \\?\UNC\ prefix first and
keeps the two leading backslashes, as file_access::plain does, with a
test of both forms.
2026-10-24 10:44:08 -07:00
dotCooCoo 1f613f8c66 MCP: the several-roots tests expect Windows paths without the \\?\ prefix
Four tests from #1678 fail on Windows. Each one builds its paths, or the
text it expects, from a folder resolved with `std::fs::canonicalize`,
which adds the `\\?\` prefix on Windows. `AutomationRoots::describe` and
the rejection messages show the roots without that prefix, so the
expected text does not match. Windows does not resolve `..` in a path
with the prefix, so the checks refuse every such path as one they cannot
resolve, including the ones the tests expect to pass from one root into
another. The code the tests check is unchanged.

The engine tests take the resolved folder through `file_access::plain`,
which the roots use for the text they show. The CLI test strips the
prefix the same way.
2026-10-24 08:41:44 -07:00