From 715bb28c1b6739b785ef6163a78bdaf088c8d7bc Mon Sep 17 00:00:00 2001 From: TZGyn Date: Wed, 9 Sep 2026 15:26:19 +0800 Subject: [PATCH] Fix supersample blur and click-cancellation on micro-drags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 3x supersample resized the whole capture (blurring content); only the corner mask is supersampled now, applied through clip(to:mask:) with the image drawn once at native scale. The tap's drag branch also clears the hovered window on sub-4px jitter, cancelling click-to-capture; the threshold is applied there too. 💘 Generated with Crush Assisted-by: Crush:deepseek-v4-flash-0731 --- Sources/Kapture/CaptureController.swift | 44 +++++++++++++++++-------- build-app.sh | 4 +-- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/Sources/Kapture/CaptureController.swift b/Sources/Kapture/CaptureController.swift index 32f2ea1..95e0691 100644 --- a/Sources/Kapture/CaptureController.swift +++ b/Sources/Kapture/CaptureController.swift @@ -301,8 +301,11 @@ final class CaptureController: NSObject { } return event } - // Drag: grow the marquee + // Drag: grow the marquee — but only after real movement, so a + // click's micro-jitter keeps the hovered window eligible. guard let start = marqueeStart else { return nil } + let distance = hypot(appKitPoint.x - start.x, appKitPoint.y - start.y) + guard distance >= 4 else { return nil } let rect = NSRect( x: min(start.x, appKitPoint.x), y: min(start.y, appKitPoint.y), @@ -443,28 +446,43 @@ final class ScreenCapture { let detected = Self.detectCornerRadius(of: result) let radius = min(max((detected.map { $0 * 1.23 + 2.6 }) ?? (10 * scaleX), 4), 40) CaptureController.log("corners: detected=\(detected.map { String(format: "%.1f", $0) } ?? "nil") using=\(Int(radius))px") + // Anti-aliased gray mask: supersample 3x, downsample, then draw + // the image through it ONCE at 1x (no content resampling blur). let ss = 3 let W = result.width * ss, H = result.height * ss - guard let hiCtx = CGContext( + guard let hiMask = CGContext( data: nil, width: W, height: H, bitsPerComponent: 8, bytesPerRow: 0, - space: CGColorSpaceCreateDeviceRGB(), - bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue + space: CGColorSpaceCreateDeviceGray(), + bitmapInfo: CGImageAlphaInfo.none.rawValue ) else { return result } - hiCtx.addPath(CGPath(roundedRect: CGRect(x: 0, y: 0, width: W, height: H), cornerWidth: radius * CGFloat(ss), cornerHeight: radius * CGFloat(ss), transform: nil)) - hiCtx.clip() - hiCtx.interpolationQuality = .high - hiCtx.draw(result, in: CGRect(x: 0, y: 0, width: W, height: H)) - guard let hi = hiCtx.makeImage(), - let downCtx = CGContext( + hiMask.setFillColor(CGColor(gray: 1, alpha: 1)) + hiMask.fill(CGRect(x: 0, y: 0, width: W, height: H)) + hiMask.setFillColor(CGColor(gray: 0, alpha: 1)) + let cornerPath = CGMutablePath() + cornerPath.addRect(CGRect(x: 0, y: 0, width: W, height: H)) + cornerPath.addRoundedRect(in: CGRect(x: 0, y: 0, width: W, height: H), cornerWidth: radius * CGFloat(ss), cornerHeight: radius * CGFloat(ss), transform: .identity) + hiMask.addPath(cornerPath) + hiMask.fillPath(using: .evenOdd) + guard let hiMaskImg = hiMask.makeImage(), + let downMask = CGContext( + data: nil, width: result.width, height: result.height, + bitsPerComponent: 8, bytesPerRow: 0, + space: CGColorSpaceCreateDeviceGray(), + bitmapInfo: CGImageAlphaInfo.none.rawValue + ) else { return result } + downMask.interpolationQuality = .high + downMask.draw(hiMaskImg, in: CGRect(x: 0, y: 0, width: result.width, height: result.height)) + guard let mask1x = downMask.makeImage(), + let ctx = CGContext( data: nil, width: result.width, height: result.height, bitsPerComponent: 8, bytesPerRow: 0, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue ) else { return result } - downCtx.interpolationQuality = .high - downCtx.draw(hi, in: CGRect(x: 0, y: 0, width: result.width, height: result.height)) - if let masked = downCtx.makeImage() { + ctx.clip(to: CGRect(x: 0, y: 0, width: result.width, height: result.height), mask: mask1x) + ctx.draw(result, in: CGRect(x: 0, y: 0, width: result.width, height: result.height)) + if let masked = ctx.makeImage() { result = masked } } diff --git a/build-app.sh b/build-app.sh index 3676233..04ab41e 100755 --- a/build-app.sh +++ b/build-app.sh @@ -108,9 +108,9 @@ cat > "$APP/Contents/Info.plist" <<'PLIST' CFBundleIconFile Icon CFBundleShortVersionString - 1.8.5 + 1.8.6 CFBundleVersion - 85 + 86 LSUIElement NSHighResolutionCapable