Skip to content

permission probe (te sluiten) - #2

Closed
switch87 wants to merge 136 commits into
mainfrom
fix/544-copyable-error-commands
Closed

switch87 wants to merge 136 commits into
mainfrom
fix/544-copyable-error-commands

Conversation

@switch87

Copy link
Copy Markdown
Owner

probeer toegang

knipknap and others added 30 commits October 8, 2026 21:21
macOS TCC kills the process the moment camera code touches AVFoundation
(even just enumerating devices) unless the app bundle's Info.plist
declares NSCameraUsageDescription. The key was never part of our
PyInstaller BUNDLE config, which is why clicking 'Add new camera'
crashed Rayforge 1.12.0 on macOS with no log output (barebaric#510, likely
also barebaric#166).
After granting camera permission, the first grab on macOS could still
crash with SIGSEGV inside -[CaptureDelegate grabImageUntilDate:] when
the first read raced the capture session startup (barebaric#510). OpenCV's
AVFoundation backend is flaky when driven from a plain Python thread,
and a segfault cannot be caught in Python, so the only defense is to
not grab before the session has settled.

_capture_has_initial_frame() is the single choke point through which
both the device scan and open() validate a freshly opened device; it
now waits 0.5s after isOpened() before the first read on macOS only
(other platforms keep zero delay and unchanged behavior). The wait is
interruptible via the controller's cancel event so shutdown stays
prompt.
Co-authored-by: medoix <149519+medoix@noreply.github.com>
Co-authored-by: medoix <149519+medoix@noreply.github.com>
Add GifImporter, TiffImporter and WebpImporter on a shared bitmap
importer that loads any libvips-readable image by content and traces
it like PNG. Animated GIFs and multi-page TIFFs import their first
frame or page. A TIFF's stored resolution sets the physical size;
images without one fall back to 96 DPI, matching the scan step.

A single BitmapRenderer renders the source asset of all three formats.

Also fixes the PNG row of the raster table in the import docs, which
listed the .webp extension.

Refs barebaric#517
Illustrator has saved .ai files with an embedded PDF by default since
version 9. AiImporter detects the PDF header and hands those files to
the PDF importer unchanged, so they need no extra dependency.

EPS, PostScript and PostScript-only .ai files are converted to PDF
with Ghostscript (-dSAFER, -dEPSCrop, -dNoOutputFonts), an optional
runtime dependency, and then imported by the PDF importer. The EPS
bounding box becomes the page size and text becomes outlines.
Conversions are cached by content, so the live import preview does not
run Ghostscript again for every change. The source asset keeps the
converted PDF, so a saved project renders and re-imports on machines
without Ghostscript.

Without Ghostscript the import dialog shows a clear message; for a
legacy .ai file it also explains how to save it again with PDF
compatibility.

Refs barebaric#517
Add an HPGL importer for .plt/.hpgl files from cutting plotters, vinyl
cutters and CAD programs. The parser handles IN/DF, SP, PU/PD, PA/PR
(with free-format parameter lists), CI, AA/AR and the EA/ER/RA/RR
rectangles, skips labels and PCL escape sequences, and converts
plotter units (40 per mm) to millimetres.

Each pen becomes a layer that can be selected in the import dialog;
layer filtering and splitting reuse the DXF importer. Instructions that
change the drawing but are not supported (for example SC, RO or LB)
are reported as a single import warning.

Also lists the new import formats in the README.

Refs barebaric#517
When the scan of a file reports errors, for example an EPS file while
Ghostscript is missing, tracing fails as well. The import dialog no
longer shows the "Switch to Trace Mode" hint next to the error banner
in that case.

Refs barebaric#517
EPS, PostScript and PostScript-only .ai sources embed the PDF that
Ghostscript produced, so original_data no longer equals the file on
disk. The importer now also records the SHA-256 and size of the
original file in the source asset's metadata.

SourceAsset gains source_file_sha256, source_file_size and
matches_source_file(). They fall back to original_data when no
fingerprint is stored, which covers every unconverted source and
projects saved before this change, so existing projects load and
compare as before. Code that checks whether the file on disk changed
since the import should use matches_source_file() instead of hashing
original_data.

Refs barebaric#517
Rpa 0.22.0 TCP connections, controller info logging, and connect-time version
Add ReloadCmd, which replaces the data of a SourceAsset with the current
file on disk and updates every workpiece made from it as one undo step.
Placement is carried over by re-running the import on the old and the
new data and applying the user's transform on top, so content that did
not change in the file stays where it was. Spec, layer, tabs and image
modifiers are kept; elements are matched by source layer id.

Add SourceWatcher, which reports sources whose file content changed and
settled, and an auto_reload flag on SourceAsset.

Refs barebaric#513
The main window polls imported files every two seconds through a
SourceReloadMonitor and, when files changed, shows one dialog listing
them. Selected files are reloaded in place; unselected or ignored ones
are not offered again until they change again. Files can be marked to
reload automatically from then on. Opening a project checks right away.

Refs barebaric#513
ReloadCmd can now point a source at another file and reload it from
there in one undoable step, and lists the sources behind a selection.
Config gains watch_source_files (on by default).

Refs barebaric#513
Reload from Disk and Relink Source File are offered in the File menu,
the canvas and layer list context menus and the asset browser. Relink
opens a file chooser and reloads from the chosen file. The General
preferences get a switch to turn watching imported files off.

Refs barebaric#513
The relink dialog expects a Gtk.Window; the caller passes the main
window, so the annotation was too narrow for pyright.

Refs barebaric#513
The step settings pages pushed raw attribute values into the varset
rows. For enum-backed attributes such as EngraveStep.dither_algorithm
the combo adapter got "DitherAlgorithm.BAYER4", matched no entry and
kept showing the first one (Floyd Steinberg), both when the dialog
opened and after undo or an external change.

Serialize the values with Step.recipe_value(), the same way recipes
store them, before handing them to the rows.
Extend DitherAlgorithm with Atkinson, Stucki, Jarvis-Judice-Ninke,
Sierra (3-row, 2-row, Lite) and Burkes error diffusion, a clustered-dot
Newsprint screen and a round-dot Halftone screen.

- apply_error_diffusion() takes any forward kernel and an optional
  serpentine scan. The error within a row is propagated per pixel, the
  error for the following rows with one vectorised add per kernel tap,
  which dithers a 2.5 MP image in about 0.6 s. Like raygeo's
  Floyd-Steinberg it works in linear light.
- apply_halftone() lays a cosine spot screen out in millimetres, so
  the dots stay round on the non-square raster pixels, and ranks the
  spot values so the dot area follows the darkness.
- Newsprint tiles a 45 degree clustered-dot matrix whose cells scale
  with the minimum feature size and stay square in millimetres.

Floyd-Steinberg without serpentine and the Bayer screens keep using
raygeo, so existing jobs produce identical output.

Refs barebaric#514
The Engrave step's dither algorithm list now offers every
DitherAlgorithm. New step settings, saved with the document, recipes
and cache params:

- Serpentine: alternate the scan direction per row, shown for the
  error-diffusion algorithms.
- Halftone Cell Size and Halftone Angle, shown for Halftone.

preprocess_raster_image() forwards them together with the Y
resolution, so the screens can keep their cells square in
millimetres. apply_import_settings() accepts the depth mode, threshold
and dither settings so importers can set them.

Refs barebaric#514
CutSetting_Img layers carried their image mode in ditherMode, which
the importer ignored, so every imported photo fell back to Variable
Power. Map it onto the Engrave step: dithered, atkinson, stucki,
jarvis, ordered, newsprint and halftone become the matching dither
algorithm (halftone with its cellsPerInch and halftoneAngle),
threshold becomes Constant Power and grayscale Variable Power. Sketch
has no counterpart and keeps the default.

Refs barebaric#514
Close open contours whose ends meet within a tolerance, join open
contours into longer paths (reversing pieces where needed), remove
duplicate contours and stacked duplicate workpieces, and break a
workpiece apart into one workpiece per contour.

The geometry work lives in rayforge.core.path_cleanup and runs in
millimetres, so tolerances do not depend on the workpiece scale. Gaps
are bridged with straight segments between existing end points, so the
bounding box and placement stay the same. Each command writes the
result through ChangePropertyCommand on _edited_boundaries and is a
single undo step. Break Apart reuses SplitCmd with a new
ContourSplitStrategy that, unlike the connectivity split, keeps holes
and open paths as pieces of their own.

Refs barebaric#516
Add Break Apart, Close Paths…, Join Open Paths… and Delete Duplicates
to the Object menu and a Clean Up Paths submenu to the canvas context
menu. Close and join ask for a tolerance in a small dialog that
remembers the last value per tool for the session; each tool reports
its result in a toast.

Includes translations for all shipped languages, a documentation page
in every website language and a changelog entry.

Closes barebaric#516
knipknap and others added 28 commits October 15, 2026 13:04
A step's workpiece selection becomes a generic workpiece_uids list
(empty = all workpieces of the layer) instead of the pipeline knowing
about the generated-workpiece concept: the intent builder now just
asks the step which workpieces it applies to. Projects saved with the
old single-uid key still load, and new projects still write it so
older versions keep rendering generated content correctly.

The step settings dialog gains a read-only Workpieces tab showing
which workpieces a step processes on its layer.
Add a CONTRIBUTING.md with an AI-assisted code clause and a pull
request template that asks for architectural reasoning and manual
test steps. A GitHub Actions workflow validates the description and
closes non-compliant PRs automatically, reopening them once the
description complies; drafts, bots, and users with write access are
exempt. Sync the website developer docs and contributing pages in
all languages, and instruct agents to leave .po catalogs to the
release process and to ship docs and screenshot updates in PRs.
Add two screenshot targets: operations:perforation loads a new
perforation.ryp asset (a rectangle and a circle on a plywood stock,
Perforation enabled at 1.0 mm cut / 0.5 mm skip) and captures a
close-up of the dashed toolpath; step-settings:contour:post:perforation
opens the post-processing page with the Perforation group enabled and
expanded. Regenerate step-settings-contour-post.webp so it includes
the new Perforation row.
Turn the bullet-heavy page into flowing prose in English and all
translations, explain where the post-processor lives and how the
pattern behaves, and show both the settings UI and the resulting
dashed cut on the canvas.
Adds a screenshot target that opens the Material Test Grid's step
settings on the Workpieces tab, and extends the operation pages: the
Material Test Grid page explains the link to its generated workpiece,
and the pages listing the dialog tabs count the new one. All translated
pages are updated accordingly.
…lter

refactor(step): generalize the generated-workpiece link into a workpiece filter
An output computed before a workpiece resize can arrive on the main
thread after the resize was committed. _on_wp_output stamped such an
artifact with the workpiece's live size instead of the size its ops
were generated at, so the canvas mapped the ops overlay by
current_size / generation_size == 1 and drew the stale ops 1:1. The
material test grid's cells and labels then appeared misaligned with
the workpiece image until the next rebuild delivered a fresh artifact.

Stamp the artifact from the output's own source_dimensions, which
every assembler step already populates with the size the ops were
generated against, and keep the live size only as a fallback for
steps that provide none.
feat: add a Perforation post-processor for Contour steps
raygeo 1.66.0 limits full-sweep raster passes to each scan line's own
content extent instead of the image bounding box (raygeo#62), fixing
barebaric#565: a shape that narrows in X (e.g. an hourglass)
no longer sweeps the widest extent on every row.

No rayforge code changes are needed; the behaviour lives entirely in
the raster assembler. Re-locks pixi.lock (raygeo-only change).
…le-size

fix(pipeline): keep ops overlay aligned when a resize races a rebuild
The latest stable release (1.12.0) ships no AppImage asset, so the
asset lookup fell through to the .deb and the AppImage section linked
to the wrong file. Match .AppImage only; the section already falls
back to the GitHub releases page when no asset is found.
The Prerelease key does not exist in any winget manifest schema; winget
derives the prerelease marker from the dash in the version string itself.
The unknown field made "winget validate" fail the submission job, and
warnings-as-errors also broke the step on winget builds that falsely warn
about the schema header URL, so the validate step now ignores warnings.
Renaming a workpiece, group, step, layer, or stock item fired the
item's `updated` signal, which the pipeline treated as a content
change: every cached render was invalidated, the intent was rebuilt,
and all workpieces were re-rendered. In large projects this burst of
background work collided with the UI's buffer handling and crashed
GTK with an access violation.

A rename is a pure label change, so it now has its own dedicated
signal instead of being flagged on top of `updated`:

- `DocItem.renamed` fires when the name changes and never bumps the
  geometry/transform revision counters.
- `DocItem.descendant_renamed` bubbles renames up the tree, mirroring
  the existing `descendant_updated` / `descendant_transform_changed`
  plumbing.

Because renames no longer reach `updated`, the pipeline controller and
the canvas elements need no special-casing, and the flag plumbing
(`name_only`, `**kwargs`) is gone.

`Step.set_name`, `Layer.set_name`, and `StockItem.set_name` no longer
re-send `updated`; they relied on the name setter, so previously they
still triggered the full rebuild the undo commands use them for.

Label-updating UI now listens to the dedicated signal: layer headers,
workpiece/group rows, step boxes, the workflow title and step tooltips,
the item properties panel, and the stock properties dialog. The
document is still marked as modified through the undo history.

Closes barebaric#571
…ender

fix: renaming an item no longer triggers a full re-render
Add the addons:sketcher:tool:polygon screenshotter target showing a
hexagon and a star as the polygon tool creates them, and embed the
image in the Polygon pages.
feat(sketcher): Polygon tool for regular polygons and stars
The jog limit check compared the controller's raw machine position
(MPos) against the soft limits, which are work-area bounds. On
machines whose machine coordinates sit offset from the work origin
(e.g. a GRBL that homes at the max end and reports negative machine
positions), jogs toward the origin appeared outside the bounds and
were silently clamped to zero, leaving the left/forward jog buttons
permanently orange and blocked (barebaric#574).

Subtract the active WCS offset before the check, so soft limits are
evaluated in the same coordinate space the position display uses.
The Z travel check keeps using machine coordinates.

The soft limits toggle only cleared the custom bounds; clamping
against the work area stayed active with no way to turn it off. The
toggle now enables and disables jog limit checks as a whole, and the
state is persisted in the device profile.
The bundled conda environment keeps absolute build-machine paths
inside its libraries, so they are dead inside the AppImage. AppRun
now exports XKB_CONFIG_ROOT so GTK can compile keymaps on Wayland
instead of segfaulting, and points SSL_CERT_FILE at the real
cacert.pem location (env/ssl, not env/etc/ssl) so TLS verification
works for the update and addon registry checks.

Adds an --apprun-selfcheck mode that verifies the CA file and an
evdev keymap compilation inside the launch environment; the CI
smoke test now runs it to catch regressions.

Fixes barebaric#578
Mirror the updated Soft Limits section of the hardware settings page
in the German, Spanish, French, Hindi, Brazilian Portuguese,
Ukrainian and Chinese docs.
…ong-coordinate-space

fix(machine): evaluate jog limits in work coordinates
…aths

fix(appimage): repair Wayland keymap and TLS in AppRun, add selfcheck smoke test
Error messages that tell the user what to run in a terminal — the Snap
serial permission failures, for one — were rendered as plain text, so
the only way to use a command was to type it by hand.

The message is now split at its trailing command block: the prose
stays in the status row or the banner that carries it, and each
command becomes a CommandRow, the single-click copy row the
permissions pre-flight page already used, now shared between both.
The probe page in the setup wizard and the machine settings' error
banner show them.

A block is only taken when every line of it looks like something to
type; whatever a message does not clearly hand over as a command is
left exactly as written.

Fixes barebaric#544

This branch was successfully deployed

1 active deployment
pypi — afba25f2 Deployed Oct 17, 2026 by switch87 via Build and Publish Wheel #1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants