diff --git a/Sources/Kapture/CaptureController.swift b/Sources/Kapture/CaptureController.swift index 95e0691..e2cae29 100644 --- a/Sources/Kapture/CaptureController.swift +++ b/Sources/Kapture/CaptureController.swift @@ -262,9 +262,21 @@ final class CaptureController: NSObject { return nil } + /// System dialogs (permission prompts, System Settings) must always + /// receive their clicks even while we're selecting. + private func isSystemDialogFrontmost() -> Bool { + guard let front = NSWorkspace.shared.frontmostApplication else { return false } + let id = front.bundleIdentifier ?? "" + return id.hasPrefix("com.apple.security") || id.hasPrefix("com.apple.SystemSettings") || id == "com.apple.systempreferences" + } + /// Returns the event to pass through, or nil to consume it. func handleTap(_ type: CGEventType, _ event: CGEvent) -> CGEvent? { guard isSelecting else { return event } + if isSystemDialogFrontmost() { + CaptureController.log("tap: system dialog frontmost — passing through \(type)") + return event + } switch type { case .tapDisabledByUserInput, .tapDisabledByTimeout: diff --git a/Sources/Kapture/OverlayView.swift b/Sources/Kapture/OverlayView.swift index 3969558..8a59387 100644 --- a/Sources/Kapture/OverlayView.swift +++ b/Sources/Kapture/OverlayView.swift @@ -57,6 +57,23 @@ final class OverlayView: NSView { NSColor.black.withAlphaComponent(0.35).setFill() NSBezierPath(rect: bounds).fill() + // Esc hint — the only way out once clicks are consumed by the tap. + let hint = "Drag to select · hover + click a window to capture it · Esc to cancel" + let hintAttrs: [NSAttributedString.Key: Any] = [ + .font: NSFont.monospacedSystemFont(ofSize: 12, weight: .medium), + .foregroundColor: NSColor.white.withAlphaComponent(0.85), + ] + let hintSize = hint.size(withAttributes: hintAttrs) + let hintRect = NSRect( + x: (bounds.width - hintSize.width) / 2 - 10, + y: bounds.height - 46, + width: hintSize.width + 20, + height: hintSize.height + 12 + ) + NSColor.black.withAlphaComponent(0.65).setFill() + NSBezierPath(roundedRect: hintRect, xRadius: 8, yRadius: 8).fill() + hint.draw(at: NSPoint(x: hintRect.minX + 10, y: hintRect.minY + 6), withAttributes: hintAttrs) + guard let controller else { return } // Highlight the hovered window (rounded, like real window corners) diff --git a/build-app.sh b/build-app.sh index 04ab41e..9b3f421 100755 --- a/build-app.sh +++ b/build-app.sh @@ -108,9 +108,9 @@ cat > "$APP/Contents/Info.plist" <<'PLIST' CFBundleIconFile Icon CFBundleShortVersionString - 1.8.6 + 1.8.7 CFBundleVersion - 86 + 87 LSUIElement NSHighResolutionCapable