Commit Graph
4092 Commits
Author SHA1 Message Date
Oleksii SukholitaandOleksii Sukholita 74698fa89f M7: links open in the browser in the desktop app, What's new on the update prompt among them (#2216)
The desktop app built eframe without its `links` feature, so egui-winit dropped every
`ctx.open_url` with only a log warning: the update prompt's What's new link and Download
button, the About and Credits links, Terms in Live and the link in the Dev Mode panel did
nothing on click. The feature adds no crate: `webbrowser` is already a dependency of the app.
DeckCraft's desktop app builds eframe with it too.

`links_in_the_interface_open_in_the_browser` fails without the feature.

Co-authored-by: Oleksii Sukholita <oleksii.sukholita@gmail.com>
2026-11-11 20:23:45 +01:00
Dylan M. Taylor 2cfd2a3531 collab-net: hand the sync client the bounded roster; assert the kept prefixes 2026-11-11 19:16:24 +00:00
Dylan M. Taylor 9d48625995 layout: leave out a grid that would pass the snap budget 2026-11-11 18:57:25 +00:00
Dylan M. Taylor 70ed6c1636 svg import: budget attribute work over the whole file and DTD, map span offsets in one pass 2026-11-11 18:53:53 +00:00
Dylan M. Taylor a8e34e75a8 components: work out each main's layer paths once while linking imported instances 2026-11-11 18:38:59 +00:00
Dylan M. Taylor 41c1ad3458 Merge pull request #2263 from storytold/chore/craft-update-6e03f65
Updates: take craft-update from craft-libs main at 6e03f65bf
2026-11-11 12:44:22 -05:00
Dylan M. Taylor 2446e8718b Updates: take craft-update from craft-libs main at 6e03f65bf 2026-11-11 12:44:16 -05:00
Dylan M. Taylor 2f8dd85f42 load: share one layer allowance across Penpot raw SVGs, sum font-run coverage once 2026-11-11 17:43:55 +00:00
Trevor BrownandClaude Opus 5.5 9f51517f23 M8: view.pan's parameter text and the MCP guide give the measured steps
64 screen pixels a step, five times as far with big (320), as the code
and the measurement have it; they still said ten times and 20 / 200.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 12:39:56 -05:00
Trevor BrownandClaude Opus 5.5 fa4883ad3a M8: UI parity doc: the main menu row after the merge with #2220
The merge spliced this branch's submenu sentence into the middle of
main's row. The row is main's again, with the measured first-frame
sentence in place of the old 0.15 s one and #2220's overflow sentence
kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 12:38:33 -05:00
Dylan M. Taylor 8415de0bad ci: run Harden-Runner on every job (#2258)
Adds step-security/harden-runner (audit, pinned to v2.22.4 like
craft-common-actions) as the first step of each job that did not have it,
so every workflow in the org's public repos reports its egress to
StepSecurity. Audit, not block: block-mode allow lists come from each
job's observed traffic.
2026-11-11 12:11:16 -05:00
ljkx 452ee9b74a Merge remote-tracking branch 'origin/main' into fill-row-copy 2026-11-11 17:58:31 +01:00
Dylan M. Taylor a40c76ab68 collab-net: cut a host's peer names and colours where the guest keeps them 2026-11-11 16:48:03 +00:00
Trevor BrownandClaude Opus 5.5 7effcfc3e9 Merge upstream/main into feat/wrap-style-paragraph-and-style-1827
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:56 -05:00
Trevor BrownandClaude Opus 5.5 607a196e35 Merge upstream/main into feat/annotation-tool-1840
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:56 -05:00
Trevor BrownandClaude Opus 5.5 a728f3fb3e Merge upstream/main into fix/shift-rotate-multiples-of-15
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:54 -05:00
Trevor BrownandClaude Opus 5.5 89d3e16168 Merge upstream/main into feat/invert-zoom-2145
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:51 -05:00
Trevor BrownandClaude Opus 5.5 b2d7b02275 Merge upstream/main into fix/panel-widths-measured
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:49 -05:00
Trevor BrownandClaude Opus 5.5 cf17c66a13 Merge upstream/main into feat/scale-tool-focus-2146
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:49 -05:00
Trevor BrownandClaude Opus 5.5 a1cb5309f4 Merge upstream/main into feat/vector-edit-clipboard-1875
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:44 -05:00
Trevor BrownandClaude Opus 5.5 83773deb92 Merge upstream/main into fix/selection-colors-single-2188
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:44 -05:00
Trevor BrownandClaude Opus 5.5 b3bb5dfda9 Merge upstream/main into fix/eyedropper-magnified-pixels-2189
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:42 -05:00
Trevor BrownandClaude Opus 5.5 74d7cff672 Merge upstream/main into fix/arrow-pan-step-measured
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:41 -05:00
Trevor BrownandClaude Opus 5.5 794fe03690 Merge upstream/main into fix/crosshair-glyph-2198
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:39 -05:00
Trevor BrownandClaude Opus 5.5 e829590fdf Merge upstream/main into fix/escape-deselects-measured
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:38 -05:00
Trevor BrownandClaude Opus 5.5 043cce4996 Merge upstream/main into fix/boolean-corner-radius-2222
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:33 -05:00
Trevor BrownandClaude Opus 5.5 c6b030ae02 Merge upstream/main into feat/vector-edit-point-xy-mixed
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:31 -05:00
Trevor BrownandClaude Opus 5.5 986f6d0a4c Merge upstream/main into fix/header-icon-size-2227
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:30 -05:00
Trevor BrownandClaude Opus 5.5 a85bd83bc7 Merge upstream/main into fix/submenu-opens-without-delay
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:25 -05:00
Dylan M. Taylor 9aaf7114e0 widgets: bound the decoded pixels of a widget's images, read from their headers 2026-11-11 16:37:35 +00:00
Dylan M. Taylor 1935c3eac2 layout: bound the snap lines a frame's grids generate 2026-11-11 16:03:10 +00:00
Dylan M. Taylor 4d3fe2aa1a svg import: cap attributes per element, map span offsets to characters once 2026-11-11 15:59:59 +00:00
Trevor BrownandClaude Sonnet 5.5 b8f05d1948 M4: a typed number and full stop start a numbered list at that number, as measured in Figma
Typing `5. ` at the start of a plain paragraph starts a numbered list whose first item reads 5 (Figma has no start-number field); the next item goes on with 6. Digits only, 1 to 9999; `0. `, `12a. ` and `2)` stay text (not measured), `1)` works as before. The measured restart rows (plain paragraph, bullet item) are no longer marked silent.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Opus 5.5 briefed; Sonnet 5.5 wrote at medium
2026-11-11 09:58:57 -05:00
Trevor BrownandClaude Opus 5.5 92753a8f6d M2.1: auto layout parity doc: a Fill child's minimum still sizes its fr track
The minmax(0, 1fr) rule holds for fixed-size and hug-size children; a
Fill child's own minimum keeps its track at least that big, as before
(not measured).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 09:39:43 -05:00
rumangerst 7bf098d75d fix(ui): paste uses the event's clipboard text instead of re-reading it (#2021) (#2243)
The paste handler read the system clipboard synchronously (2 s timeout) even
though the paste event already carries that text, and discarded the read's
result. On the desktop, the clipboard bridge delivers `event_text` that it read
while the window thread was free; re-reading from the paste handler blocks that
same window thread - and when the app itself owns the clipboard (a self-paste),
its own data source can only be served by that very thread, so every self-paste
froze the window for the full 2 s read timeout on Linux/Wayland.

Prefer the event's text and only fall back to the synchronous read when the
platform handed over none (chords, image-only clipboard, context-menu paste).
A regression test pins that a paste event carrying text never triggers the
synchronous read.
2026-11-11 15:37:20 +01:00
Trevor BrownandClaude Sonnet 5.5 2dd1b5a53a Menus: the main menu and its submenus stay inside the window and scroll when taller (#2217) (#2220)
Submenus of the main menu were not constrained to the window (constrain: false, so they sit
beside their row), so the Object submenu ran past the bottom edge with its lowest commands out of
reach. Menus and submenus are now held within the window's height (moved up, never above the top,
8 pt margins, still beside their row so menu-aim is unchanged), and a panel taller than that
scrolls with the wheel; the keyboard's focus scrolls into view.


Model-Effort: Opus 5.5 drove; Opus 5.5 briefed; Sonnet 5.5 wrote at medium

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-11 15:32:21 +01:00
Pavel Ivanov 9e815546ba M8: switching back to a tab shows its page at once (#2075)
* **No blank canvas** when switching back to a document tab or to a page in a file: the image it had when last shown is drawn from the first frame while it renders again
* Images of up to four recently shown files and pages are kept; closing a tab frees its image right away

Refs: #2074
2026-11-11 15:05:04 +01:00
Trevor BrownandClaude Sonnet 5.5 401f449729 M8: zoom previews: scan system fonts before the zoom-preview tests render (#2230)
pans_and_edits_get_no_preview_and_build_on_the_kept_image failed in full lib runs with "a pan after a previewed zoom renders strips only: Full". The render kept from the zoom is stale once the global font generation changes (retained.rs prepare: last.fonts == layout_generation()), and the once-per-process system font scan that many other tests start bumps it (fontdb.rs scan_system_fonts -> clear_layout_cache). When that scan landed between the test's zoom and its pan, the pan redrew in full instead of patching. Unrelated to the clock or the threshold. document() now runs scan_system_fonts() first (a concurrent caller waits for the scan), so the generation is settled before any render. Test-only change; the shipped staleness check is intended behaviour.

Stress, full lib binary with 16 test threads: 3 of 6 runs failed before, 0 of 25 after.


Model-Effort: Opus 5.5 drove; Opus 5.5 briefed; Sonnet 5.5 wrote at medium

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-11 15:02:45 +01:00
Dylan M. Taylor 0f08269067 fix(collab-net): never send the server key over plain ws:// to another machine (#1923)
* fix(collab-net): never send the server key over plain ws:// to another machine

Publishing a plugin, uploading or sharing with the server's key accepted a
ws:// address for a remote host, so the reusable administrative key went
out in clear text. The key now goes only over wss://, or over ws:// to
this machine (loopback or localhost); browsing without a key is unchanged.

* address review: connect only to loopback addresses for a plain ws://localhost endpoint
2026-11-11 08:36:29 -05:00
Trevor BrownandClaude Opus 5.5 daa6b5b219 M2.1: auto layout parity doc: the behaviour suite's case count
The suite has 68 cases with this branch's three (the intro still said
64, and the revision row named totals nobody had counted).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 08:27:14 -05:00
Trevor BrownandClaude Sonnet 5.5 a28c03d9f1 M2.1: grid Fill tracks share the space and let a fixed child overflow, as measured in Figma
On a fixed-size axis a Fill (1fr) track now splits the free space by its fraction, after gaps and padding, and a fixed-size or hug-size child alone in it asks nothing of the track, so a child bigger than its share overflows into the next track. Measured in Figma web: frame 300 x 200, rows 1fr / 1fr, children 100 x 150 and 100 x 20 give rows 100 / 100 (second child at y 100); with a row gap of 10, rows 95 / 95 (y 105); with the frame height on Hug the rows fit their content, 150 / 20 (frame 170). This replaces the 2026-10-11 rule from the documentation (a track never gets less than its content). Unchanged: a Fill child's own minimum, spanning children, Hug and Fixed tracks, the Hug-axis path.

Three behaviour cases flipped to the measured rule and three added with the measured numbers; the two parity docs are updated.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Opus 5.5 briefed; Sonnet 5.5 wrote at medium
2026-11-11 08:26:17 -05:00
Trevor BrownandClaude Sonnet 5.5 06ffeca801 M4: Every loop a bridge closes takes it; only a real removal closes loops (#1951)
The closing pass moves out of reopen_loops (back to main's body) into close_bridged_loops, run only by remove_segments and delete_vertices when the segment or point count changed. Every loop takes what closing_segment returns against one snapshot, so two fills that shared a deleted border both close through the bridge, as rounding already draws them. The owner map is gone.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Fable 5.1 decided; Sonnet 5.5 wrote at medium
2026-11-11 05:55:33 -05:00
Trevor BrownandClaude Sonnet 5.5 641cc41594 M4: Flatten bakes a vector's point corner radius into its path (#2195)
Flatten used the vector's network as stored, so a rounded point kept its radius and the box kept the cut-off sharp vertex. It now takes the network as the layer draws it (VectorNetwork::rounded_smoothed through geometry::drawn_network): each rounded point becomes the arc's end points joined by curves, every radius reads 0, and the layer's box is re-fitted to the baked geometry. Shapes' own radii were already baked; a rounded point beside a curved segment keeps today's behaviour.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Opus 5.5 briefed; Sonnet 5.5 wrote at medium
2026-11-11 04:54:20 -05:00
Trevor BrownandClaude Opus 5.5 153fa08d07 M4: reopen_loops looks up each closing segment's chain in a map (#1951)
Checking a loop's closing segment against every closing already accepted was quadratic in the
number of open loops. A map from closing segment to the chain that took it first answers it in
one lookup; behaviour is unchanged. A test closes 50 independent chains through their own
segments.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and wrote
2026-11-11 04:38:33 -05:00
Trevor BrownandClaude Sonnet 5.5 35d46208cf M4: Shared open loops all close through their segment; one index per rounding pass (#1951)
Two regions over one open chain both got the closing segment when rounded, but reopen_loops gave it to the first loop only, so after an unrelated deletion the second region's curved closing segment dropped out of its fill. The pass now takes the segment for every loop that walks the same chain (same segment set); a different chain still can't share it.

closing_segment no longer scans every segment and every loop per call: rounded_smoothed and reopen_loops build one LoopIndex (endpoint pair to segments, and which segments are in a loop) per pass and pass it in.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Opus 5.5 briefed; Sonnet 5.5 wrote at medium
2026-11-11 03:48:24 -05:00
dotCooCoo 3d4c798ff2 Export: the Vietnamese color profile note names the file's color profile
The Vietnamese row said "cấu hình của tệp" (the file's configuration)
for the file's profile. It now says "hồ sơ màu của tệp", the term the
Color profile label uses.
2026-11-10 23:58:47 -08:00
dotCooCoo 016dba8c34 Export: the color profile note says Display P3 tagging applies to exports that use the file's profile
An export setting set to sRGB still writes sRGB files in a Display P3
document, so the note no longer says every exported PNG, JPG and WebP is
tagged Display P3. Follows #1759.
2026-11-10 23:49:43 -08:00
Trevor BrownandClaude Sonnet 5.5 a75d8bf04f M4: Delete closes a region's loop through the segment that joins its ends (#1951)
A Pen bridge between two degree-2 points leaves the region alone, and Delete on the point between them then rotated the loop open with the bridge in no loop, so even an unrounded fill ran straight across a curved bridge. reopen_loops now pushes the one segment in no loop that joins an open chain's ends onto the loop's end (winding kept, loop by loop), as connect does. This also covers removing segments and the eraser.

closing_segment is public, derives its own start point, walks strictly (a loop out of walking order is left alone) and gives up when two segments qualify. The render fix stays as the fallback for files already saved in that state.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Fable 5.1 reviewed; Sonnet 5.5 wrote at medium
2026-11-11 02:16:29 -05:00
Trevor BrownandClaude Sonnet 5.5 8e6c342f13 M4: a rounded vector's fill and outline follow every corner after a Pen bridge (#1951)
The reporter's file has a corner cut off by a segment drawn first, with the corner point then deleted with Delete. The region's loop is left as the open chain of the other four segments, and the cutting segment, which joins the chain's two ends, is in no loop. The stroke follows the network, so it rounds both ends of that segment; the fill and the selection outline follow the loop.

Cause: VectorNetwork::rounded_smoothed rebuilds each loop by inserting a corner's arcs where the loop arrives at the point, so the point the loop starts at is never cut (in a closed loop it is arrived at last), and the open loop's closing edge ran straight to it. closing_segment now finds the segment joining an open loop's two ends when no loop holds it, and rounding walks it as the loop's last segment, so every corner of the fill and outline matches the stroke. Closed loops and the cases #1991 fixed are untouched.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Opus 5.5 briefed; Sonnet 5.5 wrote at medium
2026-11-11 02:01:32 -05:00
Trevor BrownandClaude Opus 5.5 985231858c M10: Design panel: Swap orientation and the quick actions use the shared icon size (#2227)
The frame's Swap orientation button and the selection's quick-action buttons (24 pt) still
painted their glyphs at the old 14 pt inset beside Fit to contents' 16 pt; they use
`icon_glyph_rect` now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and wrote
2026-11-11 00:38:03 -05:00