Commit Graph
18727 Commits
Author SHA1 Message Date
yw4z 8740696e75 init 2026-09-07 13:16:31 +03:00
HanifKoh 886d43d37a Fix Support Fill Cost Thresholds Being Frozen By The First Call (#15564)
Fix support fill cost thresholds being frozen by the first call
2026-09-07 16:35:36 +08:00
Kris AustinandNoisyfox 494d50bd55 fix: restore Ctrl+drag panning on macOS (#15312)
On macOS wxWidgets reports Ctrl+left as a synthetic right button, which is
what made Ctrl+drag pan the canvas. #14999 added an unconditional correction
of the event's button state from wxGetMouseState(), which reports the
physical buttons and knows nothing about that synthesis, so the synthetic
right button was overwritten with a plain left button on every event.
Ctrl+drag then matched the left button mapping and rotated instead of
panning.

Apply the correction only when the event carries no button state at all.
On macOS wx populates button state only for the mouse-down and mouse-dragged
event types, which are also the only ones the Ctrl+left translation touches,
so the ImGui capture fix keeps every event it was added for.

Fixes #15214

Co-authored-by: Noisyfox <timemanager.rick@gmail.com>
2026-09-07 14:16:45 +08:00
SoftFever eebc82cc95 clean up 2026-09-07 12:14:05 +08:00
SoftFever 4b104bb574 Merge branch 'main' into feature/filament_id 2026-09-07 11:53:50 +08:00
SoftFever 3500a1e588 unify id generation scripts 2026-09-07 10:46:59 +08:00
Kris Austin 8d44b680bd fix: bumping the bundled uv version rebuilds the whole GUI library (#15553) 2026-09-06 20:23:47 -03:00
Kris Austin 43ce8c5e46 fix: SLIC3R_PCH=OFF now builds on Windows, allowing compiler caching (#15552) 2026-09-06 18:06:18 -03:00
Kris Austin 0365304ae0 fix: G-code preview drops comment text and cuts non-ASCII lines short (#15448) 2026-09-06 15:42:57 -03:00
Rodrigo FaselliandIan Bassi 85dc866425 Spiral Inset infill (spiral-concentric infill) (#15085)
Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
2026-09-06 11:36:23 -03:00
SoftFever 06e665fca7 Merge branch 'main' into feature/filament_id 2026-09-06 22:34:06 +08:00
Kris Austin 0b6bbd85bd build: clear 75 warnings - hidden base overloads (#15542) 2026-09-06 11:08:57 -03:00
SoftFever 4aa0e1d60b Translate filament ids at the printer boundary
Orca content-addresses every system filament, Bambu's included, but a printer,
its AMS and its vendor's cloud know only that vendor's own catalog ids. The
printer agent now translates between the two: outbound MQTT and FTP traffic, the
AMS mapping sent with a print job, and the ids written into a 3mf bound for the
printer all leave in the printer's own ids, while status messages, loaded
projects and SD-card prints arrive in Orca's. An id with no mapping passes
through unchanged, and an agent whose printers already speak Orca's ids
translates nothing at all.

Bambu's map is generated from BambuStudio's own shipped bundle; a missing or
unreadable file leaves every lookup an identity rather than taking the app down.
The profile check validates the map's shape, and profile CI now runs on the paths
that can change it. docs/HLSD/filament_id.md records the places the map
deliberately does not reach.
2026-09-06 20:53:11 +08:00
Tommaso BianchiandClaude Opus 5 e5659e0f0f The value field stops being a window, and now takes what is typed
Rebases the in-canvas work onto cad-mainline and finishes it. The field is drawn
by ImGui inside the GL canvas instead of being a borderless top-level wxFrame.

WHY THE FLOATING FRAME COULD NOT BE FIXED. Whether a borderless top-level may hold
the keyboard is the window manager's decision, and it differs per desktop: openbox
grants it, mutter refuses it, macOS denies key status outright. Seven workarounds
fought that and one cost a macOS regression. Drawn inside the canvas there is no
second top-level for anyone to refuse, so the question is never asked. The field is
fed exactly like every other ImGui widget in the app — GLCanvas3D::on_char ->
ImGuiWrapper::update_key_data -> io.AddInputCharacter.

MEASURED, on behemoth: the click-edit ladder holds 28 checks — Line, Rectangle,
Circle, Slot, Polygon, Ellipse, Arc, and click-to-edit on a placed dimension label
— typing with NO click into the field first, committed == typed != prefill every
time, and 27 [UX] imgui_char lines showing the characters arriving.

WHAT WAS ACTUALLY WRONG. Not the field. The belief that "characters never reach the
ImGui InputText" came from the harness: the ladder was delivering keys with
`xdotool type --window` (XSendEvent), which GTK discards, so no build of any kind
could have received them. The new probe in ImGuiWrapper::update_key_data — the one
place ImGui is ever handed a character — is what separated that from a real defect,
and it stays, because a canvas-side probe provably cannot answer the question:
GLCanvas3D::on_char is bound later than any constructor-time probe, wx runs handlers
in reverse bind order, and on_char returns without Skip(), so such a probe is silent
whether or not the key arrived. A day was lost reading that silence as evidence.

Also drops DesignPanel's content-based forwarder and DesignCanvas::inline_type_char.
They were the right rule for a field that could not be focused; with the field
inside the canvas there is nothing to forward, and keeping them would have masked
whether the normal path works.

STILL UNVERIFIED: behaviour under mutter itself. Neither focus-stealing-prevention
WM available here survives long enough to judge — metacity SEGVs ~20s in and xfwm4
dies with BadWindow on SetInputFocus, both before the sketch opens and both
unrelated to this field. The design's claim is structural rather than measured: no
second top-level means no focus to refuse.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FbJKJAJxxkhDTs9XdZzKA
2026-09-06 11:10:02 +02:00
Tommaso BianchiandClaude Opus 5 f6c551540e The key tracer had been printing one letter of the answer all along
focus= in [KEYTRACE] was never a class name. GetClassName() returns const wxChar* — wchar_t* in
this build — and the line cast that to const char* and printed it with %s, so it emitted the first
byte and stopped at the padding NUL. "wxGLCanvas" came out as "w". So did "wxWindow". Every focus
reading taken from this instrument for a whole day of diagnosis was a single character, and the
one question it existed to answer — WHICH widget has the keyboard — was the one it could not
answer. Printed through wxString now, and it says focus=wxGLCanvas: the canvas does hold wx focus
while the field is open, which removes the focus hypothesis for good.

Also here, and HONESTLY LABELLED AS INCONCLUSIVE: a wxEVT_CHAR probe on the canvas. It logged
nothing (cc=0), and the tempting reading is "the characters never reach the canvas". That reading
is not available, because the probe is bound in the DesignCanvas constructor BEFORE
GLCanvas3D::bind_event_handlers(), and wx runs the most recently bound handler first —
GLCanvas3D::on_char returns without Skip() exactly when ImGui consumes a character, which is
precisely the case under test. A silent probe is therefore consistent with ImGui consuming the
keys correctly AND with them never arriving. It measures nothing. Rebind it after
bind_event_handlers(), or instrument update_key_data itself, before believing anything about it.

Writing this down rather than acting on it: I came within one commit of "fixing" a mechanism I had
inferred from an instrument that could not see it, which is the same mistake as the focus= field
above and the same mistake that cost a whole session in September.

Deployed binary restored to 00d6c191dc (md5 0eeb9a58cef5).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FbJKJAJxxkhDTs9XdZzKA
2026-09-06 10:58:05 +02:00
Tommaso BianchiandClaude Opus 5 b45d675488 The frames now keep coming; the characters still do not
Third measured step, and the last one I will take without a second pair of eyes.

set_as_dirty() BEFORE Refresh(): GLCanvas3D's paint handler returns without rendering when the
canvas is not marked dirty, so the previous commit's bare Refresh() posted paint events that drew
nothing and the frames stopped anyway. With both halves the pump sustains, and the trace shows the
field holding the keyboard frame after frame:

  [UX] frame want_text=1 want_kb=1 active=1 buf=158.74
  [UX] frame want_text=1 want_kb=1 active=1 buf=158.74   (repeating)

STILL OPEN, and now narrowed to one question: buf never changes. ImGui owns the keyboard and our
InputText is the active item, so what is missing is upstream of ImGui — the characters are not
reaching io.AddInputCharacter at all. The next thing to MEASURE (not to change) is whether
wxEVT_CHAR arrives at the GL canvas in the Design tab: DesignPanel's wxEVT_CHAR_HOOK Skips digits
while inline_busy(), but Skip only helps if the focused widget is the canvas, and nothing has yet
proved that it is at the moment the keys are sent.

Three attempts have now gone into this one point. Per the standing rule that is where solo
iteration stops.

Deployed binary restored to 00d6c191dc (md5 0eeb9a58cef5) — nothing from this branch is installed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FbJKJAJxxkhDTs9XdZzKA
2026-09-06 10:58:05 +02:00
Tommaso BianchiandClaude Opus 5 d82c8b59c2 The field now owns the keyboard; what it does not yet own is the characters
Measured, not reasoned. A per-frame trace of the ImGui state is what finally named the mechanism,
and it is a deadlock, not a focus problem:

  [UX] frame want_text=0 want_kb=0 active=0 buf=158.74   <- frame 1: the widget is not active yet
  [UX] frame want_text=0 want_kb=0 active=1 buf=158.74   <- frame 2: now it is
  (nothing further)                                       <- and the canvas stops

This canvas repaints ON DEMAND. ImGui decides whether it wants the keyboard at the END of a frame,
from the active item; GLCanvas3D::on_char only calls render() when update_key_data() says ImGui
wants it. So: no frames -> WantTextInput never turns on -> no render on a keystroke -> still no
frames. The characters sit in ImGui's input queue and the field is exactly as deaf as the window
it replaced, for a completely different reason.

request_frame breaks the circle, and the same trace says so:

  [UX] frame want_text=1 want_kb=1 active=1

That is the first time in this file's history that the value field has owned the keyboard without
asking a window manager for it.

STILL OPEN: the typed characters do not reach the buffer (buf stays at the prefill) and the frames
stop after nine. The pump is the suspect — on software GL request_repaint() calls m_canvas->render()
SYNCHRONOUSLY, so this asks for a render from inside a render; it needs to schedule one instead.
That is the next thing to measure, not to guess.

The deployed binary on behemoth is restored to 00d6c191dc (md5 0eeb9a58cef5), byte-identical to
the last good build. Nothing from this branch is installed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FbJKJAJxxkhDTs9XdZzKA
2026-09-06 10:58:05 +02:00
Tommaso BianchiandClaude Opus 5 5ab3072b9f WIP: the value field stops being a window — renders in-canvas, does not yet take keys
The decision (Tommaso's, put to him with the trade-offs): the field stops being a separate
top-level window, because whether such a window may receive typing is the window manager's
call and not ours. openbox grants it, mutter on his desktop refuses, and seven previous
workarounds fought that — one of them causing a macOS regression, and the test harness ending
up clicking the field before typing, which is a workaround no user can be asked to perform and
is exactly the "label value not editable" report.

DONE and proved on the rig: SketchInlineEditor is no longer a wxFrame + wxTextCtrl. It is state
plus an ImGui overlay drawn by DesignSketchTool::render(), at the same screen anchor, in the same
vocabulary as the dimension labels next to it (draw_dim_label is already an ImGui window). The
field opens where it should — [UX] open title=Length prefill=158.74 from the running app.

NOT DONE: typing does not reach it. ImGui is fed from GLCanvas3D's own key handler, so the keys
have to arrive at the canvas; giving the canvas wx focus when the field opens was not enough.
The remaining question is where a keystroke goes between DesignPanel's wxEVT_CHAR_HOOK and
GLCanvas3D::on_char in the Design tab, and whether the canvas repaints often enough for ImGui to
advance its input state. That is attempt three on this specific point, so it goes to a second
opinion rather than a third guess.

Also here: scripts/CAD/check-gui-click-edit.py, the ladder Tommaso asked for. It types into the
field WITHOUT clicking it first — the click is what check-gui-sketching.py's focus_field() does
and why that suite can never see this defect — and fails when the prefill is what gets committed.
It currently fails, correctly, on the above.

Not on cad-mainline: the deployed binary must stay the last good build until typing works.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FbJKJAJxxkhDTs9XdZzKA
2026-09-06 10:58:05 +02:00
Tommaso BianchiandClaude Opus 5 0fee4494e2 Never ask for activation with timestamp 0
present_toplevel() already asked for focus with a server timestamp, but only when
the widget happened to be realized. An unrealized widget has no GdkWindow, so
there was nothing to read a timestamp from and control fell through to
wxFrame::Raise() — which asks for activation with GDK_CURRENT_TIME, i.e. 0.

Zero is exactly what focus-stealing prevention discards. metacity says it out loud
when a sketch value field opens:

    Buggy client sent a _NET_ACTIVE_WINDOW message with a timestamp of 0

and mutter, same lineage, refuses it silently on the user's desktop. That refusal
is the reported defect: the field is visible, never receives the keyboard, and
Enter commits the as-drawn prefill.

So realize the widget and retry, and do NOT fall back to Raise() on X11 — a
timestamp-0 activation is refused anyway, and on some window managers it only
marks the window as demanding attention.

Not yet confirmed end to end: both window managers with focus-stealing prevention
available here abort on this frame — metacity at frames.c:1239, xfwm4 with
BadWindow on SetInputFocus as the frame is destroyed under it — so the ladder
cannot yet return a trustworthy verdict under one. Two WMs crashing on the same
borderless, repeatedly re-mapped STAY_ON_TOP frame is its own signal about this
design. Tracked in projects-1p5 and projects-40m.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FbJKJAJxxkhDTs9XdZzKA
2026-09-06 10:39:50 +02:00
Tommaso BianchiandClaude Opus 5 9134299233 Sketch value fields: content-based key arbiter + the gate that can judge it
The reported defect: sketch dimension labels are "not editable" — you draw a
rectangle, its Width field opens, you type, and the as-drawn number is committed
instead. It affects every sketch tool, not just the rounded rectangle.

WHAT THIS ADDS

1. The arbiter (DesignPanel CHAR_HOOK -> DesignCanvas::inline_type_char ->
   SketchInlineEditor::type_char). Routes a key by what it IS, not by who the
   window manager focused: digits, sign, decimal separator and Backspace/Delete
   go to the open value field, Enter/Tab commit, letters stay tool shortcuts.
   This is FreeCAD Sketcher's rule (DrawSketchKeyboardManager::
   detectKeyboardEventHandlingMode), and the reason its sketcher behaves the same
   on every desktop: it never asks who has focus.

2. The [UX] trace (SNAPORCA_UXTRACE) in SketchInlineEditor: open/commit/refused/
   cancel, with the prefill and what the control actually held at Enter. It did
   not exist — the ladder below was written against a surface no build emitted,
   so it could only ever report "nothing opened". typed == prefill on a commit is
   the defect's signature and nothing else makes it visible.

3. A draw-then-edit trace in DesignSketchTool: four early returns can swallow the
   value-field chain and from outside they are indistinguishable.

4. scripts/CAD/check-gui-click-edit.py — types WITHOUT clicking the field, as a
   person does, across Line/Rectangle/Circle/Slot/Polygon/Ellipse/Arc plus label
   click-to-edit, and asserts committed == typed != prefill.

5. scripts/CAD/focus-loop.sh — sync/build/assert on behemoth. NOT the orcacad-gui
   rig: its image pins deps 216 non-CAD files behind cad-mainline, so today's CAD
   sources cannot build there without a deps rebuild.

WHAT IS PROVEN, AND WHAT IS NOT

Green under openbox: 28 checks, every tool, committed == typed != prefill.

But openbox CANNOT adjudicate this bug and the ladder says so in place. There the
field always wins the keyboard, so the same ladder also passes against a binary
with the arbiter compiled out — measured twice. Two ways of removing the keyboard
were tried and both are recorded as dead ends: XSetInputFocus loses to the field's
own re-focus CallAfter, and XSendEvent (xdotool --window) is dropped by GTK, which
made every run red regardless of the code.

Under metacity — same focus-stealing-prevention lineage as the user's mutter — the
mechanism appears in the WM's own log:

    Buggy client sent a _NET_ACTIVE_WINDOW message with a timestamp of 0

That is the activation being refused, which is exactly the reported symptom.
present_toplevel() already asks for a server timestamp, so a path is still falling
through to frame->Raise(), which sends time 0. That is the next thing to fix, and
it is tracked; the arbiter alone does not close it. metacity also aborts on this
window (frames.c:1239), so the gate needs a WM that survives before it can return
a verdict.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FbJKJAJxxkhDTs9XdZzKA
2026-09-06 10:35:22 +02:00
Tommaso BianchiandClaude Opus 5 af4bbe0217 A shape you selected whole had nothing left to click
"Still cannot edit labels in rounded rectangles." Reproduced on the rig in a few minutes, and it
is NOT the window-manager defect the rest of this week has been about — it happens on openbox,
where typing into a value field works perfectly. The value was never the problem. The LABEL was
not there.

render_live_quotes picks the entity to speak for like this:

    else if (m_selection.size() == 1)  ei = m_selection[0];
    if (ei < 0 || ...) return;

A rounded rectangle is EIGHT entities — four lines and four arcs — so selecting the shape makes
m_selection.size() == 8 and the pass returns before drawing anything. Its Width, Height and fillet
Radius are live labels and nothing else, so with them gone there is no affordance at all: no
number to click, no field to open, no value to refuse. The rule hid the characteristic quotes for
precisely the shapes that have nothing but characteristic quotes.

A plain rectangle looked fine only by accident. Typing into its auto-edit chain creates a DRIVEN
dimension, which render_dimensions draws from the annotation list, so its labels survive. The
rounded rect's W/H/R go through set_rounded_rect, which rebuilds the geometry and leaves no
annotation behind. Same for slot, arc-slot and polygon: every grouped feature was in this hole.

A selection that is entirely ONE feature now speaks through any member. The switch below already
keys off feature_of(ei) rather than the entity, so nothing else had to change.

Measured on behemoth :10, before and after, same binary path:
  before  8 selected -> no labels at all
  after   8 selected -> R26.6 / 117.4 / 150.7 drawn; clicking R26.6 opens Radius prefilled 26.60;
          typing 8 gives R8.0 mm and visibly sharper corners.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FbJKJAJxxkhDTs9XdZzKA
2026-09-06 08:14:44 +02:00
Kris Austin c0c2cc5068 fix: Virtual Camera Tools install downloads the network plugin (#15540) 2026-09-05 22:11:40 -03:00
yw4z 71e4e19191 Fix crash on startup if mixed filament has invalid component (#15432) 2026-09-05 18:17:42 -03:00
ocidburn 6014f3fb43 Fix: guard the fifth null deref of the same kind, on the project-settings path (#15451) 2026-09-05 17:05:11 -03:00
Wegerich 5302f703c0 Automatically disable scarf seams when activating retraction calibration (#15543) 2026-09-05 15:36:10 -03:00
Ian Bassi cd011e6385 Fix CHB parciall bridge (#15387) 2026-09-05 15:22:05 -03:00
Kris AustinandRodrigo Faselli 067dfa35c6 fix: make Windows debug builds work (#15353)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-09-05 14:14:59 -03:00
Kris Austin 2ad9c87dda fix: GIT_COMMIT_HASH forces full rebuilds and defeats compiler caching (#15537) 2026-09-05 14:08:38 -03:00
Kiss Lorand 0224741105 Fix organic support being printed into object top surfaces (#15539) 2026-09-05 11:48:35 -03:00
Kiss Lorand 134b9ad96e Fix organic tree support generating one less bottom interface layer than defined (#15525) 2026-09-05 11:47:58 -03:00
Tommaso BianchiandClaude Opus 5 00d6c191dc The chip in the corner was holding the keyboard, and the planes were holding the bed
Two reports, three defects, all three measured on the running app rather than reasoned about.

"Keyboard focus in drawing tool is broken so that now they are slow and cumbersome." After a
dimensioned entity the bottom-right readout chip — 119x31, borderless, a wxFrame — held the X
input focus. Pressing r produced NO [KEYTRACE] line at all: the key never reached the panel's
CHAR_HOOK. One bare canvas click moved focus back to the main window and the identical key armed
the tool. So every shortcut was dead after every dimension, and the way to get the keyboard back
was to click somewhere harmless. That is the whole of "slow and cumbersome".

Its sibling, the status chip, is a wxPopupWindow for exactly this reason and carries a comment
warning against turning it back into a frame. The readout was left a frame on the premise that
"it appears mid-gesture and the next input is the mouse" — which the measurement falsifies: the
chip keeps the last value on screen after the gesture ends, and a frame that has the focus does
not give it back. It is now a popup too, with the placement and the iconise/deactivate lifecycle
its sibling already needed, because an override-redirect window would otherwise sit on the bare
desktop when the app is minimised.

"Planes hide the bed." Literally true, twice over. The reference planes were half-extent 0.6 *
the bed's larger side — a square 1.2x the plate — and all three are drawn with depth testing
off, so they painted over the plate grid from edge to edge. 0.3 puts them inside the bed, which
is also the Onshape look the size was reaching for: a modest square at the origin, not a
tablecloth.

And the other half was mine. 3f52166e32 muted the bed for the duration of a sketch, on the
argument that a plate grid and a sketch grid are the same visual language. The argument is right
and the call was wrong, because there IS no sketch grid to take over. Pick XY, arm Line, and the
viewport was an empty grey field: no bed, no grid, no origin, nothing to judge a length or a
direction against. The plate grid was carrying the ground reference for the whole tab. The banner
already says where you are; taking the floor away as well only made the sketch harder to draw.
The Bed checkbox is the one thing that governs the bed, in every mode.

Verified on behemoth :10 with the rebuilt binary: focus after a dimension chain is the main
window, r arms Rectangle with no click in between, and the plate grid is under the sketch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FbJKJAJxxkhDTs9XdZzKA
2026-09-05 13:58:40 +02:00
Tommaso BianchiandClaude Opus 5 cf444a6ab6 A field that is logically closed can still be eating every key
Measured on the running app, not deduced. After a queued dimension chain the value field's frame
is left MAPPED on purpose (mutter refuses keyboard focus to a re-mapped window), so there is a
window in which m_open is already false and the frame is still on screen holding the X input
focus. GTK meanwhile reports that window inactive and routes nothing into the text control. Every
key then lands somewhere that cannot use it and will not give it back:

  [KEYTRACE] key=27 ui_mode=1 inline_busy=0     <- the last key the panel ever sees
  === MARK press Delete ===                     <- no trace line at all
  xdotool getwindowfocus -> 0xe00404 86x60      <- the value field, still mapped

Delete, Esc and typing all read as dead, which is exactly the report. And nothing could recover
it: close(), cancel() and do_cancel() all return early on !m_open, so the one window still
receiving keystrokes was also the one window no code could dismiss.

is_mapped() asks the question the flag cannot answer, and dismiss() tears the frame down with no
m_open guard, since m_open is precisely what lies in this state. Esc inside the field falls back
to it — while the frame holds focus that handler is the only code the keyboard can still reach,
so if it refuses, nothing else gets a turn. Every close now hands focus back to the canvas
explicitly, because hiding a window does not move the X input focus off it. And inline_busy()
reports the union of "a value is pending" and "a frame is mapped", so Esc routes to the field
whenever one is on screen at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FbJKJAJxxkhDTs9XdZzKA
2026-09-05 13:00:23 +02:00
Tommaso BianchiandClaude Opus 5 3f52166e32 A sketch should not look like plate preparation
Three cues, because one is missed. A teal banner across the top of the viewport names the session
("Editing: Sketch N") and where its exits are; the printer bed is muted for the duration, since a
plate grid and a sketch grid are the same visual language and reading one as the other is how a
sketch gets drawn against the wrong reference; and N looks straight down the plane normal at the
current zoom, with the plane's own y axis as up, because no hand-orbit lands exactly square and a
sketch read at an angle is one whose right angles do not look like right angles.

The banner is an INDICATOR. Finish and Cancel stay on the single ribbon action bar — the tab had
three competing confirm surfaces once and that is not being reopened for a strip of colour. It
sits above the canvas rather than floating inside it: a child window over a wxGLCanvas is a native
window on GTK with no reliable stacking over GL, and being unmissable beats being clever.

The bed checkbox stays the stored preference and is restored on leaving the sketch; ticking it
mid-sketch still shows the bed, because that is a deliberate act and this is only a default.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FbJKJAJxxkhDTs9XdZzKA
2026-09-05 11:45:29 +02:00
Tommaso BianchiandClaude Opus 5 324b558747 Esc is the safe key again: one press, one level, nothing destroyed
Two presses used to discard a live sketch. The key was answered in four places that could not
see each other — the inline value field, a sketch branch, a feature-card branch, and the canvas
— so a press aimed at one fell through to the next, and request_exit() carried a fourth layer
that deliberately let the SECOND consecutive press through to cancel_sketch(). The warning it
showed first did not help: the two presses are never one decision, the first is aimed at a field
or a tool and the second at whatever was underneath it.

The stack is now explicit. CadLevel (DesignInteraction.hpp) is four levels deep, the enum value
IS the LIFO depth, and cad_escape_level() is a constexpr function over a POD of four booleans —
so the ordering that is the entire contract is checked by static_assert at compile time, with no
window, GL context or event loop. DesignPanel::escape() acts on the one level escape_level()
names and on no other, and every Esc in the tab routes through it.

The destructive layer is gone from request_exit() itself rather than guarded at its callers, so
the guarantee cannot be re-opened by adding a route: a session holding geometry is left only
through Finish (keep) or Cancel (discard). Cancel now asks before discarding — it used to refuse
and tell the user to press the button they had just pressed, which meant a drawn sketch could be
kept but never thrown away.

Right-click also stops rewarding navigation with a menu: the offer needs BOTH budgets, released
within 200 ms and moved no more than 3 px, and the raycast uses the press position, so the menu
describes what was pointed at rather than where the camera stopped. Two budgets because drift
alone still popped a menu at the end of a slow, careful orbit.

docs/ux/interaction-model.md carries the state machine, the routing and the transition table.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FbJKJAJxxkhDTs9XdZzKA
2026-09-05 11:35:12 +02:00
HanifKoh 1170b048e8 [CLI]: Fix Plate Config Reading and BuildVolume Height Checks (#15479)
* Fix incorrect early exit for CLI mode no-support preventing parameters from being read

* Use PartPlate's m_height to allow CLI to perform proper BuildVolume check

* Add safeguard against extruder_pintable_heights and extruder_areas vector size mismatch

* Preserve printable_height precision in PartPlate/PartPlateList

* Fixed multiple BuildVolume warning issue, and keep check_outside diff minimal
2026-09-04 23:24:59 +08:00
HanifKoh df30e22427 [CLI]: CLI Crash Guards (#15477)
# Description

<!--
> Please provide a summary of the changes made in this PR. Include
details such as:
  > * What issue does this PR address or fix?
  > * What new features or enhancements does this PR introduce?
> * Are there any breaking changes or dependencies that need to be
considered?
-->

Part 1 of 3 of the CLI-mode bug sweep, split out of #15452 per review
feedback there. This PR contains the crash fixes.

## Fixes

- **`--outputdir`/`--datadir` with a missing parent directory aborted**
via unguarded `create_directory`. Directories are now created
recursively, with a graceful early exit and a specific error message if
creation fails.
- **`--slice` + `--export-3mf` segfaulted on a from-scratch slice**:
`ConfigOptionVector::get_at()` on an empty vector is `.front()` of an
empty vector (UB). Guards added for `filament_color`/`filament_id` at
the CLI call site, and inside `DynamicPrintConfig::get_filament_type`
for `filament_type`/`filament_is_support`/`filament_id`. Only *empty*
vectors are treated as missing — the existing clamp-to-front behavior
for merely out-of-range indices is preserved, so GUI callers are
unaffected.
- **OOB heap write from stale `filament_self_index` on
`--load-filaments`** (fixes #14181): a 3MF carrying more
`filament_self_index` entries than loaded filaments wrote past the end
of `old_variant_counts`. The guard validates both bounds — entries `>
filament_count` *and* non-positive entries (`< 1`), since a single `0`
in an otherwise-valid array indexes `old_variant_counts[-1]`.
- **Wrong printable-area check** for non-rectangular beds: use the
printable area's bounding box instead of a naive vertex calculation
(fixes #15363).
- **`nozzle_height` and `align_center` were not read into the arrange
config** in CLI mode.

# Screenshots/Recordings/Graphs

<!--
> Please attach relevant screenshots to showcase the UI changes.
> Please attach images that can help explain the changes.
-->

## Tests

<!--
> Please describe the tests that you have conducted to verify the
changes made in this PR.
-->
- Repro'd each crash on CLI before the fix; all resolved after.
- `tests/libslic3r` suite passes; full binary builds clean on Linux.
- Added `get_filament_type` unit tests 

<!--
> A guide for users on how to download the artifacts from this PR.
-->

[How to Download Pull Requests Artifacts for
Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
2026-09-04 15:46:03 +08:00
Ian Chua 9df23cab62 fix: opc updates being discarded 2026-09-04 14:59:53 +08:00
Lam Wei Lun c6ab725584 Fixes issue with mixed filament being loaded into a real slot 2026-09-04 14:41:20 +08:00
Lam Wei Lun bbb4681b32 Merge branch 'main' into publish_3mf 2026-09-04 12:24:57 +08:00
HanifKoh 57ce18d70d [CLI]: CLI Argument Parsing Fixes (#15478)
* Reject invalid CLI argument values instead of silently accepting them

* Add read_cli accept/reject tests

* Update Option Type for LogFile argument

* Add read_cli vector option tests

* Accept common bool spellings on the CLI, cover --logfile in tests

* Add unit tests for truthy bool parsing
2026-09-04 11:31:42 +08:00
TheLegendTubaGuyandRodrigo Faselli 7acea3ed09 Honor symbolic default bed types for new printers (#15273)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-09-03 19:42:31 -03:00
Kris Austin b370d8ef31 build: clear 31 warnings - copy and move declarations (#15507) 2026-09-03 18:35:10 -03:00
Kiss Lorand c57ea0ec67 Fix nozzle type undo and unsaved changes tracking (#15515) 2026-09-03 18:28:26 -03:00
Kiss Lorand 6a13cc2ab6 Fix Detach from parent checkbox not updating visually (#15520)
Refresh detach-from-parent checkbox state

Allow the detach checkbox toggle event to propagate to the custom CheckBox control so it refreshes its bitmap after the value changes.
2026-09-04 00:25:21 +03:00
SoftFever df101ead91 fix more issues 2026-09-04 00:29:52 +08:00
SoftFever 7c9b38ba04 remove retired_filament_ids.json 2026-09-03 21:03:42 +08:00
Ian Chua 07dafaf299 fix: default enable-ota flag and fixing startup missing vendor 2026-09-03 17:13:09 +08:00
Ian Chua c5952c3308 Merge branch 'main' into fix/opc-support-for-ota 2026-09-03 14:54:51 +08:00
Lam Wei Lun 904796cf24 Correctness fixes. Remove hard-coded appends for printer settings 2026-09-03 14:12:51 +08:00
Lam Wei Lun bcff39661c Comments and dead code cleanup 2026-09-03 13:40:58 +08:00