diff --git a/CMakeLists.txt b/CMakeLists.txt index 1478107..e815971 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.24) -project(KSwitcher VERSION 0.4.0 LANGUAGES CXX RC) +project(KSwitcher VERSION 0.4.1 LANGUAGES CXX RC) if(NOT WIN32) message(FATAL_ERROR "KSwitcher uses native Windows APIs") endif() diff --git a/Release/KSwitcher-win-x64.zip b/Release/KSwitcher-win-x64.zip index dd0f02d..28de3a6 100644 Binary files a/Release/KSwitcher-win-x64.zip and b/Release/KSwitcher-win-x64.zip differ diff --git a/Release/README.md b/Release/README.md index a8da036..4421f52 100644 --- a/Release/README.md +++ b/Release/README.md @@ -1,7 +1,9 @@ # Latest Windows release -## v0.4.0 — 2026-10-28 +## v0.4.1 — 2026-10-28 +- Fix Settings spacing around Screen capture, automatic layout correction and layout controls. +- Verify update checksums through .NET SHA-256 without requiring the PowerShell Get-FileHash command. This fixes updates from processes launched with a conflicting PowerShell module environment. - Capture a rectangular screen region with Win+Shift+S (configurable), with dimmed selection and independent editor windows. - Annotate screenshots with numbered markers, arrows, straight/freehand lines, highlights, rectangles, circles, ellipses and inline text. - Edit color, line style, arrowheads, thickness, font and size. Link arrow endpoints to markers and attach captions. @@ -10,10 +12,12 @@ - Compact Lucide toolbar, contextual status bar, pencil cursor and confirmation before discarding an uncopied screenshot. Escape no longer closes the editor. - Preserve the separate on-demand configurator and configurable capture shortcut. -Verified: 173 native checks, 373 input/rendering checks, screenshot editor UI integration checks, -28 updater checks and package validation using the unchanged v0.3.0 updater. +Verified: 173 native checks, 379 input/rendering checks, screenshot editor UI integration checks, +29 updater checks, including missing Get-FileHash coverage, and package validation. -**Upgrade from v0.3.0:** use Update in the tray menu. Both executables are supported by that updater. +**Upgrade from v0.3.0 or v0.4.0:** use Update in the tray menu. Both executables are supported. +If an older updater reports missing `Get-FileHash`, restart KSwitcher normally from Explorer +(outside a PowerShell 7 session) or install this ZIP manually once. v0.4.1 removes that dependency. **Upgrade from v0.2.3 or earlier:** install manually once because those updaters reject the additional configurator EXE. Exit KSwitcher and extract the entire ZIP into its installation folder. Keep personal `data/` and customized dictionaries. diff --git a/Release/SHA256SUMS.txt b/Release/SHA256SUMS.txt index 388718e..059b0e1 100644 --- a/Release/SHA256SUMS.txt +++ b/Release/SHA256SUMS.txt @@ -1 +1 @@ -c2ad230f9946fddcf6faf17378814cba474c104fa155f63cd1a9ac61fc489ee7 KSwitcher-win-x64.zip +7c29980c5d3b8862b1d78c06d1c3daa2b2bff24b56d200616971b92d784b51e6 KSwitcher-win-x64.zip diff --git a/resources/app.rc b/resources/app.rc index 67ab48c..dd255f4 100644 --- a/resources/app.rc +++ b/resources/app.rc @@ -6,8 +6,8 @@ IDC_SCREENSHOT_PENCIL CURSOR "icons/lucide/pencil.cur" 1 RT_MANIFEST "app.manifest" 201 RCDATA "update.ps1" 1 VERSIONINFO - FILEVERSION 0,4,0,0 - PRODUCTVERSION 0,4,0,0 + FILEVERSION 0,4,1,0 + PRODUCTVERSION 0,4,1,0 FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_APP BEGIN @@ -17,7 +17,7 @@ BEGIN BEGIN VALUE "FileDescription", "KSwitcher — native keyboard and clipboard utility" VALUE "ProductName", "KSwitcher" - VALUE "FileVersion", "0.4.0" + VALUE "FileVersion", "0.4.1" END END BLOCK "VarFileInfo" diff --git a/resources/update.ps1 b/resources/update.ps1 index 47e7173..982f03c 100644 --- a/resources/update.ps1 +++ b/resources/update.ps1 @@ -63,7 +63,13 @@ function Assert-Checksum([string]$Archive,[string]$Checksum) { $matchesFound = @([IO.File]::ReadAllLines($Checksum) | Where-Object { $_ -cmatch '^([a-fA-F0-9]{64})\s+\*?KSwitcher-win-x64\.zip$' }) if ($matchesFound.Count -ne 1) { throw 'Missing or ambiguous archive checksum.' } $expected = ($matchesFound[0] -split '\s+')[0] - if ((Get-FileHash -LiteralPath $Archive -Algorithm SHA256).Hash -ne $expected) { throw 'Release checksum verification failed.' } + # Do not depend on PowerShell module autoloading: hosts can inherit a + # PowerShell 7 PSModulePath while this helper runs in Windows PowerShell 5.1. + $stream = [IO.File]::OpenRead($Archive) + $sha = [Security.Cryptography.SHA256]::Create() + try { $actual = [BitConverter]::ToString($sha.ComputeHash($stream)).Replace('-','') } + finally { $sha.Dispose(); $stream.Dispose() } + if ($actual -ne $expected) { throw 'Release checksum verification failed.' } } function Expand-Release([string]$Archive,[string]$Destination,[version]$Expected) { Add-Type -AssemblyName System.IO.Compression.FileSystem diff --git a/src/ui.cpp b/src/ui.cpp index 6db1719..5f5eeff 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -1651,17 +1651,17 @@ void showSettings(App &app, bool visible) label(w, names[i], 420, 48 + i * 30, 115); hotkeyEdit(app, w, 210 + i, 540, 44 + i * 30, 220); } - checkbox(w, L"Automatically correct layout (experimental)", 207, 420, 211, 350); - label(w, L"Layout cycle — top to bottom", 18, 210, 400); + checkbox(w, L"Automatically correct layout (experimental)", 207, 18, 210, 395); + label(w, L"Layout cycle — top to bottom", 18, 240, 400); control(w, L"LISTBOX", L"", WS_TABSTOP | WS_VSCROLL | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT | WS_BORDER, 220, - 18, 232, 470, 190); - button(w, L"Move up", 232, 504, 232, 120); - button(w, L"Move down", 233, 632, 232, 128); - checkbox(w, L"Include in cycle", 230, 504, 275, 240); - label(w, L"Direct layout shortcut", 504, 313, 240); - hotkeyEdit(app, w, 231, 504, 340, 256); - label(w, L"Backspace / Delete clears a shortcut", 504, 365, 256); - button(w, L"Refresh layouts", 253, 504, 384, 150); + 18, 262, 470, 172); + button(w, L"Move up", 232, 504, 262, 120); + button(w, L"Move down", 233, 632, 262, 128); + checkbox(w, L"Include in cycle", 230, 504, 300, 240); + label(w, L"Direct layout shortcut", 504, 332, 240); + hotkeyEdit(app, w, 231, 504, 356, 256); + label(w, L"Backspace / Delete clears a shortcut", 504, 382, 256); + button(w, L"Refresh layouts", 253, 504, 408, 150); label(w, L"History limits", 18, 444); label(w, L"Items", 18, 478, 50); edit(w, 240, 70, 474, 90); diff --git a/src/update.h b/src/update.h index 024d59e..c4b6518 100644 --- a/src/update.h +++ b/src/update.h @@ -2,7 +2,7 @@ #include "platform.h" namespace ks { -inline constexpr wchar_t AppVersion[] = L"0.4.0"; +inline constexpr wchar_t AppVersion[] = L"0.4.1"; inline constexpr UINT UpdateMessage = WM_APP + 7; struct UpdateResult { diff --git a/tests/input.cpp b/tests/input.cpp index 8875da4..66a639d 100644 --- a/tests/input.cpp +++ b/tests/input.cpp @@ -487,6 +487,11 @@ int main(int argc, char **argv) { ks::showSettings(app,false); auto settings=app.settingsWindow; require(settings&&!IsWindowVisible(settings),"settings layout tested without changing user focus"); + for(auto pair:{std::pair{207,215},std::pair{207,232},std::pair{207,220},std::pair{232,230},std::pair{230,231},std::pair{231,253}}) { + RECT first{},second{},overlap{}; + GetWindowRect(GetDlgItem(settings,pair.first),&first); GetWindowRect(GetDlgItem(settings,pair.second),&second); + require(!IntersectRect(&overlap,&first,&second),"capture hotkey and layout controls do not overlap"); + } RECT frame{},client{},cancel{}; GetWindowRect(settings,&frame); MONITORINFO monitor{sizeof(monitor)}; diff --git a/tests/update.ps1 b/tests/update.ps1 index 0a5f3aa..3695e4d 100644 --- a/tests/update.ps1 +++ b/tests/update.ps1 @@ -43,6 +43,11 @@ try { $sum=Join-Path $root 'SHA256SUMS.txt' ((Get-FileHash -LiteralPath $archive -Algorithm SHA256).Hash+' KSwitcher-win-x64.zip') | Set-Content -LiteralPath $sum Assert-Checksum $archive $sum; ++$script:checks + & { + function Get-FileHash { throw 'Get-FileHash unavailable in inherited module environment' } + Assert-Checksum $archive $sum + } + ++$script:checks $stage=Join-Path $root 'stage' Expand-Release $archive $stage $binaryVersion; ++$script:checks Reject { Expand-Release $archive (Join-Path $root 'wrong-version') ([version]'9.0.0') } 'version mismatch rejected'