mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-06-11 14:33:04 +00:00
Compare commits
1 Commits
release/si
...
fix/optimi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74b34beeca |
4
.github/workflows/build_all.yml
vendored
4
.github/workflows/build_all.yml
vendored
@@ -13,8 +13,6 @@ on:
|
||||
- 'localization/**'
|
||||
- 'resources/**'
|
||||
- ".github/workflows/build_*.yml"
|
||||
- 'signpath/**'
|
||||
- 'scripts/*.ps1'
|
||||
- 'scripts/flatpak/**'
|
||||
|
||||
pull_request:
|
||||
@@ -28,11 +26,9 @@ on:
|
||||
- '**/CMakeLists.txt'
|
||||
- 'version.inc'
|
||||
- ".github/workflows/build_*.yml"
|
||||
- 'signpath/**'
|
||||
- 'build_linux.sh'
|
||||
- 'build_release_vs2022.bat'
|
||||
- 'build_release_macos.sh'
|
||||
- 'scripts/*.ps1'
|
||||
- 'scripts/flatpak/**'
|
||||
|
||||
|
||||
|
||||
64
.github/workflows/build_orca.yml
vendored
64
.github/workflows/build_orca.yml
vendored
@@ -292,53 +292,6 @@ jobs:
|
||||
# WindowsSDKVersion: '10.0.26100.0\'
|
||||
run: .\build_release_vs.bat slicer
|
||||
|
||||
- name: Pack PDB
|
||||
if: runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
working-directory: ${{ github.workspace }}/build/src/Release
|
||||
shell: cmd
|
||||
run: '"C:/Program Files/7-Zip/7z.exe" a -m0=lzma2 -mx9 Debug_PDB_${{ env.ver }}_for_developers_only.7z *.pdb'
|
||||
|
||||
- name: Upload unsigned Windows portable artifact for SignPath
|
||||
id: upload-windows-portable
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) && runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: OrcaSlicer_Windows_${{ env.ver }}_portable_unsigned
|
||||
path: ${{ github.workspace }}/build/OrcaSlicer
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Submit Windows portable artifact to SignPath
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) && runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
uses: signpath/github-action-submit-signing-request@v2
|
||||
with:
|
||||
api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
|
||||
organization-id: ${{ secrets.SIGNPATH_ORGANIZATION_ID }}
|
||||
project-slug: OrcaSlicer
|
||||
signing-policy-slug: test-signing
|
||||
artifact-configuration-slug: windows-portable-v1
|
||||
github-artifact-id: ${{ steps.upload-windows-portable.outputs.artifact-id }}
|
||||
wait-for-completion: true
|
||||
output-artifact-directory: ${{ github.workspace }}/build/signpath/windows-portable
|
||||
|
||||
- name: Verify SignPath Windows portable signatures
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) && runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
shell: pwsh
|
||||
# -AllowUntrustedRoot is required while signing with the SignPath test
|
||||
# certificate (self-signed). Remove it once signing-policy-slug switches
|
||||
# to release-signing with a production CA-issued certificate.
|
||||
run: ./scripts/verify-authenticode.ps1 -ArtifactDirectory '${{ github.workspace }}/build/signpath/windows-portable' -AllowUntrustedRoot
|
||||
|
||||
- name: Replace Windows portable bundle with signed output
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) && runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
shell: pwsh
|
||||
run: |
|
||||
$source = Join-Path "${{ github.workspace }}" "build/signpath/windows-portable"
|
||||
$destination = Join-Path "${{ github.workspace }}" "build/OrcaSlicer"
|
||||
if (-not (Test-Path -LiteralPath $source -PathType Container)) {
|
||||
throw "SignPath output directory not found: $source"
|
||||
}
|
||||
Get-ChildItem -LiteralPath $source -Force | Copy-Item -Destination $destination -Recurse -Force
|
||||
|
||||
- name: Create installer Win
|
||||
if: runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
working-directory: ${{ github.workspace }}/build
|
||||
@@ -348,14 +301,14 @@ jobs:
|
||||
- name: Pack app
|
||||
if: runner.os == 'Windows'
|
||||
working-directory: ${{ github.workspace }}/build
|
||||
shell: pwsh
|
||||
run: |
|
||||
$zipPath = "OrcaSlicer_Windows_${{ env.ver }}_portable.zip"
|
||||
Remove-Item -LiteralPath $zipPath -Force -ErrorAction SilentlyContinue
|
||||
& "C:/Program Files/7-Zip/7z.exe" a -tzip $zipPath "${{ github.workspace }}/build/OrcaSlicer"
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
shell: cmd
|
||||
run: '"C:/Program Files/7-Zip/7z.exe" a -tzip OrcaSlicer_Windows_${{ env.ver }}_portable.zip ${{ github.workspace }}/build/OrcaSlicer'
|
||||
|
||||
- name: Pack PDB
|
||||
if: runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
working-directory: ${{ github.workspace }}/build/src/Release
|
||||
shell: cmd
|
||||
run: '"C:/Program Files/7-Zip/7z.exe" a -m0=lzma2 -mx9 Debug_PDB_${{ env.ver }}_for_developers_only.7z *.pdb'
|
||||
|
||||
- name: Upload artifacts Win zip
|
||||
if: runner.os == 'Windows'
|
||||
@@ -363,7 +316,6 @@ jobs:
|
||||
with:
|
||||
name: OrcaSlicer_Windows_${{ env.ver }}_portable
|
||||
path: ${{ github.workspace }}/build/OrcaSlicer
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload artifacts Win installer
|
||||
if: runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateScript({ Test-Path -LiteralPath $_ -PathType Container })]
|
||||
[string]$ArtifactDirectory
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
function Get-RelativePath {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Root,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Path
|
||||
)
|
||||
|
||||
$rootWithSeparator = $Root.TrimEnd([IO.Path]::DirectorySeparatorChar, [IO.Path]::AltDirectorySeparatorChar) + [IO.Path]::DirectorySeparatorChar
|
||||
$rootUri = [Uri]$rootWithSeparator
|
||||
$pathUri = [Uri]$Path
|
||||
|
||||
[Uri]::UnescapeDataString($rootUri.MakeRelativeUri($pathUri).ToString()).Replace("/", [IO.Path]::DirectorySeparatorChar)
|
||||
}
|
||||
|
||||
$artifactRoot = (Resolve-Path -LiteralPath $ArtifactDirectory).Path
|
||||
$binaries = Get-ChildItem -LiteralPath $artifactRoot -Recurse -File |
|
||||
Where-Object { $_.Extension -in @(".exe", ".dll") } |
|
||||
Sort-Object -Property FullName
|
||||
|
||||
if (-not $binaries) {
|
||||
Write-Warning "No .exe or .dll files found under '$artifactRoot'."
|
||||
exit 0
|
||||
}
|
||||
|
||||
$binaries | ForEach-Object {
|
||||
$signature = Get-AuthenticodeSignature -LiteralPath $_.FullName
|
||||
|
||||
[pscustomobject]@{
|
||||
RelativePath = Get-RelativePath -Root $artifactRoot -Path $_.FullName
|
||||
Status = $signature.Status
|
||||
SignatureType = $signature.SignatureType
|
||||
Signer = if ($signature.SignerCertificate) { $signature.SignerCertificate.Subject } else { "" }
|
||||
SignerThumbprint = if ($signature.SignerCertificate) { $signature.SignerCertificate.Thumbprint } else { "" }
|
||||
Timestamped = [bool]$signature.TimeStamperCertificate
|
||||
TimeStamper = if ($signature.TimeStamperCertificate) { $signature.TimeStamperCertificate.Subject } else { "" }
|
||||
}
|
||||
} | Format-Table -AutoSize
|
||||
@@ -1,115 +0,0 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateScript({ Test-Path -LiteralPath $_ -PathType Container })]
|
||||
[string]$ArtifactDirectory,
|
||||
|
||||
[string[]]$Files = @(
|
||||
"orca-slicer.exe",
|
||||
"OrcaSlicer.dll"
|
||||
),
|
||||
|
||||
[string]$SignToolPath,
|
||||
|
||||
# Accept signatures whose certificate chain terminates in an untrusted root.
|
||||
# Required for the SignPath test certificate (self-signed). Do NOT pass this
|
||||
# once a production CA-issued certificate is in use, so release builds enforce
|
||||
# a fully trusted chain.
|
||||
[switch]$AllowUntrustedRoot
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
function Resolve-SignToolPath {
|
||||
param(
|
||||
[string]$ExplicitPath
|
||||
)
|
||||
|
||||
if ($ExplicitPath) {
|
||||
if (Test-Path -LiteralPath $ExplicitPath -PathType Leaf) {
|
||||
return (Resolve-Path -LiteralPath $ExplicitPath).Path
|
||||
}
|
||||
|
||||
throw "SignTool was not found at '$ExplicitPath'."
|
||||
}
|
||||
|
||||
$fromPath = Get-Command -Name "signtool.exe" -ErrorAction SilentlyContinue
|
||||
if ($fromPath) {
|
||||
return $fromPath.Source
|
||||
}
|
||||
|
||||
$candidateRoots = @(
|
||||
"${env:ProgramFiles(x86)}\Windows Kits\10\bin",
|
||||
"${env:ProgramFiles}\Windows Kits\10\bin"
|
||||
) | Where-Object { $_ -and (Test-Path -LiteralPath $_ -PathType Container) }
|
||||
|
||||
foreach ($root in $candidateRoots) {
|
||||
$candidate = Get-ChildItem -LiteralPath $root -Recurse -Filter "signtool.exe" -File -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -match "\\(x64|arm64)\\signtool\.exe$" } |
|
||||
Sort-Object -Property FullName -Descending |
|
||||
Select-Object -First 1
|
||||
|
||||
if ($candidate) {
|
||||
return $candidate.FullName
|
||||
}
|
||||
}
|
||||
|
||||
throw "signtool.exe was not found. Install the Windows SDK or pass -SignToolPath."
|
||||
}
|
||||
|
||||
$artifactRoot = (Resolve-Path -LiteralPath $ArtifactDirectory).Path
|
||||
$signtool = Resolve-SignToolPath -ExplicitPath $SignToolPath
|
||||
|
||||
Write-Host "Using SignTool: $signtool"
|
||||
Write-Host "Verifying Authenticode signatures in: $artifactRoot"
|
||||
|
||||
foreach ($relativePath in $Files) {
|
||||
$filePath = Join-Path $artifactRoot $relativePath
|
||||
if (-not (Test-Path -LiteralPath $filePath -PathType Leaf)) {
|
||||
throw "Expected signed file was not found: $filePath"
|
||||
}
|
||||
|
||||
Write-Host "Verifying $relativePath"
|
||||
|
||||
# Capture signtool output without letting native stderr (redirected via 2>&1)
|
||||
# raise a terminating NativeCommandError under $ErrorActionPreference = 'Stop'.
|
||||
$previousErrorActionPreference = $ErrorActionPreference
|
||||
$ErrorActionPreference = "Continue"
|
||||
try {
|
||||
$output = & $signtool verify /pa /all /tw /v $filePath 2>&1
|
||||
$exitCode = $LASTEXITCODE
|
||||
}
|
||||
finally {
|
||||
$ErrorActionPreference = $previousErrorActionPreference
|
||||
}
|
||||
|
||||
$output | ForEach-Object { Write-Host $_ }
|
||||
|
||||
if ($exitCode -eq 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
if ($AllowUntrustedRoot) {
|
||||
# signtool interleaves its stdout (chain details) and stderr (the error)
|
||||
# unpredictably, so the error text cannot be matched reliably. Use the
|
||||
# structured Get-AuthenticodeSignature result instead: accept only when the
|
||||
# file is genuinely signed and the sole problem is that the chain terminates
|
||||
# in an untrusted root (i.e. the self-signed SignPath test certificate).
|
||||
$signature = Get-AuthenticodeSignature -LiteralPath $filePath
|
||||
$isSigned = ($signature.SignatureType -eq "Authenticode") -and ($null -ne $signature.SignerCertificate)
|
||||
$untrustedRootOnly = $signature.StatusMessage -match "terminated in a root certificate which is not trusted"
|
||||
if ($isSigned -and $untrustedRootOnly) {
|
||||
Write-Host " Accepted: '$relativePath' is signed but its certificate chains to an untrusted root (expected for the SignPath test certificate)."
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
throw "SignTool verification failed for '$relativePath' with exit code $exitCode."
|
||||
}
|
||||
|
||||
Write-Host "Authenticode verification passed."
|
||||
|
||||
# signtool exits non-zero for the untrusted test-cert root even when we accept
|
||||
# it above, leaving $LASTEXITCODE = 1. The GitHub Actions pwsh wrapper exits
|
||||
# with that lingering code, so reset it to report success explicitly.
|
||||
exit 0
|
||||
@@ -1,16 +0,0 @@
|
||||
# SignPath configurations
|
||||
|
||||
This directory contains SignPath artifact configurations used by GitHub Actions.
|
||||
|
||||
## `windows-portable-v1`
|
||||
|
||||
`windows-portable-v1.xml` is the initial conservative Windows portable-bundle signing configuration. It signs only the two first-party binaries:
|
||||
|
||||
- `orca-slicer.exe`
|
||||
- `OrcaSlicer.dll`
|
||||
|
||||
Do not broaden this to all DLLs without first confirming ownership, provenance, and whether upstream vendor signatures should be verified instead.
|
||||
|
||||
The Windows workflow uploads `${{ github.workspace }}/build/OrcaSlicer` with `actions/upload-artifact`. GitHub stores that artifact as a ZIP, and the uploaded directory contents are rooted at the ZIP root. Because of that, the SignPath configuration uses `<zip-file>` with `orca-slicer.exe` and `OrcaSlicer.dll` directly beneath it.
|
||||
|
||||
The release portable ZIP is a separate archive created with 7-Zip from `${{ github.workspace }}/build/OrcaSlicer`; that archive keeps the top-level `OrcaSlicer/` folder. After SignPath returns the signed artifact, the workflow copies the signed files back into `build/OrcaSlicer` and recreates the portable release ZIP so the public ZIP layout stays unchanged.
|
||||
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<artifact-configuration xmlns="http://signpath.io/artifact-configuration/v1">
|
||||
<zip-file>
|
||||
<pe-file path="orca-slicer.exe">
|
||||
<authenticode-sign />
|
||||
</pe-file>
|
||||
|
||||
<pe-file path="OrcaSlicer.dll">
|
||||
<authenticode-sign />
|
||||
</pe-file>
|
||||
</zip-file>
|
||||
</artifact-configuration>
|
||||
@@ -71,6 +71,7 @@
|
||||
#include <dbt.h>
|
||||
#include <shlobj.h>
|
||||
#include <shellapi.h>
|
||||
#include <windowsx.h> // GET_X_LPARAM / GET_Y_LPARAM
|
||||
#endif // _WIN32
|
||||
|
||||
#ifdef __WXGTK__
|
||||
@@ -906,27 +907,68 @@ WXLRESULT MainFrame::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam
|
||||
return HTCAPTION;
|
||||
}
|
||||
|
||||
// Allow resizing from top of the title bar
|
||||
wxPoint mouse_pos = ::wxGetMousePosition();
|
||||
if (m_topbar->GetScreenRect().GetBottom() >= mouse_pos.y) {
|
||||
RECT borderThickness;
|
||||
SetRectEmpty(&borderThickness);
|
||||
AdjustWindowRectEx(&borderThickness, GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION, FALSE, NULL);
|
||||
borderThickness.left *= -1;
|
||||
borderThickness.top *= -1;
|
||||
wxPoint client_pos = this->ScreenToClient(mouse_pos);
|
||||
if (!m_nchit_cache.valid || !m_topbar)
|
||||
break;
|
||||
|
||||
bool on_top_border = client_pos.y <= borderThickness.top;
|
||||
// lParam already encodes the cursor screen position
|
||||
// All other values come from the cache updated in WM_WINDOWPOSCHANGED/WM_DPICHANGED,
|
||||
// so this handler makes zero system calls at 1000 Hz polling rates.
|
||||
LONG screen_x = GET_X_LPARAM(lParam);
|
||||
LONG screen_y = GET_Y_LPARAM(lParam);
|
||||
|
||||
// And to allow diagonally resizing, we check if mouse is at window corner
|
||||
if (client_pos.x <= borderThickness.left) {
|
||||
return on_top_border ? HTTOPLEFT : HTLEFT;
|
||||
} else if (client_pos.x >= GetClientSize().x - borderThickness.right) {
|
||||
return on_top_border ? HTTOPRIGHT : HTRIGHT;
|
||||
}
|
||||
if (screen_y > m_nchit_cache.topbar_screen_bottom)
|
||||
break; // below topbar: let default proc handle it
|
||||
|
||||
return on_top_border ? HTTOP : HTCAPTION;
|
||||
LONG client_x = screen_x - m_nchit_cache.client_origin_x;
|
||||
LONG client_y = screen_y - m_nchit_cache.client_origin_y;
|
||||
|
||||
bool on_top_border = client_y <= m_nchit_cache.border.top;
|
||||
|
||||
// Check window corners for diagonal resize
|
||||
if (client_x <= m_nchit_cache.border.left) {
|
||||
return on_top_border ? HTTOPLEFT : HTLEFT;
|
||||
} else if (client_x >= m_nchit_cache.client_width - m_nchit_cache.border.right) {
|
||||
return on_top_border ? HTTOPRIGHT : HTRIGHT;
|
||||
}
|
||||
return on_top_border ? HTTOP : HTCAPTION;
|
||||
}
|
||||
|
||||
case WM_WINDOWPOSCHANGED: {
|
||||
const auto* wp = reinterpret_cast<const WINDOWPOS*>(lParam);
|
||||
if (m_topbar) {
|
||||
if (!m_nchit_cache.valid) {
|
||||
// First-time init (or post-DPI-change): compute border thickness and topbar height.
|
||||
// WINDOWPOS x/y always hold the current window position even when SWP_NOMOVE is set.
|
||||
SetRectEmpty(&m_nchit_cache.border);
|
||||
AdjustWindowRectEx(&m_nchit_cache.border,
|
||||
GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION, FALSE, NULL);
|
||||
m_nchit_cache.border.left *= -1;
|
||||
m_nchit_cache.border.top *= -1;
|
||||
m_nchit_cache.topbar_height = m_topbar->GetSize().y;
|
||||
m_nchit_cache.client_width = GetClientSize().x;
|
||||
m_nchit_cache.client_origin_x = wp->x + m_nchit_cache.border.left;
|
||||
m_nchit_cache.client_origin_y = wp->y + 1;
|
||||
m_nchit_cache.topbar_screen_bottom = m_nchit_cache.client_origin_y + m_nchit_cache.topbar_height;
|
||||
m_nchit_cache.valid = true;
|
||||
}
|
||||
if (!(wp->flags & SWP_NOMOVE)) {
|
||||
// client_origin_y = window_top + 1 (the 1-px top resize strip added in WM_NCCALCSIZE)
|
||||
m_nchit_cache.client_origin_x = wp->x + m_nchit_cache.border.left;
|
||||
m_nchit_cache.client_origin_y = wp->y + 1;
|
||||
m_nchit_cache.topbar_screen_bottom = m_nchit_cache.client_origin_y + m_nchit_cache.topbar_height;
|
||||
}
|
||||
if (!(wp->flags & SWP_NOSIZE)) {
|
||||
m_nchit_cache.topbar_height = m_topbar->GetSize().y;
|
||||
m_nchit_cache.client_width = GetClientSize().x;
|
||||
m_nchit_cache.topbar_screen_bottom = m_nchit_cache.client_origin_y + m_nchit_cache.topbar_height;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_DPICHANGED: {
|
||||
// Border thickness and topbar height are DPI-dependent; force recompute.
|
||||
m_nchit_cache.valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -206,6 +206,19 @@ protected:
|
||||
|
||||
#ifdef __WXMSW__
|
||||
WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) override;
|
||||
|
||||
// Cached values for WM_NCHITTEST to avoid 5+ system calls per mouse event at
|
||||
// high polling rates (e.g. 1000 Hz mice cause visible window drag lag without this).
|
||||
// Refreshed in WM_WINDOWPOSCHANGED; invalidated on DPI change.
|
||||
struct {
|
||||
LONG client_origin_x = 0;
|
||||
LONG client_origin_y = 0; // window_top + 1 (1-px top resize strip, see WM_NCCALCSIZE)
|
||||
LONG topbar_screen_bottom = 0;
|
||||
int client_width = 0;
|
||||
int topbar_height = 0;
|
||||
RECT border = {}; // positive NC border thickness from AdjustWindowRectEx
|
||||
bool valid = false;
|
||||
} m_nchit_cache;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user