Commit Graph
244 Commits
Author SHA1 Message Date
batistalucasv 139aa7a51b Merge branch 'main' into fix/6205-image-copy-paste 2026-11-12 15:30:43 -03:00
FredApps 11318f9226 Merge main and preserve both UI parity histories (#6225) 2026-11-12 18:13:35 +01:00
FredApps 0196647dc6 Merge main and preserve both UI parity histories (#6232) 2026-11-12 18:13:35 +01:00
10e5bb8bce View: editable Markdown source view for .md files (#5826) (#6004)
* View: editable Markdown source view for .md files (#5826)

Co-authored-by: oldgranola <marken.john206@gmail.com>

* Address review feedback on Markdown source view

- Fix view.markdownSourceText purity and input validation
- Single-pass block line mapping in markdown parser
- Reuse parsed documents and block line ranges on apply and leave
- Bound memory usage with MAX_SOURCE_BYTES and clamp caret byte offsets
- Isolate temp directories in tests and test caret validation
- Preserve dirty state while markdown text edits are pending
- Flush pending markdown text edits in swap_doc

* Address CodeRabbit review feedback on Markdown source view

- Exempt view.markdownSourceText in command refusal
- Preserve original source line mapping when filtering link definitions
- Map between egui char indices and byte-offset caret in history and undo

* Remap block line numbers in a single linear pass

* Refuse over-limit Markdown Source edits to prevent document truncation

* Keep a Markdown file's own text when it is opened from handed-over bytes

`file.open` kept a Markdown file's exact text only for path-backed opens, so a
platform that hands the bytes over (data) lost front matter, comments and the
author's line endings on the first save, and the rewritten flag could not say
so. The kept text now comes from the same bytes `read_document` decodes, still
bounded by MAX_SOURCE_BYTES through FileText::from_bytes; the path read stays
for opens without data.

---------

Co-authored-by: oldgranola <marken.john206@gmail.com>
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-11-12 17:59:04 +01:00
batistalucasv 664b033071 Save As: don't open the rfd fallback after the portal dialog was given up (#6180)
Giving the dialog up cancels the request. If the portal then fails with an
error other than its cancellation code, the worker opened the rfd dialog even
though nothing was waiting for the answer, leaving an unwanted Save dialog on
screen. The fallback now checks this request's cancellation token first.
2026-11-12 12:52:55 -03:00
batistalucasv 2d286fe252 Save As: only the request that armed the portal cancel token disarms it (#6180)
An abandoned portal request finishing late cleared the token of a newer
request in the shared slot, which left the newer Save dialog uncancellable.
Each arming now carries an identity and only its owner clears the slot; a
regression test arms two requests and disarms the older one.
2026-11-12 12:36:00 -03:00
batistalucasv 02f8022e57 Merge remote-tracking branch 'upstream/main' into fix/6205-image-copy-paste
# Conflicts:
#	docs/gaps.md
#	docs/ui-parity.md
2026-11-12 10:41:04 -03:00
batistalucasvandCommandCodeBot 4671e47b50 Save As: cancel a stalled portal request and recognize the Flatpak document portal (#6180)
- Recognize the XDG document portal mount inside a Flatpak sandbox
  (`/run/flatpak/doc/`), so a changed extension reopens the dialog for the
  overwrite confirmation like the host mount does.
- Give the portal SaveFile request a real cancellation path: the CancelToken is
  armed before the waiting thread starts and cancelled when the system dialog is
  given up (File > Open > Browse in WordCraft...). The request closes and the
  answer reads as a cancel, so a portal that stops answering cannot keep Save As
  stuck; a late cancel after the answer is ignored.
- Map the cancellation error to a cancelled dialog instead of the rfd fallback.
- Regression tests for the Flatpak mount, the CancelHandle arm/cancel/disarm,
  and the UI calling the host's cancel hook when the dialog is given up.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-11-12 10:15:36 -03:00
batistalucasv cd4e63849e Clipboard: qualify the CF_HTML helper in the Windows host (#6205) 2026-11-12 10:06:07 -03:00
batistalucasv a1d4495cfb Clipboard: account for fragment media and test CF_HTML offsets (#6205) 2026-11-12 09:53:17 -03:00
batistalucasv cc27f29a01 Save As on Linux: the file type picked in the save dialog sets the extension (#6180) 2026-11-11 18:08:29 -03:00
batistalucasv 7013411a2f cli: skip update-fields with warning on protected document (#5839) (#5849) 2026-11-11 18:53:10 +01:00
bmh129andbmh129 639b8133ea Linux: stay on native Wayland when the X11 libraries are missing (#3359)
The deb and rpm only recommend the X11 libraries, and the release tarball
doesn't install them. When the display-server choice (#2184) or
WORDCRAFT_WAYLAND=0 asked for XWayland without them, the app failed to
start: winit panicked in xkbcommon-dl without libxkbcommon-x11 (seen on
Fedora 44 and Ubuntu 26.04).

uses_x11 now also takes a check of the libraries winit's X11 backend opens
(libX11, libXcursor, libX11-xcb, libXi, libxkbcommon-x11), asked only when
X11 would be forced. If any is missing, X11 isn't forced and the log line
names them. The packages now also recommend libX11-xcb and
libxkbcommon-x11, and the README lists the libraries XWayland needs.

Tests: missing_x11_libraries_leave_the_app_on_wayland (every way of asking
for X11, and that asking for Wayland doesn't run the check).

Co-authored-by: bmh129 <11478682+bmh129@users.noreply.github.com>
2026-11-11 12:04:55 -05:00
batistalucasv 28af39b610 Clipboard: preserve system clipboard and ownership when copy has no selection (#6205) 2026-11-11 09:34:43 -03:00
FredApps 45db128c15 fix(wordcraft): satisfy clippy on clipboard.rs after #5441
#5441 (92e0e67f) landed a Wayland clipboard size check in `apps/wordcraft/src/clipboard.rs` that left two clippy `-D warnings` failures on main:

- an unused `self` import in the Unix `platform` module (`use wordcraft_ui_egui::paste_picture::{self, ClipboardPicture}`)
- `items_after_test_module`: `platform::picture()` was defined after `mod tests`

This removes the unused import and moves `picture()` above the test module. Behaviour is unchanged.

Local checks: `cargo fmt -p wordcraft` and `cargo clippy -p wordcraft --all-targets --locked -- -D warnings` on Linux.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

<!-- coderabbit-ai-generated:v1 -->

## Summary by CodeRabbit

* **Refactor**
  * No user-visible changes.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-11-11 08:51:03 +01:00
Dylan M. Taylor 92e0e67f3a Clipboard: size-check a Wayland clipboard picture before anything decodes it (#5441)
* fix(clipboard): size-check a Wayland clipboard picture before it is decoded

* address review: refuse a clipboard PNG the renderer cannot decode within its budget
2026-11-10 21:33:46 -05:00
batistalucasv 22f01131d8 Clipboard: use process-unique token for Windows clipboard ownership (#6205) 2026-11-10 21:47:52 -03:00
batistalucasv 860426adda Clipboard: remap conflicting media keys, format Windows CF_HTML, and complete docstrings (#6205) 2026-11-10 21:33:22 -03:00
batistalucasv 7458a18468 Clipboard: collapse nested checks in Windows clipboard host (#6205) 2026-11-10 21:12:03 -03:00
batistalucasv 49e777cce5 Clipboard: transfer copied images to system clipboard and preserve media across internal paste (#6205) 2026-11-10 20:59:58 -03:00
Martin BallandClaude Opus 5.5 d40d1b2718 CLI: --strict on convert and render refuses missing glyphs and pictures (#6039)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-09 20:16:05 +01:00
dotCooCoo 642f5dd6bf Updates: the updater reports installing, ready, installed and failed, and installs at exit
Moves craft-update, craft-pdf and the krilla patch from storytold/craft-libs
c5a1cbfb to dotCooCoo/craft-libs c7c84230, which is craft-libs main at
0a9d1f48 with storytold/craft-libs#687 and #696 merged in.

- The result window opens whenever the updater's status is not idle: at
  the first start after an update it says the version that was installed
  or why the update failed, and Help > Check for Updates shows Installing,
  Ready and the launcher's choice. A check asked for from the ribbon now
  shows the window on the next frame.
- Restart to Update closes the window and asks the app to quit. An update
  that asks the app to close quits every window, after asking about each
  document with unsaved changes.
- on_exit and the macOS terminate path start the waiting update's helper.
- The update prompt and the result window draw their words through the
  interface catalog.
2026-11-08 10:56:53 -08:00
FredApps 0655e651fb Merge upstream control delivery changes 2026-11-08 17:35:06 +01:00
FredApps be75ee90e3 Merge upstream main and reconcile control documentation 2026-11-08 17:22:59 +01:00
FredApps 480511eaa5 Merge upstream main into control delivery changes 2026-11-08 17:15:38 +01:00
batistalucasvandMartin Ball fde39ab061 Desktop: constrain newly opened window dimensions to available screen width (#5871) (#5876)
Co-authored-by: Martin Ball <martin.ball@ucscaregroup.co.uk>
2026-11-08 06:44:01 +01:00
vangel76andClaude Opus 5.5 833c0154aa Merge upstream/main into control-mcp-delivery-1326-1331
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 06:18:12 +01:00
Helen Kwok de4ca29309 wordcraft-web: window.wordcraft, the page command API from craft-web-api (#5860)
The web shell queues the page's calls as control requests (the channel the desktop control server uses) and answers them on the next frame. The API is installed in every mode; opening, saving, the file name and the unsaved flag stay with the host messages.
2026-11-08 05:53:01 +01:00
vangel76andClaude Opus 5.5 6367400215 Merge upstream/main into control-mcp-delivery-1326-1331
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 04:21:51 +01:00
852e67d587 A template opened from the file manager starts a new document (#3433) (#5698)
A Word template (.dotx, .dotm, .dot) the platform hands the app, from a
double-click in the file manager, the command line or the Finder, opened
as itself: the window called it saved, AutoSave was on, and Ctrl+S wrote
over the template. Word's default verb for a template makes a new,
untitled document based on it.

WordApp::open_from_platform sends a Word template to file.newFromTemplate
and opens anything else as File > Open does; main.rs (also for a name that
isn't valid Unicode) and the Apple Events handler use it.
file.newFromTemplate reads the template as file.open reads a file
(password, data, an empty file) and, with replaceBlank, takes an untouched
blank document's place, so a launch shows one window. The Password box
retries the command that asked for it, so a protected template still
starts a new document. File > Open and drops still open a template itself.


Claude-Session: https://claude.ai/code/session_01LvG6E1XTfHtZDbfYwfREhR

Co-authored-by: Filip Strajnar <filip.strajnar@proton.me>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Martin Ball <martin.ball@ucscaregroup.co.uk>
2026-11-08 03:25:17 +01:00
eb100edfd6 Linux: ignore an AppImage environment inherited from another program (#5653) (#5690)
* Linux: ignore an AppImage environment inherited from another program (#5653)

An AppImage app that opens a document through xdg-open passes its APPIMAGE,
APPDIR, ARGV0 and OWD on to the WordCraft it starts. The self-update trusts
APPIMAGE, so an installed WordCraft replaced the other app's file with its own
AppImage.

The app now starts over without those variables, first thing in main, unless
its executable is under APPDIR. The update then goes through the package or
plain file this copy really is, and a real AppImage keeps its variables.

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

* #5653 review: turn the self-update off when starting over fails

If the process can't start again without another program's AppImage
variables, it still carries APPIMAGE, and an accepted update would replace
that program's file. The app now turns its self-update off for that
process: no update is offered, and Help > Check for Updates says why. The
app still opens, so the document the user asked for isn't lost.

Also documents the test helpers.

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

---------

Co-authored-by: Filip Strajnar <filip.strajnar@proton.me>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Martin Ball <martin.ball@ucscaregroup.co.uk>
2026-11-08 03:09:52 +01:00
MexandMartin Ball ea8c45a4ca CLI: preserve non-Unicode input paths after options (#5611)
* M14: keep native CLI input names after options

* docs(M14): clarify native CLI path option exceptions

Qualify the roadmap summary and history: text option values need Unicode, while run --file and run --script retain native paths. Addresses review4485129728. Documentation only; no CLI behavior changes.

* docs(M14): qualify Unicode values in format parity notes

Exclude the existing run --file and run --script native path operands from the text option Unicode requirement. Addresses review4485129728; documentation only.

* docs(M14): qualify Unicode values in CLI gap notes

Document the existing native path exceptions for run --file and run --script. Completes the three-file wording correction requested in review4485129728, without changing readiness estimates or CLI behavior.

---------

Co-authored-by: Martin Ball <martin.ball@ucscaregroup.co.uk>
2026-11-08 02:52:08 +01:00
vangel76andClaude Sonnet 5.5 1c7c4e66e0 Merge upstream/main into control-mcp-delivery-1326-1331
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 11:38:09 +01:00
ashandClaude Opus 5.5 035982e34e Printing: the printer list doesn't wait on drivers, and a job stuck on its driver can be cancelled (#5710) (#5732)
* #5710: the Print panel lists printers without asking their drivers

On Windows the printer list waited until every printer's driver said
whether it prints on both sides. A networked printer in power save can
hold that query for a long time, so the list stayed empty and Refresh
stayed unavailable. WordCraft never used the answer.

Discovery now uses craft-print's printer_queues, which lists the same
queues and default without asking any driver (storytold/craft-libs#618).
Printing still checks the job's options with the driver. Only the
craft-print pin moves; craft-ui doesn't depend on it.

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

* #5710: the docs say what is proven, not that the sleeping printer is fixed

Review: the progress log and gap rows stated the reported outcome as
certain, but the sleeping network printer hasn't been retested. They now
say the driver query is removed and the reported printer awaits retest.

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

* #5710: craft-print pin moves to the merge of storytold/craft-libs#618

e653048 is craft-libs main's merge of #618; crates/print is identical
to the reviewed and tested head 81c2488.

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

* #5710: a print job waiting on its driver can be cancelled, and quitting doesn't wait for it

On Windows a print job asks the printer's driver for its capabilities
before it is sent, and a networked printer in power save can hold that
query for a long time. The Print page stayed locked until the driver
answered, and quitting waited for the job before saving preferences
(CodeRabbit on #5732).

Each job now carries a craft-print Cancel token. Cancel printing
(ui.printCancel) stops a job that hasn't started reaching the spooler,
so it is never sent, and frees the Print page with the settings kept;
a job already being sent completes, and the page says to cancel it
from the system's queue. Quitting cancels jobs still waiting and waits
only for jobs already being sent.

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

* #5710: quitting cancels every waiting print job before it waits; Cancel asks the active job

Review: quitting cancelled and waited for jobs one by one, so a job left
waiting while an earlier one was being sent could start sending
meanwhile. Every job is now cancelled first, then only those already
being sent are waited for. Cancel printing asked every unfinished job,
so a job that had just been sent could be reported as cancelled and its
receipt lost; it now asks the job being submitted, which answers that it
was already sent.

The tests cover both orders, junk parameters for ui.printCancel, and the
kept printer list and status message.

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

* #5710: craft-print pin moves to storytold/craft-libs#622 for submit_cancellable

85c8ca1 is #622's head (craft-libs main e653048 plus the Cancel token);
it moves to #622's merge on craft-libs main before this merges.

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

* #5710: craft-print pin follows storytold/craft-libs#622 (230d522)

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

* #5710: pin craft-print to merged cancellation fix

* #5710: allow print cancellation after closing the document

* #5710: correct print-cancellation status date

* #5710: clarify when a print job cannot yet be cancelled in the queue

* #5710: isolate Windows print submissions in cancellable helper processes

* #5710: strengthen helper retry and crash-cleanup regressions

* #5710: erase helper inputs before driver work

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 08:52:57 +01:00
vangel76andClaude Sonnet 5.5 4e334166e5 Merge upstream/main into control-mcp-delivery-1326-1331
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-06 01:10:42 +01:00
vangel76andClaude Sonnet 5.5 4ac7292d62 Merge upstream/main into feat/recent-remove-2716
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-06 01:09:58 +01:00
28925fac8c Linux: a setting chooses the display server (Wayland / X11) (#3189)
Lands #3189.

Co-Authored-By: Yasas-Sri <164534752+Yasas-Sri@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: vangel76 <271991477+vangel76@users.noreply.github.com>
2026-11-06 00:04:18 +01:00
2fb91eece2 Clipboard: copy and paste RTF (#2630)
Lands #2630.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: dkhlapov <19991457+dkhlapov@users.noreply.github.com>
2026-11-05 23:36:19 +01:00
Martin BallandMMexicann 83bef65a1d CLI: reject malformed conversion format options (#5610)
Lands #5610.

Co-Authored-By: MMexicann <44814932+MMexicann@users.noreply.github.com>
2026-11-05 23:09:30 +01:00
Helen Kwok 5a8e6e4894 wordcraft-web: speak the host messages through craft-web-host
The transports, the message types and the origin checks come from the shared crate (storytold/craft-libs#420); WordCraft keeps the host save and dirty hooks, the saveAs rule, the open size limit and the author.
2026-11-05 17:51:01 +08:00
Helen Kwok 22989a77da web host mode: refuse an oversized host file before copying it, cap the name, and document trust and limits 2026-11-05 17:11:53 +08:00
Helen Kwok 5f9bb3f111 feat(web): page host mode, so a page can host WordCraft in its own document (#4366)
data-host="page" on the canvas opts a page that loads the module into its own document into the host bridge. The ?host=parent messages travel as non-bubbling CustomEvents on the canvas; the bridge holds a Transport (Parent or Page) with one send, and the open, save, dirty, ready and failure handling is shared. ?host=parent is checked first and unchanged, including no bridge for an unframed page. The hosting guide documents both modes.
2026-11-05 17:11:53 +08:00
NetterSilverandClaude Opus 5.5 94cbdeb4cb Keep wgpu indirect validation for x86_64 builds on Apple silicon (#5244)
Fixes #5199

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 09:13:57 +01:00
vangel76andClaude Sonnet 5.5 951b255b80 Merge upstream/main into control-mcp-delivery-1326-1331
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-05 03:26:18 +01:00
vangel76andClaude Sonnet 5.5 d5495ea4f8 Merge upstream/main into feat/recent-remove-2716
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-05 00:12:16 +01:00
Aleksander HelgakerandClaude Opus 5.5 650a97b623 ODT: remove the display settings; one choice for each open case (#5609)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 23:08:09 +01:00
Joseph AngladaandClaude Opus 5.5 bf7715785c Desktop: a window restored onto no monitor opens on screen (#4742)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-04 21:19:03 +01:00
FredApps d2f504e29a Review fixes: package-wide PBKDF2 budget, CLI keeps the ODF style, turned linked boxes, path close, centred PDF fill, doc status (gap 19) 2026-11-04 12:50:36 +01:00
FredApps 53bccd5442 ODT: two display styles (Microsoft Word style, LibreOffice style) and review fixes (gap 19)
- odf.preset: word (Microsoft Word style, default) or libreoffice; wordcraft still read as word
- Options, CLI (WORDCRAFT_ODF), docs and ROADMAP follow the two styles
- CodeRabbit: kept groups and story fingerprints follow fill_objects; padding serde default;
  list field depth; literal doubled quote; ASK/SET results not exported; dc:date offsets;
  first_pages order; unique picture names; finite raise clamp; PDF rotated-text guard;
  .ott in the password message; flat element bounded by depth; cell tile fallback;
  ROADMAP and docs reconciled
- Remove clean-room wording from the ODT tests
2026-11-04 11:55:49 +01:00
alehelandClaude Opus 5.5 56c85834f1 Merge origin/main into the ODT branch (gap 19)
Conflicts kept both sides. Where the two branches met:
- Para.mark: both added it. It stays CharProps (ODT needs it); HTML's
  `<p>&nbsp;</p>` converts its Fmt, and to_doc reads it in one place.
- Arrowheads: the PR's line ends (top left to bottom right) with main's
  arrowhead styles.
- inline_rect: the PR's depth below the baseline with main's rule room.
- Spacing and Cell literals take main's new fields.
- The zip entry guard (#3660) also covers the encrypted ODT paths, which
  parsed a package before it; regression test in tests_more/encryption.rs.
- chunks_exact to as_chunks in odt/frames.rs and odt/path.rs (clippy).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 10:51:35 +01:00