* 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 https://github.com/wxWidgets/wxWidgets/commit/436c16135ec7ddf580f44624bf74c592aae43b66
* 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>
# Description
Fixes some bugs reported by users and the community
# Fix 1: Latest Version
If the user updates the plugin version on OrcaCloud without a changelog,
the latest version shown on OrcaSlicer won't be accurate.
## Issue
OrcaSlicer uses the changelog returned by OrcaCloud backend as the
source of truth, even though we query a latest version from the backend
as well. The changelog only consists of version entries that have
changelogs so if the latest one, e.g. 1.2.0 has no changelog, but 1.1.0
has, the latest version will be interpreted as 1.1.0.
## Fix
Don't use the changelog for version tracking, just use it for the
plugins dialog changelog tab.
# Fix 2: Host theme script / window.orca bridge leaks into cross-origin
child iframes
If a plugin's embedded app renders its own `<iframe>` (its real
catalog/dashboard UI, or a third-party auth/payment widget), that child
document also gets, uninvited: the host theme `<style>` block fighting
whatever CSS the child page already defines.
## Issue
OrcaSlicer injects host themed scripts and window.orca bridge into every
page, potentially breaking any cross origin child frames or `<iframes>`
in general.
## Fix
Only inject top level frames by checking `if (window.top !==
window.self) return;`.
# Fix 3: Transferring Slicing Pipeline Plugin config when switching
printers (#14832)
Select an entry in the Process tab's "Slicing Pipeline Plugin" picker,
switch the active printer preset, then click **Transfer** in the
"modified settings" dialog — OrcaSlicer crashes immediately and
repeatably. Changing other settings (e.g. a single scalar option) does
not reproduce it; only this picker does.
## Issue
`slicing_pipeline_plugin` is a vector option (`coStrings`) with an empty
default. `deep_diff` diffs vector options per-index, so selecting a
plugin produced a `"slicing_pipeline_plugin#0"` dirty key instead of a
plain one. Unlike genuine per-extruder options, this key wasn't caught
by the printer-switch filter that discards stale per-extruder changes,
so it got cached and replayed through `ConfigBase::apply_only`'s
`'#'`-indexed branch, which calls `ConfigOptionVector::set_at()` on the
freshly-reloaded (and still empty) destination vector. `set_at()`'s only
empty-vector guard is an `assert()`, which is compiled out of Release
builds, so it dereferences `values.front()` on an empty vector —
undefined behavior, matching the reported ACCESS_VIOLATION.
## Fix
Treat `slicing_pipeline_plugin` as a single atomic value in `deep_diff`
(`Preset.cpp`), same as `printable_area`/`thumbnails`/etc.,
since it isn't actually per-extruder data. It's now diffed and replayed
as a whole option (`ConfigOptionVector::set()`, a plain vector
assignment) instead of the index-based `set_at()` path — removing the
crash unconditionally, regardless of whether the two printers share the
same extruder configuration.
# Fix 4: Stale .whl cache
After a .whl was loaded once, if at runtime, the .whl is replaced with a
new one, the plugin system will use the stale .whl cache.
## Fix
Added an option in the context menu to Reload or Delete Cache and Reload
for locally installed plugins. The assumption here is that users
shouldn't be modify cloud plugins, and if they want to develop on a
subscribed cloud plugin, they should create a local copy of it.
<!--
> 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)
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).
- FilamentMapDialog's manual page understands volume types: a mixed
(Hybrid) extruder shows separate Standard / High Flow drop zones
with live sub-nozzle counts, a validation timer with an inline
error + "set nozzle count" suggestion, and composes a per-filament
volume map on OK (persisted to the plate or globally)
- switching an extruder's Flow type rewrites the affected plate map
entries; plate maps stay sized across filament add/delete/count
changes (values keep their filament, no index shift)
- CLI: manual mapping on multi-nozzle printers synthesizes the volume
map from extruder flow types when absent; nozzle-manual mode
requires explicit maps; computed maps land on the plate so exported
projects carry filament_volume_maps
- filament_nozzle_map joins the project options (selection seeding +
filament-count resizing)
- pot entries for the new dialog strings
All 19 reference fixtures byte-identical; slicing an exported Hybrid
project reproduces its g-code byte-for-byte with the volume map
round-tripped through model_settings.config.
The sidebar extruder cards get an interactive title row — "<name> ( <count> )"
with an edit button — showing the extruder's physical nozzle count on
multi-nozzle printers (hidden elsewhere). Clicking it opens the existing
"Set nozzle count" dialog, which now also handles a Hybrid extruder by
offering both Standard and High Flow counts (an empty mix is rejected) and
shows a hotend thumbnail.
Because `extruder_nozzle_stats` is session-only (saved presets never carry
it, so preset switches rebuild the edited config without it), the stats are
re-baselined whenever they are missing: each extruder starts with
extruder_max_nozzle_count nozzles of its selected volume type. Switching an
extruder's flow type carries its total count over to the new type, except
when the stats came from a device sync — the machine-reported per-type
breakdown must survive a manual flow switch.
The badge refreshes on preset load, flow-type change, manual edit, device
sync, and project load. Single-extruder cards keep the title row but never
enable editing.
The Filament Track Switch (H2-series accessory, product code O2L-FTS) feeds
every AMS to both extruders through a two-track switch. Port full support
across the device layer, project config, and GUI.
Device / config:
- Model the switch-aware AMS binding (the set of extruders an AMS can feed
and which input track A/B feeds it), switch readiness, the O2L-FTS firmware
module, and the fun2 capability bit for checking a slice against installed
hardware.
- Register has_filament_switcher and enable_filament_dynamic_map as project
config that persists with the project and restores from a saved 3mf, and
force both back to false on every project/printer/CLI load path. Live
device sync is the only thing that sets them true.
GUI:
- Sidebar sync activates the switch from live device state, attributes each
AMS to the extruder its input track feeds, shows a floating status icon
(ready / not-calibrated), and surfaces a one-time tip / not-calibrated
warning.
- Send dialog gains a non-blocking slice-vs-hardware mismatch warning and a
blocking error when a slice needs dynamic nozzle mapping but the switch is
missing or not set up.
- AMS load/unload guards, AMS-view routing glyph + un-calibrated banner +
hidden external-spool road, and mapping-popup external-spool lockout.
- Filament pickers collapse the per-extruder split into a single deduplicated
"AMS filaments" group with a smart-assign toggle when the switch is ready.
- Firmware-upgrade panel lists the O2L-FTS accessory and its version.
- Device-provided filament-change steps (ams.cfs) drive the change-step
display when firmware sends them, including the three switch steps.
- "Load current filament" asks which extruder to feed via a
FeedDirectionDialog when the switch is calibrated.
Inert without the accessory: every path is gated on the switch being
installed (MQTT aux bit 29, default off) or ready, both project flags default
false, and the per-extruder AMS attribution is byte-identical, so AMS state,
the send/load UI, and sliced g-code are unchanged for every printer that does
not report a Filament Track Switch.
Multi-nozzle sync widget, AMS rack-nozzle mapping popup, calibration rework, send-dialog nozzle mapping and extruder-count UI. Includes the fix to persist the AMS sync badge on filament cards (H2C/A2L and direct-sync printers).
* feat: native Windows ARM64 build support
Builds on the merged DEPS_ARCH=arm64 plumbing (#13424) by adding the
dependency and source fixes needed for a green native ARM64 build on the
windows-11-arm runner. Validated end-to-end on Snapdragon X Elite hardware
(via a downstream fork using the same fixes); see OrcaSlicer/OrcaSlicer#8271
for the full writeup.
Dependencies:
- OpenEXR 2.5.5: ImfSimd.h hard-codes IMF_HAVE_SSE2 for any MSVC, pulling in
<emmintrin.h> (x86-only) -> C1189. Patch the header to require an x86 target
and force SSE cache vars off on ARM64.
- Boost.Context: use the winfib implementation on ARM64 (Windows Fiber API)
to avoid the armasm64 / CMake ASM_ARMASM linker-module bug, while keeping
the Boost::context target Boost.Asio needs.
- OpenCV: disable WITH_IPP on ARM64 (Intel IPP/IPP-ICV is x86/x64 only;
otherwise ~200 unresolved ippicv* externals at link).
- OpenSSL: use VC-WIN64-ARM on ARM64.
- FindGLEW: add an ARM64 arch branch.
Sources:
- clipper Int128.hpp: _mul128 is an x64-only intrinsic guarded by _WIN64
(true on ARM64); guard on _M_X64 and use the portable path.
- imgui imgui_widgets.cpp: fix va_start(vaList, &text) -> va_start(vaList, text)
(the &-form compiled on x64 but is invalid on ARM64).
- crash reporter: StackWalker.cpp gains an _M_ARM64 branch; BaseException.cpp
uses Cpsr instead of the x86-only EFlags on ARM64.
CI:
- New build_windows_arm64.yml on windows-11-arm: pins CMake 3.31.x, stages
ARM64 GMP/MPFR from MSYS2 clangarm64 (with llvm-dlltool import libs),
caches deps with a fixed-depth hashFiles key, builds and uploads the binary.
OCCT/STEP, SVG-to-3D and text emboss all build and work on ARM64 (no stubs
needed). Full feature parity with x64.
* fix(ci): use forward-slash DESTDIR to avoid CMake '\a' escape error
deps configure failed at GMP/GMP.cmake: "Invalid character escape '\a'"
because DESTDIR carried Windows backslashes (C:\a\...) and is re-parsed
when re-set with the /usr/local suffix. Pass DESTDIR (and the slicer's
DEPS prefix) with forward slashes via %CD:\=/%.
* fix(ci): don't export DESTDIR env var (CMake staged-install doubles paths)
Setting a DESTDIR *environment* variable made CMake treat it as the staged
install prefix and prepend it to every dependency's install path, so e.g.
FreeType installed to <DESTDIR>/a/.../OrcaSlicer_dep/usr/local and OCCT
then couldn't find its headers. Compute the forward-slash path into a
differently-named var (ORCA_DESTDIR) and pass it only via -DDESTDIR.
* ci(windows-arm64): fold ARM64 build into the standard Windows matrix
Replace the standalone build_windows_arm64.yml with a matrix entry on the
existing build_windows job, so x64 and ARM64 share one reusable workflow
chain (build_all -> build_check_cache -> build_deps -> build_orca), per
review feedback on #14059.
- build_all.yml: build_windows now matrices over {x64: windows-latest,
arm64: windows-11-arm} and threads `arch` through. Self-hosted runner
stays x64-only.
- build_check_cache.yml: cache key and dep-prefix path are now
architecture-specific on Windows (deps/build-arm64/OrcaSlicer_dep).
- build_release_vs.bat: accept an `arm64` argument (mirrors
build_release_vs2022.bat) -> uses `-A ARM64` and the build-arm64 tree.
The top-level CMake auto-derives CMAKE_PREFIX_PATH from the build dir,
so no explicit prefix is needed.
- build_deps.yml / build_orca.yml: gate the ARM64-only prep behind
`inputs.arch == 'arm64'` -- pin CMake 3.31.x, and stage MSYS2
clangarm64 GMP/MPFR import libs. NSIS installer/PDB/profile_validator
remain x64-only; ARM64 ships the portable zip. Artifact names get an
arch suffix to avoid collisions between the two Windows jobs.
https://claude.ai/code/session_0164c7ZhCLsYBmCiVN9pWDjK
* ci(temp): generate GMP/MPFR win-arm64 blobs to commit to repo
* feat(deps): add prebuilt GMP/MPFR win-arm64 blobs
The repo ships prebuilt GMP/MPFR import libs + DLLs for win-x64 and
win-x86; the Windows ARM64 build path copies from win-${DEPS_ARCH}
(CMakeLists.txt) but the win-arm64 blobs were missing, so the slicer
configure failed at "file COPY cannot find .../win-arm64/libgmp-10.dll".
Add win-arm64 libgmp-10.{dll,lib} and libmpfr-4.{dll,lib}, generated from
the MSYS2 clangarm64 gmp/mpfr packages with MSVC-compatible import libs via
llvm-dlltool. Headers are shared across arches and unchanged.
* simplify OpenEXR.cmake
* set default arch
* support msix
* ship installer
* try to fix webview2runtime issue
---------
Co-authored-by: Adam Behrman <adam.behrman@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Adam Behrman <abehrman@users.noreply.github.com>
Since the wxWidgets 3.3 upgrade the Slice/Print split-button's transient
popup was dismissed the moment the cursor entered the gap between the
button and the menu, making "Print -> Export" impossible to select.
Anchor the menu flush against the button (with a 2 px overlap) instead of
6 px below it, removing the dead-zone the cursor had to cross.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Delay opening the object-list filament dropdown on wxGTK until the editor
window is mapped, avoiding popup creation without a valid native toplevel.
Also set the GTK transient parent for dropdown popups created from data-view
cell editors.
Hovering a group item (e.g. "Generic" in the filament list) now opens
its submenu correctly. The dropdown stays usable while moving the
cursor between the parent list and the submenu, and dismisses normally
when the user clicks outside.
* Add OrcaCloud sync platform and preset bundle sharing system
Introduce OrcaCloud, a cloud sync platform for user presets, alongside
a preset bundle system that enables sharing printer/filament/process
profiles as local exportable bundles or subscribed cloud bundles.
OrcaCloud platform:
- Auth to Orca Cloud
- Encrypted token storage (file-based or system keychain)
- User preset sync with
- Profile migration from default/bambu folders on first login
- Homepage integration with entrance to cloud.orcaslicer.com
Preset bundles:
- Local bundle import/export with bundle_structure.json metadata
- Subscribed cloud bundles with version-based update checking
- Thread-safe concurrent bundle access with read-write mutex
- Canonical bundle preset naming (_local/<id>/... and _subscribed/<id>/...)
- Bundle presets are read-only; grouped under subheaders in combo boxes
- PresetBundleDialog with auto-sync toggle, refresh, update notifications
- Hyperlinked bundle names to cloud bundle pages
Co-authored-by: Sabriel Koh <sabrielkcr@gmail.com>
Co-authored-by: Derrick <derrick992110@gmail.com>
Co-authored-by: Mykola Nahirnyi <mnahirnyi@amcbridge.com>
Co-authored-by: Ian Chua <iancrb00@gmail.com>
Co-authored-by: Draginraptor <draginraptor@gmail.com>
Co-authored-by: ExPikaPaka <112851715+ExPikaPaka@users.noreply.github.com>
Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
Co-authored-by: Ocraftyone <Ocraftyone@users.noreply.github.com>
Co-authored-by: yw4z <ywsyildiz@gmail.com>
Co-authored-by: peterm-m <101202951+peterm-m@users.noreply.github.com>
* Fixed an issue on Windows it failed to login Orca Cloud with Google account