Commit Graph
254 Commits
Author SHA1 Message Date
BFlat c62d1d8713 Merge pull request #6908 from dotCooCoo/fix/actions-toggle-limits
Actions: recording, step exclusions and set edits keep sets that Load Actions reads
2026-11-13 00:50:37 +07:00
BFlat 3fed6e3380 Merge pull request #6911 from dotCooCoo/fix/canvas-zoom-ignores-ui-scaling
View: the art keeps its size at a zoom whatever the UI Scaling
2026-11-12 23:54:20 +07:00
dotCooCoo 1bf8bce083 Actions: Begin Recording params name the command that passes a limit only as it runs
ui.action.record's params text now says that a recorded command whose
step passes a limit only from the values it adds as it runs keeps its
edit and result, that later recorded commands are an error and do not
run, and that ui.action.stop leaves its step out.

crates/mcp/src/ui_catalog.rs now matches the desktop table again
(cargo xtask ui-commands --check), including the action-limit params
texts of the earlier commit.
2026-11-12 08:27:21 -08:00
BFlat 0cb73d0d66 Merge pull request #6845 from dotCooCoo/feat/linux-screen-color-portal
Color: Sample Color from Screen works on Linux through the desktop portal
2026-11-12 23:10:13 +07:00
dotCooCoo 5d40a1c6d0 View: the art keeps its size at a zoom whatever the UI Scaling
Preferences > User Interface > UI Scaling sets egui's zoom factor, and the
canvas mapped one document point to one of the interface's points at
100%. A document point then covered UI Scaling times as many device pixels,
so the art grew and shrank with the interface.

The canvas now maps the document at the view's zoom divided by the UI
zoom (View::screen_zoom, Xf::at). The rendered frame, the pointer, rulers,
grids, Fit and Actual Size, pan, scroll, zoom and turn about a point, the
Zoom tool's marquee, Pixel Preview's check, tiled panes, the Navigator's
view box and the tools' tolerances use that mapping. The zoom value means
the same at every UI Scaling, and the interface still follows UI Scaling.
fit_zoom, zoom_about, rotate_about, pan_pixels and scroll_by take the UI
zoom, and Xf::new is now test-only.

Found while looking into a report by bortek about the art's size at 100%.
2026-11-12 07:24:43 -08:00
dotCooCoo 8db00cbbe2 Merge main into feat/linux-screen-color-portal 2026-11-12 05:54:25 -08:00
Ahmed Gomaa c66335eaa7 Merge upstream main into file/save-read-only-offers-save-as 2026-11-12 13:40:13 +02:00
BFlat f4df78ef4a Merge pull request #6790 from dotCooCoo/feat/hpgl-export
File formats: HP-GL (.plt) plots export for pen plotters and cutters
2026-11-12 18:19:22 +07:00
dotCooCoo e6d5c8846e Color: Sample Color from Screen works on Linux through the desktop portal
On Linux, ui.sampleScreenColor and the Color Picker's eyedropper button
now show the XDG desktop portal's color sampler (Screenshot.PickColor,
https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Screenshot.html).
A thread of its own makes the call and waits for the person, and the
picked sRGB color goes through the same conversion into the working RGB
space as on macOS and the web. A cancel leaves the colors as they were.

A session without a portal that has PickColor, a portal that does not
return from the call within 25 seconds (VectorCraft's own limit) or
leaves the bus before it answers, and a portal that ends the request in
another way each show a status message and end the wait. The two new
messages are translated in every catalog that has the sampler's other
messages. The request token is random, as the Request documentation
asks (https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Request.html).

The window is named for the portal on the UI thread, as for the save
dialog, and the sampler's thread keeps the window and its export until
the portal answers.
2026-11-12 01:12:13 -08:00
BFlat 183b2ed7e4 Merge pull request #6770 from dotCooCoo/feat/learn-panel
Learn: a Learn panel lists tutorials by skill, opened from Explore tutorials on the app bar
2026-11-12 16:02:15 +07:00
BFlat 1a7aa834db Merge pull request #6786 from dotCooCoo/fix/save-export-show-every-note
Save and Export: the status bar's hover lists every note
2026-11-12 15:13:51 +07:00
dotCooCoo 656d63e4d2 Merge main into feat/learn-panel 2026-11-11 23:31:06 -08:00
dotCooCoo 9c5d22bccc Merge main into feat/hpgl-export 2026-11-11 23:31:04 -08:00
BFlat 48e066f475 Merge pull request #6755 from dotCooCoo/fix/ui-params-wrong-type
Commands: app and control channel params of the wrong type are refused
2026-11-12 14:17:29 +07:00
BFlat 5e63104d88 Merge pull request #6800 from dotCooCoo/fix/plugin-automation-install-approval
Plug-ins: an install that automation asked for is not approved in its dialog
2026-11-12 14:16:59 +07:00
BFlat ccfe14f671 Merge pull request #6799 from Hassan1305/docs-6340-followup
Commands: draw_shape and object.reflect say which way they turn (#6340 follow-up)
2026-11-12 14:15:37 +07:00
dotCooCoo e846710e85 MCP: the css.exportFile catalog entry matches its desktop description 2026-11-11 23:02:26 -08:00
dotCooCoo 60c2130960 Merge main into feat/hpgl-export 2026-11-11 22:29:22 -08:00
dotCooCoo 023d2c6c39 Plug-ins: ui.installPlugin's description says it answers null when the web picker opens 2026-11-11 22:26:03 -08:00
dotCooCoo ad05c3b99d Plug-ins: an install that automation asked for is not approved in its dialog
An approval question that a control request, MCP, injected input, or a
file dialog one of them opened leads to now keeps OK disabled and
refuses every confirm, a person's click included. The dialog says to
choose Object › Plug-ins › Install Plug-in…, and ui.installPlugin answers
approval: "personMustStartInstall". The person's own Install Plug-in…,
File › Open or drop inspects the module again and asks a new question
with its half-second delay.

The origin is fixed when the request is made and goes with a native
file dialog's deferred answer and the web picker's answers, which now
arrive apart from drops and from window.vectorcraft.openFile (always
automation). A question about taking another module's place now opens
in the approval dialog, and automation's replace: true no longer skips
it. A module that needs no approval still installs at once.
2026-11-11 21:56:58 -08:00
HassanKhan 386e405800 Commands: draw_shape and object.reflect say which way they turn; test the notes the key walk misses (#6340)
draw_shape's rotation also turns rectangles and ellipses; object.reflect's numeric axis is counter-clockwise from horizontal. A test covers that axis and the Scatter brush's rotation range, which every_turn_param_says_which_way_it_turns can't reach.
2026-11-12 10:47:06 +05:00
dotCooCoo 832fad16e0 Merge main into feat/hang-report 2026-11-11 21:17:30 -08:00
dotCooCoo e83c36785e Commands: pointer events refuse pen values and spaces of the wrong type
ui.pointer and the headless pointer call read a pointer event's pressure,
holdMs, tiltX, tiltY and rotation with a default for any value that was not a
number, and treated any space other than screen as document space. Each event
is now checked before the packet runs: those values must be numbers and space
must be doc or screen, with null keeping the default. docs/mcp.md says so.
2026-11-11 21:04:01 -08:00
dotCooCoo 987dd18aff File formats: HP-GL (.plt) plots export for pen plotters and cutters
VectorCraft could open and place HP-GL plot files but not write them,
so art for a pen plotter or a vinyl cutter had to go through another
program.

Export As, document.export and Export Selection now write HP-GL.
vectorcraft_cad::hpgl::export draws each visible path once along its
own line: a filled shape is its closed outline and a stroked path its
center line. Type is drawn as glyph outlines, a gradient mesh as its
outline, and a symbol instance as its art with its effects and the
instance's stain. Clipping masks cut the art they clip, and the art is
cut at the artboard's edges. Hidden and non-printing layers, hidden objects,
objects at 0% opacity, template layers, guides and placed images are
left out. Coordinates are plotter units (1016 to the inch, y up) from
the artboard's bottom-left corner or its center, and art more than
8,388,607 units from the origin is cut off.

Each color is a pen, in the order the plot first draws in it (up to
255), or a pen table maps each path to the pen of the nearest color.
With Use Artboards every file of the export uses the same numbering.
The pens draw in turn, each in paint order or, with sortPaths, nearest
path first. Curves are flattened to curveTolerance (0.1 pt by default).
hpglVersion "hpgl" writes IN, SP, PU and PD; "hpgl2" also writes the
palette (NP, PC) and each pen's paths as one encoded polyline (PE).
Options are checked, and Export As writes the file with the defaults.
Plots read back by the HP-GL reader give the same lines.

Docs: docs/mcp.md, docs/control-protocol.md, docs/file-format-parity.md,
docs/target-app-parity.md.
2026-11-11 20:44:32 -08:00
BFlat aa4657e1ce Merge pull request #6704 from dotCooCoo/fix/shape-tool-handles-scale
Shape tools: a drag on a bounding-box handle scales the selection
2026-11-12 11:43:06 +07:00
dotCooCoo 7c28138ce3 Commands: pointer packets are read whole before any event runs
A headless or control channel pointer packet now checks every event's kind,
coordinates and mods before it sends any of them, so a malformed later event
no longer leaves the earlier ones applied. A mods value that is not an object,
such as an array, is refused. Rotate View takes null mods as omitted. The MCP
docs name the params that refuse null.
2026-11-11 19:57:39 -08:00
dotCooCoo 396de45501 Merge main into feat/learn-panel 2026-11-11 19:10:42 -08:00
dotCooCoo 4f08f19ce4 Learn: a Learn panel lists tutorials by skill, opened from Explore tutorials on the app bar
Window › Learn and a new Explore tutorials button beside the search icon on
the app bar show and hide the Learn panel. Its For you tab holds a Get started
section with a Quick skill guide card that opens the Skills tab. The Skills tab
lists VectorCraft's own skills with their tutorial counts and empty progress
rings; a skill lists its tutorials, a tutorial shows its numbered steps, and
Back goes up one level. The tutorials live in a data catalog whose test checks
unique ids, that every named tool and command exists and that no skill is
empty.

- window.learn {show?} shows, hides or toggles the panel; showing it also
  shows a hidden dock, and the panel counts as hidden while the dock is hidden
  or a full screen mode hides the panels.
- learn.list lists the skills and tutorials; learn.show {tutorial} opens one.
  A missing, non-string or unknown id is an error and changes nothing.
- New labels and messages have rows in every catalog. The tutorial text is
  English.

Docs: docs/mcp.md, docs/target-app-parity.md, docs/ui-parity.md.
2026-11-11 19:10:02 -08:00
BFlat 765bd30783 Merge pull request #6744 from dotCooCoo/feat/color-show-recent-colors
Color: the panel menu's Show Recent Colors shows or hides the Recent Colors row
2026-11-12 09:55:35 +07:00
BFlat aeffe1d004 Merge pull request #6731 from dotCooCoo/feat/actions-insert-menu-item
Actions: Insert Menu Item adds a menu command to an action
2026-11-12 09:40:12 +07:00
dotCooCoo 172e2923c0 MCP: regenerate the UI catalog 2026-11-11 18:33:55 -08:00
dotCooCoo a8989aff6d Commands: app and control channel params of the wrong type are refused
view.setZoom, view.screenMode, window.panel, file.revert, file.close,
ui.newSwatch, ui.symbolOptions, ui.batchDialog and file.exportSelection
read a number or switch of the wrong type as its default and went on, so
`view.setZoom {"zoom": "200"}` set 100%. They now refuse it and change
nothing.

The control channel's ui.key, ui.move, ui.wheel, ui.click, ui.drag,
ui.pointer, ui.resize, ui.screenshot, ui.render and ui.set, and the
headless session's key, pointer and render calls, do the same for their
numbers, switches and mods, before any input is queued. Omitting a param
or giving null keeps its default.
2026-11-11 18:22:01 -08:00
BFlat ac8c60cad4 Merge pull request #6675 from dotCooCoo/fix/plugin-filter-progress-cancel
Plug-ins: a light filter that reports progress runs in the background with Cancel
2026-11-12 09:14:14 +07:00
BFlat 8f65aaa7fb Merge pull request #6718 from dotCooCoo/fix/issue-6634
Fix #6634: Pen closing drag no longer gives the first anchor symmetric handles
2026-11-12 09:08:12 +07:00
BFlat 358a47c559 Merge pull request #6737 from dotCooCoo/feat/control-bar-options-menu
Control bar: the panel menu turns each group of options on or off
2026-11-12 09:07:47 +07:00
dotCooCoo 7c90c6e93d Shape tools: a press scales only on the drawn handle square
A shape tool now takes a press as a bounding-box handle's only on the
drawn handle square, kept square to the screen: 3 screen points from the
handle's centre along each axis at the default Anchor Size, a half point
more or less per step. A press just beside a handle draws a new shape.

drawing_gestures_snap_to_smart_guides started its second rectangle on the
first rectangle's corner handle, which stays selected; it now deselects
first.
2026-11-11 17:57:08 -08:00
dotCooCoo f3339a47f8 Actions: Insert Menu Item leaves out Image Trace and Pattern, counts recorded steps
Object > Image Trace > Make and Make and Expand, and Object > Pattern >
Make and Edit Pattern, are no longer listed or accepted by
`ui.action.insertMenuItem`. Their menu items do more than run the
command: Image Trace traces off the UI thread with progress and Cancel,
and the Pattern items open the Pattern Options panel. Action playback
runs only the command.

Insert Stop and Insert Menu Item, given a set and action, now count the
steps that the recording in progress adds to that set, so the set as
Stop Playing/Recording leaves it stays within 10,000 steps per action
and 8 MiB as a file.

The command descriptions list every kind of menu item that cannot be
a step.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-11 17:43:32 -08:00
dotCooCoo 62b6f53533 Color: the panel menu's Show Recent Colors shows or hides the Recent Colors row
The Color panel's menu gets a checked Show Recent Colors item under Show
Options / Hide Options. Unchecking it hides the panel's Recent Colors row;
checking it shows the row again. Applied colors still join the list while
the row is hidden, Hide Options hides the row either way, and the Swatches
panel keeps its own row.

The setting is on by default and is kept with the preferences
(ui.color_show_recent_colors); a saved value that is not true or false
reads as on. ui.colorPanel takes recentColors: bool and answers it.

Docs: docs/mcp.md, docs/control-protocol.md, docs/target-app-parity.md.
2026-11-11 17:26:16 -08:00
dotCooCoo 6b4056a447 Control bar: the panel menu turns each group of options on or off
The Control bar's panel menu lists the bar's groups of options above
Dock to Top and Dock to Bottom, each checked while it is on. A click
turns that group off or on, and a group that is off stays out of the
bar even while its tool or object is selected. A group that is off
takes no room, so the groups after it fit a narrower window. The menu
scrolls in a window too short for all its items.

- window.control.options {group, visible?} sets or toggles a group and
  returns {group, visible}; an unknown group or a non-boolean visible
  is an error and changes nothing.
- The groups are off only by choice: every group starts on. The choice
  is kept with the preferences and with each workspace; files saved
  without it show every group, and unknown ids are dropped on read.
- The Artboard tool's bar follows the Artboard Options and Transform
  groups; with Image Options off, an image shows neither its controls
  nor Fill and Stroke.
- New labels have rows in every complete catalog.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-11 16:40:10 -08:00
dotCooCoo 45e6aa4948 Tests: MCP Pen closing drag keeps a clicked first anchor a corner
tests::pen::a_drag_from_the_first_anchor_closes_the_path expected the
closing drag to give the first anchor an outgoing handle mirroring the
incoming one, which is the behavior #6634 reports. The first anchor is
placed by a click, so after the close it stays a corner with its
outgoing handle at the anchor. The test now checks that.
2026-11-11 16:39:55 -08:00
dotCooCoo e4a126f08d Paragraph Styles: Style Options edits indents, spacing, composition, hyphenation and justification
Double-clicking a paragraph style, or Paragraph Style Options... in the
Paragraph Styles panel menu, opens Paragraph Style Options
(`ui.paraStyleOptions`) instead of the rename dialog. Its sections are
General (name and stored attributes), Basic Paragraph Formats (Alignment,
indents, space before and after), Composition (composer, Roman Hanging
Punctuation), Hyphenation and Justification. OK runs the new
`paraStyle.edit {name, to, attrs}`, which replaces the name and attributes
in one undo step; paragraphs that use the style keep their local
overrides. Fields left as they were keep the style's values, empty fields
leave an attribute unset, Preview can be canceled, and each section's
Reset Panel (`ui.paraStyleOptions.resetPanel`) clears only its own
attributes. New Paragraph Style shows the same sections, filled in from
the selected paragraph or the interface language's paragraph defaults.

`paraStyle.new`, `paraStyle.setAttrs` and `paraStyle.edit` now reject a
changed indent or space outside -1296 to 1296 pt, Hyphenation counts and
zone outside their ranges, Justification values outside their ranges or
out of Minimum/Desired/Maximum order, and tab positions outside 0 to
100000 pt. A value the style already holds is kept.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-11 16:34:42 -08:00
dotCooCoo 788d0f517f Actions: Insert Menu Item adds a menu command to an action
The Actions panel menu's Insert Menu Item… opens a dialog that lists the
menu items an action can hold. Find picks the one item that matches the
words typed, or a click on a listed item picks it, and OK inserts its
command as a step after the selected step, at the end of the selected
action, or into the recording in progress, without running it.
Playback runs the step as the menu does.

Items that open a dialog, Object > Align, and the File, Window and Help
menu items are not listed. `ui.action.insertMenuItem` does the same for
agents and refuses a command no listed item runs.

Insert Stop and Insert Menu Item refuse a step that would give an action
more than 10,000 steps or its set a file larger than 8 MiB, the most
Load Actions… reads, for actions and recordings alike.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-11 16:21:55 -08:00
Ahmed Gomaa 9a77c2ee11 Save As fallback asks for a changed format's options
When the read-only fallback's Save As panel returns a different format, drop the options captured for the original format and open the picked format's normal Save options; an unchanged format keeps its options. Regenerate the file.save entry in the MCP command catalogue.
2026-11-12 01:27:25 +02:00
Ahmed Gomaa f0e50437c2 Save on a read-only location offers Save As
A plain Save that the location refuses (read-only filesystem or permission denied) now opens Save As with the name filled in, instead of ending in an error dialog. The refusal travels as a typed engine error (READ_ONLY_LOCATION), so the control protocol and MCP still return an error and never open a panel. Recovery failures, explicit destinations, a busy picker and Close/Quit keep their existing flow.

Closes #6146
2026-11-11 23:16:03 +02:00
dotCooCoo 96e20d548d Plug-ins: a light filter that reports progress runs in the background with Cancel
A light filter of plug-in API level 2 with the `progress` permission ran
on the UI thread, so its progress reports and `vc_cancelled` never
reached a progress window. It now runs in the background under its light
budget, as a heavy filter does, when it runs at once from Object ›
Plug-ins or its shortcut, or when OK runs it with Preview off. The
progress window shows its share and Cancel stops it. With Preview on, OK
keeps the previewed run. A filter that lists a `commandAllowlist` still
runs on the UI thread.

Docs: docs/plugins.md, docs/mcp.md, docs/target-app-parity.md.
2026-11-11 12:18:18 -08:00
BFlat f83d916d8a Merge pull request #6631 from Hassan1305/docs-6340-rotation-direction
Commands: every angle and rotation param says which way it turns (#6340)
2026-11-12 01:32:17 +07:00
HassanKhan b3860bf7d0 Commands: every angle and rotation param says which way it turns (#6340)
The params docs now state the direction (and the zero) of each angle or
rotation a command takes; behaviour is unchanged. Shape creation, text.create,
the grids, add-on shapes, saved views, Liquify, Puppet Warp pins, Mirror and
Radial Repeat and Vector Halftone turn clockwise; text character rotation,
gradients, the eraser tip and print screen angles turn counter-clockwise.

view.saved.new's rotation note changes its schema, so the API level goes to 3.

A test walks every command's params doc and fails when a param named like an
angle or rotation doesn't say clockwise or counter-clockwise.
2026-11-11 21:40:27 +05:00
Fabio William Conceição 3f26409d4a MCP: keep UI_COMMANDS mirror in sync via xtask
Add `cargo xtask ui-commands` (and `--check` in ci) so the headless
catalogue cannot drift from desktop UI_COMMANDS, and fix params-doc
escaping that printed literal backslashes.
2026-11-11 15:56:33 +00:00
Fabio William Conceição 13098fa9f4 MCP: list UI_COMMANDS in command_list and close catalogue gaps (#6460)
Headless command_list exposes the desktop UI catalogue with ui: true, docs
clarify effect vs command ids, and prompts cover spelling, variables and path tools.
2026-11-11 15:48:05 +00:00
dotCooCoo d9e9adbf45 MCP: answer_dialog sets the fields and answers the dialog in one request
answer_dialog sent ui.dialog.set and then ui.dialog.confirm or
ui.dialog.cancel as two requests. A dialog another control connection
opened between them was confirmed or canceled without the fields.

ui.dialog.set takes `action: confirm | cancel`, checked before any field
is set, and confirms or cancels the dialog the fields were set in within
the same request, replying {dialog, result}. answer_dialog sends set and
action together; an app whose reply has no `dialog` key did not answer
it, and the dialog is then confirmed or canceled with its own request.
2026-11-10 14:51:50 -08:00