Commit Graph
5431 Commits
Author SHA1 Message Date
David Mann 9e7b35b716 Integration: stack #6055 (its merge onto main, conflicts resolved) 2026-10-22 23:40:11 +02:00
David Mann c6e628afad Integration: stack #5815 (its merge onto main, conflicts resolved) 2026-10-22 23:40:10 +02:00
David Mann 8748dcbf16 Integration: stack #5598 (its merge onto main, conflicts resolved) 2026-10-22 23:40:09 +02:00
David Mann ddf1bba02f Integration: stack #5485 (its merge onto main, conflicts resolved) 2026-10-22 23:40:09 +02:00
David Mann 7546c9d60d Integration: stack #4221 (its merge onto main, conflicts resolved) 2026-10-22 23:40:09 +02:00
David MannandClaude Opus 5.5 945a10dc7c Merge PR #6055: Color panel: Photoshop's panel-menu modes, the same in every theme (#6000)
Conflicts:
- crates/ui-egui/src/i18n/{cs,de,el,es,fr,hu,id,it,ja,ko,nl,pl,pt-br,ru,sr,tr,uk,vi,zh-hans,zh-hant}.tsv: kept every key of both sides (main's block, then the PR's Color panel block); no duplicate keys.
- crates/ui-egui/src/panels.rs: took the PR's removal of color_picker/hsb_sliders/rgb_sliders (moved to color_panel_ui.rs); kept main's color_field_height doc comment; main's #5842 slider recolour tests ported to color_panel_tests.rs for the new HSB/RGB slider modes; main's black-HSB test dropped as the PR's hsb_sliders_take_values_on_black covers it.
- crates/ui-egui/src/color_panel_ui.rs (no textual conflict, adapted): set_color now goes through apply_color::foreground_changed with the gesture (was type_tool::foreground_changed), so every mode (sliders, ramp, alerts, wheel) recolours selected type/shapes tool-gated in one undo step per gesture; panel() calls apply_color::track_focus.
- crates/ui-egui/src/color_panel_tests.rs (adapted): new every_slider_mode_recolours_the_selected_shape test.
- docs/gaps.md, docs/ui-parity.md: union of both sides' status lines, rows and revision history; the PR's done row replaces the old "missing" Color panel row.
- docs/scorecard.md: generated, took b7-base's version.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:39:04 +02:00
David MannandClaude Opus 5.5 cab3ef6191 Merge PR #5815: perf(doc): share the XMP packet, Duotone PSD data and unsupported adjustment bytes between snapshots
- crates/engine/src/tests.rs: kept both tests (main's restore_layer_selection test and the PR's history_states_share_large_document_payloads).
- crates/io/src/psd_import.rs: kept main's parsed Duotone inks (duotone_map) with the PR's Arc<[u8]> psd_raw; also main's unknown-adjustment-key import (#6575) now builds Arc<[u8]> raw.
- crates/io/tests/adjust_warnings.rs: moved to tests/it/adjust_warnings.rs on main; PR's .into() edits applied there, plus #6322's Color Lookup test (raw.as_slice().into()).
- docs/architecture.md: union; status line names both changes, both revision-history rows kept.
- Adapted main-new sites to the PR's types: psd_export.rs (Duotone write-back via as_deref/to_vec, Unsupported block compare by slice), inspect.rs and ui-egui unsupported_marker_tests.rs (raw .into()), io tests/it/psd_unknown_adjustment.rs (slice compare).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:38:56 +02:00
David MannandClaude Opus 5.5 ced9aa6947 Merge PR #5598: Plug-ins: wire Enable Generator (Image Assets needs it)
docs/scorecard.md: conflict in generated file, kept ours (b7-base); regenerated later.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:38:50 +02:00
David MannandClaude Opus 5.5 f56147655d Merge PR #5485: Add opt-out startup release checks and manual update status
Conflicts resolved:
- crates/ui-egui/src/i18n/hu.tsv: kept base's Bevel & Emboss keys, then the PR's update-check keys
- crates/ui-egui/src/i18n/ru.tsv: kept base's Bevel & Emboss keys, then the PR's update-check keys
- crates/ui-egui/src/i18n/sr.tsv: kept base's added sections, then the PR's update-check keys
- crates/ui-egui/src/i18n/tr.tsv: kept base's Bevel & Emboss keys, then the PR's update-check keys
- crates/ui-egui/src/menus.rs: kept base's saved-workspace entries, then the PR's Help › Check for Updates reordering
- docs/gaps.md: base status line with the PR's G17 clause prepended; PR revision row above base's rows
- docs/target-app-parity.md: base status line (updated 2026-10-22) with the PR's clause prepended; PR revision row above base's rows
- docs/scorecard.md: generated, took b7-base's version

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:38:46 +02:00
David Mann e7c53231a5 Merge PR #8547: perf(gpu): layer pages that just miss the budget borrow the effect-map share, P60/P61 10× faster on integrated GPUs 2026-10-22 23:38:40 +02:00
David MannandClaude Opus 5.5 08f951b909 Merge PR #4221: Options bar: the same tool options in every theme (#4178)
Conflicts:
- crates/ui-egui/src/panels.rs: took b7-base's file (keeps align_bar in the Move bar and all other main changes) and re-applied the PR's change: dropped the six `if t.pro` guards (Marquee, Lasso, Paint Bucket, Perspective Crop, Crop, Move) and deleted the eight non-Pro hint/fallback arms (incl. the Studio Move arm, now covered by the Pro arm which already has Auto-Select, Show Transform Controls and align_bar); rustfmt reindent.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:38:40 +02:00
David Mann 4d6e2b08c5 Merge PR #8465: perf(camera-raw): exposure with all scopes under its 10 ms budget (P36), same output 2026-10-22 23:38:39 +02:00
David Mann 9487065314 Integration: merge main (one test binary per crate, #8644)
# Conflicts:
#	docs/file-format-parity.md
#	docs/gaps.md
#	docs/scorecard.md
#	scorecard/file_compat.toml
2026-10-22 19:55:06 +02:00
Dylan M. Taylor 6649b78526 Use chrono instead of hand-rolled UTC conversion (#8234)
* Use chrono for UTC/calendar conversion instead of hand-rolled copies

Replaces the civil_from_days copies behind the app's log timestamp, the
Measurement Log's date/time, and the perf report date with chrono as a
workspace dependency (reusing the version already in the tree). Output formats
are unchanged and pinned by the existing tests. AGENTS.md now says time goes
through chrono.

Follow-up to storytold/cadcraft#1785

* Never panic on a clock outside chrono's range; keep 5-digit years unprefixed

chrono's From<SystemTime> unwraps internally, so a clock past year 262143
panicked. logging::timestamp and analysis_cmds::now_iso now read the duration
since the epoch and go through the fallible DateTime::from_timestamp, reading
an out-of-range or pre-epoch clock as the epoch as the old saturating code
did. All three ISO helpers (timestamp, now_iso, perf::iso_utc) write the year
with {:04} rather than %Y, which prefixes a '+' past year 9999.

Tests cover the far-future and year-10000 cases for timestamp and iso_utc.

* Don't build an unrepresentable SystemTime in the far-future test

UNIX_EPOCH + Duration::from_secs(u64::MAX / 2) overflows Windows'
SystemTime and panicked before timestamp() ran, failing the Windows
test job. Build it with checked_add and only assert where it exists.

* time: preserve old out-of-range date conversion (no epoch fallback)

`DateTime::from_timestamp(...).unwrap_or_default()` silently reset any
instant past chrono's year range to 1970-01-01, changing output the old
hand-rolled Howard-Hinnant code converted exactly (e.g. 10_000_000_000_000 s
was 318857-05-20 17:46:40, not the epoch). Restore the old conversion domain
with a cycle-based helper that routes the calendar through chrono (the
calendar repeats every 400 years = 146_097 days, so month/day/time come from
chrono and only the year is carried in i128, keeping every i64 exact).

- apps/photocraft/src/logging.rs: `timestamp` via `utc_parts`; keep the
  pre-1970 epoch clamp; u64 secs past i64::MAX saturate, not epoch.
- crates/engine/src/analysis_cmds.rs: extract pure `iso_from_unix` (cycle
  based) from `now_iso` so the conversion is tested directly.
- xtask/src/perf.rs: `iso_utc` cycle-based, accepts the full u64 range the
  old code did.

Pinned old outputs in tests:
  logging u64::MAX/2 s -> 292277026596-12-04T15:30:07.000Z (was epoch),
          10_000_000_000_000 s -> 318857-05-20T17:46:40.000Z
  iso_from_unix 10_000_000_000_000 -> 318857-05-20T17:46:40Z,
          -10_000_000_000_000 -> -314918-08-13T06:13:20Z, i64 extremes
  iso_utc u64::MAX -> 584554051223-11-09T07:00:15Z (was epoch),
          10_000_000_000_000 -> 318857-05-20T17:46:40Z

* Don't build a year-318857 SystemTime unchecked in the logging test

Windows' SystemTime only reaches about year 30828, so
UNIX_EPOCH + Duration::from_secs(10_000_000_000_000) panicked before
timestamp() ran and failed the Windows test job. Build it with
checked_add and assert where the platform can hold it. The year-10000
case fits everywhere and stays unconditional.

* Name the 400-year range extension as the one exception to the time rule

The rule said never to hand-roll calendar math, but the range fix
(shifting by whole 400-year Gregorian cycles so dates past chrono's year
range keep their old output) is cycle arithmetic, so the rule and the code
disagreed. The rule now names that exception: the library still computes
month, day and time, and only whole cycles are carried in the year.

* Say the library computes month and day; time-of-day is plain arithmetic

Narrows the range-extension wording: the date library computes the
calendar fields, and splitting seconds into hours, minutes and seconds
is ordinary arithmetic, which is what the code does.
2026-10-22 13:54:10 -04:00
aiongg 46394c5976 Merge pull request #8644 from aiongg/tests-one-binary-r4
Build each crate's integration tests as one binary
2026-10-22 13:53:15 -04:00
David MannandClaude Opus 5.5 607a84de75 Integration: the Color panel gesture test picks a swatch of another colour after merging main
Main's #5568 (now in apply_color) skips a shape that already has the
picked colour. The test's last drag ends on black, the first swatch, so
that swatch click added no step. It now clicks the second swatch and
checks the foreground changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 19:26:25 +02:00
David MannandClaude Opus 5.5 f5533e5d82 Integration: merge main into batch 6
Main merged #5940, #6472, #7838 and #7922 directly. Kept from the batch:
the snapshot/History-follow identity at the history limit (#5940,
c7ef3676a; main still had the 3-tuple HistorySpot) and the strokeless
shape at a 0 px width step (#6472, 962539607; main still added the
stroke). Main already carries the other two fix-ups (34c9d0ea4, dff8bfd0e).

Overlaps with main resolved:
- #5842 vs main's #5568: one path, apply_color, tool-gated as #5842
  has it, with #5568's float fill, kept fill opacity and lock skip;
  shape_fill_ui's duplicate foreground_changed/gesture dropped; #5568's
  tests run with a shape tool.
- #6230 vs main's #5180: one Type tool path click (path_target), no
  second type.attachToPath; vertical type does not start type on a path,
  as main has it; main's path_at/path_cursor and canvas arm dropped.
- #5452 moved the shape swatch to shape_paint_ui.rs: main's hex field
  (#6201) ported there.
- type_extra_cmds::with_text takes main's dpi form, pub(crate) for
  type_area_cmds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 19:20:26 +02:00
aiongg ffa400c754 Keep tests correct and docs current with one test binary per crate
- gpu: the test modules share one GPU_LOCK, and timing and vector_mask
  take it too, so one process drives one wgpu device at a time.
- ui-egui: the wgpu tests in pattern_preview_canvas, adjust_preview_gpu,
  marquee_autoscroll and layout_perf take gpu_lock().
- affinity compound_limits: the child process selects its test by the
  module path (compound_limits::<name>); with --exact, the bare name
  matches no test and the child passes without running the check.
- xtask scorecard reads crates/io/tests/it/corpus.rs.
- Docs and comments name the new test paths and the --test it filters.
2026-10-22 16:55:34 +00:00
aiongg a6428d3dfb Build each crate's integration tests as one binary
Every tests/*.rs file is its own executable that links the whole crate
graph. Move each crate's test files into tests/it/ as modules of one
tests/it/main.rs; helper modules under tests/common move with them.

These keep their own binary (own process):
- engine panic_hunt: a process-wide panic hook counts every panic.
- engine text_gamma: changes the process-wide text gamma.
- engine smart_filter_stages, mask_cache_purge: assert on global caches.
- codecs pnm_peak_memory: reads the process's peak RSS.
- photocraft mac_menu_appkit: harness = false.
2026-10-22 16:55:34 +00:00
aiongg 6d807ba34c Merge pull request #8577 from aiongg/r4
Backlog batch: 271 reviewed contributor PRs
2026-10-22 12:53:31 -04:00
aiongg fa010ff7c3 Integration: regenerate docs/scorecard.md 2026-10-22 16:03:31 +00:00
aiongg 1370c7a642 Integration: #7811 cargo fmt on process_outputs 2026-10-22 15:47:53 +00:00
6d3092f243 Integration: merge main, resolve conflicts, JPEG Options docs and encoder test (#7883)
Merges main (8f09d122d). Conflicts: the replay_save doc comment (main added
file.export.exportAs replay) and the status lines and history rows of
docs/file-format-parity.md and docs/gaps.md; both sides kept.

The docs called FILE-215-19 done and said only Save As and Save a Copy ask.
Photoshop's JPEG Options also has Matte, the progressive scan count
(Scans 3-5) and the size preview, none of which is offered, and Baseline
Optimized writes the same file as Baseline for RGB (4:2:0). The row is now
partial with those gaps named, and the docs say File > Save asks too.
docs/scorecard.md is regenerated.

Adds jpeg_options_ui::tests::the_answer_reaches_the_encoder. Every UI test
used a fake exporter, so dropping `opts.encode.jpeg_format` from
ExportSettings::io_options (the desktop and web save path) left them all
green; this test writes a real JPEG through io_options and fails without it.

Co-authored-by: Michael Higgins <55243596+Higgs32584@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:45:30 +00:00
a74b9a72a1 Integration: merge main, resolve conflicts (#6793)
The 20 i18n catalogs: main and the PR both appended a block at the end;
both kept, main's first. docs/gaps.md: main's text with the PR's
TYPE-218-2 change applied (G8 Missing, Evidence 5 done / 4 partial /
0 missing, revision row), dated 2026-10-22. docs/scorecard.md
regenerated with cargo xtask scorecard.

The TYPE-218-2 note now also says PSD doesn't store the paragraph
direction (crates/text psd.rs maps only the vertical WritingDirection),
so a direction set with the new buttons reopens from a PSD as Auto.

docs/localization-parity.md: the Arabic row said paragraph direction has
no UI (TYPE-218-2); it now has the buttons, the RTL caret is still missing.

Co-authored-by: tareqziad1998 <83318513+tareqziad1998@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:44:17 +00:00
a2a6f1e13f Integration: Zoom Resizes Windows shows the whole image, clear of the scrollbars (#7662)
A Zoom tool click or wheel zoom keeps the clicked spot under the pointer, so
the view centre moves off the image's middle. The window then grew to the
image's size around that off-centre view: a 400x300 image zoomed to 200% about
(50, 50) showed grey on the left and top and lost its right and bottom edges.
The size also left out the 12 pt scrollbars, which are drawn over the canvas
and hid the image's right and bottom edges.

The window now makes room for the scrollbars, and a window that grows around
the whole image centres it in the area the scrollbars leave free (any flip,
rotation, pixel aspect and display scale). A window the screen caps keeps the
zoomed spot where it is. Scrubby zoom and the Animated Zoom hold re-anchor the
view only when the zoom changes, so their release frame and the frames at the
zoom limit keep that centred view. A maximized or full-screen window keeps the
size the user gave it.

Co-authored-by: Nguyễn Minh Long <181250616+KLBMinhLong@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:42:54 +00:00
893b54ea8c Integration: keep the font menu's arrows walking with recent fonts (#3559)
Each arrow step in the open font menu applies its family, the options bar,
Character and Glyphs panels record it as the most recent font, and the next
frame hoisted it to row 0: with Recent Fonts on (default 10), Down then
alternated between two families and Up stayed on the first row (CodeRabbit's
open thread on #3559). The menu now keeps the recent group it opened with.

As in Photoshop, the recent families now head the menu in their own group
above a divider and keep their alphabetical place below it, instead of
moving out of it. The arrows start from the current family's alphabetical
copy (or the row the last arrow chose), and only that row is marked.

Tests: open_menu_arrows_walk_on_through_recent_fonts,
options_bar_menu_arrows_walk_on_while_recording_recent_fonts and
open_menu_on_a_recent_font_steps_through_the_alphabet fail without the
fix; recent_fonts_appear_first_in_the_menu pins the group, divider and
alphabetical copies.

Co-authored-by: Reynold Hu <88558425+reynold-hu@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:42:42 +00:00
81925d7769 Integration: Raw Defaults resolution on Revert, Batch, Stack, headless open and CLI convert (#7811)
The resolution preference reached File › Open, but the other ways a raw
becomes a document of its own still opened it at 72 ppi: File › Revert
(a raw opened at 240 dropped to 72), Batch / Image Processor / Lens
Correction batch (a raw saved as PSD came out at 72 while Open + Save
gave 240), Load Files into Stack, the headless MCP `doc.open`, and the
CLI (`convert` at 72 while `run`/`info`, which open headless, now take
the default 300). They now apply the same `raw_defaults` rule; Batch
passes the user's value into its scratch sessions.

Tests that fail without this change (72 vs 240/300):
revert_batch_and_stack_open_a_raw_at_the_raw_defaults_resolution
(engine, one assertion per path), doc_open_gives_a_raw_the_raw_defaults_resolution
(automation), convert_opens_a_raw_at_the_raw_defaults_resolution (CLI).

Co-authored-by: Korg1ch <57859048+Korg1ch@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:42:42 +00:00
b526378de4 Integration: 32-bit Hue/Saturation with Photoshop's saturation factor, finite at lightness 1 (#5781)
The 32-bit branch cut the slider to floor(|s| * 255) / 255, which only matches
Photoshop near 25 and 50 %: measured at every whole percent from -100 to +100
on a 32-bit document, Photoshop lowers by 1 - floor(|s| * 256) / 256 and raises
by 255 / (255 - floor(s * 254)) taken to 1/256 and capped at 32767/256 (201 of
201 exact). +100 gave 512x where Photoshop gives 128x, +90 9.8x for 9.44x.

It also kept the HSL saturation unclipped, which is inf at HSL lightness 1 and
0 and negative above 1: (2, 0, 0), red at +1 stop, turned NaN with any edit,
Hue +40 alone included, where Photoshop gives (2, 1.333, 0). The 32-bit branch
now scales the chroma around the lightness instead (same result in gamut),
on the CPU and in the shader, in whole numbers on both. Colorize clamps its
saturation before the 32-bit scaling, so a PSD's out-of-range value renders
the same on the GPU.

Tests (fail without this): thirty_two_bit_saturation_steps_match_photoshop,
thirty_two_bit_hue_saturation_keeps_bright_colours, the GPU parity
hdr_hue_saturation_bright_colours. Photoshop-oracle floor 188 -> 190 of 258,
measured after merging main.

Co-authored-by: Timothy Daly <100327160+timothydaly1@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:42:03 +00:00
f1d947de8a Integration: test that a and b round after the opacity mix (#5771)
The PR's test checks L at full opacity only, so it still passes when a and b are left unrounded or
the rounding moves before the opacity mix, or truncates. New test: Curves taking a 140 to 151.4 at
50% opacity in an 8-bit Lab document must show a 146 (145.7 unrounded, 145.5 rounded before the
mix, 145 truncated: all three fail).

Co-authored-by: timothydaly1 <100327160+timothydaly1@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:41:21 +00:00
dff8bfd0e4 Integration: a unit per field, no Percent, not remembered, as in Photoshop (#7922)
Photoshop's Create Rectangle switches only the right-clicked field
(Width 35.28 mm, Height still 100 px), lists the six length units
without Percent, and opens in pixels again after OK. The PR shared one
unit between both fields, offered Percent, and saved the unit on every
OK, so after one use with the rulers in px the dialog stayed in px even
after the rulers changed to cm, though no unit was ever picked.

Now each field has its own widthUnit / heightUnit (set only by the
menu, never remembered), and the menu is rulers::unit_menu_of with
LENGTH_UNITS. The new test right-clicks the real field and clicks the
menu item through egui input.

Co-authored-by: Korg1ch <57859048+Korg1ch@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:41:21 +00:00
34c9d0ea4d Integration: History follows the history, not every revision, and never moves a visible row (#5940)
The panel scrolled with `scroll_to_rect(current, Some(Align::BOTTOM))` on every revision
change. In egui an explicit alignment always realigns, and the revision also changes when
nothing in the history does (selecting a layer, a channel eye). So clicking a visible older
state slid it to the bottom under the pointer, Undo hid the greyed redo states, a layer click
threw a user who had scrolled up back to the bottom, and selecting a snapshot scrolled it out
of view.

Now the panel follows the history position (document, past/redo counts, current name, and the
newest past state, which also changes at the state limit), skips it while a snapshot is
selected, and scrolls without alignment, so only a hidden current row moves into view. New
tests: a clicked visible state stays put, Undo keeps the redo state in view, a layer click keeps
the scroll, a selected snapshot stays in view, a new state at the limit is revealed; the first
three fail on the PR head, the others without the snapshot guard / the newest-state key.

Co-authored-by: nrq6993-a11y <342501791+nrq6993-a11y@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:41:21 +00:00
aiongg 64fb74f1e7 Integration: #8143 the branchless floor test accepts any NaN for NaN inputs
MSVC's floor quiets a signalling NaN while branchless_floor keeps its payload, so the Windows job failed the bitwise compare; every other input still compares bit for bit.
2026-10-22 15:40:11 +00:00
aiongg 753b910f5d Merge PR #5988: Raw: a Nikon maker note's ColorSpace sets the preview colour space (#5987) (new head, a rebase of the merged one; its changes are already in) 2026-10-22 15:40:10 +00:00
aiongg 884ea76691 Merge PR #5980: Raw: the Nikon D4 white level follows the sample depth (#5978) (new head, a rebase of the merged one; its changes are already in) 2026-10-22 15:40:09 +00:00
aiongg 22d912a108 Integration: #8142 #8535 Quick Export accepts a .exr path
Main's extension check (#8519) refused .exr, the format #8142 adds to Export Preferences; the path's extension now may also name EXR.
2026-10-22 15:40:08 +00:00
aiongg add0fbc706 Integration: merge main (through #8562)
contributors/people.toml: kept both sides' new entries (r4's list and main's benandez).
2026-10-22 15:40:05 +00:00
aiongg 4819f5b7d4 Merge PR #8372: Compose: effect maps that don't fit in the effect cache are built over the render rect, not rebuilt whole on every render (#8330) (new head) 2026-10-22 15:40:02 +00:00
aiongg 9cba44307d Merge PR #8236: Add interactive drag positioning to print preview (new head)
crates/ui-egui/src/file_ui.rs: kept r4's print_params and added the new head's doc comment on print_confirm.
2026-10-22 15:40:00 +00:00
aiongg 4a9034a762 Merge PR #8168: File names: keep Windows device names (nul, con, com1…) off the disk (new head)
The new head only merges main; crates/engine/src/file_cmds/tests.rs conflicted on the sanitize test's position, kept r4's single copy.
2026-10-22 15:39:57 +00:00
aiongg eb199bcefe Merge PR #7721: fix(actions): refuse lossy fractional Crystallize ATN export (new head) 2026-10-22 15:39:55 +00:00
aiongg fb05540774 Merge PR #6452: Hand tool: hold Ctrl/Cmd to zoom in, Alt to zoom out (#6434) (new head) 2026-10-22 15:39:53 +00:00
aiongg 934eb71d84 Integration: merge main
crates/engine/src/file_cmds.rs: batch keeps the save-point closure (takes the output path) and also copies the session's authorize hook into each scratch session, as main now does.
crates/raw/src/sensor.rs: both sides cap the memory of retained tiles; kept the existing retained_segment_bytes check (checked multiplication, same limit) and dropped main's duplicate inline loop.
2026-10-22 15:39:51 +00:00
aiongg f618cdea29 Integration: #8371 the .atn corpus round trip merges the per-property Sets that Save now writes 2026-10-22 15:39:49 +00:00
aiongg e6f7af8ce7 Integration: #5566 the panel-defaults harness waits for the font scan 2026-10-22 15:39:47 +00:00
aiongg af12584f47 Integration: #6974 depth labels and delete-layer prompt in hi.tsv 2026-10-22 15:39:45 +00:00
aiongg dc6fe754a8 Integration: #6186 New Layer during a background transform commit expects main's refusal, then retries 2026-10-22 15:39:42 +00:00
aiongg dd2cba6e81 Integration: #7325 #6452 Command-click under Curves adds its point with the Hand tool, not a Hand-tool zoom 2026-10-22 15:39:40 +00:00
aiongg fafbb4bbdf Integration: #7388 #6936 the Crop popup key tests make the ratio-fitted frame a drawn one first 2026-10-22 15:39:38 +00:00
aiongg 63de4df31b Integration: #8030 #5571 the group indent test opens the group, which Group Layers creates collapsed 2026-10-22 15:39:36 +00:00
aiongg f905c72434 Integration: #8162 #7256 the Brushes tab test waits for the window to settle after the preview-size slider row 2026-10-22 15:39:34 +00:00