Compare commits

...

1 Commits

Author SHA1 Message Date
agrynco d1eabfca88 Release v0.4.1: harden update checksum and fix Settings overlap 2026-10-28 22:22:08 +02:00
10 changed files with 41 additions and 21 deletions
+1 -1
View File
@@ -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()
Binary file not shown.
+8 -4
View File
@@ -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.
+1 -1
View File
@@ -1 +1 @@
c2ad230f9946fddcf6faf17378814cba474c104fa155f63cd1a9ac61fc489ee7 KSwitcher-win-x64.zip
7c29980c5d3b8862b1d78c06d1c3daa2b2bff24b56d200616971b92d784b51e6 KSwitcher-win-x64.zip
+3 -3
View File
@@ -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"
+7 -1
View File
@@ -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
+10 -10
View File
@@ -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);
+1 -1
View File
@@ -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
{
+5
View File
@@ -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)};
+5
View File
@@ -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'