Commit Graph

570 Commits

Author SHA1 Message Date
Andrew
501af81ba9 Replace fake-enum printer agent dropdown (#121)
A dedicated PrinterAgentChoice field
reads rows straight from the live
agent registry and stores the agent
id string, replacing the fake-coEnum
index mapping. The field moves to
TabPrinter and registers with the
searcher so UnsavedChanges renders
it; the PhysicalPrinterDialog copy
and its update hook are removed
(#125). switch_printer_agent now
resolves ids via
resolve_printer_agent_id.
2026-08-04 18:12:10 +08:00
Misterff1
1b71835337 Fixed some desktop environments showing title bar on splash screen when running on Wayland (#15019)
* Remove titlebar from splash screen on Wayland

* Broadly check for window decorations and added explanatory description

* Fixed hiding title bar on Wayland for all desktop environments

* Update format

---------

Co-authored-by: noisyfox <timemanager.rick@gmail.com>
2026-08-02 18:58:49 +08:00
SoftFever
f60e0e776e Add back 02.03.00 plugin to support debugging (#14966)
* Add back 02.03.00 plugin to support debugging
2026-07-26 23:49:53 +08:00
Noisyfox
63044b7661 feat: Add layout debugging/inspecting tool (#14919)
* Add wxInspector dep

* Initial intergration of wxInspector

* docs: add wxInspector plugins design spec

Design spec for two wxInspector plugins (DPIAware + CustomWidgets) that expose
OrcaSlicer's custom control properties in the inspector property grid.

Covers: DPIAware scale-factor properties, Button, CheckBox, TextInput,
SwitchButton, ProgressBar, Label, and LabeledStaticBox.

* docs: add wxInspector plugins implementation plan

6-task plan covering: source changes to existing widget headers,
DPIAwarePlugin, CustomWidgetsPlugin, registration helper,
MainFrame/CMake wiring, and build verification.

* feat: add getters/setters for wxInspector plugin access

Add minimal public accessors to DPIAware (set_scale_factor,
set_prev_scale_factor, set_em_unit, force_rescale), Button
(GetStyle, GetType, IsSelected), CheckBox (IsHalfChecked),
TextInput (GetCornerRadius), and LabeledStaticBox
(GetCornerRadius, GetBorderWidth, GetBorderColor, GetScale).

* feat: add wxInspector plugin registration helper

Add RegisterOrcaInspectorPlugins() inline function that creates
and registers the DPIAwarePlugin and CustomWidgetsPlugin as
static instances (matching wxInspector's built-in pattern).

* feat: add DPIAware wxInspector plugin

Exposes DPI scaling properties (scale_factor, prev_scale_factor,
em_unit, normal_font, force_rescale) on DPIFrame and DPIDialog
widgets. Uses dynamic_cast for detection and a template helper
to capture the correct static type for lambda accessors.

* feat: add OrcaCustomWidgets wxInspector plugin

Exposes Orca-specific properties on 7 widget types:
- Button: Style, Type, Selected
- CheckBox: Half Checked
- TextInput: Label, Text Value, Corner Radius
- SwitchButton: Value
- ProgressBar: Proportion, Show Number
- Label: Is Hyperlink, Font Point Size
- LabeledStaticBox: Corner Radius, Border Width, Border Color, Scale

Each widget type uses dynamic_cast for safe detection.

* feat: wire wxInspector plugins into MainFrame and build

Call RegisterOrcaInspectorPlugins() in MainFrame constructor after
SetupInspectorAccelerator(). Add all 5 plugin source files to
SLIC3R_GUI_SOURCES in CMakeLists.txt.

* fix: move plugin registration to GUI_App::on_init_inner

Register plugins once in app init rather than in MainFrame
constructor, which may be recreated during the application
lifetime.

* fix: include plugin headers in Registration.hpp for complete types

Static locals require complete type. Include DPIAwarePlugin.hpp and
CustomWidgetsPlugin.hpp instead of forward-declaring. Also remove
unused include from MainFrame.cpp (registration moved to GUI_App).

* fix: qualify DPIFrame/DPIDialog with Slic3r::GUI namespace

* Make DPIDialog inspectable. For other dialogs, we will add them if necessary later.

* docs: add spec for moving wxInspectable into DPIAware template

Move wxInspector::wxInspectable base class from DPIDialog and MainFrame
into the common DPIAware<P> template, making all DPIAware widgets
automatically visible in the inspector tree.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: add implementation plan for moving wxInspectable into DPIAware

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: update spec/plan — move SetupInspectorAccelerator into DPIAware too

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: move wxInspectable and SetupInspectorAccelerator into DPIAware

DPIAware<P> now inherits wxInspector::wxInspectable and calls
SetupInspectorAccelerator in its constructor, making all DPIAware
widgets automatically appear in the inspector tree with the
Ctrl+Shift+I shortcut. DPIDialog now uses 'using' to inherit the
constructor. Remove redundant wxInspectable inheritance and
SetupInspectorAccelerator calls from DPIDialog and MainFrame.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: use LB_HYPERLINK constant instead of magic number 0x0020

Co-Authored-By: Claude <noreply@anthropic.com>

* Clean up

* Fix Linux build

* Don't build wxInspector sample

* Use shallow clone

* Try fix flatpak build

* Attempt to fix build again

* Fix build failure caused by 436c16135e

* wxWidgets build only download required submodules

* This should fix build on Windows on ARM

* Enable PIC

* Disable layout inspector by default for public release

* Use wxInspector 1.0.0 release

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-26 20:25:25 +08:00
SoftFever
43f38c0eb6 Attempt to fix crash on switching printer (#14870)
# Description

attempt to fix #14851

# 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.
-->

<!--
> 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-07-23 23:24:29 +08:00
Kris Austin
b86501cd3c fix: guard Bambu Lab dev-mode dialog against repeat spam (#14774) 2026-07-21 15:40:40 -03:00
SoftFever
8d528b2a8f Attempt to fix crash when switching printers in the Device tab (#14851) 2026-07-21 03:49:03 +08:00
SoftFever
afb4505ea7 Store network plug-in identity by AA.BB.CC series
The stored plug-in identity is now the AA.BB.CC series (matching BambuStudio)
rather than the full build version, so the meaningless 4th build digit stops
driving config, the whitelist, filenames, and the version selector. This fixes
the macOS "can't switch to an older build" bug: the cloud endpoint is
series-keyed and only ever serves a series' newest build, so downgrade-by-
download was impossible and the download silently adopted the latest.

A startup migration normalizes an existing full-version config and file name to
the series form with no re-download, the loader resolves a bare series to the
newest same-series build on disk, and user-provided custom-named plug-ins
(libbambu_networking_02.08.01_custom.*) are still enumerated and loaded.
2026-07-19 00:26:05 +08:00
SoftFever
8b60291ed9 Restart printer discovery after a network-plugin hot reload
restart_networking() rebuilds m_agent with a null printer agent, so the bare
m_agent->start_discovery() no-oped (NetworkAgent::start_discovery returns false when
m_printer_agent is null) and LAN discovery stayed dead until the user next changed a
preset. Call switch_printer_agent() instead - it installs the printer agent for the
active preset and then starts discovery, mirroring startup.
2026-07-18 15:16:15 +08:00
SoftFever
ddfa961111 Merge branch 'main' into feature/bambu_printer_housekeeping
# Conflicts:
#	tests/slic3rutils/CMakeLists.txt
2026-07-18 02:08:13 +08:00
SoftFever
12720ccbd8 Gate network plugin loading to ABI-compatible series
Trim the version whitelist to the latest series plus the pinned legacy build,
and reject out-of-series configured versions at startup, compatibility check,
and load failure - falling back to the latest installed build or the clean
re-download flow so the config never keeps pointing at an unsupported build.
2026-07-18 01:45:54 +08:00
SoftFever
9d9bb9cdbd Install the OTA plugin update immediately and hot-reload it 2026-07-17 16:25:10 +08:00
SoftFever
5808ae5ab0 Fix the network plugin OTA update flow 2026-07-17 14:23:39 +08:00
Andrew
b4f6573753 Merge branch 'feat/plugin-feature' into feature/speed-dial
# Conflicts:
#	src/slic3r/GUI/PluginsDialog.hpp
2026-07-17 13:59:56 +08:00
SoftFever
f2ccbfc8b5 Open the plugin terminal off the webview callback stack
open_terminal_dialog is reached from the plugins dialog's webview
command, and TerminalDialog hosts a webview of its own — same class as
the plugin-window crash. Defer the window work via CallAfter, guard the
re-front Show() per #13657, and drop the redundant Raise() on creation.
2026-07-16 21:25:30 +08:00
Ian Chua
d9f8460a4e fix: merge PythonFileUtils into PluginFsUtils 2026-07-16 20:40:32 +08:00
Ian Chua
a86202b45b fix: change speed dial from popup to dialog for consistent behavior on linux 2026-07-16 19:47:26 +08:00
Ian Chua
f142716e51 fix: change popup to dialog with popup behavior 2026-07-16 18:29:40 +08:00
Andrew
13575601ff Give speed-dial popup GUI_App ownership 2026-07-16 16:09:30 +08:00
Andrew
13f5c777cc Rename SpeedDialDialog files to SpeedDialPopup 2026-07-16 16:09:30 +08:00
Andrew
c816e48b78 refactor: collapse speed-dial action source abstraction
Only one action source ever existed, so the
IActionSource interface and ScriptActionSource
are gone. ActionRegistry now subscribes to the
plugin loader and enumerates actions directly
in init() - no polymorphism for one impl.

Replace the opaque FNV-hash SpeedDialActionId
with a readable composed id of the form
prefix:title:source_key. Split AppAction's
single source field into source_key (stable
identity, e.g. plugin_key) and source_name
(display), so identity and display no longer
share one field.
2026-07-16 13:08:48 +08:00
Ian Chua
8ba478913f fix merge conflicts 2026-07-15 22:09:47 +08:00
Ian Chua
62afea225a Fix/impl refactor (#14776)
* fix: impl refactor

* fix: unload/load python module, race conditions, freezes

* remove dead code

* remove extra hook

* remove more dead code

* fix gil run script
2026-07-15 20:12:51 +08:00
SoftFever
1551898846 Plugin-gate the reslice check and drop non-plugin leftovers
reslice() now enforces only the missing-plugin block via
refresh_missing_plugin_block (no second Print::validate); plate
ready-status returns to upstream's plain model_fits, matching
GLCanvas3D::reload_scene. Also restores main's use_bbl_device_tab and
the check_track_enable comment, and drops two unused MainFrame includes.
2026-07-15 19:18:45 +08:00
SoftFever
e116181c07 Use one agent id in switch_printer_agent and restore the preset_bundle guard
Merge-resolution cleanup. The #12506 re-select path kept main's preset_bundle
null check, and both select_machine calls now use effective_agent_id rather than
mixing it with the equal-but-differently-named agent_info.id.
2026-07-15 17:54:39 +08:00
SoftFever
8cb0cb7693 Merge branch 'main' into feat/plugin-feature
Resolve five conflicts, all of which needed both sides rather than a pick:

- BackgroundSlicingProcess: ours was a pure tabs->spaces reformat of base, so
  keep main's per-filament volume/nozzle map read-back (its only change here).
- GUI_App: main's #12506 else-if attached to an `if` this branch deleted;
  re-expressed onto the same-agent early-return path (the agent factory caches
  per id, so pointer equality is the same predicate).
- MainFrame: both sides relocated Sync Presets independently; keep main's
  push_notification plus the branch's Plugins menu items.
- Tab: the "TODO: Orca: Support hybrid" blocks were unchanged base, not a branch
  decision; take main's enabled Hybrid to match the already auto-merged siblings.
- test_config: union of both sides' cases (6 plugin + 9 multi-nozzle).
2026-07-15 17:18:46 +08:00
foXaCe
c41e685a69 i18n: wrap hardcoded GUI strings (undo/redo labels, dialogs, notifications) + FR (#14729) 2026-07-13 12:19:33 -03:00
Andrew
635f5a3529 Merge remote-tracking branch 'public/feat/plugin-feature' into feature/speed-dial
# Conflicts:
#	src/slic3r/GUI/PluginsDialog.cpp
2026-07-13 19:39:42 +08:00
Andrew
5a3e4abb18 Catch plugin actions loaded during startup 2026-07-13 16:00:25 +08:00
bobomb
4eb9a85a49 Fix filament sync targeting wrong printer after switching printer presets (#12506) (#14587)
For non-BBL host printers (Moonraker/Klipper, Qidi, Snapmaker, Creality), switch_printer_agent() only re-selected the machine when the agent type changed. Switching between two printer presets that use the same agent left the selected machine and the agent's cached device_info pointing at the previously active preset's host, so filament sync kept hitting the old printer.

Re-select the machine when the agent type is unchanged but the target host differs, so the selected machine and device_info always follow the active printer preset.

Co-authored-by: Noisyfox <timemanager.rick@gmail.com>
2026-07-13 15:08:53 +08:00
Andrew
c29ffdfc1a Extract script actions into an action source
Move plugin capability enumeration, loader
subscriptions, and action construction into
ScriptActionSource. Keep ActionRegistry focused
on generic action state, dispatch, and snapshots.

Use source rather than package for generic origin
metadata so future non-plugin providers share the
same interface. Action IDs and persisted
configuration remain unchanged.

Subscribe before initial enumeration so plugin
events cannot be missed between the snapshot and
callback registration. Add a focused test for
source startup.
2026-07-13 14:28:05 +08:00
SoftFever
03094df10e refactor(plugin): move libslic3r hook wiring out of GUI_App into PluginHooks
GUI_App::on_init_inner() carried the plugin dispatch policy inline (the
capability resolver and the slicing-pipeline dispatcher) and would grow
with every capability that fires from inside libslic3r.

plugin/PluginHooks.{hpp,cpp} now owns one file-local installer per hook,
aggregated by plugin_hooks::install() -- called from
PluginManager::initialize(), reset in shutdown() so no hook can enter
Python after the interpreter finalizes. The wx-side loader subscriptions
move into GUI_App::init_plugin_gui_wiring().

No behavior change; dispatch bodies moved verbatim.
2026-07-12 00:20:39 +08:00
SoftFever
126e4d5445 refactor(plugin): split orca.host bindings into host/ by domain
PluginHostApi.cpp had grown into one TU holding the module entry point plus
three unrelated domains (presets, model/mesh graph, app access), and
PluginHostSlicing.cpp mixed ownable geometry value types with the
non-owning live print graph. Reorganize the orca.host surface into
plugin/host/ with one registrar per domain:

- PluginHost.hpp/.cpp        entry point (replaces PluginHostApi)
- PluginHostBindings.hpp     internal per-domain registrar declarations
- PluginHostGeometry.cpp     BoundingBox, Point, Polygon, ExPolygon + ndarray parsing
- PluginHostMesh.hpp/.cpp    TriangleMesh snapshot (own TU ahead of planned
                             mesh construct/mutate APIs)
- PluginHostPresets.cpp      Preset, PresetCollection, PresetBundle
- PluginHostModel.cpp        scene graph: Model, ModelObject, ModelInstance, ModelVolume
- PluginHostApp.cpp          Plater + plater()/model()/preset_bundle() accessors
- PluginHostSlicing.cpp      live print graph only, now with a single lifetime story
- PluginHostUi.hpp/.cpp      moved unchanged

PluginBindingUtils.hpp stays at plugin/ root: it is shared with pluginTypes/
and tests, not host/-specific.

No Python-visible change: same submodules, class names and docstrings.
Verified with slic3rutils and fff_print suites.
2026-07-11 16:18:59 +08:00
SoftFever
19352215da feat(plugin)!: merge G-code post-processing into the slicing pipeline as psGCodePostProcess
G-code post-processing is now a step of the slicing-pipeline plugin rather than a
separate capability type. One capability class can transform slices at the geometry
seams AND edit the final G-code, behind a single picker/option.

- Add SlicingPipelineStepPlugin::psGCodePostProcess (bound as
  orca.slicing.Step.psGCodePostProcess). Unlike the geometry steps it fires from the
  GUI export path in PostProcessor.cpp, not from Print::process(): ctx.print/ctx.object
  are None and the plugin edits the file at ctx.gcode_path in place. It may run more
  than once per slice (file export and/or upload) and its output is not shown in the
  preview.
- Extend SlicingPipelineContext with gcode_path/host/output_name and a C++-only
  full_config; config_value() falls back to it when there is no live Print.
- PostProcessor.cpp dispatches SlicingPipelinePluginCapability at psGCodePostProcess,
  driven by the existing slicing_pipeline_plugin option.
- The exported G-code lives outside data_dir(), so the plugin audit sandbox would
  block the write; the trampoline's audit setup grants ctx.gcode_path's folder as a
  scoped allowed root, gated on a non-empty gcode_path so the geometry-step hooks gain
  no extra filesystem access.

BREAKING CHANGE: the separate G-code post-processing capability type is removed.
- orca.gcode.GCodePluginCapabilityBase and orca.PluginType.PostProcessing are gone;
  post-processing plugins migrate to orca.slicing.SlicingPipelineCapabilityBase +
  Step.psGCodePostProcess (and gain ctx.params / ctx.config_value()).
- The post_process_plugin config option is removed; use slicing_pipeline_plugin.
  Presets carrying the old key degrade to the standard unknown-key warning.
- Manifest type = "post-processing" now maps to Unknown (advisory only; the loader
  dispatches on the C++ get_type()).

Also repairs two latent build breaks the branch carried: stale Step enum value usages
in test_slicing_pipeline_hook.cpp and a reference to the removed
ConfigOptionDef::PluginType::None in Tab::on_value_change (now is_plugin_backed()).
Adds the orca_gcode_stamp sample plugin and a psGCodePostProcess binding test.
2026-07-10 19:57:35 +08:00
SoftFever
21ed68963f refactor(plugin): prefix SlicingPipelineStepPlugin values with pos/ps to mirror Print steps 2026-07-10 17:28:26 +08:00
SoftFever
05ed2e4dfa Fixed a rare crash on app startup caused by ENOTSUP (errno 45) on Mac (#14686)
fix: prevent startup crash when preset-sync directory scan hits a transient FS error

On startup the user-preset sync thread scans the preset folder for orphaned
.info files (scan_orphaned_info_files). It iterated the directory with a
throwing boost::filesystem::directory_iterator while running on a background
thread that has no exception guard. On macOS, readdir() can intermittently
fail with ENOTSUP (errno 45); boost then throws filesystem_error, which --
uncaught on the sync thread -- calls std::terminate and aborts the whole
application on startup.

- Iterate with the error_code-based directory_iterator so a transient read
  failure is logged and skipped instead of thrown. The orphan scan is
  best-effort and re-runs on the next sync, so skipping a cycle is harmless.
  This mirrors the existing pattern in has_json_presets() and the plugin scan.
- Wrap the entire sync-thread body in try/catch as defense-in-depth, so no
  future uncaught exception on that otherwise-unguarded thread can abort the
  app.
2026-07-09 21:57:59 +08:00
Andrew
3ebb4b274d Own the speed dial ActionRegistry in GUI_App and keep it fresh from loader callbacks 2026-07-09 16:21:54 +08:00
Andrew
6daef171c1 Add actions speed dial 2026-07-09 16:21:53 +08:00
SoftFever
f81a24abfb feat(plugin): expose the slicing print-graph as raw orca.host classes + Twistify sample
Adds PluginHostSlicing, which registers the print-graph data model (Print,
PrintObject, Layer, LayerRegion, Surface, ExPolygon, extrusions, ...) into the
orca.host submodule in the same raw-class style as PluginHostApi's Model/Preset
graph, with shared helpers in PluginBindingUtils. SlicingPipelinePluginCapability
is trimmed to the capability surface (the standalone SlicingNumpy helper is folded
away). Adds the Twistify example plugin next to Inset and broadens the binding,
hook, and plugin-install tests.
2026-07-08 00:05:28 +08:00
SoftFever
a1ff45284c Fix version was not properly updated on non windows OS (#14617)
Fixed an issue where on non-Windows systems, the version was not properly written to the appconfig.
2026-07-06 22:16:28 +08:00
SoftFever
ee1f4ef1d6 Show preset name in cloud sync conflict and error messages (#14592)
The 409 conflict notification, the force-push confirmation dialog, and the payload-too-large (413) dialog now name the affected preset. The name was already parsed from the conflict body but never surfaced. The account-level preset-limit message stays generic since it isn't about one specific preset.
2026-07-05 17:05:41 +08:00
SoftFever
b0bacdd00b feat(plugin): add the slicing-pipeline plugin capability
Introduces a plugin capability that runs Python at the seams of Print::process(),
letting a plugin read and rewrite slicing state as it is computed.

- New slicing_pipeline_plugin config option; selected plugin refs are serialized
  into the print manifest.
- Print gains an injectable hook fired at each pipeline step (posSlice,
  posPerimeters, posInfill, ...). It is a no-op when unset, fires only on genuine
  (re)computation, and never on the use-cache path.
- orca.slicing submodule: SlicingPipelineCapabilityBase plus a trampoline and a
  Step enum. Capabilities read the live graph through zero-copy int64 numpy views
  (contour/holes geometry with unscaled coordinates, flattened toolpath data) and
  edit it through 2D-geometry mutators with cache-invariant refresh.
- GUI dispatcher runs capabilities during slicing under the GIL, turns plugin
  errors into slicing errors, honors cancellation, and adds the plugin picker.
- Ships the InsetEverySlice sample plugin and binding/hook tests.
2026-07-04 04:33:20 +08:00
Ian Chua
3668b01721 Merge branch 'main' into feat/plugin-feature 2026-07-03 13:29:40 +08:00
Gabriel Monteiro
dbe99d0d6f feat(log): enable console logging in RelWithDebInfo builds (#14439)
* feat(log): enable console logging in RelWithDebInfo builds

* perf(log): make console logging async to avoid blocking startup

* fix(log): gate console sink to RelWithDebInfo builds

---------

Co-authored-by: Gabriel <bielpaess912@gmail.com>
2026-07-02 21:49:51 +08:00
ExPikaPaka
5bccc25705 Fix "plug-in file may be in use" install failure when migrating from older versions (#14373) (#14528)
Fix network plug-in install failing when the plug-in DLL is in use (#14373)

Switching or reinstalling the Bambu network plug-in from a running
OrcaSlicer failed with "The plug-in file may be in use". install_plugin()
deleted each existing file before extracting the new one, and on Windows a
currently-loaded DLL (BambuSource.dll, or the legacy networking library)
cannot be removed or overwritten in place, so the whole install aborted.

Rename an in-use file aside to "<name>.old" before writing the new one: the
running module keeps mapping the renamed file while the new version is
extracted, so the install succeeds without having to unload the plug-in
first. Stale ".old" files are cleaned up at the start of on_init_network(),
before the plug-in is (re)loaded, so they do not accumulate.
2026-07-02 18:58:23 +08:00
Ian Chua
ecddf3d18f feat: Python Plugins 2026-07-02 17:49:36 +08:00
Noisyfox
6b886b04f2 Don't keep a separate use_legacy_network which is error-prone. Always infer from installed plugin version. (OrcaSlicer/OrcaSlicer#14441) 2026-07-01 21:17:11 +08:00
KrishManan
8d84204aeb Add startup progress bar to loading screen (#14155)
* Add startup progress bar to splash screen

* Move progress bar down and remove percentages

* Cleaned up changes

* Update GUI_App.cpp

---------

Co-authored-by: yw4z <ywsyildiz@gmail.com>
2026-07-01 11:45:25 +03:00
SoftFever
943a75af0a Preventing removal of old networking plugins on app version update as Orca allow user to pin the plugin version 2026-06-28 13:26:07 +08:00
SoftFever
b7ab7f4225 update locale 2026-06-26 11:56:29 +08:00