eframe runs only App::logic while a window or browser tab is hidden, so a
?file= download that finished then opened the document without the titles
changing. The titles are now set at the end of logic as well as in ui.
Prepare's arrow nudge read the frame's Alt, so an Alt+arrow whose Alt was
let go in the same frame nudged the field instead. Each press's own
modifiers now decide, as for objects, pictures and comments.
The dirty mark now follows has_unsaved_work, the same test the close
prompt uses, so text typed into a field or text box shows the mark before
it is applied. The web page's title, which an embedding host reads to tell
which file opened, now always names the file, even when the document asks
to show its own title; the native window title is unchanged.
The title now reads "<name> • — PdfCraft" while the active document
has unsaved changes, as the other Craft apps write it, and goes back to
"<name> — PdfCraft" once saved.
eframe's web runner ignores ViewportCommand::Title, so the web build
never named the open document. It now also sets the page's
document.title, which an embedding host reads to confirm which document
opened and whether it has unsaved changes.
The comment nudge matched arrows with egui's key patterns, which let an
extra Alt through, so with a comment selected Alt+Left moved it a pixel
instead of going back. It now takes only arrows pressed alone or with
Cmd/Ctrl or Shift, judged by each key press's own modifiers, as the
picture and object nudge does.
Previous view and Next view had only Cmd+[ / Cmd+] (Ctrl elsewhere), and
Alt+Left turned the page, since the arrow keys ignore Alt. The document
view now takes Alt+Left / Alt+Right (Option on macOS) for them, as Acrobat
and browsers do, before the arrows turn the page. Following a link
already records where it was followed from.
With a picture or objects selected in Edit text & images, the arrow-key
nudge ran first and also matched a press with Alt, so Alt+Left moved the
selection. It now takes only arrows pressed alone or with Shift, judged
by each key press's own modifiers rather than the frame's.
Help > Keyboard shortcuts lists the pair under the existing Previous view
/ Next view labels.
The old doc comment was left above the constants added in this change, where it
documents PREFERENCES_BUTTON_ROW wrongly, and its "Returns true to close" no
longer holds for preferences_body, which returns ().
Move its first sentence onto preferences_body, drop the "Returns" sentence, and
leave each constant with only its own comment.
The settings scroll when the window is short, but OK was the last thing inside
the scrolled content, so in a short window it was off screen until you scrolled
to it, and the dialog was cut off partway through the theme cards.
OK is now a row below the scroll area, outside it. The scroll area gets the
height the window leaves (at least 60 pt, so OK stays on screen in the smallest
window, 520 pt, at the largest interface size, 300%) and a scrollbar of its own
instead of the floating one that lay over the right edge of the theme cards.
A scroll area starts from the room its modal offers, and a modal offers more
each frame for the first few, so with OK outside the scroll the dialog opened
small and stretched by about 45 pt a frame for ten frames, and clicks in the
first frames missed. The scroll area is asked for its full height from the start
(min_scrolled_height, which egui applies only when the settings overflow it),
so it opens at full size and does not stretch in a tall window.
- test: OK and the title are on screen at window heights from 173 to 1100; OK
closes the dialog and does not move while the settings scroll, and a far-down
setting scrolls into view between the title and OK; the dialog does not grow
after it opens; a very tall window has no blank gap above OK. Both the
original layout and the stretching variants fail them.
- parity: misc.preferences-dialog evidence and what is still missing.
A bookmark made in the app always went to the top of the page. It now goes to
the top-left of the selected text, or with nothing selected to the top of the
window, as /XYZ left top null: the reader's zoom is kept, and with only the top
pinned so is the horizontal position.
- render: PageInfo::xyz_for_view, the inverse of dest_fraction. It pins only
the coordinates given; on a page turned a quarter the displayed y decides the
user left and the displayed x the user top.
- organize: add_bookmark_at and OutlineError::BadPosition (a coordinate that is
not finite is refused before anything changes).
- engine: Edit::AddBookmark takes left and top (None, None is the page top, as
before).
- automation: bookmark_add takes top and left in points from the top-left of the
displayed page, as bookmark_list reports them, bounded and refused when not a
usable number.
- ui: DocView::bookmark_position. It follows the window's vertical when the view
is turned a quarter (View > Rotate View), picks the selection's corner that
shows at the top-left, and in a spread of unequal pages uses the page that
crosses the window's top edge.
- parity: organize.bookmark-add evidence and what is still missing.
A checkmark, cross, dot or line placed on a page with /Rotate was drawn
in the page's own axes, so on a page turned 180 degrees the checkmark
came out upside down, and on a quarter turn it lay on its side.
Marks now record the page rotation (PCStampRotate, as rubber stamps do)
and their appearance is drawn upright in the displayed box and mapped
into /Rect, sharing the stamps' code for it. The mark's box is sized in
displayed axes (FillMark::rect_at), used by both the Fill & Sign tool and
fill_sign_add, so a line runs across the page as displayed.
Opening the Print dialog reset the printer to the system default every
time, while copies, range and paper carried over, so Save as PDF or a
non-default printer had to be picked again for each print.
The dialog now keeps the printer picked last time, Save as PDF included,
while it is still listed. A fresh list that no longer has it (the
printer was removed) falls back to the default.