- Panels dock through craft-ui's shared docking. On desktop, a floating
panel opens in its own OS window (feature native-windows); the web
build keeps floats in the page.
- Keys pressed in a floating window run the main window's shortcuts,
clipboard and tool keys in the same frame.
- A default layout's floating windows keep their ids.
- The canvas paints no tool cursor while another of the app's windows
has the pointer, and a pointer beside a float stays the canvas's.
- Story joins Glyphs in the default icon column.
note.delete removes the note's anchor (3 bytes) from the story, and
note.convertToText replaces it with the note's text. Both left a caret or
selection in the story text at its old byte offsets. With "copy" selected
after a note in "Draft copy.", Delete Note left the selection at 9..13 in
an 11-byte story, and Convert Note to Text with the note's text "ab" left
"opy." selected.
Both commands now move a caret or selection in the story's own text by
the change in length when it comes after the anchor. A caret before the
anchor stays where it is, and a caret in a table cell or in another story
is unchanged.
layout_line set a line with a tab or a right indent tab without the optical
margin or CJK edge hangs, while the greedy breaker and the paragraph composer
counted them. A line that fit only because its period hangs was then squeezed
into the measure or set past it.
layout_line now hangs the edge glyphs of every line. Tabs are measured from the
hung start, so tab stops stay where they are, and a right indent tab fills to
the hung end. A tab at a line edge hangs nothing. Lines without tabs lay out as
before.
Editing one keyword in File Info re-split the whole field, so a stored
keyword holding a comma or semicolon became two. A stored keyword that is
still in the field whole now stays one keyword.
An Export PDF title equal to the document's name was dropped, so the PDF
took File Info's title. The dialog's title now starts empty, and a title
given there is always the PDF's title; without one the file is named
after the document.
file.info refuses parameters that are not an object; null reads the
fields like {}.
File Info's OK stores the fields in the document the dialog was opened
for, even when another document became active meanwhile, and stores
nothing once that document has closed.
Found while testing crates/textimport/src/docx.rs:~272 (the "tbl" branch of Ctx::blocks: `st.insert_table(len, t); first = false;`)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
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.
The new command note.split {story, id, at} splits an editorial note at
byte `at` of its text. The note keeps the text before that point, and
the rest moves into a new note by the same author whose anchor directly
follows the first one. A split point at the start or end of the text,
or inside a character, is refused. The Notes panel shows each note's
text in a read-only field, and its Split Note button splits the note at
the insertion point in that field.
footnote.delete and endnote.delete removed the reference character from
the story but left a caret or selection in the story text at its old
byte offsets. Everything after the reference moved back by the
reference's length, so the caret ended up three bytes further along the
text. A caret or selection after the reference now moves back with the
text, and one before it stays where it is.
footnote.setText left a caret in the replaced footnote at its old
offset, which could fall past the end of the new text or inside a
character. Backspace there then failed with an internal error. The
caret now goes to the end of the new text.
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.
Found while testing crates/tools/src/gradient.rs:62 (PointerKind::Drag branch: `let to = *sp + (end - *start);`)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Two designcraft-engine tests fail on Windows on main. The code they
test is unchanged.
eps_relink_update_and_folder_relink_retain_source built the expected
link as dir.join("new/replacement.eps"), which on Windows ends in
new/replacement.eps, while links.relinkFolder stores the folder
joined to the file name, ending in new\replacement.eps. The test now
joins the folder and the file name separately.
only_local_graphic_files_are_read_from_links allowed a read of the
link only at the link's own text. For the link /dev/zero the import
checks C:\dev\zero on Windows, because craft-docpath joins a
root-relative path to the document's drive. The test now allows the
path that crate::io::document_path resolves the link to.
Open #1444 by AndreRese makes the same change to the relink test and
a similar one to the IDML test.
* Type: story Optical Margin Alignment with a size, and Ignore Optical Margin (engine, IDML)
A story's Optical Margin Alignment applies to every paragraph except those
with Ignore Optical Margin; hang amounts scale with the story's size.
story.options sets it, type.para and paragraph styles take
ignoreOpticalMargin. IDML imports and exports StoryPreference
OpticalMarginAlignment/OpticalMarginSize and IgnoreEdgeAlignment. The
per-paragraph opticalMargin switch keeps hanging at the text's own size.
Part of #947.
* Type: the Story panel, and Ignore Optical Margin in the Paragraph panel menu and Paragraph Style Options
Window > Type & Tables > Story sets Optical Margin Alignment and its size
for the stories of the text selection or the selected text frames through
story.options, and is disabled without either. type.selectionAttrs
reports the stories' values as storyOptions, null where they differ.
The Paragraph panel menu toggles ignoreOpticalMargin, and Paragraph Style
Options > Indents and Spacing has an Ignore Optical Margin checkbox.
Part of #947.
* ROADMAP: the story Optical Margin Alignment entry names its default and scope
Go to Footnote Reference, Insert Footnote and Delete Footnote (when the
caret is in the deleted footnote) moved the caret without clearing the
pending typing format. Formatting chosen at the old insertion point and
not yet typed then came back when the caret returned there, for example
in a new footnote that takes a deleted footnote's id. The three
commands now clear it, as text.select and text.move do.