* ci: build the Windows x64 dependencies and slicer with clang-cl
Passes -l -x from the Windows jobs, using the clang-cl and Ninja options
added in #15373. Ninja runs each dependency's build step as a plain command,
so the jobs set up a VC environment for OpenSSL's nmake. arm64 stays on MSVC
for now.
The deps cache key gains the compiler, so windows-x64 becomes
windows-x64-clang and windows-arm64 becomes windows-arm64-msvc.
* deps: select OpenSSL's ARM64 target from DEPS_ARCH
CMAKE_GENERATOR_PLATFORM is only set by -A, which Ninja never receives, so
the Ninja build selected the x64 target on ARM64. DEPS_ARCH is derived from
CMAKE_SYSTEM_PROCESSOR and is already independent of the generator.
* ci: build the Windows ARM64 dependencies and slicer with clang-cl
Three dependencies need handling first. libpng and OpenCV each build an ARM
SIMD path that does not compile with clang-cl, so those paths are off; PNG
already had the same opt-out for Apple ARM. OCCT is built with cl, since
clang-cl cannot emit one of its large generated files and there is no option
to turn that off. All three are gated to Windows ARM64 with clang.
The FFmpeg camera view port made pkg-config a required build tool on
Windows. Windows does not ship one, so every Windows developer has to
install it before the build will configure:
Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE)
Call Stack (most recent call first):
CMakeLists.txt:480 (find_package)
Nothing on Windows needs it. FFmpeg there is a prebuilt zip unpacked
into the deps prefix, whose DLLs the top level CMakeLists already names
by exact soname. The version is fixed before configure runs, so
find_library against that prefix does the job, as on macOS.
Also drops the CI step that installed pkg-config, gated on !SELF_HOSTED
so it never ran on self-hosted runners, and re-comments the if(WIN32)
block that #15234 uncommented only for that find_package.
PartPlate::store_to_3mf_structure read first_layer_time from the indirect cali_bboxes_data struct,
which the GUI populates at Plater.cpp:10600 but the CLI never writes to. The result was uninitialized
memory leaking into slice_info.config
Read directly from get_slice_result()->initial_layer_time, which is populated by
GCodeProcessor::finalize() in both code paths and matches the pattern already used a few lines
above for gcode_prediction.
Also default-initialize PlateBBoxData::first_layer_time to 0.0f as a defense against any other consumer
reading it without an explicit write.
build: clear 54 dead private fields
54 of the 161 -Wunused-private-field warnings, across 31 files. These are
the ones needing no judgment. Each member is declared once and appears
nowhere else in src/, counting the .mm and .c sources as well as .cpp and
.hpp, so nothing writes them and nothing reads them. Every removal is a
whole line, and no declaration shares a line with another member.
The remaining 107 are left alone. Those members are mentioned elsewhere,
usually assigned and never read, where the fix might be deleting the
member or might be restoring a read that went missing.
build: clear 53 unused value warnings
49 of them are deliberate i18n markers. L(s) expands to s, so
L("Main Extruder"); is a string literal as a statement and its value is
discarded. The strings have to stay, because the real values come from
printers/*.json at runtime and xgettext cannot scan those. Each block is
now a static const char *const markers[], which uses the values rather
than discarding them. Extraction is unchanged: the xgettext invocation
from scripts/run_gettext.bat gives 76 msgids over the two marker files
before and after, with identical msgid and msgctxt sets.
The other 4 are statements with no effect. AMSItem.cpp:117 and :174
construct and drop a wxColour(255, 255, 255); AMS_TRAY_DEFAULT_COL is
that colour, and the line above already assigns it. UpgradePanel.cpp:865
reads a member and drops it.
wgtDeviceNozzleSelect.cpp:269 writes
if (item; auto ptr = m_nozzle_rack.lock()), which puts the null check in
the init-statement position where its value is discarded, so the check
never runs, and sGetNozzlePosId then dereferences item. Nothing reaches
that today, because the only sender of the event sets itself as the
event object and the dynamic_cast always succeeds. The check now runs.
git config wrote core.autocrlf into the repository git init creates in the
extracted CPython source. Nothing outside deps/build reads that repository, so
the setting was already contained.
-c applies the override to the one invocation instead, so no repository config is
written at all. It cannot reuse PATCH_CMD, so the shared flags are spelled out here.
These dialogs treated a filament with no compatible_printers as compatible with
nothing, while the rest of the app treats it as compatible with everything, so
the entire Orca Filament Library was missing from the AMS material and
calibration filament lists. They now resolve compatibility the same way the
plater does, and a vendor profile still supersedes the library generic of the
same name.
# Description
This is an initial draft of the plugin audit workflow.
It focuses on the user experience and developer-facing permission
workflow. It does not yet include the complete implementation of every
operation that should be audited, such as the full filesystem,
networking, and process-spawning event coverage.
## User workflow
When a plugin is loaded:
1. The plugin’s register_capabilities() function is executed.
2. The plugin declares the permissions it requires.
3. OrcaSlicer displays a permission dialog listing the requested
resources.
4. If the user grants access:
- The permission is persisted in the plugin’s .install_state.json.
- Capability registration continues.
- The plugin is materialized and loaded.
5. If the user denies access:
- Plugin loading fails before capabilities are materialized.
- on_load() is not called.
- The plugin’s install state is marked with "enabled": false to prevent
repeated automatic load attempts.
At runtime, if a plugin accesses a resource that was not approved during
loading, the audit hook displays another permission dialog. For
filesystem requests, the dialog identifies the requested filepath.
- Granting access persists the permission and allows the operation.
- Denying access raises a Python PermissionError.
- The error propagates to the host, which records the failure and
unloads the plugin.
Host-side traceback logging is performed outside the plugin audit
context so that logging does not generate additional permission dialogs.
## Developer-facing API
Plugins can declare filesystem read permissions through the new API:
```python
import orca
AUDIT_PATH = __file__
@orca.plugin
class ExamplePackage(orca.base):
def register_capabilities(self):
orca.request_permissions(
fs_read=[AUDIT_PATH],
)
orca.register_capability(ExampleCapability)
```
orca.request_permissions() must be called from register_capabilities()
while the plugin is being loaded.
Currently supported permission:
orca.request_permissions(fs_read=[...])
The paths should be explicit filesystem paths that the plugin intends to
read. The host deduplicates repeated paths, presents the request after
registration completes, and persists granted paths in the plugin
install-state sidecar. This API is still experimental, and is by no
means the final implementation.
Support for additional permission categories, including filesystem write
access, networking, and process spawning, is reserved for subsequent
work.
# Screenshots/Recordings/Graphs
<!--
> Please attach relevant screenshots to showcase the UI changes.
> Please attach images that can help explain the changes.
-->
<img width="869" height="799" alt="image"
src="https://github.com/user-attachments/assets/8a5903cc-0cbb-45a8-b88a-706d6cba790f"
/>
## 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)