Commit Graph
325 Commits
Author SHA1 Message Date
NetterSilverandClaude Haiku 5.5 02c555cad7 Reject a plus sign in Windows GPU PCI id hex digits
Found while testing apps/vectorcraft/src/gpu.rs:313 (pci_ids)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-09 02:03:09 +07:00
Don Omondi d8074562d1 Alt + keypad codes: docs say the Windows path is unit-tested only; fix two comments
The type parity row no longer says the NumLock-on path was tried on
Windows: neither path has been run on a Windows machine yet. The comment
on the NumLock-off egui keys says Clear comes as the top-row 5, and the
test comment names the keys 0151 and 0234 actually use.
2026-11-09 02:03:04 +07:00
Don Omondi 8b6e358f0c Alt + keypad codes: with NumLock off the keypad keys count as digits and don't move the caret
Follow-up to #5939. With NumLock off the keypad sends Insert, End, arrows,
Clear, Home and Page Up/Down; Windows still composes the code from them,
but the app also moved the caret, so the character landed elsewhere. With
Alt held, those keys without the extended-key flag now count as digits and
are taken out of the frame; the separate navigation keys keep their meaning.
2026-11-09 02:03:03 +07:00
dotCooCoo b5e6f6e80f Plug-ins: Safe Mode starts without plug-ins, offered after a launch stops while one loads
Squashed from #6185 onto main.
2026-11-09 00:30:24 +07:00
dotCooCoo fb413b39f3 Title bar: a Linux and BSD preference uses the app bar where the desktop draws the frame
Squashed from #6101 onto main.
2026-11-09 00:27:21 +07:00
dotCooCoo d61a7abc96 Save: include a PDF in new native files by default
Squashed from #5320 onto main.
2026-11-09 00:25:34 +07:00
dotCooCoo d5e1c00470 File formats: HEIC and HEIF images open and place
File › Open and File › Place read HEIC and HEIF still images (.heic,
.heif) through heic-rs 0.1.4, the pure-Rust decoder photocraft-heif
uses, and store the pixels as PNG. Single pictures and grids of tiles,
8 to 10 bits, with or without an alpha image, are read with the
container's rotation, mirror and crop applied. A grid without a color
box of its own takes its tiles'. When neither the image nor its tiles
have an nclx box, the HEVC stream's video signal type gives the
samples' matrix and range. An RGB ICC profile, or Display P3 with the
sRGB curve named by an nclx box or, without a color box, by the
stream, is converted to sRGB. The EXIF resolution tags size the image;
without them it is 72 ppi. When the container's rotations turn the
image an odd number of quarter turns, the resolution's axes swap with
the pixels'.

Image sequences, images that aren't HEVC-coded, grids of cropped tiles
and images past the pixel allowance are refused with a message before
the pixels are decoded. The allowance counts each coded picture at the
size its sequence parameter sets give it.

The decoder is in the engine's `heif` feature, which is on by default
and listed by the desktop, CLI and web apps. A build without it still
recognizes the files and refuses them with a message.
2026-11-08 23:51:41 +07:00
dotCooCoo 8c7e7041fd Title bar: the app bar shows no brand mark under the desktop's own frame
On Linux, when the desktop draws the window's frame (KDE, Sway,
Hyprland, COSMIC and X11 sessions), the app bar painted the brand mark
under the desktop's title bar unless System Title Bar was on. The mark
followed the live preference instead of the frame the window has.

The desktop app now records the frame it opened the window with
(VectorcraftApp::desktop_frame), and system_title_bar reads it. A
change to System Title Bar during a session no longer shows or hides
the mark; it changes with the frame at the next start. Embedders
without a window of their own keep the mark.
2026-11-08 23:50:37 +07:00
dotCooCoo b17a744a9c Panels: floating panels reopen on the monitor where they were left
Squashed from #6038 onto main.
2026-11-08 11:22:40 +07:00
BFlat a7733acc7e Merge pull request #5984 from BOXELS/fix/5980-nssavepanel-null
#5980: macOS save sheet uses alloc/init instead of +savePanel
2026-11-08 12:00:58 +08:00
Helen Kwok f9bf685cbd vectorcraft-web: window.vectorcraft takes its request functions from craft-web-api
request, execute, commands and screenshot move onto the shared crate (storytold/craft-libs#413): a timeout on every call, the screenshot's PNG also in data, and docInspect and uiInspect beside them. A call the page gave up on gives up its request if the app has not started it, so the app skips it. openFile, captureDownloads, files, readFile and inspect stay VectorCraft's own, on the same object.
2026-11-07 09:18:00 +07:00
Jared SmithandCursor 3617987e35 #5980: macOS save sheet uses alloc/init instead of +savePanel
+[NSSavePanel savePanel] returned nil inside VectorCraft on macOS 15.7 and
objc2 panicked; build the panel with init (and Option fallbacks) so Save As
shows again, and do not hand a refused panel to rfd.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-06 15:18:21 -07:00
Don Omondi b8ec5f4b23 Type: Alt + numeric-keypad codes type their character on Windows; type.insert takes a code (#5108) 2026-11-07 00:17:15 +07:00
dotCooCoo b8155698b5 Remove temporary test files after failures 2026-11-05 23:25:05 +07:00
Locme a3ec061995 .ai import: 6D Art Pen brushes open live, and Windows reads pen tilt and rotation (#372)
Squashed from #5815 onto main.
2026-11-05 23:25:05 +07:00
dotCooCoo 877b3de3ad Tests: the read_file_head test creates its file exclusively and removes it on failure 2026-11-05 21:18:44 +07:00
dotCooCoo 2cd68fbdcb Actions: loading an action set checks its size before reading it
Load Actions… read the whole file before checking the 8 MiB limit, so
picking a very large file could take a lot of memory before it was
refused. A new read_head service reads at most a given number of bytes;
the desktop app provides it, and loading an action set reads one byte
past 8 MiB with it. A larger file is refused without reading the rest.
Hosts without the service keep reading the whole file. Automation
roots apply to read_head as they do to read.
2026-11-05 20:55:58 +07:00
KnottyDyes c9588457b9 Export: raster output defaults to the document resolution 2026-11-05 19:02:23 +07:00
FredAppsandClaude Opus 5.5 c1f7e4ed6d #1280: PathData::bounds closes a NaN anchor as kurbo does; the perf row names what it times
Follow-up to CodeRabbit's review of #5778.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 17:17:36 +07:00
FredAppsandClaude Opus 5.5 0a8566e1b0 perf: the import comes first
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 16:49:06 +07:00
a33d83d84f #1280: perf --deep measures pointing; PathData::bounds builds no path
First slice of https://github.com/storytold/vectorcraft/pull/1281, split
as the review asked. `--deep` gains rows for hovering, a hit test that
misses, marquee, smart guide targets and shift-click on a large document,
so the later slices have a baseline.

PathData::bounds built a kurbo path on every call. It now measures the
segments in place, with the same guards, and a proptest compares the
result bit for bit with what the path gave.

Co-Authored-By: arhammusheer <arhammusheer@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 16:49:06 +07:00
bflatastic 7b608b2dab Control server: close connections gracefully, so a reply is not lost to a reset
A connection ended (a junk line, an idle or stalled peer, the app going away) by dropping its socket. On Windows, a reset can follow and discard replies the peer has not read yet, which made tcp_connection_is_closed_after_junk fail at random in CI with ConnectionReset. serve_socket now shuts the write side down and reads what the peer still sends until it closes, for at most a second and 1 MiB, before dropping the socket. The test goes through serve_socket, the path the app uses.
2026-11-05 07:13:06 +07:00
dotCooCoo 59a3cad1dc Type: Paste keeps a copy the system clipboard refused
When a Copy in the Type tool cannot be written to the system clipboard
(another app holds it open, or a format fails after the clipboard was
emptied), Paste into type or a text field now inserts that copy, with
its style in type, instead of the text the clipboard kept. This covers
Edit > Paste, the paste key, and a paste that arrives while the copy is
still being written. When another app copies something, before or after
the failed write, Paste takes that.

The new SystemClipboard::change_count reports the clipboard's change
count (Windows' sequence number). Where a platform has none, a change
of the clipboard's text marks a new copy.
2026-11-05 07:13:03 +07:00
dotCooCoo 8555ac42c4 UI-1661: Use Windows clipboard ownership for Type paste 2026-11-05 04:11:40 +07:00
dotCooCoo a2947df1fa File dialogs: Open and Place list files with capitalized extensions on Linux
GTK and the desktop portal match a filter's *.ext patterns case-sensitively,
so on Linux and the BSDs files such as image.DIB, photo.PNG or art.Svg did not
show under any Open or Place filter, "All readable files" and "All placeable
files" included. On those systems each open and place filter now also lists
every extension with each letter as a [xX] pair, the form the portal's
FileChooser documentation recommends. Save dialogs and the other platforms
keep the plain extensions.
2026-11-04 22:57:50 +07:00
Don Omondi 609528220b Fix #5160: a slow first frame is waited for, not blamed on the graphics adapter
Squashed from #5635 onto main.
2026-11-04 22:29:32 +07:00
bflatastic 292b385a66 Tests: the font menu and idle-socket tests don't fail on a busy machine
type_font_menu_lists_every_available_family compared two reads of Type › Font while a test running alongside could add a font in between, so the menu was rebuilt with one more family. It now judges a run in which the font generation held still.

idle_expiry_closes_without_writing_a_line took a connection reset as a failure; on Windows the server's close of an idle connection can reach the client as one.
2026-11-04 21:46:50 +07:00
byoungyoonandClaude Opus 5.5 c82a1eb0e8 Fix #5555: Cmd+V pastes once on the web
eframe's web runner reports a Cmd+V press both as the key press and, with the
clipboard's text, as a Paste event; the app pasted on each (egui's window
integration sends only the Paste). The web shell now drops the paste key's
press when a Paste is in the same frame's input; its release stays for
PasteChord, and a Cmd+V with no text on the clipboard keeps its press.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 16:33:24 +07:00
bflatastic 1e3553843d Single instance: the stale-endpoint test connects to no freed port
The test bound a port, freed it and then connected to it as a gone app.
Tests run in parallel, so another test's listener could take that port
meanwhile and accept this connection in place of its own client's,
whose connection was then reset when the listener closed: the cause of
the intermittent tcp_connection_is_closed_after_junk failures on
Windows. The gone app is now a listener that closes without a greeting.
2026-11-04 16:08:43 +07:00
bflatastic 821757acef Control server: the junk-closes test leaves no unread input
On Windows, closing a socket with unread input resets the connection, and
the reset can discard the reply before the client reads it, so the test
failed under load. The request after junk is still covered by the
in-memory tests.
2026-11-04 09:43:38 +07:00
dotCooCoo 04e154510a Edit Original: read PhotoCraft's App Paths entry as UTF-16 on Windows
The lookup ran reg.exe and decoded its output as UTF-8, but reg.exe
writes in the console's code page, so a registered path with characters
outside ASCII came back wrong, and characters outside that code page
came back as "?". The path is now read with RegGetValueW.
2026-11-04 08:12:40 +07:00
Dylan M. Taylor 9b10a40709 fix: Templates folder needs write access; portal saves keep exact file names 2026-11-03 22:17:45 +07:00
Dylan M. Taylor c879ff369b fix(app): keep preference copies, dialog passwords and migrated folders private 2026-11-03 22:17:45 +07:00
Dylan M. Taylor 8e595afdf0 fix(app): open and paste read only regular files 2026-11-03 22:17:45 +07:00
bflatastic f3a9114e55 Edit Original: the PhotoCraft lookup test holds where PhotoCraft is installed 2026-11-03 19:58:28 +07:00
ruchirguitarandClaude Opus 5.5 46f1ddf170 Fix #5236: find PhotoCraft where its Windows installer puts it
Per CodeRabbit on #5327: on Windows Edit Original looked for photocraft.exe
only on the PATH, but PhotoCraft's MSI installs it to ArtCraft\PhotoCraft
under %LOCALAPPDATA%\Programs (per user, the default) or Program Files (for
everyone), neither on the PATH. Look first at the path the installer
registers under App Paths (HKCU, then HKLM; `reg query`, as i18n reads the
locale, which also covers a folder chosen in setup), then those two default
folders, then the PATH. Each candidate must still be an .exe.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:57:04 +07:00
ruchirguitarandClaude Opus 5.5 d7aa1c561f Fix #5236: Edit Original is one checkbox, Use System Defaults for Edit Original
Per review on #5327: Preferences › File Handling › Edit Original With (an app
path and Choose…) becomes the checkbox Use System Defaults for Edit Original,
on by default. Off, Edit Original opens a raster image in the app that made
it, PhotoCraft, looked for only where it installs; any other file, or no
PhotoCraft, goes to the system's default app. The preference is a boolean, so
prefs.set over control or MCP can no longer name an executable. The label has
a row in all 26 catalogs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:57:04 +07:00
ruchirguitarandClaude Opus 5.5 79c8d1a7e0 Fix #5236: cap the wait for open -a at two seconds
A stalled `open -a` no longer holds the window: Edit Original waits at most
two seconds for its exit status (enough to report an app it can't open),
then leaves the launch running and reaps it on a thread of its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:57:04 +07:00
ruchirguitarandClaude Opus 5.5 7c5670b797 Fix #5236: report a failed open -a, and keep Other Application while its path is cleared
macOS: wait for `open -a` (it returns once Launch Services has the
request) and report its error, such as a folder named .app that isn't a
bundle; other platforms still start the editor without waiting. A saved
or typed path also sets the dialog's Other Application choice, so
clearing it to type another keeps the field.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:57:04 +07:00
ruchirguitarandClaude Opus 5.5 d11764c117 Fix #5236: Edit Original opens linked files in a chosen app
Preferences › File Handling › Edit Original With picks the app Links
panel › Edit Original opens a linked file in: System Default (as before),
PhotoCraft (found in /Applications or ~/Applications on macOS, on the
PATH elsewhere) or Other Application, with a path field and Choose….

The desktop host's new `open_file_with` service starts only an
application (an .app bundle on macOS, an .exe on Windows, an executable
file elsewhere), with the path as its only argument and never through a
shell. Edit Original still refuses control requests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:57:04 +07:00
dotCooCoo b1c98821d6 Clipboard: a bitmap pasted from another app is decoded off the UI thread
Squashed from #4277 onto main.
2026-11-02 14:33:02 +07:00
dotCooCoo e8e09af782 Brushes: Calligraphic and Scatter values follow pen tilt, bearing and rotation
Squashed from #5031 onto main.
2026-11-02 14:33:02 +07:00
dotCooCoo 90179904d8 Actions: the saved current set follows its set when windows merge
When two windows save the preferences, the current set's index and the
list of sets can come from different windows. The index now points at
the same set in the merged list, found by its contents or its name, and
no set is current when the merge cannot tell which set it was. Recording
into, renaming or deleting the current set, or deleting a set before it,
does not override a set the other window made current.
2026-11-02 14:32:50 +07:00
bflatastic 51dcb94661 Fix #4967: a drawing tablet's pen draws on a Wayland session by default
On a Wayland session Linux Display Server's default, Automatic, opened
the window on native Wayland. winit 0.30 doesn't bind the Wayland tablet
protocol, and KWin (since Plasma 6.3) and Mutter turn no tablet input
into pointer input, so the pen moved only the compositor's cursor and
the app got no motion or presses. Only X11 (XWayland) When a Pen Is
Attached, which users had to find and choose, sent the window through
XWayland, where the pen works as a mouse with its pressure.

Automatic now opens the window through XWayland when a pen is attached
as the app starts, as PhotoCraft does by default.
VECTORCRAFT_NATIVE_WAYLAND=1 keeps the window on Wayland, like
PhotoCraft's PHOTOCRAFT_NATIVE_WAYLAND. The X11 choice is unchanged.
2026-11-01 05:32:30 +07:00
dotCooCoo cbde11d593 Fix #2105: the window asks the GPU for no more than it offers
eframe's default device descriptor asks for wgpu's default limits (WebGL2
defaults on OpenGL) with 8192 px textures, whatever the adapter offers. A GPU
short of any one of them, such as a Raspberry Pi 5's V3D 7.1 (15 inter-stage
shader variables on Vulkan, 4096 px textures on OpenGL), failed to create a
device, and the window fell back to the software rasterizer.

The device now asks for eframe's limits lowered to the adapter's wherever the
adapter offers less, and for the adapter's own texture side, which still
raises it above 8192 px when the adapter allows more (#1459).
2026-11-01 04:53:40 +07:00
dotCooCoo dfd07552c8 Cursors: Caps Lock gives the drawing tools the crosshair
While Caps Lock is on, the tools whose pointer General > Use Precise
Cursors changes show the crosshair, and the saved preference does not
change. The desktop app reads the lock state on macOS, Windows and
Linux X11 and passes each change to the new view.capsLock command. A
change to view.capsLock or usePreciseCursors through app.run refreshes
the canvas pointer. The view.preciseCursors command is labeled Use
Precise Cursors, so command search finds it by the preference's name.
2026-11-01 01:59:54 +07:00
bflatastic 9b17e38a5c Fix #4892: a file opened while VectorCraft runs opens in that window 2026-10-31 23:11:00 +07:00
bflatastic da9eaaacf8 Windows cores: test the affinity mask in-process
A test that spawned the test binary with `start /affinity 1` ran while the control server's socket tests held connections; the child inherited them and reset one (idle_expiry_closes_without_writing_a_line failed every full run). The one-core worker count stays covered by `automatic_threads`.
2026-10-31 19:43:13 +07:00
dotCooCoo 4e785b40ce Part of #4516: Windows renders start workers only for the cores the process may use
The renderer sized its worker pool from available_parallelism, which on
Windows counts every processor in the machine, also when the process's
affinity mask allows fewer. A process allowed one core started 8 workers,
and the renderer's flush spun on that core while the workers got no time,
so renders crawled or stalled.

The desktop app and vectorcraft-cli now read the affinity mask at startup
(src/windows_cores.rs, shared) and pass the count to the renderer with
vectorcraft_render::set_usable_cores. With one usable core the renderer
renders on the calling thread.
2026-10-31 18:44:55 +07:00
dotCooCoo de72fc3998 Clipboard: TEXT_ONLY is built on Linux only
The constant is used only by the Linux Wayland arms, so on macOS it is
dead code and `cargo clippy -p vectorcraft --all-targets -- -D warnings`
fails with "constant `TEXT_ONLY` is never used". Gate it with
`#[cfg(target_os = "linux")]`, as the `Wayland` variant beside it is.
2026-10-31 06:28:35 +07:00