Commit Graph
177 Commits
Author SHA1 Message Date
dotCooCoo 3004a05e46 Updates: take craft-update from craft-libs main at 1b34eba41 2026-11-08 19:45:34 -08:00
dotCooCoo 99bbd237fc Updates: the updater reports installing, ready, installed and failed, and installs at exit
craft-update, craft-window, craft-print and craft-ui move from craft-libs
c5a1cbfb to c7c84230, a branch with storytold/craft-libs#687 and #696
merged into craft-libs main.

- The check result window shows whenever the updater's status is not
  idle, so the first start after an update reports that it installed or
  why it failed. Restart to Update asks the app to quit once nothing is
  unsaved.
- An update's close request quits the app (Quit asks about each unsaved
  workbook), so every workbook window closes.
- on_exit starts the install helper of a ready update before the macOS
  process exit.
2026-11-08 11:53:25 -08:00
Helen Kwok fb17d0d1d5 gridcraft-web: say a call the app already took still finishes after a timeout 2026-11-07 10:28:03 +08:00
Helen Kwok 89ec06f041 gridcraft-web: window.gridcraft, the page command API from craft-web-api
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. A call the page gave up on is released, so the app skips it instead of running it late. The API is installed in every mode; opening, saving, the file name and the unsaved flag stay with the host messages.
2026-11-07 08:03:07 +08:00
Helen Kwok e06b2a7ead gridcraft-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); GridCraft keeps the download hook, the open size limit, the workbook-saved rule and the author.
2026-11-05 17:51:00 +08:00
Helen Kwok bf6bee500a web host mode: refuse an oversized host file before copying it, cap the name, and document trust and limits 2026-11-05 17:03:44 +08:00
Helen Kwok d628abb7b0 Web: page host mode, so a page can host GridCraft in its own document (#2592)
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; Bridge holds a Transport (Parent or Page) and shares the save, dirty and ready logic. Unframed ?host=parent still gets no bridge. Hosting guide documents both modes.
2026-11-05 17:03:44 +08:00
Dylan M. Taylor 74111e5a93 check: charge relationship parts to the package's decompression budget (#3185)
* check: charge relationship parts to the package's decompression budget

* address review: charge bytes read before a package part decompression error
2026-11-03 22:50:40 -05:00
Brandon Thomas 3bdfa6ed71 Merge PR #3253 2026-11-03 09:55:38 -05:00
Hector VillarrealandClaude Opus 5.5 94b4f6a3a2 #1481: open SYLK (.slk) files
A small reader for the SYLK text format: cell values (numbers, text,
booleans, errors), formulas converted from R1C1 to A1 as Excel does
(relative/absolute references, ranges, whole rows and columns, shared
formulas) with their cached results, number formats (P / F;P) and
column widths (F;W). Import only; saving as .slk says so. The sheet is
named after the file, and damaged records are skipped with a warning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 02:51:39 -06:00
adifiedio ac27137cd8 Clipboard: paste a picture from the system clipboard at the active cell (#699)
Cmd/Ctrl+V dropped egui's PasteImage event, and the ribbon/menu Paste only read
text, so screenshots and images copied in a browser reported "Nothing to paste".
Both now encode the pixels as PNG (bounded to 16384 px per side, 64 Mpx) and run
insert.picture as a floating picture anchored at the active cell, as Excel does.
Text on the clipboard still wins. New host service: Services::paste_image (arboard).

Fixes #699, #3018, #3182.
2026-11-03 14:14:34 +05:30
Dylan M. Taylor e8ccb5eb15 check: find volatile defined names with a worklist instead of repeated passes (#3187) 2026-11-02 23:33:31 -05:00
FredApps 6558f26ba8 Merge current main into fix/gnome-window-decorations 2026-11-02 19:10:45 +01:00
Brandon Thomas 229b6001ec Merge PR #3083 2026-11-01 12:18:01 -05:00
vioreltusandClaude Opus 5.5 5e415cdd34 macOS: Intel Macs skip wgpu's indirect-call validation shaders (fixes #2812) (#3039)
* Fix #2812: Intel Macs skip wgpu's indirect-call validation shaders

Metal's Intel compiler aborts on wgpu's indirect-validation compute shaders
("Compiler encountered an internal error"; MTLCompilerService crashes in
reportUnsupportedMaxWorkGroupSizeMetadataError), the device is lost inside
request_device and GridCraft exits before its window opens. GridCraft issues
no indirect draws or dispatches, so on Intel Macs the instance leaves
VALIDATION_INDIRECT_CALL out; WGPU_VALIDATION_INDIRECT_CALL=1 turns it back
on. Every other platform keeps wgpu's default. Same as WordCraft (#2652 there).

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

* Review: test that WGPU_VALIDATION_INDIRECT_CALL=1 still turns it on; qualify the doc line

The override is checked in a child test process with the variable set, since
tests can't set environment variables without unsafe code. The revision line
no longer says Intel Macs start: OpenCore Legacy Patcher Macs on macOS 15 can
still fail on the MSL version (#1116).

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-11-01 10:54:28 +01:00
aiongg 7ed8a9f312 fix(quit): bring GridCraft forward through AppKit for a Dock quit
egui's Visible/Minimized/Focus go through winit, whose macOS focus_window skips a minimized window or a hidden app, and macOS can refuse the activation. When a Dock quit opens a question, unhide the app, deminiaturize its windows and activate it through AppKit, and bounce the Dock icon if it still isn't active.
2026-11-01 04:30:17 +00:00
aiongg 79722c7666 updates: show check results with craft-update's CheckResultDialog 2026-10-31 04:42:26 +00:00
Brandon Thomas 885a5dd6bc Merge PR #2970 2026-10-30 15:42:31 -04:00
Brandon Thomas 3e4a2ccc9a Merge PR #2726 2026-10-30 15:42:10 -04:00
Brandon Thomas 92256075f2 Merge PR #2722 2026-10-30 15:42:10 -04:00
Brandon Thomas 9e2d5ef17f Merge PR #2718 2026-10-30 15:42:10 -04:00
Aimar Mendez 1d38a25c8d macOS menu test: use the whole native menu, so clippy passes on a Mac
e6df6f42 removed the #[allow(unused_imports, dead_code)] on the
native_menu module that tests/mac_menu_appkit.rs builds in. That test
only compiles on macOS, so `cargo xtask ci` has failed at clippy on
every Mac since, while the Linux gate stayed green:

- the test called only `install`, leaving `poll`, `sync_windows`,
  `select_theme`, `WINDOW_ITEM` and most `NativeMenu` fields unused;
- the harness = false build has cfg(test) but drops #[test] functions,
  so the unit tests' `use super::*` was an unused import.

The test now also polls the menu with a one-workbook session and checks
that the Window menu lists that workbook (#716), which uses the rest of
the module. The unit tests name `super::` items instead of a glob import.

Verified on macOS 27 (arm64): `cargo xtask ci` passes all 10 steps (with
CRAFT_FONTS_DIR at the gate's craft-fonts commit), and the new check
fails when the poll is removed (Window menu's last item "" vs "Book1").
2026-10-30 18:19:50 +00:00
Dylan M. Taylor f6bcd77b01 Update prompt shows the app icon and accent color instead of a letter (#2928)
UPDATE_APP (native builds; craft-update is a native-only dependency) carries our 128 px icon and accent (#1f9d55, its colour in ArtCraft Launcher). The updater, the self-update
helper and craft-update's startup prompt all get them through crate::UPDATE_APP; the
prompt draws the icon, the accent and "by ArtCraft" (craft-update's default developer).

craft-update is pinned to storytold/craft-libs main at 1065653e7 (#434).
2026-10-30 01:28:55 -04:00
Dylan M. Taylor e6df6f423b Refactor the gridcraft apps for strict Clippy checks 2026-10-28 10:52:53 +00:00
Daniel 44c3a36ea1 Merge upstream main and refresh Wayland decoration dependencies
Keep the Linux Adwaita no-title feature with X11 fallback; preserve
non-Linux Unix targets, regenerate the merged lockfile entries, and
retain the dependency's MIT notice without duplicate package installs.
2026-10-28 10:33:31 +01:00
AnhNgoo c22f46628c fix(desktop): load preferences before creating startup workbook 2026-10-28 10:47:42 +07:00
aiongg 6303865054 fix(ui): dropdown menus grow back after a search with no matches (#2743)
* fix(ui-egui): dropdown menus regrow while open

Use craft_ui's ComboBox and combo::Menu so a menu that shrank (a filter with
no matches) grows back when the filter is cleared (egui#5225). Repin
craft-libs to one revision.

* chore(deps): craft-libs 60d60d48 (dropdown fixes)

* chore(deps): craft-libs 6af63481 (dropdown fixes)

* chore(deps): craft-libs 4d7b82f7 (dropdown fixes)

* chore(deps): craft-libs 92d392cf (#387 merged)
2026-10-27 10:26:30 -04:00
Higgs32584andClaude Opus 5.5 a38aed68cb Security: control channel enforces its 10 s token deadline and caps waiting connections (#2717)
authenticate() set the read timeout on the writing half of the socket while it read the
token through a try_clone; on Windows the clone has its own timeout, so a peer that never
sent a line held its thread forever (and a per-read timeout let a byte-at-a-time peer
stretch it elsewhere). The first line now has one total deadline, set on the handle being
read and shortened before each read. At most 16 connections may wait to authenticate (more
are closed on accept, as #2174 suggested), and accept errors back off instead of spinning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 00:55:44 -04:00
Higgs32584andClaude Opus 5.5 4cc2c44678 Security: web links open with noopener as a window feature, not in the window name (#2715)
window.open(url, "_blank,noopener") named the new window "_blank,noopener" and passed no
features, so a page opened from a workbook link kept window.opener and could navigate the
editor tab. Pass "noopener,noreferrer" as the features argument instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 00:39:40 -04:00
aiongg da0cb382ae refactor(gridcraft-cli): move check.rs items to check/ 2026-10-26 21:16:41 +00:00
aiongg a8db625e6b style: cargo fmt on the moved test files 2026-10-26 18:15:59 +00:00
aiongg da40ecba3a refactor(gridcraft-cli): move check tests to src/check/tests.rs 2026-10-26 18:15:39 +00:00
aiongg 58e33dfef6 refactor(gridcraft): move logging tests to logging/tests.rs 2026-10-26 18:15:32 +00:00
aiongg c7911c836a G3: craft-libs at storytold main b926b5c0 2026-10-26 03:28:46 +00:00
aiongg 94fcbf8b4c G3: craft-libs at e8b4dde5 (craft-libs#340)
craft-update, craft-window, craft-ui and craft-print all come from one craft-libs revision, the
head of storytold/craft-libs#340 on the aiongg fork, until #340 merges.
2026-10-26 02:37:42 +00:00
aiongg 015b9abe5b Merge g2 into g3
# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	ROADMAP.md
#	apps/gridcraft/src/main.rs
#	crates/ui-egui/src/lib.rs
#	docs/ui-parity.md
2026-10-26 02:37:36 +00:00
aiongg 929495e274 Merge g1 into g2
# Conflicts:
#	ROADMAP.md
#	crates/engine/src/cmd/extra.rs
#	crates/engine/src/lib.rs
#	crates/engine/src/tests.rs
#	docs/control-protocol.md
#	docs/ui-parity.md
2026-10-26 02:37:33 +00:00
aiongg 903bece86f Merge upstream main into g1
# Conflicts:
#	ROADMAP.md
#	crates/engine/src/tests.rs
#	crates/ui-egui/src/lib.rs
#	docs/ui-parity.md
2026-10-26 02:23:11 +00:00
Dylan M. Taylor 6f0e43c21c Linux: default to XWayland for file drag-and-drop on Wayland desktops (#165)
* Linux: default to XWayland for file drag-and-drop on Wayland desktops

* Ignore an empty DISPLAY before forcing X11
2026-10-25 19:37:08 -04:00
Daniel 0cb1745597 Merge latest upstream main and resolve GNOME Wayland control conflicts 2026-10-26 00:00:39 +01:00
Dylan M. Taylor 2fbbed33bc Merge pull request #783 from vangel76/fix/control-auth-777
Security: the --control server requires an auth token and closes bad connections (#777)
2026-10-25 16:45:46 -04:00
Dylan M. Taylor 1a36d9db07 feat: startup update prompt modal and direct self-updating (#2566)
* feat: startup update prompt modal and direct self-updating

The update flow (check at start or on request, the startup prompt, the self-update worker) is craft-update's Updater; the app only supplies the suite, its close path and its status message. An install holds back while the workbook is unsaved.

Ref: storytold/craft-libs#319

* build: refresh the lock

* build: pin craft-update to craft-libs main (db19c37)

* fix(updates): address review feedback

Wake the UI when a manual check is queued from a menu callback; the update prompt owns the keyboard while it is open (LightCraft); Download opens through the desktop URL hook (FilmCraft); the Help menu dispatches through menus::invoke (FigCraft); print jobs and comment drafts hold an install back (WordCraft); Check for Updates is a registered command (GridCraft); an install holds back while documents are unsaved.

* fix(updates): add Check for Updates… to the native macOS Help menu
2026-10-25 15:37:52 -04:00
skylar taylor-barrick 41769f1d16 Migrate GridCraft to egui 0.37 (#2543)
* E37: migrate GridCraft to egui 0.37

Pin the reviewed fork and shared dependencies, adapt input and rendering to the
new frame lifecycle, and preserve bounded capture handling and font notices.
Add representative accessibility checks and meaningful control labels.

Validation: full repository CI passed all ten stages, with 2,249 tests passed,
zero failed and one existing timing test ignored. Native workflows and paired
performance qualification remain documented separately.

* egui037: record final published pins and local qualification

* M0.37: fix RTL clipping and preserve screenshot budgets

* test: share migrated GridCraft UI harness setup

* egui037: document migrated UI and regression contracts

* egui-037: align popup test fonts and avoid redundant tooltip probes
2026-10-25 14:55:00 -04:00
3b65b9af58 Sonar maintainability: explicit imports, method paths, smaller functions (#2412)
* Sonar: explicit imports, fn paths for closures, extract helpers for cognitive complexity

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

* Fix imports

* Fix serde imports

* Fix engine imports

* Fix clippy gate and a type error from the explicit-import change

Remove the unused imports the review flagged (cf.rs, pivot.rs, tables.rs, cmd/sheet.rs) so clippy -D warnings passes, and point the backstage parent-folder lookup at Path::to_str, which the fn-path rewrite had broken.

Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* Apply rustfmt to the explicit-import cleanup so the fmt gate passes

* Share the per-directory font path expansion in theme.rs

The candidate font lists repeated the same loop over the Linux font
directories in every role. A single helper expands them in the same order,
so the lookup order is unchanged and the duplicated blocks go away.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* Read the Windows fonts folder in one place in theme.rs

Every script-font list repeated the same WINDIR lookup. A single helper
returns the same path, so the duplicated lines go away without changing
which font files are tried.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* Build the light and dark UI palettes from one table in theme.rs

Tokens::light() and Tokens::dark() listed the same 40 colour fields in the
same order, so every change had to be made twice. A single palette
constructor takes the mode and picks each colour's value, so each field is
written once and both modes keep their exact colours.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* Share the Noto CJK font list between the CJK script lists in theme.rs

The Japanese, Simplified and Korean lists each repeated the same loop over
the Linux CJK directories with a different locale file name. One helper
builds that loop, and each list keeps its own face index, so the lookup
order is unchanged.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* Share Linux Noto directory list across Thai and Hebrew font lookups

Removes the duplicated directory arrays flagged by SonarCloud new-code duplication.

* Reuse in_dirs for Thai and Hebrew Noto font candidates

Removes the remaining duplicated per-directory loops flagged by SonarCloud.

* Share one font-list builder for the Thai and Hebrew faces

The two per-script functions repeated the same Windows, macOS, Linux and
variable-font setup. A single script_fonts helper now builds both lists,
keeping the candidate order unchanged, which clears the Sonar duplication gate.

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Codebuff <noreply@codebuff.com>
2026-10-25 12:32:02 -04:00
Brandon Thomas 0469b51c93 Merge pull request #2444 from OdooPudakMachinery:web-chrome-flag 2026-10-25 09:36:37 -04:00
NetterSilverandClaude Haiku 5.5 64a78a7210 Print huge and tiny CLI numbers in exponent form
Found while testing apps/gridcraft-cli/src/main.rs:196-199 (number_text, used by value_text and check.rs:627)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 09:44:39 +00:00
Arie NugrahaandClaude Code 276cd0fe78 web: parse ?chrome= so an embedding host can leave out the title bar and File tab
#1877 added Chrome to SheetApp for hosts that embed the sheet natively, but the web build never set it: an iframe host that owns the files still draws the title bar it duplicates, and Backstage's Open/Save As can replace the document behind the host's back. Parse the flag where the other URL flags are parsed; the UI already honours Chrome, so nothing else changes.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-24 13:00:37 +00:00
Dylan M. Taylor 10bec74810 M6: misc hardening — unbounded picture cache, stats walk, signing tmpdir, web clipboard, dash budget, fs cycle, rezip loop (#2422)
- floating_pictures: draw without retaining when eviction can't free
  enough room, so a large workbook can't pin the cache past its budget
- xtask stats: skip unreadable subtrees instead of aborting the walk
- import-cert.sh: per-run private temp dir instead of predictable
  paths in a shared root
- gridcraft-web: gate clipboard ops behind user activation
- chart raster: cap dash rendering to the stroked budget
- cli check: mark directories visited by identity on unix so hard-link
  loops can't recurse; reuse one decompression of a reused part
2026-10-24 06:33:19 -04:00
Daniel b36a3a9b8b Merge upstream main and preserve GNOME Wayland controls
Integrate GridCraft's latest Cargo/package changes and keep the font-free CSD feature, NOTICE and packaging.
2026-10-24 10:23:59 +02:00
Brandon Thomas 2a4cc2a5b6 Merge PR #2369 2026-10-23 16:04:58 -04:00