Commit Graph
321 Commits
Author SHA1 Message Date
Livio OswaldandClaude eafe9e2c0b M8: typing the last page of a range keeps what is typed (#5574) (#5579)
* M8: typing the last page of a range keeps what is typed (#5574)

The page-range dialogs (Redact pages, Rotate pages, Duplicate field,
Number pages) raised the end to the start on every frame, so the
half-typed "1" of "12" became the start before the "2" arrived.
The end is now ordered only once its field is no longer being typed
into. Number pages no longer lowers the start to a half-typed end, and
its preview cannot underflow while the end is below the start.

* M8: a test types the last page of Rotate Pages' range (#5574)

Rotate Pages' From and to fields are labelled, and a test types "12" after a
first page of 5 (pages 5-12 are turned) and "3" left by clicking OK (page 5
alone), as croquete1 asked on #5579.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GbuSKAS2k5248LGFEapMUR

* M8: page ranges stay typed while the window is in the background, and OK orders them (#5574)

Review follow-up. The end field's typing check used Response::has_focus,
which is false while another window is in front, so switching apps
halfway through "12" still raised the typed "1" to the start. It now
asks egui's memory (widgets::typing_into). OK pressed while the end is
still focused (a screen reader's click) orders the range first in Rotate
pages, Duplicate field and Redact pages, and Number pages builds its edit
from the ordered end, so a reversed range never reaches the edit.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-11-01 15:05:01 -05:00
Livio OswaldandClaude Opus 5.5 901050a31f M14: the comments panel lays out only the cards in view (#5488) (#5583)
* M14: the comments panel lays out only the cards in view (#5488)

With more than 100 comments, a card or page header out of view that
was measured at the current width only takes up its height instead of
being laid out every frame. The selected card is always drawn, so it
still scrolls itself into view. Shorter lists are laid out whole and
keep every card in the accessibility tree.

The 500-comment panel in tests/perf.rs drops from about 23 ms to 5 ms
per frame locally, well inside the 40 ms budget it overran on CI.

* M14: the comments panel measures a card again when it changes (#5488)

A card's kept height is now per document and per what the card shows (its
thread's text, author, date, status, colour and lock, and whether it is the
selected card), so another document at the same width, an edit, an undo or a
redo never lays the cards below it out at a stale height (CodeRabbit on #5583).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GbuSKAS2k5248LGFEapMUR

* M14: a comment card with an editor open is never skipped (#5488)

A card with an inline editor open on it or on one of its replies is laid out
wherever it is, and its kept height is apart from the one without the editor,
so the cards below make room for the editor (CodeRabbit on #5583).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GbuSKAS2k5248LGFEapMUR

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-11-01 15:04:57 -05:00
Livio OswaldandClaude Opus 5.5 2242eb322f M10: Create ▸ Blank page uses the system region's paper (#5644) (#5651)
* M10: Create ▸ Blank page uses the system region's paper (#5644)

A new blank document was always US Letter. It now takes the paper of the
system region: Windows' own Region paper size (iPaperSize) first, then the
system locale on macOS or LC_ALL/LC_PAPER/LANG, A4 everywhere outside CLDR's
US-Letter regions, and Letter when the region can't be told (web).
The region parsing is shared with the Units preference.

* M10: the first locale variable set decides the paper; extensions are not regions (#5644)

LC_ALL, LC_PAPER and LANG are read in POSIX order and the first one set
decides, so LC_ALL=C no longer falls through to LANG's region; and a locale
tag's region is read from its base tag only, so en-US-u-nu-latn is US, not
NU (CodeRabbit on #5651).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GbuSKAS2k5248LGFEapMUR

* M10: the blank page test covers A4 as well as Letter (#5644)

The app keeps the paper Create ▸ Blank page makes (blank_paper, the system
region's at start), so the test makes a blank page on A4 and on Letter
whatever the host's region (CodeRabbit on #5651).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GbuSKAS2k5248LGFEapMUR

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-11-01 15:04:52 -05:00
VoiceLessQ 424ca0e972 M14: Preferences sets how many recent files to keep (#5572) (#5675)
The list was fixed at 12. Preferences ▸ Documents and view now takes a
number from 0 to 50, with 12 as the default. At 0 Home has no Recent
section and File ▸ Open Recent is disabled.

The list is cut when Preferences closes, so the number can pass through
0 on its way to another. Until then Home and saved settings already
leave out what is past it. A settings file can't ask for more than 50.

The control channel and launch options take it as recent-files. The two
new strings go in every catalog as English copies.
2026-11-01 13:52:47 -05:00
FredAppsandCodex GPT-6.1 6816d14e02 Fix context image placement and canvas selection ownership
Convert context-paste user coordinates into AddImage display coordinates and
identify the inserted image through its new owning stream and XObject. Keep
legacy added-image metadata aligned with the active image controller, route
Delete to the visible selection, and clear hidden image selections when leaving
the controller while preserving text selections and drafts.

Separate selection-dependent Copy from whole-page Snapshot and document Export
permissions. Add synthetic UI regressions covering transformed page placement,
identity collisions, shared image references, saved deletion results, tool
transitions, and permission controls.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 17:54:15 +01:00
FredAppsandCodex GPT-6.1 fdb6a6f33e fix(ui): rotate cropped image previews around the committed pivot
Project the visible user-space bounds centre for the drag preview, matching the RotateBy engine operation. The full image centre differs for cropped artwork and caused the preview to jump on release.

The regression compares actual painted preview corners with saved/reopened image corners and verifies a requested 90-degree turn on cropped and uncropped controls, including page rotation. Linux scoped clippy, 106 tests, wasm, formatting, layering and assets pass.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 17:34:13 +01:00
FredAppsandCodex GPT-6.1 c0a5a5cbf8 fix(ui): resize image frames relative to the captured press
Invert the actual affine basis instead of projecting onto assumed orthogonal axes. Capture the displayed crop frame for handles and apply its relative transform to the full artwork, preserving author clips on rotated pages. Exact out-and-back gestures preserve bytes and undo state, including off-centre presses.

Synthetic headless regressions verify sheared and rotated images, crop-frame anchors, press-offset independence and saved/reopened placement. Degenerate and nonfinite bases are refused; the inverse guard has a negative-control test.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 17:34:13 +01:00
FredAppsandCodex GPT-6.1 393bd30701 fix(ui): leave source text untouched when script conversion is a no-op
Only request a script conversion from the panel; the caller decides whether conversion changed the text. Do not create a paragraph rewrite merely because the button was clicked. A hidden QQQ fixture checks both script buttons preserve document bytes, undo history and saved rendering, while supported conversions remain covered. Actual reverted-fix raster failure and scoped Linux native, wasm, clippy and repository checks passed.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 17:19:21 +01:00
FredAppsandCodex GPT-6.1 a3840e1eda fix(ui): paste delivered images instead of guessing from key releases
The pinned integration consumes native clipboard shortcut keys and delivers PasteImage pixels. Handle those payloads in order, keep text cache invalidation, and use the delivered image even if the OS clipboard changes before processing. Preserve alpha and validate dimensions and byte counts before allocation.

Remove release timestamps so Windows clipboard history cannot reuse a completed paste gesture. Keep explicit shortcut fallback for control-channel and browser internal-image paste, with modal, focus and permission guards unchanged. Tests cover both release orderings, history after prior paste, mixed batches and duplicate prevention.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 16:30:06 +01:00
FredAppsandCodex GPT-6.1 0595d4d397 fix(ui): preserve author clips and route crop controls before page content
Offer Remove Crop only for editor-owned clips, reset draft cropping to the author-visible bounds, and remove only an owned crop when confirming the full image. Active crop mode owns presses on its page so underlying text and marquee selection cannot steal crop controls. Label the painted controls for accessibility and automation.

The author-clip regression opens the real menu, resets a draft crop and confirms it while preserving the authored clip. It failed before ownership checks and again before the router fix.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 14:58:21 +01:00
FredAppsandCodex GPT-6.1 d423dd03ec fix(ui): keep image grips and flips aligned with the visible page
Use matrix resizing whenever image axes are turned or reflected on screen, including document and view rotation. Share the visible grip geometry for cursor claims and hit routing, and use only the drawn rotate knob. Map flip labels to the visible axis and defer Cut selection clearing to its result.

Regressions cover all page/view rotation combinations and 64 outward drags across every grip, asserting fixed anchors and pointer tracking for upright and rotated images.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 14:58:21 +01:00
FredAppsandCodex GPT-6.1 d4810fd00f refactor(ui): finish shared image selection and clipboard state cleanup
Use the common image-selection constructor across owners, remove obsolete crop and copied-coordinate fields, keep only a shortcut timestamp, and make the internal UI modules private. Combined GGEO-AI02 validation: 4198 tests passed, scoped clippy, doctests, fmt, layers, assets, parity and wasm; 25-step CLI save/reopen smoke and real-shell screenshot checked.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 13:00:26 +01:00
FredAppsandCodex GPT-6.1 2c6a0fed48 fix(ui): honor current clipboard text and elapsed paste timing
Menu paste refuses cached images when system text supersedes them. Keyboard and menu paste share the text check; image validation reuses Create. Expire shortcut context by elapsed time even when frames are sparse. Regression tests fail with the old checks restored.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 12:54:52 +01:00
FredAppsandCodex GPT-6.1 d08097f286 chore: restore formatting and lint gates for preserved edits
Remove the rectangle helper whose only caller was the deleted crop test, and format the preserved text_script tool additions.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 12:54:51 +01:00
FredAppsandCodex GPT-6.1 355078d141 refactor(ui): consolidate image preview geometry and cached inventory
Use the shared content Matrix, one image-frame painter, texture-mesh builder, crop-pill style and rectangle comparison. Replace rotated resize arms with signed anchors and reduce crop arithmetic while preserving UV and screen scale. Reuse the edit-generation image cache for drag painting and image menus, and keep the menu flag temporary.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 12:45:14 +01:00
FredAppsandCodex GPT-6.1 91f94ec26a refactor(ui): simplify image and page context menus
Share click handling, set crop mode in the image menu, remove duplicate export and inactive editor entries, and format shortcuts for the platform. Add a selection constructor for callers.

Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
2026-11-01 12:39:45 +01:00
FredAppsandClaude Opus 5.5 a016923829 refactor(ui): crop mode is crop.is_some(); drop dead drag state
crop_rect was only ever reset to None outside tests, and crop_mode was
always set together with crop, so readers now test crop.is_some() and
the writers are gone. The fields stay until the last struct literals in
content_ui stop naming them. Tests that set crop_rect to drive the crop
now set the crop's box the same way crop_input did.

The rotated-drag match had a DragTarget::Rotate arm that the turning
branch above always pre-empts, and image_input's ImageAction parameter
was unused (let _ = &action).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 12:35:35 +01:00
FredAppsandClaude Opus 5.5 fc6dc4f2d6 refactor(ui): drop dead and test-only image geometry
HandleId duplicated ImageHandle with conversion tables both ways; the
image engine now takes ImageHandle, which also carries the cursor icon,
and the crop grips map through one GRIPS table instead of two index
matches. ImageObb loses from_center_size_angle, scale_proportional,
project_delta, new, handle_id, handles_with_ids and the width, height
and theta fields, which only the test of scale_proportional read.
reset_crop, RESIZE_ACCENT, image_owns_pointer and DragTarget::CropHandle
had no callers, and turn_degrees is test-only. The image engine is
private and its unused re-exports are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 12:35:35 +01:00
FredAppsandClaude Opus 5.5 d1cba7fdd1 refactor(ui): remove update_image_crop, which only its test called
The image panel crops through Edit::UpdateContent with the fractions it
reads, and nothing else called update_image_crop. Removed with its test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 12:34:57 +01:00
FredAppsandClaude Opus 5.5 ac4f26a00d chore: revert unrelated churn from #2155
Restore main's text where the PR changed things it did not need to:
intra-doc links turned into plain code spans (engine js.rs and
camera_edges.rs, forms raster.rs, fonts pdf.rs, sign keys.rs and
pkcs12.rs, ui-egui motion.rs and web_print.rs), the #[allow(dead_code)]
on render's byte_capacity and ui-egui's unit_for_tag (both are used on
every native target, as on main), the loosened combine_grid timings, the
forms test case rename (scratch() already numbers its folders), and the
computed xref size in a_recovered_page_tree_survives_a_full_save (always
5 there).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 12:33:50 +01:00
FredAppsandClaude Opus 5.5 29913dcfca Merge current main into #2155
Brings the branch up to date with main (47f42ba0), which moved 37 commits since
the merge base, including page-edge shadows (#2088), full rewrite after page
delete (#4279) and the licence-check stage (#2212). No conflicts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 11:23:43 +01:00
FredApps f2e1a8ce29 Merge branch 'main' into fix/1577-optional-page-edge-shadows-integration 2026-10-31 23:38:40 +01:00
FredApps bad4c81800 Merge current main into PR2088 and port shadow preference to split UI modules 2026-10-31 22:13:25 +01:00
FredApps 286a3c6eee Merge current main into PR1433 and preserve launch override across module splits 2026-10-31 22:12:05 +01:00
Combiler01 6de6339736 fix(ui): preserve selection clearing semantics after format application 2026-10-31 23:52:00 +05:30
Combiler01 fdc0e6404a fix: address review feedback on arrange, image flips, rotate knob, and format panel
- [P1] Arrange: track and replay inherited non-ExtGState drawing state (colors, line widths, etc.) across q/Q scopes for stencil and form artwork
- [P2] Flips: route ImageEdit::Flip through coordinate-aware transform logic to swap axes when rotated at odd quarter turns (90°/270°)
- [P2] Rotation knob: measure clockwise angle delta from drag start relative to the rotated image center to prevent reapplying existing angle
- [P2] Format panel: connect superscript/subscript controls to line editor and content draft selections, and update parity evidence
2026-10-31 23:18:58 +05:30
Combiler01 e781d31187 fix(ui, test): resolve font-size inspect query and command-key paste tracking 2026-10-31 17:09:50 +05:30
Combiler01 79eed72c08 Merge upstream/main into main preserving custom features
- Resolve all 13 merge conflicts between upstream/main and main
- Preserve full image editing suite: OBB, crop, proportional resize, arrange, and context menu actions
- Preserve text editing formatting tools: bullet/numbered lists, subscript/superscript, and line spacing
- Cleanly integrate upstream's canvas modularization, font updates, and styling changes
- Refactor arrange_image and run_edit_page_image helpers to satisfy clippy cognitive complexity limits
- All engine, edit, and UI integration test suites passing cleanly
2026-10-31 15:50:31 +05:30
Combiler01 87c1e858e3 Coderavbit Fixes 2026-10-31 14:23:19 +05:30
aiongg 635a840164 updates: show check results with craft-update's CheckResultDialog 2026-10-31 04:43:07 +00:00
FredApps 4791cacd2c test: qualify conservative tone retention and format review regressions 2026-10-30 14:55:44 +01:00
FredApps d7f3e67141 fix: bound backdrop edits and withhold unsafe integration behavior 2026-10-30 14:45:50 +01:00
FredApps ee71348bc8 fix: bound soft-wrap metadata and preserve unknown backdrop content 2026-10-30 12:47:37 +01:00
FredApps 7d3d4830e5 Integrate remaining six PdfCraft parity PRs with conflict resolutions
Includes #4325 #1952 #4180 #2529 #4320 #4805, preserving their original histories.
Keep paragraph alignment and hard/soft wrap metadata together; retain CCITT/downsampling/RGB ownership guards with bounded JBIG2 export and exact-copy symbol encoding.
Combined interaction regressions added. Validation pending.
2026-10-30 11:02:07 +01:00
FredApps a07f94f2f7 test: supply Fill & Sign colour in combined window-title fixture 2026-10-30 10:46:11 +01:00
FredApps b21af3b969 Integrate 21 clean-merging PdfCraft parity PRs
Preserve each original PR head and its authorship as a merge parent.
Includes #4304 #4335 #4384 #4404 #4179 #5300 #4719 #4541 #2815 #4620 #3789 #3779 #2960 #5208 #4596 #3636 #4494 #4013 #5134 #2133 #2635.
Conflicting candidates skipped. Combined CI pending; see docs/integration-20261030.md.
2026-10-30 10:35:42 +01:00
FredApps 4b319bb383 Keep typed font sizes accessible and within the current panel layout
Use a named compact preset arrow beside the field, retain the row alignment/width assertions for the editable control, and open the current colour flyout in the saved-text regression. No accessibility or layout checks are disabled.
2026-10-30 09:29:42 +01:00
FredApps 7227eb68ab Name the Pages sidebar keyboard group and record its accessible snapshot 2026-10-30 09:10:05 +01:00
FredApps b07a012cd7 Reconcile button export values with current form authoring modules
Preserve caption editing and current form/Prepare module boundaries. Carry export-only appearance preservation, validation and data round-trip tests to their current paths, and retain current attribution metadata. Hosted CI must validate this refreshed head.
2026-10-30 08:56:21 +01:00
FredApps ea66a642fe Reconcile Pages sidebar selection with current keyboard and panel modules
Preserve main's continuous text selection, page tools and module split. Carry only this branch's sidebar-focus feature and regression onto main, without resurrecting old common files from criss-cross merge bases. Hosted CI remains required.
2026-10-30 08:52:06 +01:00
FredApps 6b38a5ab47 Reconcile typed font sizes and Fill & Sign colours with current UI
Use the unified Format Text panel and current page-input context instead of restoring old monolithic UI code. Preserve main's pointer routing, editor accessibility and preferences; retain colour, save and input regressions. Hosted CI must validate this refreshed head.
2026-10-30 08:47:42 +01:00
Grzegorz MartensandClaude Opus 5.5 46382092f1 M6: Field Properties refuses a notation it couldn't store, and stays open with what was typed
set_props refuses such a notation before writing anything, so the
Calculate tab can't store one either (the tool already refused it). A
refused edit used to close Field Properties and lose everything typed
into it; the dialog now stays open with its changes, as the dialog for
several fields does, and the notice says why (from the review).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
2026-10-29 20:48:48 +01:00
Grzegorz MartensandClaude Opus 5.5 6a5020760e M6: calculation checks: formulas by field object, whole AFSimple lists only, no all-clear beside a broken formula
- CalculatedField carries the field object: form_calculation_order and
  the Calculation order page find each row's formula and value by it,
  so two calculated fields sharing a name (a malformed form) each show
  their own.
- An AFSimple_Calculate list counts as written out only when it ends
  the call: "row" + suffix and [...].concat(more) are names built at
  run time, and an array item counts only when it ends at a comma or
  the list's end, so ["row" + i] no longer reads, or renames, "row".
- After a reorder, Undo is offered on the missing-field card instead of
  bringing back the all-clear beside it.

From CodeRabbit's review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BfMGHQNgdq5yf5tKZHGR3z
2026-10-29 20:48:37 +01:00
Grzegorz MartensandClaude Opus 5.5 feefeb8c95 M6: Calculation order: a formula that reads a missing field is marked, not only explained on hover
The row gets a red step and a "Missing field" caption, as a loop does; a
red card names the formulas and links to the first, in place of the
all-clear; a script that builds names gets a grey "Unchecked reads"
caption and a note; the summary above the page lists a missing field
among the reads and says so, and says when a script names fields as it
runs. The name and formula lines of a row are sized by their own
right-hand text, so a wide caption no longer cuts the name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BfMGHQNgdq5yf5tKZHGR3z
2026-10-29 20:48:37 +01:00
Grzegorz MartensandClaude Opus 5.5 907a9fa917 M11: monochrome downsampling: black-and-white images above 450 ppi are averaged down to 300
The PDF Optimizer and Reduce File Size downsampled colour and grey images
but not black-and-white ones. Settings::mono is now MonoSettings {
downsample, target_ppi, above_ppi, compression }, 300 ppi above 450 ppi
and CCITT Group 4 by default (Monochrome Images ▸ Downsample to;
doc_optimize mono: { downsample, ppi, above_ppi, compression }).

A 1-bit image or image mask (no filter, general-purpose filters, or CCITT
fax after any of them) and eight-bit grey of only black and white are averaged by
area: each new pixel takes the sample covering more of it, a tie 0, so a
dark line half a new pixel wide stays. They are stored as Group 4, or as
1-bit Flate when that is smaller; with Retain a resampled image keeps its
kind of compression. Images with a soft mask keep their size.

CCITT decoding moves from Export ▸ Images into pdfcraft-filters
(decode_ccitt, CcittParams, through hayro-ccitt), and
pdfcraft_cos::Document::decoded_image reads a fax image's /DecodeParms
for it (undoing filters before CCITT, such as ASCII85Decode, with any
/DecodeParms given by reference made direct first), so export
and the optimizer share one reader, and Group 4 scans can be
downsampled. A 600 ppi text page went from 79 KB to 40 KB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BfMGHQNgdq5yf5tKZHGR3z
2026-10-29 20:48:03 +01:00
Grzegorz MartensandClaude Opus 5.5 f175beb25a M11: PDF Optimizer stores black-and-white images as CCITT Group 4 when smaller
pdfcraft_filters::encode_g4 encodes packed 1-bit rows as Group 4 (ITU-T
T.6, /K -1) through the fax crate (MIT, already in the tree via tiff),
with rows capped at 32,767 samples so its 16-bit positions can't
overflow; round trips are checked against hayro-ccitt.

The optimizer (Settings::mono, CCITT G4 by default, so Reduce File Size
too) re-encodes a 1-bit image of one colour component, or an image
mask, stored with no filter or general-purpose ones, when that is
smaller as stored. The samples decode to the same bits, so colour
space, decode array and masks stay. PDF Optimizer gets a Monochrome
Images row and doc_optimize a mono option. optimize.mono-compression
goes from planned to partial (JBIG2 and monochrome downsampling not
yet).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BfMGHQNgdq5yf5tKZHGR3z
2026-10-29 20:47:39 +01:00
alehelandClaude Opus 5.5 11bc8c5652 fix(ui): Add text finishes a paragraph drag that leaves the paragraph's box
With Add text the page's own paragraphs took input only while the pointer was over one
(over_source), and their drags end in edit_text_ui::page_input. A paragraph dragged off its box
was left hanging after the release (block_drag), to land wherever the pointer next met a
paragraph; one flicked off in its first move never started, so nothing moved. main has the same
test. Add text now also acts on the paragraph the page router says holds the press, until the
button is up, so the drag ends where it is released, as with Edit text, and Add text's
new-box path does not take the press over.

New test add_text_finishes_a_paragraph_drag_that_leaves_its_box, seen failing before the fix
(the drag still pending after the release); the flick was checked by hand the same way. From
CodeRabbit's third review of #5300.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 15:32:48 +01:00
alehelandClaude Opus 5.5 2929ba854e fix(ui): a click on a link or a form button counts only released over it
A click acted on what its press was on wherever the button came up: a press on a link, a push
button, a signature field or a list box that slipped off it before the release (still a click to
egui, within 6 px) followed the link, ran the button's action, opened signing or picked a list
box's option. On main a click went to what lay under its release. Now it needs both: the
link's or the fields' hit test at the release point must give what the press was on, as a button
pressed and released off itself does nothing. Check boxes and radio buttons already did so, by
their overlay's click-outside test.

New tests a_press_on_a_link_released_off_it_follows_nothing and
a_press_on_a_button_released_off_it_runs_nothing, seen failing with this commit's source
reverted; the check box test shares their slipping_click helper. From CodeRabbit's second review
of #5300.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 15:14:31 +01:00
alehelandClaude Opus 5.5 8a21ed1236 fix(ui): Add text opens a paragraph from just inside its edge again
With Add text, the page router's hits kept only the paragraphs' bodies (3d14ffd7), so a click
just inside a closed paragraph's left or right edge, within the edge's grip, had no owner: it
neither opened the paragraph (over_source counts the point as the paragraph's) nor started a new
box. Add text now keeps a paragraph's hit wherever the point lies in a paragraph's box, edges
included, by the same test as over_source (edit_text_ui::over_paragraph), and drops it only
beside the box, where a click starts a new box. The edge's grip shows there again, and a drag
from it rewraps the paragraph, as on main.

New test add_text_opens_a_paragraph_from_just_inside_its_edge, seen failing with this commit's
source reverted. From CodeRabbit's second review of #5300.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 15:14:31 +01:00
alehelandClaude Opus 5.5 3d14ffd722 fix(ui): Add text places a box on a picture and beside a paragraph again
With Add text, the page router's hits included Edit text's pictures and paragraph edges, which
nothing acts on with Add text, and Add text starts a box only where nobody owns the press: on a
scanned page (a picture filling it) no click placed a box, a click within a paragraph's edge
grip beside it did nothing, and the cursor over a picture was the hand. Add text now has only
the paragraphs' bodies, over their text, where it finishes the box being typed (over_source).

New test add_text_places_a_box_on_a_picture_and_beside_a_paragraph, seen failing on the
previous commit. From CodeRabbit's review of #5300.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 14:27:40 +01:00