Commit Graph
1477 Commits
Author SHA1 Message Date
bflatastic 960e479d9e Paste: text from another app in a function of its own 2026-10-24 02:37:40 +07:00
bflatastic e2000bbafc Dev Mode: Revert to saved is refused there (it throws unsaved design edits away) 2026-10-24 02:35:15 +07:00
bflatastic efbe359abb Dev Mode: a drag under way when Dev Mode starts is dropped, not committed 2026-10-24 02:14:26 +07:00
bflatastic 6d85f14238 Merge branch 'main' of https://github.com/storytold/figcraft into feat/devmode-tail
# Conflicts:
#	docs/gaps.md
2026-10-24 02:07:14 +07:00
BFlat d6e8a6e874 Docs: roadmap entries for the community PRs in #507, #510, #529 and #530 (#587)
Roadmap, milestone and parity rows for the 93 community PRs landed in batches #507, #510, #529 and #530.
2026-10-24 02:02:19 +07:00
bflatastic 8972340a4e Dev Mode: explicit test imports; the Dev Mode switch and the compare view's body in helpers of their own 2026-10-24 01:59:23 +07:00
bflatastic 334b388aa3 Dev Mode review fixes: slot imports keep the slot's depth base, Shift-click deselects, a comment link pastes, Enter on a drawing tool returns to the design, formal German 2026-10-24 01:53:08 +07:00
bflatastic 16a78cc11e Keep cfg(test) on the test modules after the merge 2026-10-24 01:32:00 +07:00
aiongg 87e0c8a7da CI: shared gate workflow; FreeBSD nightly and on release (#1206)
* CI: run the gate through craft-common-actions' shared gate.yml; FreeBSD nightly and on release

ci.yml calls the shared workflow (cached apt packages, nextest, main-only cache saves, Cargo.lock check). FreeBSD runs nightly and on pushes to release instead of on pull requests. Depends on storytold/craft-common-actions#69.

* CI: build the shared gate without craft-fonts, as before

* CI: build the shared gate with release.yml's craft-fonts pin
2026-10-23 14:31:08 -04:00
bflatastic 7d5de76236 Merge remote-tracking branch 'origin/main' into feat/devmode-tail
# Conflicts:
#	ROADMAP.md
#	crates/engine/src/lib.rs
#	crates/engine/src/tools.rs
#	crates/ui-egui/locales/de.toml
#	crates/ui-egui/locales/en.toml
#	crates/ui-egui/locales/fr.toml
#	crates/ui-egui/locales/ja.toml
#	crates/ui-egui/locales/ko.toml
#	crates/ui-egui/locales/pt-BR.toml
#	crates/ui-egui/locales/zh-Hans.toml
#	crates/ui-egui/src/canvas.rs
#	crates/ui-egui/src/lib.rs
#	crates/ui-egui/src/menus.rs
#	docs/control-protocol.md
#	docs/gaps.md
2026-10-24 01:29:37 +07:00
aiongg 6ba0223636 Tests: the paragraph indent test loads system fonts and skips only without glyphs (#1227) 2026-10-23 13:50:42 -04:00
aiongg c48102350b Packaging: pin the signing client and appimagetool, and check their hashes (#950)
* Packaging: pin the Windows signing client and check its hash

* Packaging: pin appimagetool and check its hash

* Reject AppImage download for architectures without a pinned appimagetool

* Pin the AppImage runtime
2026-10-23 13:02:11 -04:00
aiongg fc7a744519 CI: one test binary per crate, nextest, line tables only (#1208)
* Dev profile: line tables for workspace crates, no debug info for dependencies

* Tests: one integration-test binary per crate with several test files

* xtask ci: nextest, doctests, tests without examples, --keep-going; add xtask test
2026-10-23 13:01:12 -04:00
Dylan M. Taylor e66780a39b packaging: use [[ for bash conditional tests (SonarCloud S7688) (#1225)
SonarCloud flags every bare [ conditional in bash scripts under packaging/ as a reliability smell (rule S7688). Convert the flagged [ ... ] tests to [[ ... ]]: safer word-splitting and no glob surprises, same semantics for these string and file tests.
2026-10-23 12:56:34 -04:00
Dylan M. Taylor 8d790607ff packaging: bash test and function hygiene (SonarCloud S7688, S7679, S7682, S131, S7677) (#1201)
- Use [[ ]] instead of [ ] for conditional tests in the bash packaging scripts (S7688). Every
  converted test compares quoted values to literals, so no pattern-matching change.
- Name positional parameters with locals inside functions (S7679).
- End the env.sh helpers with an explicit return that keeps their exit status (S7682).
- Give case statements a default branch (S131).
- Send the check-app-specific.sh error to stderr (S7677).

packaging/freebsd/package.sh is left alone while #1158 rewrites it.
2026-10-23 11:17:32 -04:00
Dylan M. Taylor 92b83521af Merge pull request #1221 from dylanmtaylor/sonar/security-reliability
test: explain the discarded reads in the fake servers (SonarCloud rust:S7450)
2026-10-23 09:57:08 -04:00
Dylan M. Taylor 32735549c4 test: explain the discarded reads in the fake servers (SonarCloud)
read() returns Result<Message>, not a lock guard; these test loops
deliberately ignore what the client sent first.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
2026-10-23 09:44:02 -04:00
Brandon ThomasandClaude Opus 5.5 80f916326f Release 0.10.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.10.0
2026-10-22 15:39:04 -04:00
Dylan M. Taylor 9ec80bf2c2 Say the library computes month and day; time-of-day is plain arithmetic
Narrows the range-extension wording: the date library computes the
calendar fields, and splitting seconds into hours, minutes and seconds
is ordinary arithmetic, which is what the code does.
2026-10-22 07:12:29 -04:00
Dylan M. Taylor a0e937918c Name the 400-year range extension as the one exception to the time rule
The rule said never to hand-roll calendar math, but the range fix
(shifting by whole 400-year Gregorian cycles so dates past chrono's year
range keep their old output) is cycle arithmetic, so the rule and the code
disagreed. The rule now names that exception: the library still computes
month, day and time, and only whole cycles are carried in the year.
2026-10-22 07:12:29 -04:00
Dylan M. Taylor e3169e5a61 collab/ui-egui: keep old UTC output past chrono's year range
`utc_date` (collab) and `date` (ui-egui) took `u64` seconds, which the old
hand-rolled civil-from-days code converted for the whole `u64` range. The
chrono rewrite used `from_timestamp(..).unwrap_or_default()`, so any instant
past chrono's own year limit (262143) silently became the epoch — changing
existing output. `u64::MAX` seconds, for example, used to read
`584554051223-11-09 07:00 UTC` / `Nov 9, 584554051223`, not 1970.

Fix: add a `utc_parts(days, sod, nanos)` helper per crate that moves the
instant into chrono's range by whole 400-year Gregorian cycles (146_097 days),
lets chrono do the month/day/time, and restores the real year afterwards.
chrono stays the only calendar logic; the cycle count just shifts the year, and
every `u64` day count fits in `i64` so the conversion is always exact (no epoch
fallback). Split seconds with `u64` arithmetic first to avoid the `i64` seconds
overflow near `u64::MAX`, matching the old code.

Tests now pin the old output instead of the epoch:
- collab utc_date(u64::MAX) == "584554051223-11-09 07:00 UTC"
  (and utc_date(253_402_300_800) == "10000-01-01 00:00 UTC", already pinned)
- ui-egui date(253_402_300_800) == "Jan 1, 10000"
  date(u64::MAX) == "Nov 9, 584554051223"
2026-10-22 07:12:29 -04:00
Dylan M. Taylor 630e0dd403 Keep 5-digit years unprefixed in utc_date
chrono's %Y writes a '+' before years past 9999, whereas the old hand-rolled
{y:04} did not. utc_date now writes the year with {:04} to keep the exact old
output. from_timestamp already reads a clock past chrono's range as the epoch
rather than panicking. Tests cover the 5-digit-year and out-of-range cases.
2026-10-22 07:12:29 -04:00
Dylan M. Taylor 0e3876e6d6 Use chrono for UTC/calendar conversion instead of hand-rolled copies
Replaces the two hand-rolled Howard Hinnant days-from-civil copies with chrono
as a workspace dependency:
- crates/collab/src/message.rs: utc_date (YYYY-MM-DD HH:MM UTC)
- crates/ui-egui/src/home_recents.rs: date (Mon D, YYYY, UTC; keeps the
  translated month names and trf formatting)
Output is unchanged. Neither function had a test, so each gains one pinning the
exact strings the old code produced (leap days included). chrono uses only std,
so wasm stays safe. AGENTS.md/CLAUDE.md now say time goes through chrono.

Follow-up to storytold/cadcraft#1785
2026-10-22 07:12:29 -04:00
BFlat 5fa586306a Merge pull request #1049 from storytold/readme/app-icon
README: the app icon above the title
2026-10-22 18:01:42 +07:00
bflatastic ce8a224c9e README: the app icon above the title 2026-10-22 17:57:45 +07:00
Dylan M. Taylor a86897dc91 ci: pin GitHub Actions to full commit SHA (SonarCloud githubactions:S7637) (#1015)
Pin third-party actions to full-length commit SHAs (with version comments)
instead of mutable tags/branches to prevent supply-chain tampering via
retagged releases. Resolves SonarCloud rule githubactions:S7637.
2026-10-21 19:36:23 -04:00
Dylan M. Taylor cb7966556c security: enforce HTTPS on curl downloads (SonarCloud S6506) (#1016)
Add --proto '=https' to curl invocations so redirects cannot downgrade to
plaintext HTTP. Resolves SonarCloud S6506 (shell/docker/githubactions).
2026-10-21 19:36:11 -04:00
Dylan M. Taylor c1a4f2d954 ci: add sonar-project.properties for CI-based analysis
Marks the project ineligible for SonarCloud Automatic Analysis, resolving the
CI-vs-automatic-analysis conflict so the SonarCloud workflow succeeds.
2026-10-21 16:00:36 -04:00
Dylan M. Taylor 0ab000b74b ci: add SonarCloud scan via shared reusable workflow
Calls storytold/craft-common-actions/.github/workflows/sonarcloud.yml@main
with secrets: inherit. Adds SonarCloud badge to README where missing and
removes the redundant sonar-project.properties (config now passed by the
reusable workflow).
2026-10-21 15:46:57 -04:00
Brandon ThomasandClaude Opus 5.5 28de91d9ae Release 0.9.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.9.0
2026-10-21 13:56:51 -04:00
Dylan M. Taylor 35da7b7cff feat(window): adopt shared craft-window for Linux decorations (depends on craft-libs#217) (#971)
* feat(window): adopt shared craft-window for Linux decorations

Replace FigCraft's bespoke Wayland xdg-decoration probe
(apps/figcraft/src/linux_window.rs) with the shared craft-window crate
from craft-libs, so every Craft app agrees on who draws the window frame
per desktop.

The decision is now made once, before the viewport is built, by
craft_window::Choice::probe(Prefix::new("FIGCRAFT")) and mapped onto
FigCraft's existing TitleBar enum:

  Frame::Desktop => TitleBar::Native   (TitleBar::Inset on macOS, unchanged)
  Frame::App(_)  => TitleBar::Custom

This drops the old runtime send_viewport_cmd(Decorations(..)) switch and
the linux_window probe. macOS keeps its inset traffic lights and Windows
keeps the system frame exactly as before. The only behaviour change: on
KDE and other Wayland compositors with server-side decorations (Sway,
Hyprland, COSMIC) FigCraft now keeps the native frame instead of always
drawing its own custom title bar, matching the rest of the suite.

NOT MERGEABLE YET: craft-window is pinned to the unmerged feature branch
from storytold/craft-libs#217 and must be repointed to a merged rev
before this can land.

* fix(window): preserve Windows titlebar; pin craft-window to merged rev

- Keep FigCraft's own custom title bar on Windows. craft-window returns
  Frame::Desktop on Windows, and the mapper was turning that into
  TitleBar::Native, flipping Windows from its existing undecorated custom
  bar to the system frame. Map Frame::Desktop to Custom on Windows (as
  macOS maps to Inset); only Linux/BSD Frame::Desktop becomes Native. This
  keeps macOS and Windows unchanged; the sole change stays KDE/Wayland.
- Repoint craft-window from the (now-merged) feature branch to the squash
  commit on storytold/craft-libs (craft-libs#217), and commit Cargo.lock.

Verified: cargo build -p figcraft and cargo test -p figcraft (53 tests)
pass against the merged dependency; rustfmt clean.
2026-10-21 06:05:08 -04:00
BFlat 74c4a84da3 Merge pull request #907 from RiceDee/fix/idle-tests-font-scan
test(ui-egui): idle harness scans system fonts before its first frame
2026-10-21 16:32:52 +07:00
BFlat 123e46550f Merge pull request #909 from RiceDee/fix/component-set-name
#903 follow-up: name new component sets from the variant path, not the first property
2026-10-21 16:31:04 +07:00
BFlat 44e64d8d47 Merge pull request #933 from SiadeLucas/feat/pages-scroll-area
ui: keep the current page scrolled into view in the pages list (#930)
2026-10-21 16:21:38 +07:00
BFlat bb532a5790 Merge pull request #908 from RiceDee/feat/903-variants-discoverability
#903: Combine as variants in the context menu and Design panel; Add variant on a lone component
2026-10-21 16:01:25 +07:00
BFlat f6f44dcc53 Merge pull request #928 from AganzeFelicite/fix/web-drop-opens-documents-916
M7: a document dropped on the canvas opens as a new file (#916)
2026-10-21 15:50:24 +07:00
BFlat 96a82edecf Merge pull request #939 from YarilaFox/fix/comment-draft-on-tool-switch
M7: dismiss comment draft when switching tools
2026-10-21 15:48:42 +07:00
BFlat f143260c3a Merge pull request #935 from YarilaFox/fix/saved-document-title
M7: show the chosen filename for saved documents
2026-10-21 15:47:09 +07:00
BFlat bb93e5e433 Merge pull request #929 from Silvertree2010/fix/h881-local-from-link-accepts-a-sign-i
Reject non-hex characters in Local::from_link token
2026-10-21 15:44:45 +07:00
BFlat da96d54157 Merge pull request #961 from Silvertree2010/fix/h1145-reversesubpaths-reverse-subpaths
Keep open subpaths open in ReverseSubpaths::reverse_subpaths
2026-10-21 15:35:17 +07:00
BFlat a1758c163f Merge pull request #958 from Silvertree2010/fix/h1112-live-text-svg-export-capitalises
Fix Title Case restarting mid-word across styled runs in SVG export
2026-10-21 15:34:55 +07:00
BFlat b1d00f0802 Merge pull request #943 from Silvertree2010/fix/h932-trim-num-prints-any-whole-number
Fix trim_num saturating whole numbers beyond i64 range
2026-10-21 15:34:34 +07:00
BFlat efb95b29bf Merge pull request #938 from Silvertree2010/fix/h911-same-server-ignores-the-scheme-s
Strip default port in same_server when the address has a path
2026-10-21 15:34:08 +07:00
BFlat 9257f97d69 Merge pull request #911 from Silvertree2010/fix/h737-parse-css-accepts-a-malformed-al
Reject malformed alpha and extra args in Color::parse_css
2026-10-21 15:33:47 +07:00
NetterSilverandClaude Haiku 5.5 2e12bdfd91 Keep open subpaths open in ReverseSubpaths::reverse_subpaths
Found while testing crates/geom/src/lib.rs:287

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 02:46:23 +02:00
Siade Lucas f53f37dfe0 ui: scope page tracker by document UID and update on render
Include document UID in pages_seen_page to correctly handle page selection and scroll tracking when switching between documents. Record page as seen only after the active row renders so that pages filtered out by search scroll into view when the filter is cleared.
2026-10-20 21:28:09 -03:00
NetterSilverandClaude Haiku 5.5 59f3b3b733 Fix Title Case restarting mid-word across styled runs in SVG export
Found while testing crates/svg/src/lib.rs:589 (also :604 and :611)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 00:31:03 +02:00
NetterSilverandClaude Haiku 5.5 77f4271061 Fix trim_num saturating whole numbers beyond i64 range
Found while testing crates/doc/src/text.rs:64

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 17:03:45 +00:00
YarilaFox 8f3afbf6a1 M7: clear comment drafts for control-channel tool changes 2026-10-20 21:04:04 +05:00
Siade Lucas 1c79c1646f ui: scroll active page into view when selection changes 2026-10-20 12:53:21 -03:00