Commit Graph
6292 Commits
Author SHA1 Message Date
Dylan M. Taylor fa0c7cb891 test(optimize): restore the file around the appended tests 2026-11-10 21:36:52 -05:00
Dylan M. Taylor ba0812fd87 fix(optimize): walk shared resource dictionaries and name-tree kids once 2026-11-10 21:36:52 -05:00
Dylan M. Taylor d2916decb3 packaging: use [[ for bash tests (SonarCloud S7688) (#6932)
Behaviour-preserving: `[[ ]]` in place of `[ ]` for bash tests (SonarCloud shell:S7688). Every script has a bash shebang; no test uses `-a`/`-o`, escaped parentheses or an unquoted pattern on the right of `=`. `bash -n` passes on each script; the rest is left to CI.

- `packaging/freebsd/package.sh`
2026-11-10 19:19:40 -05:00
Dylan M. Taylor 25f3f5429c fix(cos): remove duplicate decoded_strict_within that broke main after #6046 (#6934) 2026-11-10 19:08:05 -05:00
Dylan M. Taylor 9345b5caaa cos: drop the second decoded_strict_within that #6046 merged in (#6933)
main fails to compile (E0592): the merge of #6046 added Stream::decoded_strict_within next to the one already there. Both decode the whole chain bounded by max and map the error to CosError::Filter; the earlier one stays, with #6046's test.
2026-11-10 18:54:55 -05:00
Dylan M. Taylor ad3e6d4b85 fix(optimize): bound each unused-resource decode by the remaining shared budget (#6046) 2026-11-10 17:53:58 -05:00
Harrison BoothandFredApps 832a51e6d7 Fix #5211: persist JavaScript field colours (#5499)
* Fix #5211: persist JavaScript field colours

* Read current document state in field scripts

* Redraw form fields after validation changes

* Format validation redraw regression test

* Keep field list alive in redraw test

* Refresh fields only after same-field scripts

* Format conditional field refresh

* Borrow accepted field value for storage

* Redraw calculated fields from current appearance

* Format JavaScript field state merge

* Restore JavaScript runner document state

* Group JavaScript runner form inputs

* Read current field display state in scripts

---------

Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-10 23:43:44 +01:00
Harrison BoothandFredApps d0b17ef95f Add JavaScript push-button caption methods (#5505)
* Add push-button caption script methods

* Apply scripted caption with other field changes

* Complete caption field property initializers

* Apply scripted captions to every button widget

* Format caption regression test

* Cover caption getter errors and redo state

* Assert button caption undo state

* Reject button caption writes during format events

* Test empty push-button captions

* Validate push-button caption updates

* Keep no-widget caption test data alive

* Check caption clipping marker

---------

Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-10 23:21:48 +01:00
FredApps 3ad707d07b Test: wait for the paper row before clicking Custom… while discovery is pending (#6925)
adding_custom_paper_overrides_pending_driver_default clicked Custom… as soon as the background
paper read started; on hosted macOS the dialog hadn't drawn its paper row by then and the test
failed (no node "Custom…"). It now waits for the button, up to 10 s, before clicking. Found by the
first nightly macOS run.
2026-11-10 23:14:40 +01:00
Harrison BoothandFredApps c73a53705b Fix #5211: make calculateNow synchronous (#5304)
* Fix #5211: make calculateNow synchronous

* Bound and cache calculation execution

* fix(engine): invalidate field calculation cache

* perf(js): build calculation scripts lazily

* Refresh calculation cache after page insertion

* Load calculations for document script helpers

* Assert imported calculation result

* Initialize formatted field-change state

* Update formatted calculation test expectations

* Include the referenced field in calculation test

---------

Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-10 22:48:50 +01:00
FredApps 1be1cfa6ed CI: the workspace's tests on macOS each night (and on demand) (#6921)
Pull requests and main run Linux and Windows only; release.yml builds and signs the macOS app
without running the tests, so macOS-only failures went unseen. On 10 Nov 2026 a hand-started run
found three (two print tests and a bates test, fixed in #6905 and #6913) plus one more
(min_window, fixed separately). One macos-latest leg a night, through the shared gate.
2026-11-10 22:13:16 +01:00
FredApps 85987baef0 Test: at the minimum width on macOS the main menu may be the folded Menu button (#6920)
The menu bar folds titles that don't fit into "⋯", or all of them into one "Menu" when not even
the first fits. On hosted macOS, at MIN_WINDOW_SIZE, the bar is the Menu button (the system font is
wider), so the test's File menu item wasn't there and it failed; the main menu is still reachable.
A real macOS window uses the native menu bar.
2026-11-10 21:51:38 +01:00
Harrison BoothandFredApps 3df6be4eff feat(js): expose document page boxes (#5501)
* feat(js): expose document page boxes

* Normalize page boxes for getPageBox

* Correct page box test expectations and formatting

* Use local page helper in box test

---------

Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-10 21:37:10 +01:00
Yusuf MANTAM 1fc9501cf3 fix(platform): preserve file visibility when saving replaced files (#5001) (#5048) 2026-11-10 21:01:27 +01:00
FredApps b10f85262c Test: the non-UTF-8 output-name probe test doesn't run on macOS (#6913)
output_probe_paths_preserve_non_utf8_names creates files named with bytes that aren't UTF-8.
APFS keeps only UTF-8 file names, so on macOS creating the probe fails before the check runs and
the test fails; no output can have such a name there. It runs on the other unix systems as before.
Found running the automation tests on hosted macOS.
2026-11-10 20:57:08 +01:00
Perchenko Anton d47adeff89 M4: bind property drafts with edit-session and replay UI scenarios (#4594)
Binds Properties dialog drafts to the vendored edit-session crate (byte-identical to PerchAnton/edit-session@033f7c3a, ledger in vendor/README) and adds replayable UI scenarios. Includes a merge of main and a test covering the clean Properties inspection-tab live refresh.
2026-11-10 20:22:58 +01:00
FredApps 8e6ec925c8 macOS: a job that names no paper tray asks for Auto Select (craft-print 1ee01a4c, #3752) (#6905)
* macOS: a job that names no paper tray asks for Auto Select (craft-print 1ee01a4c, #3752)

craft-print 1ee01a4c (storytold/craft-libs#232) sends `AP_D_InputSlot=` on macOS for a job whose
options name no tray, as the system Print dialog's Paper Feed: Auto Select does. Without it CUPS
used the PPD's default tray, and a printer whose default tray is empty held every job while CUPS
reported it completed (the Xerox AltaLink in #3752).

- The Print dialog's driver options take the queue's defaults through craft-print's
  apply_queue_defaults: option and choice names match as CUPS matches them, and on macOS the
  paper tray starts on Auto Select, which is what the job sends.
- The two tests that pin the exact `lp` arguments expect the Auto Select option on macOS.

* Tests: on macOS a CUPS queue on its driver's default tray shows Auto Select (craft-libs#232)

instances_read_the_queue_ppd_and_their_own_defaults and
a_queue_that_never_answers_is_given_up_at_the_deadline expected the PPD's default tray; on macOS
apply_queue_defaults now offers Auto Select first and as the default there, which is what a job
naming no tray sends. Found by running the print tests on hosted macOS.
2026-11-10 20:17:41 +01:00
FredApps 0bffa42fc5 Merge pull request #6889 from Combiler01/fix/continuous-scrolling-default-6780
fix: Continuous Scrolling toggle not working in Preference tab (#6780)
2026-11-10 20:05:21 +01:00
FredApps b16cd32659 Print: a printer's remembered paper wins over its driver's default paper (#6906)
#5861 (#6100) reads the chosen printer's papers and default paper in the background, and the
default replaces the dialog's paper unless it was chosen in the dialog (paper_overridden). The
paper a printer's setup restores (#2001, #6779) didn't count as chosen, so on Windows the driver's
default replaced it each time the dialog opened: an office printer last printed on A3 came back
on A4.

apply_setup now marks the paper it restores as chosen. A test drives the dialog with a printer
remembered on A3 whose driver's default is A4.
2026-11-10 20:03:14 +01:00
Harsh Verma 572ee68cb2 Merge branch 'storytold:main' into fix/continuous-scrolling-default-6780 2026-11-11 00:01:24 +05:30
Combiler01 ef18d60cb8 fix(ui): update only changed display fields when defaults preference is already active 2026-11-10 23:23:53 +05:30
Combiler01 91e54eeb37 fix(ui): preserve presentation display state when applying preferences 2026-11-10 23:08:08 +05:30
Kyle KassenandFredApps 92b965dba3 M10: preserve annotation layers in vector print output (#5019)
* M10: preserve annotation layers in vector printing (#5005)

* #5019 test: a Popup is the annotation that never prints; a Link prints since #5028

---------

Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-10 18:26:50 +01:00
FredApps 655aa92b5e Merge pull request #6100 from Combiler01/fix/paper-size-driver-5861
fix(print): auto-detect printer paper size and add page setup sync (fixes #5861)
2026-11-10 18:18:09 +01:00
FredApps e03d5a1c29 Render: an isolated CMYK group of any size blends in CMYK, in bands (#6885)
* Render: an isolated CMYK group of any size blends in CMYK, in bands

hayro patch (27) blended an isolated DeviceCMYK transparency group in CMYK only up to 2^24
device pixels (a 4096 x 4096 square); a larger one was blended in RGB. Print as image renders a
whole page at once, up to 8192 px on the long side, so a page enlarged to 11 x 17 in at 600 dpi
(about 43 MP) blended any group covering most of it in RGB, and a print test file's CMYK blend
patches drew their X's. The same applied to exporting a large page as an image.

A larger group is now blended in bands of whole rows, each within the old limit: both ink passes
and the tint conversion run per band, so their memory stays as before, and only the finished
group (4 bytes a pixel) is kept whole. Every band is blended before any is drawn, so a group a
pass has no tints for is still drawn as before, whole.

The regression test lowers the band to 7 rows (set_cmyk_band_pixels, hidden, per thread like
set_skip_offscreen_paths) and checks the banded group matches the whole one across an
anti-aliased edge, and is CMYK's green where magenta is under black with Difference.

* Test: CMYK green through the profile is (0, 166, 81); check green against RGB's magenta
2026-11-10 18:11:33 +01:00
Combiler01 6b51ed655a Merge remote-tracking branch 'upstream/main' into fix/continuous-scrolling-default-6780 2026-11-10 22:20:38 +05:30
8559306f77 Do not send duplex to printers without two-sided support (#6673)
On Windows the printer list reports whether a driver supports two-sided printing, but the job still asked for it anyway, so duplex jobs printed single-sided or misaligned on printers such as the reported Brother model.

Leave duplex unset for a printer reported as not two-sided, so that printer keeps its own setting, while printers that support two-sided or report no capability keep the chosen setting.

Test: duplex_is_not_sent_to_a_printer_without_two_sided failed before the change and passes after.

Co-authored-by: eliets2 <287273517+eliets2@users.noreply.github.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-10 17:48:48 +01:00
FredApps 1c1a5d746e Merge main and retain grayscale spooler conversion 2026-11-10 17:42:46 +01:00
Combiler01 9ec3c48f84 fix(ui): preserve viewport anchor on gaps change and guard set_fit 2026-11-10 22:06:54 +05:30
FredApps 6748830620 test(print): assert idle prerequisites before testing worker wake 2026-11-10 17:36:40 +01:00
FredApps 4bbfd51718 test(print): isolate the options worker wake from printer discovery 2026-11-10 17:35:24 +01:00
FredApps fe70ecce73 Print in grayscale prints on a Windows driver with no grey option (#5806) (#6863)
* Print in grayscale prints on a Windows driver with no grey option (#5806)

Windows refused Print in grayscale ("the printer's driver did not retain the requested
grayscale; nothing was sent") on drivers that list no grey option the ticket can name:
Microsoft Print to PDF, and an HP Photosmart driver whose grey is its own vendor setting.

- On Windows, a grayscale job's copy for the spooler is made grey first with Convert colours
  (all pages, comments and form fields, black kept black, pictures re-encoded where they can
  be), and the job says so (Job::grey_pages). The driver is still asked for grey where it has
  it; one without prints the grey pages instead of refusing them. A copy that can't be read
  goes as it is and asks the driver strictly, as before.
- craft-print 970644b7 (storytold/craft-libs#774) adds Job::grey_pages and asks a driver that
  lists only psk:Grayscale for that, not psk:Monochrome.
- Both the Print dialog and doc_print go through spooler_copy, which now takes the job.

* craft-print 1146cdc4: craft-libs main with #774 (grey pages) and #773 (the CUPS printer list waits at most 15 s, storytold/pdfcraft#6761)
2026-11-10 17:31:12 +01:00
Combiler01 ac46a4a26c fix(ui): handle Fit::None with set_zoom in preferences fit_changed 2026-11-10 21:41:18 +05:30
Kyle KassenandFredApps 919db9bd51 M10: preserve NoRotate appearance geometry in vector printing (#5036)
* M10: preserve annotation placement precision (#4995)

* M10: preserve NoRotate and implicit Text print orientation (#5029)

Keep existing printable appearances upright on rotated source pages, including Text annotations whose NoRotate flag is clear.
Preserve original flags and appearance streams, print eligibility and outer page transforms.

* M10: clarify NoRotate verification docs

---------

Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-10 17:04:04 +01:00
FredApps eaff44e4d7 Merge main and retain one printer for paper and duplex discovery 2026-11-10 16:45:09 +01:00
FredApps 257c026c8a fix(print): guard paper discovery and retain explicit custom stock 2026-11-10 16:42:49 +01:00
6cded6a5a3 M10: a booklet's both sides follow a driver that keeps its own two-sided setting (#5772) (#5903)
* M10: a booklet's both sides follow a driver that keeps its own two-sided setting (#5772)

Booklet ▸ Both sides always asked for two-sided printing on the short
edge (#2707). A driver that doesn't take two-sided settings from other
programs (no two-sided printing, manual two-sided only in its
Properties, Microsoft Print to PDF) then made craft-print refuse the
whole job. The reporter's Epson ET-2870 offers only OneSided, and its
manual two-sided setting is what prints their normal two-sided jobs.

print::booklet_job_duplex asks such a driver for nothing on both
sides, so its own setting applies, as for ordinary printing (#2422)
and as Acrobat enables two-sided for a booklet only "if available".
Unknown support still asks for the short edge; one side on its own
stays one-sided. The Print dialog takes the chosen printer's support
from the printer list (PrintDraft::printer_two_sided, also behind its
"its own setting applies" note), and doc_print reads it only for a
booklet's both sides.

The dialog's booklet test used the machine's printers, and on Windows
the default, Microsoft Print to PDF, now gives the other answer: it
sets its own printers and checks the note too.

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

* M10: doc_print's lookup of a booklet printer's two-sided support is tested (#5772)

The booklet test fed job_duplex the printer's answer directly, so a
lookup that missed the default printer or matched the wrong one would
have gone unnoticed. The search over the printer list is now its own
function, two_sided_in, tested with a list of named, default and
unknown printers.

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

* M10: a booklet printed to "default" goes to the printer whose driver was asked (#5772)

doc_print decides a booklet's both sides from the printer's two-sided
support. For "default", the job named no printer, so the spooler picked
whichever printer was the default when the job was submitted, after the
document was rendered. The printer found in the list is now the job's
printer, by name, and the lookup test covers a one-sided default.

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

* #5903: the booklet test lists its printers through a stand-in source

It set the dialog's printer list by hand while the real list was still loading. On a machine with
no printers (CI's Linux runner) the list that arrived replaced them and reset the printer, so the
dialog the test clicked through was not the one it set up. The printers now come from the
dialog's own source, drivers unasked as #3554 lists them, with each driver's two-sided answer in
the map.

---------

Co-authored-by: austin62jake <340374338+austin62jake@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-10 16:34:48 +01:00
Combiler01 4f16190e52 fix(ui): apply continuous scrolling and view defaults to active and remembered documents (#6780) 2026-11-10 21:01:34 +05:30
0e4b9171c0 fix(ui-egui): keep hotbar picker stationary while resizing (#6513)
* fix(ui-egui): keep hotbar picker stationary while resizing

* fix(ui-egui): keep hotbar picker pinned during keyboard resize

Pin the Hotbar tools picker while the Toolbar size slider is adjusted with the arrow keys, until the slider loses focus. Widen the regression test to both drag directions and every layout, add a keyboard test, and document the new helpers.

* fix(ui-egui): closing the hotbar picker ends a size adjustment

close_picker() also clears picker_drag_pos and keyboard_sizing. Main's
close_hidden_picker() closes the picker on passes that don't draw the
hotbar, where show() can't clear them, and the next opening would start
at the held position. Adds closing_the_picker_ends_a_size_adjustment, a
doc comment for picker_drag_pos, and says "picker" where the comment
meant it.

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

---------

Co-authored-by: FredApps <FredApps@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 16:24:33 +01:00
3bcaacc272 fix(print): keep the localized reset label off the properties panel title (#5550)
* fix(print): keep the localized reset label off the properties panel title

The header of Print ▸ Properties… laid the title out first and gave what
was left of the row to Done and Reset. When the translated "Reset to
printer defaults" needs more room than that, egui keeps placing the two
buttons from the right edge of the child leftwards and paints them back
over the title: in Italian the label is 51 characters against 25 in
English, and both strings end up unreadable (#5545).

Laid out with egui::Sides::shrink_left().truncate instead: the buttons
take their room first and the title takes what is left of the row, cut
with an ellipsis. Nothing moves in English, where the title still fits.

* test(print): pin the header against every catalog and the title's tooltip

The geometry tests behind #5545 tried English, Italian and German at four
widths. They now walk every catalogued language at the row the settings column
really gives the header (470 px less the frame's 10 px margins), so the longest
translation of "Reset to printer defaults" is covered by the run instead of by a
guess at which locale is the worst one.

Two more tests: hovering the elided title opens a tooltip with the full string,
while a title that fits whole opens none; and a row too narrow to give the title
even an ellipsis leaves it out instead of painting it back over the buttons.

That last case is why driver_options_header returns Option<Response>. Bulgarian
(370 px of button), Spanish (365) and Ukrainian (361) fill the row with the two
buttons alone at 450 px: the ellipsis is 12.4 px wide and the clearance was
0.1 px, so a pixel less and the label was painted over the buttons again.

---------

Co-authored-by: Jarvis (Hermes) <jarvis@localhost>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-10 16:19:34 +01:00
FredAppsandKyle Kassen afca38ad71 M10: retain printed artwork with indirect annotation metadata (lands #4668) (#6855)
* M10: retain printed artwork with indirect annotation rectangles

* M10: resolve indirect annotation appearance states when printing

* M10: follow bounded annotation reference chains when printing

---------

Co-authored-by: Kyle Kassen <85040622+KyleKassen@users.noreply.github.com>
2026-11-10 16:05:43 +01:00
905e9abf6f fix(forms): ignore print requests from automatic field scripts (#4166)
* fix(forms): ignore print requests from automatic field scripts

* docs(contributors): opt in to GitHub profile name sync

---------

Co-authored-by: enriquemelzer-bit <319226743+enriquemelzer-bit@users.noreply.github.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-10 15:50:16 +01:00
Harsh Verma de24a4ddba Merge branch 'storytold:main' into fix/paper-size-driver-5861 2026-11-10 19:58:34 +05:30
Kyle KassenandFredApps debb826f29 M10: preserve annotation placement precision (#4995) (#5002)
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-10 15:17:15 +01:00
Combiler01 1427a114e5 Merge remote-tracking branch 'upstream/main' into fix/paper-size-driver-5861 2026-11-10 18:56:42 +05:30
Combiler01 ebc9de101b Merge remote-tracking branch 'upstream/main' into fix/paper-size-driver-5861 2026-11-10 18:46:05 +05:30
BFlat 1a159c57fc Merge pull request #6820 from storytold/merge/print-snapshot-area-2491
Print a selected area from Take a Snapshot (lands #2491)
2026-11-10 19:58:04 +07:00
BFlat 4ddf52ef90 Merge pull request #6824 from storytold/merge/egui-725a39fc-6699
Bump storytold/egui to 725a39fc (lands #6699)
2026-11-10 19:23:37 +07:00
huppifluppandFredApps 8864903795 M10: Recognize text no longer clips the first and last letters of a line (#5058)
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-10 19:23:21 +07:00
KiwiKwiandBabaKush 4a83ec87f5 fix(annot): drop Apple Markup's stale copy when a page's annotations change (#2829)
iOS Markup keeps a private copy of a page's markup (/AAPL:PPK, /AAPL:PPKHash on the page,
/AAPL:AKExtras on each annotation) and draws from it. Once /Annots changes, that copy is stale:
iOS 26 drew a Markup signature twice. Adding, deleting or answering a comment now drops the copy,
records the drop in the repair log, and leaves a refused edit untouched.

The change lives in lookup.rs (change_annots), called from create.rs (add) and modify.rs (delete,
reply, mark). Each of the four operations has a regression test on an Apple Markup page.

Co-authored-by: BabaKush <101988920+BabaKush@users.noreply.github.com>
2026-11-10 12:38:55 +01:00