Commit Graph
112 Commits
Author SHA1 Message Date
bflatastic f38f6fafc3 Fix #2603: a panel per swatch library, with Persistent
Each swatch or graphic style library now opens in a panel of its own,
`library:<kind>:<library id>`, in the shared docking system: several can be open
at once, and they float, group as tabs, dock and close like any panel.
Opening a library that is open brings its panel forward; Previous / Next
Library show the neighbouring library in the same panel.

The library panel menu gains Persistent. The panels' view, Show Find Field
and Persistent are kept in the UI preferences (`library_panels`); at startup
the persistent panels reopen where the saved layout had them, a library
loaded from a file read again from its path (a missing file is skipped with
a status-bar note). `ui.libraryPanel {panel, library?, view?, showFind?,
persistent?}` reaches all of it; docs/mcp.md documents the panels.
2026-10-17 19:13:49 +07:00
bflatastic 2879c206a8 Fix #2541: installed plug-ins stay installed after a restart
Install Plug-in (plugin.install) now keeps the plug-in's module in a
Plug-ins folder next to the preferences, as Illustrator keeps plug-ins in
its Plug-ins folder, and the desktop app and vectorcraft-cli install the
ones there at startup (a module that doesn't load is skipped with a log
record, at most 512 MB are read). Remove Plug-in deletes it from the
folder. The Additional Plug-ins Folder preference is still loaded from
where it is. Confined MCP servers and VECTORCRAFT_NO_PREFS keep nothing,
as with the PDF preset and colour profile stores.

Docs: docs/mcp.md, docs/plugins.md, docs/target-app-parity.md.
2026-10-17 17:49:38 +07:00
bflatastic 74ee51313d Print: Printer Setup passes only an installed printer's name to PrintUIEntry (#2569) 2026-10-17 15:14:43 +07:00
DENNIS MUUO b959cd90da Print: open printing preferences for the selected printer on Windows (#2569)
When pressing Ctrl+P to open the Print dialog and clicking Setup (or Settings), print.printerSetup previously discarded the selected printer name and unconditionally launched explorer ms-settings:printers. On Windows 10, this opened the Windows Settings Printers and scanners page, displaying the list of installed printers instead of the printer driver printing preferences.

Launch Windows native Printing Preferences dialog for the target printer using rundll32.exe printui.dll,PrintUIEntry /e /n printer, falling back to the system default printer or Settings if no printer is available or detected. Add unit tests covering command construction and fallback behavior.

Fixes #2569.
2026-10-17 15:14:43 +07:00
dotCooCoo f526671534 Save and Export ask before replacing a file that an added extension names
After the desktop save panel closes, the app adds the file type's
extension to a name typed without it (or with one the save does not
write). The panel asked only about the name as typed, so on Linux
typing `card` with `card.vectorcraft` in the folder wrote over
`card.vectorcraft` without a question. On Linux the save panel is the
XDG desktop portal, and its GTK and GNOME file choosers return the
name as typed. Windows and macOS add the extension themselves only
when the panel lists file types, and the panels of Document Info's
Save, the presets dialogs' Export…, the CSS Properties export, the
swatch and graphic style library saves and the Libraries panel's
export list none.

When the added extension names a file that exists, Save, Save As, Save
a Copy, Save as Template, the exports and the other writes through a
save panel now ask "“card.vectorcraft” already exists. Replace it?"
first (dialog `replaceFile`). OK runs the write again with the same
answer and replaces the file. Cancel writes nothing and shows the
dialog it was asked over again. The host reports whether a file exists
through a new `Services::exists`.

Docs: docs/control-protocol.md, docs/target-app-parity.md.
2026-10-17 15:14:42 +07:00
dotCooCoo 08dc614938 File formats: PostScript (.ps) and .epsf files open and place
The EPS reader read PostScript by any name, but the Open and Place
dialogs hid .ps and .epsf files, and a .ps or .epsf file whose header
is only %! could not be opened or placed ("not a format VectorCraft
reads"). The reference app lists .eps, .epsf and .ps under Open and
Place.

- A read-only PostScript format (ps) joins the format table. A .ps
  file opens and places through the EPS reader and reports the
  ps format. document.export does not write .ps; file.print does.
- .epsf is an EPS extension.
- OPEN_EXTS and PLACE_EXTS list epsf and ps, so the dialogs, the CLI
  help and the MCP open_file description list them.
  UNASSOCIATED_EXTS lists them too: the macOS bundle declares neither.
- A .ps or .epsf file whose header is only %! now pastes as EPS when
  copied in a file manager, as one with a %!PS header already did, and
  clipboard.importEps reads PostScript whose header is only %!, which
  it rejected before.

Docs: docs/mcp.md, docs/file-format-parity.md (.ps row),
docs/target-app-parity.md.
2026-10-17 14:43:14 +07:00
vangel76andClaude Opus 5.5 a8e45f0e2d Persistence: saved PDF presets and loaded ICC profiles survive a restart (#2168, #2174)
PDF presets are kept one file each in a PDF Presets folder, ICC profiles as copies in a Color Profiles folder, next to the preferences; the desktop app and vectorcraft-cli use them. Adds color.removeProfile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 13:49:48 +07:00
bflatastic 1fbd35560d Tests: the cursor-theme test compares paths, so it passes on Windows (#2450) 2026-10-17 13:06:51 +07:00
vangel76andClaude Opus 5.5 37dfdd5da5 Cursor: keep the system pointer where no cursor theme loads on Wayland (#2450)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 12:50:38 +07:00
vangel76andClaude Opus 5.5 743930ac11 Wayland: give winit the desktop cursor theme so the pointer returns over panels (#2450)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 12:50:38 +07:00
dotCooCoo 1d7ad173aa Fix #866: macOS save sheets have a Format menu again
On macOS, the save sheets of Save As, Save a Copy and the first Save of
a new document have a Format menu again, and the Save as Template sheet
now has one too. The panel is an NSSavePanel built in
apps/vectorcraft/src/mac_save_format.rs, and the menu is its accessory
view, set before beginSheetModalForWindow:completionHandler: shows the
sheet. The menu from #1235 was added after rfd had begun the sheet, and
recent macOS versions dismissed the sheet at once (#1800, #1831,
#1518); #1855 removed it.

Choosing a format changes the extension in the name field and puts
that format's extension first in the allowed file types, which AppKit
adds to a name typed without one. A name typed with another listed
extension is saved in that format. Save panels with one file type and
the open and folder panels are still shown by rfd.

Docs: docs/target-app-parity.md, docs/ui-parity.md.
2026-10-17 12:26:10 +07:00
Marco Arnulfo d21040d746 Portable mode: the marker beside the .app or .AppImage, a first-start copy of the profile, nothing under NO_PREFS (#1366)
The install folder is where the user sees the app: next to VectorCraft.app on
macOS (nothing is written inside the signed bundle) and next to the .AppImage
file on Linux ($APPIMAGE; the mounted executable's folder is read-only).

The first time VectorCraftData is created, the settings in the user's profile
are copied into it, so a portable zip that gains portable.txt keeps its users'
settings; the originals stay, a second start copies nothing, a copy that fails
halfway is logged and left as it is.

VECTORCRAFT_NO_PREFS never looks for the marker or creates the folder; a
portable copy skips the one-time read of DrawCraft's old settings; the
unwritable-folder warning goes to the log only (eprintln! panics on a closed
standard error).
2026-10-16 15:27:55 +07:00
Marco Arnulfo 314bfe802f Portable mode: a portable.txt beside the executable keeps the settings in VectorCraftData (#1366) 2026-10-16 15:27:55 +07:00
dotCooCoo ee5b0938aa Windows: after a graphics driver crash, the next start leaves that adapter out
When a graphics driver crashed the process while the window started,
as Intel's Direct3D 12 driver (igd12umd64.dll) did on an Intel UHD
Graphics 605 (#2243), the next start picked the same adapter again. The
restart without a failing adapter and the first-frame watch run inside
the process, so the crash ended them along with it.

Each start now writes graphics-start.json in the log folder before the
graphics start, adds the adapter once one is picked, and clears both
when the first frame reaches the screen or the app ends without
crashing. A start that finds an earlier start still recorded there
leaves that adapter out, as a restart does, logs it and shows a note in
the status bar. When the crash came while the adapters were being
listed (wgpu's Direct3D 12 backend creates a device on each GPU to list
it), the next starts list OpenGL's adapters alone, except on macOS. The
adapters stay left out until the app version or the Graphics Processor
preference changes, a start shows its first frame on one, or no adapter
is left. WGPU_BACKEND and WGPU_ADAPTER_NAME choose regardless of the
record.

Docs: docs/development.md, docs/target-app-parity.md.
2026-10-16 06:16:34 +07:00
Gert Pellin e2df2e774c vectorcraft --help prints the usage before the app starts (#2110)
--help and -h used to be taken for a file to open: from a terminal, SSH or an
agent's shell the window opened, or the start hung or failed without a display.
They now print the desktop app's options and point to vectorcraft-cli for
headless work, exiting before logging, preferences or the window, as
--version does.
2026-10-16 04:44:31 +07:00
Marco Arnulfo 4b8a987445 Windows: a maximized window stays clear of the taskbar (fixes #1977) 2026-10-16 04:44:11 +07:00
dotCooCoo 25df070576 Color: Sample Color from Screen picks a color anywhere on the screen
The Color Picker gets an eyedropper button beside the New and Original
chips, and `ui.sampleScreenColor {stroke?, picker?}` shows the system's
color sampler. The command answers at once. When the person clicks a
color anywhere on the screen, the color becomes the fill or the stroke
through paint.setFill / paint.setStroke as one undo step, or with
`picker` it becomes the open Color Picker's color, which previews on the
selection as any pick does. Escape cancels the sampler. The sampled sRGB
color goes through Cms::srgb_to_rgb, so in a Display P3 working space a
color inside sRGB shows as it did on the screen. `ui.inspect` reports
`screenSampler` while the sampler is open.

- macOS uses NSColorSampler (apps/vectorcraft/src/mac_screen_color.rs).
- The web app uses the browser's EyeDropper API where the browser has
  one.
- Without a sampler (Windows, Linux, other browsers) the button is gray
  and the command returns an error. Keyboard Shortcuts lists the
  command, so it can be given a key.

Docs: docs/control-protocol.md, docs/target-app-parity.md.
2026-10-16 02:25:53 +07:00
bflatastic ea30e411e7 Fix #1725: a control request its caller timed out on is withdrawn, not run later
The worker answered "timeout" after 60 s and left the request on the queue, so
the app ran it whenever it next drained the queue: an edit nobody was waiting
for, and a second one if the caller had retried. A request now leaves the
queue once: taken by the app, or given up by its caller, whichever comes
first. The timeout reply says which ("will not run" / "still running").
2026-10-14 08:47:10 +07:00
BFlat ba5447bbd9 Merge pull request #1855 from storytold/fix/1800-mac-save-sheet
Fix #1800: macOS Save As shows its sheet again
2026-10-14 08:12:38 +07:00
bflatastic 494ce39de5 Fix #1747: Preferences are written when confirmed, not only at exit
The preferences file was written only when the app quit normally, so settings
confirmed with OK were lost when the session ended any other way (the system
shutting down, the process being ended, a crash). OK now asks the host to
write the file at once.
2026-10-14 08:11:06 +07:00
bflatastic a60f7e1858 Fix #1800: macOS Save As shows its sheet again
The Format menu added to the save sheet after rfd began it (#866) made recent
macOS versions (26.6.2 and 27.0.1 reported) dismiss the sheet at once: Save As,
Save a Copy and Save of an untitled document flashed and answered as cancelled,
while panels without it (Open, Export As) worked. The accessory is withdrawn
until it can be set before the sheet is presented; the format still follows
the extension typed in the name field, as before #866.
2026-10-14 08:10:58 +07:00
bflatastic 85c81ff1e9 Control: an idle connection is closed without a line, so no error waits where a client's next reply would be (#1726) 2026-10-14 04:31:43 +07:00
DWAA1660 a0bd1fd16b M1: bound control connection transport waits
Fix #1726 with idle, absolute line and reply-write deadlines and connection-slot guards. Add real-loopback regressions and document reconnect behavior.

Validated with cargo xtask ci: all seven gates passed; 6156 tests passed, zero failed, seven existing ignored.
2026-10-14 04:31:43 +07:00
Ayberk A. cb9fa7042f Fix #1758: keep the custom title bar window borderless on Windows
winit 0.30 gives an undecorated window WS_CAPTION | WS_BORDER; on some Windows
systems the compositor still reserves that frame, so the content is drawn
offset while the pointer isn't, and the cursor no longer points at what is under
its tip. Strip the two styles once and again each frame (winit restores them on
maximize/restore), as PhotoCraft does (storytold/photocraft#2401).
2026-10-14 03:55:40 +07:00
dotCooCoo 7fde8739a7 Control: replies are buffered, so a 17 MB reply is sent in 0.09 s instead of 34 s on Windows
The control server wrote each reply with writeln!(out, "{r}") on the
bare TcpStream. serde_json formats a Value one piece at a time, and
each piece (a brace, a quotation mark, a key, a colon, a number) was
sent as a write of its own: the 17 MB document.inspect reply of a
document with 50,000 objects on one layer was sent in 7,857,200 writes.
On Windows 11, sending that reply to a client over loopback took 34 s,
and sending the 28 MB document.json reply took 57 s.
vectorcraft-cli mcp reads every reply from a running app over this
connection.

write_line now writes each reply, each refusal and the "too many
control connections" line through a 64 KiB BufWriter, then flushes
it. The 17 MB reply takes 262 writes. Sending it now takes 0.09 s,
and sending the 28 MB reply takes 0.2 s. The bytes are the same.

Docs: docs/target-app-parity.md.
2026-10-14 02:09:15 +07:00
Marco Arnulfo e50bd58146 Cursors: paint the tool cursors on Wayland, where the compositor showed the bitmap twice too big (fixes #1645) 2026-10-14 02:09:09 +07:00
bflatastic b3f6edddfe Fix #1499: PDF and EPS another app copied paste as editable vector art
Paste read PDF only from the Windows clipboard and EPS nowhere, so on macOS a copied
equation or drawing pasted nothing new (the last thing copied in the app came back).
- macOS: the pasteboard's PDF, EPS and SVG are read, ahead of text and bitmaps.
- Windows: EPS is read beside PDF.
- Everywhere: an .eps file copied in a file manager pastes.
- clipboard.importEps loads an EPS into the clipboard as document.open reads one.
2026-10-13 06:34:12 +07:00
bflatastic ff6e136b97 Part of #1459: the window's surface may be as large as the graphics adapter allows 2026-10-13 02:54:08 +07:00
RealtaNuaandClaude Opus 5.5 4744c2f04b Fix #1373: --control without a valid port stops the desktop before it starts
--control took the next argument as its port and dropped it when it wasn't a number, so the app
started without a control server and `--control --automation-read-root DIR` opened DIR as a
document. automation_args::ControlArg now reads --control <port> or --control=<port> once and
requires a port from 1 to 65535; VECTORCRAFT_CONTROL_PORT must be one too, checked only when
--control isn't given so --control and --version win over a bad value. Errors go through the
same exit as the root flags (#1157).

Tests: unit tests in automation_args.rs; tests/automation_args.rs runs the binary for each bad
form and checks the exact message and a prompt failing exit.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:56:36 +07:00
skylar taylor-barrick e74c2f113c Print: adopt craft-print while retaining Windows 7 support 2026-10-12 14:20:48 +07:00
arhammusheerandClaude Opus 5.5 023c8e3edd #1244: streaming open and save, per-section limits, recovery that keeps images apart, background open
Save serializes JSON straight into the compressor and writes images from their Arc into the
file; open reads each image into its own buffer, and NodeKind reads its tag first instead of
buffering every node. Already-compressed images are stored rather than deflated again in the
same gzip stream. Limits apply per section, so any file VectorCraft writes opens again. Data
Recovery writes each image once, content-addressed, instead of every interval. Native files open
on a background thread. Files stay readable by main both ways; JSON-only saves are identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VmMmc1J8XeNLxhRihWv9cc
2026-10-12 11:02:33 +07:00
LosminekandClaude Opus 5.5 e3dec2e87b M14.i18n: translate Czech labels at UI render sites
Localize native/web file filters, diagnostic labels, numbered presets
and contributor tooltips with English fallback and Czech plural forms.
Fix gradient adjective agreement and disambiguate Japanese printer marks
in PDF/Print choices and summaries. Keep file extensions and names intact.

Add Czech catalog rows and regression coverage; update localization evidence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 08:18:13 +07:00
Ikki Nishihara f08c970588 fix: macOSの保存画面に形式選択を追加する #866 2026-10-12 01:15:16 +07:00
bflatastic 6a214253a8 Review: rewrap the adapter order docs (#1200) 2026-10-11 22:18:10 +07:00
Atos Lins 9c40a2643f Linux: Automatic draws on the GPU the Wayland compositor draws with
On a hybrid laptop whose Wayland compositor runs on the discrete GPU
(Hyprland with AQ_DRM_DEVICES naming the NVIDIA card first), the built-in
panel still hangs off the integrated GPU, so the display rule put it first,
and the window stayed empty: the compositor took the frames and showed
nothing, with no error, so neither the restart on a failed adapter (#502)
nor the first-frame watch (#964) noticed.

Which GPU drives a display stands in for which GPU the compositor draws
with. Under Wayland the compositor says so itself: the main_device of its
linux-dmabuf feedback (version 4), the device it imports client buffers on,
which Mesa's Vulkan device-select layer reads for the same purpose.
compositor_gpu.rs asks for it on a short-lived connection, maps the dev_t
to PCI ids through /sys/dev/char, and under Automatic adapter_order ranks
that adapter ahead of the display GPUs. No answer (X11, an older compositor,
a GPU no adapter matches) leaves the existing rules in charge; a user's own
choice, WGPU_ADAPTER_NAME and the restart skip list still come first.

wayland-client and wayland-protocols are already in the tree through winit;
they become direct Linux-only dependencies.
2026-10-11 22:18:06 +07:00
bflatastic 21459f4df4 #1194: Direct3D 12 shaders compile with FXC
wgpu's default DX12 shader compiler loads whichever dxcompiler.dll the
DLL search path finds first; VectorCraft ships none, so it was another
program's, and one without its dxil.dll warns that the DXIL is unsigned.
wgpu takes the warning for a compile error, the device is lost before
the first frame, and the app falls back to OpenGL. FXC (d3dcompiler_47,
part of Windows) compiles everything the window needs, as LightCraft
does since its #484; WGPU_DX12_COMPILER still picks another.
2026-10-11 22:03:40 +07:00
bflatasticandClaude Opus 5.5 731c30ff6d Review: house header for the root-argument integration test (#1157)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 18:16:43 +07:00
BFlat 71b7ae3d56 Merge pull request #1157 from piero-83/ll-root-preflight
Reject malformed desktop automation root arguments before startup
2026-10-11 18:15:54 +07:00
bflatasticandClaude Opus 5.5 a809f270eb #1151: Preferences › Performance › Linux display server opens the window through Xwayland, where file drops work
winit 0.30 delivers no file drops on native Wayland. The new Linux Display
Server preference (Automatic / X11 (XWayland), shown on Linux only, read at
startup) has winit open the window on X11 when the session is Wayland,
DISPLAY is set and the X11 libraries winit loads are installed (ldconfig
check ported from PhotoCraft); otherwise the window opens on Wayland and
the log says why. README, development notes, parity docs, ROADMAP and the
complete catalogs updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:29:23 +07:00
piero-83 d9c48bddef test(app): reject root errors before initialization 2026-10-11 11:18:31 +02:00
piero-83 3d4caa917a fix(app): reject malformed automation roots before startup 2026-10-11 11:17:58 +02:00
EmlembowandClaude Opus 5.5 7ff0269a1d Fix #867: macOS file dialogs are sheets, and no dialog runs inside the event handler
The crash: rfd's blocking dialog ran -[NSSavePanel runModal] inside
winit's event handler; when a resize of the panel ends, AppKit runs the
closures winit queued meanwhile, and winit's re-entrancy panic fires
inside an Objective-C block, where it can't unwind, so the app aborts.
As PhotoCraft (#673) and PdfCraft (#145) ship it:

- macOS: picks::ask shows an rfd::AsyncFileDialog as a sheet on the
  window (beginSheetModalForWindow returns at once); a waiter thread
  sends the paths and wakes the window. A pick asked outside an entry is
  refused and logged instead of running a modal. Linux keeps its thread
  (#592) and now also wakes the window; Windows is unchanged.
- Nine paths that asked outside an entry now run as entries: Load
  Profile, Swatches and Graphic Styles Other Library, the shortcut
  editor's Import and Export, and the presets dialogs' Export.
- While a dialog is open: the macOS menu bar is inert except Hide, Hide
  Others and Minimize; Quit, Close, Close All and the close button are
  refused; Finder/Dock opens and the IME discard wait; another dialog
  is refused with a status message. The answer re-activates the
  document that asked (by uid) and Save Changes finds its document by
  uid; a frame guard clears a stale picks entry after a recovered panic.
- ui.inspect reports fileDialog.

Squashed onto current main by the maintainer (with main's automation
sandbox wrappers and font-name menus kept).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:14:17 +07:00
skylar taylor-barrick 0c57b1d5d2 UI.6: reconcile shared docking with native panel sets 2026-10-10 19:28:31 -06:00
skylar taylor-barrick ed14640756 UI.9: integrate shared docking and preserve panel workflows 2026-10-10 14:49:35 -06:00
bflatasticandClaude Opus 5.5 199a464140 #964: start again when the first frame never reaches the screen
With High Performance chosen on a hybrid laptop, the window's first
frame never reached the screen: no error, no panic, the app stayed in
the background without a window and the log stopped after "rendering
with". The start-up recovery of #502 only saw failures.

A watch thread now gives the first frame 20 seconds from the app's
creation (after the files named at the start opened). When the second
frame hasn't begun by then, so the first was never presented, the app
starts again without that adapter, as it does after a graphics failure,
and this process ends. A window minimized at the start isn't counted.
When the hung processor was chosen in Preferences, the status bar's
note after the restart points to Automatic.

docs/development.md explains it and how to recover from a Graphics
Processor choice that doesn't work; ROADMAP Last updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 23:38:58 +07:00
bflatasticandClaude Opus 5.5 6315086f96 Review: System Title Bar only where it applies, docs, title repaint
- Preferences hides System Title Bar on macOS and the web, where it did
  nothing (it fell through to the plain checkbox row), and lists it with
  the window options instead of under Language.
- The next-launch note reuses "Applies the next time VectorCraft starts."
  instead of a second wording in every catalog.
- A new window title asks for one more frame: AppKit lays the title bar
  out again for it, and the next frame centres the window buttons (#968).
- The menu bar drops the bold branch for the VectorCraft menu it no
  longer shows; theme is imported where the tests use it.
- Docs: Language is Preferences › User Interface › Language (VectorCraft
  › Language on macOS); the control protocol describes System Title Bar;
  ROADMAP Last updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 21:15:21 +07:00
rafi612 12f8a77a00 User Interface › System Title Bar: native decorations on Windows/Linux, file in OS title 2026-10-10 21:01:38 +07:00
bflatasticandClaude Opus 5.5 258d61ced0 #968: centre the macOS window buttons on the app bar
AppKit places close, minimize and zoom in a standard title bar, shorter
than the 44-point app bar they sit over, so they rode high on it. They
are now moved to the middle of the bar, inset from its left as far as
from its top, with the title bar container made as tall as the bar so
they stay clickable. AppKit lays the title bar out again on resize and
when leaving full screen, so the placement runs every frame and sets a
frame only when it is out of place. The app bar keeps the room the
buttons take, measured, instead of a fixed 78 points.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 20:56:18 +07:00
bflatasticandClaude Opus 5.5 0eb4ce5e98 Fix #918: PSD and PSB files open and place as their merged image
File › Place and File › Open read PSD and PSB files: the merged image
every such document carries after its layers, which is what a linked PSD
shows. A placed PSD links like any image, so the Links panel updates and
relinks it, and it is sized by its ResolutionInfo resource.

The reader is written from the public file format specification. It
reads Bitmap, Grayscale, Duotone, Indexed, RGB, CMYK (through the colour
settings' CMYK) and Lab, at 1, 8, 16 and 32 bits per channel (32-bit
values are linear), raw, PackBits or zipped with or without prediction.
A document with transparency stores its merged image on white with the
alpha in the first extra channel. It comes back with straight colours,
also for 16- and 32-bit files, which say so in their Lr16/Lr32 block.
Multichannel files are refused with a message. The file is untrusted:
every read is bounds-checked and the image's size is checked against
the decode budget before anything is allocated.

PSB is a read-only format of its own, so exports never write a PSD under
a .psb name. The desktop packaging still doesn't associate either
extension with VectorCraft (UNASSOCIATED_EXTS): they belong to raster
editors. Layers (import options) are left for later.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 16:09:41 +07:00
bflatasticandClaude Opus 5.5 9f875050ef Fix #832: --automation-read-root and --automation-write-root confine the MCP server's files
vectorcraft-cli mcp and vectorcraft --control take the flags PhotoCraft
takes. While roots are in force, every path a command reads (open, place,
relink, SVG image links, library and profile loads, plug-ins, preset
imports, font searches) must lie inside the read root and every path it
writes (save, export, package, Export for Screens and for Web, print to
file, captures, library saves) inside the write root. Paths are made
absolute, links are followed (a missing file's nearest folder's), and the
result is compared by whole components, ignoring case on Windows; `..`
below a missing folder, dangling links and device names are refused. A
root left out grants none of its access; without the flags nothing
changes.

The checks live in one place, vectorcraft_engine::file_access, consulted
by the engine's file helpers and the app's file services. The headless
server confines its whole process; the app confines control requests,
the frames carrying input they inject and the background saves they
start, leaving the person at the keyboard and the app's own folders
alone. The screenshot tool now has the backend write its file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 14:27:24 +07:00