Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b8bb14a985 |
Binary file not shown.
+6
-10
@@ -1,17 +1,13 @@
|
||||
# Latest Windows release
|
||||
|
||||
## v0.6.3 — 2026-10-29
|
||||
## v0.6.4 — 2026-10-29
|
||||
|
||||
- Hide the fullscreen capture selection before submitting a notification when automatic editor opening is disabled. Previously the selection remained visible during submission, which could suppress the banner under Windows fullscreen notification rules.
|
||||
- Default to capture → notification → click → editor. **Open editor after screen capture** is now off by default; explicitly saved preferences are preserved.
|
||||
- Retain the editor fallback for immediate notification errors.
|
||||
- Check for updates in the background every 6 hours after the startup check. Notify once per version per session, retry after network failures at the next interval, and install only after confirmation.
|
||||
## Changes
|
||||
- Fix accidental arrow/line detachment when dragging two linked numbered markers in turn. Clicking a visible marker now selects the marker instead of a connector endpoint underneath it, including when the connector is selected.
|
||||
- Preserve intentional endpoint dragging outside the marker.
|
||||
|
||||
Verified: 176 native checks, 403 input/layout checks at 240 DPI, screenshot editor UI integration,
|
||||
isolated notification registration checks, and 45 updater checks. The new UI regression test failed
|
||||
before the fix and passes afterward: the selection is hidden at notification submission.
|
||||
Banner behavior still needs confirmation on the affected laptop. Windows Do Not Disturb can
|
||||
send notifications directly to the notification center; asynchronous toast failures are not yet monitored.
|
||||
## Validation
|
||||
176 native checks, 403 input/layout checks at 240 DPI, screenshot editor UI integration, isolated notification registration, and 45 updater checks. The new UI regression test fails before the fix and passes afterward, covering alternating marker drags with arrows, lines and freehand connectors, both endpoint links, and endpoint selection outside markers.
|
||||
|
||||
**Upgrade:** choose Update in the tray menu. Legacy v0.3.0–v0.4.1 clients first receive the
|
||||
v0.4.2 compatibility bridge, then the current full release. v0.2.3 and earlier require manual installation.
|
||||
|
||||
@@ -1 +1 @@
|
||||
a43786b06878da0f069dbad0fa29587a736dd2d8904c7bc991f5cf0c0570a16f KSwitcher-win-x64.zip
|
||||
da86748a476deec9323c39e119c89dc008e2fe62691b207eb3b0f3bb0da32cf6 KSwitcher-win-x64.zip
|
||||
|
||||
+3
-3
@@ -9,8 +9,8 @@ IDC_SCREENSHOT_PENCIL CURSOR "icons/lucide/pencil.cur"
|
||||
1 RT_MANIFEST "app.manifest"
|
||||
201 RCDATA "update.ps1"
|
||||
1 VERSIONINFO
|
||||
FILEVERSION 0,6,3,0
|
||||
PRODUCTVERSION 0,6,3,0
|
||||
FILEVERSION 0,6,4,0
|
||||
PRODUCTVERSION 0,6,4,0
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
BEGIN
|
||||
@@ -20,7 +20,7 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "FileDescription", "KSwitcher — native keyboard and clipboard utility"
|
||||
VALUE "ProductName", "KSwitcher"
|
||||
VALUE "FileVersion", "0.6.3"
|
||||
VALUE "FileVersion", "0.6.4"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -575,6 +575,15 @@ std::pair<int,MarkPart> markAt(Capture &c, POINT p)
|
||||
{
|
||||
if((c.arrow || c.highlight || c.freehand || c.textTool) && (GetKeyState(VK_CONTROL)&0x8000)) return {-1,MarkPart::None};
|
||||
double tolerance=double(std::max(6,c.unit/6))*c.image->width/std::max(1L,c.view.right-c.view.left);
|
||||
// Badges are painted above connectors. Their visible bodies must also win
|
||||
// hit testing, even when an attached connector is currently selected.
|
||||
for(int i=int(c.marks.size())-1;i>=0;--i) {
|
||||
const auto &m=c.marks[i];
|
||||
if(m.number && std::hypot(double(p.x-m.from.x),double(p.y-m.from.y))<=m.radius) {
|
||||
auto part=hitScreenshotMark(m,p,tolerance);
|
||||
return {i,part};
|
||||
}
|
||||
}
|
||||
if(c.selected>=0)
|
||||
{
|
||||
const auto &m=c.marks[c.selected];
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
#include "platform.h"
|
||||
namespace ks
|
||||
{
|
||||
inline constexpr wchar_t AppVersion[] = L"0.6.3";
|
||||
inline constexpr wchar_t AppVersion[] = L"0.6.4";
|
||||
inline constexpr UINT UpdateMessage = WM_APP + 7;
|
||||
inline constexpr UINT UpdateCheckIntervalMs = 6 * 60 * 60 * 1000;
|
||||
struct UpdateResult
|
||||
|
||||
@@ -94,6 +94,37 @@ int main()
|
||||
c.hoveredPart=ks::MarkPart::Rotation; ks::updateStatus(c);
|
||||
require(c.statusText.find(L"15-degree")!=std::wstring::npos,"rotation hint explains Shift snapping");
|
||||
c.hoveredPart=ks::MarkPart::None;
|
||||
// Drag the two badges in turn, including a click near the attached endpoint.
|
||||
for(bool freehand : {false,true}) for(auto ends : {ks::LineEnds::End,ks::LineEnds::None}) {
|
||||
c.marks={{{60,80},{60,80},1},{{230,80},{230,80},2},{{60,80},{230,80},0}};
|
||||
auto &connector=c.marks[2]; connector.fromNumber=1; connector.toNumber=2;
|
||||
connector.ends=ends; connector.freehand=freehand;
|
||||
if(freehand) connector.points={{60,80},{140,80},{230,80}};
|
||||
ks::resolveScreenshotLinks(c.marks); c.selected=-1; c.selectedLabel=false;
|
||||
auto mouse=[&](UINT message,POINT p) {
|
||||
LONG x=c.view.left+MulDiv(p.x,c.view.right-c.view.left,c.image->width);
|
||||
LONG y=c.view.top+MulDiv(p.y,c.view.bottom-c.view.top,c.image->height);
|
||||
SendMessageW(window,message,message==WM_LBUTTONUP?0:MK_LBUTTON,MAKELPARAM(x,y));
|
||||
};
|
||||
for(int badge : {0,1,0,1}) {
|
||||
auto origin=c.marks[badge].from;
|
||||
// The second badge's inner edge overlaps the connector endpoint hit area.
|
||||
if(badge==1) origin.x-=12;
|
||||
mouse(WM_LBUTTONDOWN,origin);
|
||||
require(c.selected==badge && c.part==ks::MarkPart::Body,"click on linked badge selects badge instead of connector endpoint");
|
||||
mouse(WM_MOUSEMOVE,{origin.x,origin.y+20});
|
||||
mouse(WM_LBUTTONUP,{origin.x,origin.y+20});
|
||||
require(c.marks[2].fromNumber==1 && c.marks[2].toNumber==2,"alternating badge drags preserve both connector links");
|
||||
auto start=c.marks[0].from,end=c.marks[1].from;
|
||||
require(std::abs(std::hypot(double(c.marks[2].from.x-start.x),double(c.marks[2].from.y-start.y))-15)<1 &&
|
||||
std::abs(std::hypot(double(c.marks[2].to.x-end.x),double(c.marks[2].to.y-end.y))-15)<1,
|
||||
"connector endpoints follow both badge rims");
|
||||
}
|
||||
c.selected=2;
|
||||
require(ks::markAt(c,c.marks[1].from).first==1,"selected connector cannot steal a badge click");
|
||||
auto outside=c.marks[2].to; outside.x-=4;
|
||||
require(ks::markAt(c,outside)==std::pair{2,ks::MarkPart::End},"endpoint remains draggable outside badge");
|
||||
}
|
||||
std::vector<ks::Mark> nudgeMarks;
|
||||
nudgeMarks.push_back({{60,60},{60,60},1});
|
||||
nudgeMarks.push_back({{60,60},{120,100},0});
|
||||
|
||||
Reference in New Issue
Block a user