diff --git a/Sources/Kapture/App.swift b/Sources/Kapture/App.swift
index 0e94f23..c336588 100644
--- a/Sources/Kapture/App.swift
+++ b/Sources/Kapture/App.swift
@@ -48,6 +48,13 @@ struct MenuView: View {
Divider()
+ Button("Copy Diagnostics") {
+ let diag = CaptureController.shared.diagnostics()
+ let pasteboard = NSPasteboard.general
+ pasteboard.clearContents()
+ pasteboard.setString(diag, forType: .string)
+ }
+
Button(LoginItem.isEnabled ? "Disable Launch at Login" : "Launch at Login") {
if !LoginItem.toggle() {
let alert = NSAlert()
diff --git a/Sources/Kapture/CaptureController.swift b/Sources/Kapture/CaptureController.swift
index de16215..6db5f73 100644
--- a/Sources/Kapture/CaptureController.swift
+++ b/Sources/Kapture/CaptureController.swift
@@ -10,6 +10,38 @@ final class CaptureController: NSObject {
private var previousApp: NSRunningApplication?
private var overlayIDs: [Int] = []
+ /// Diagnostic snapshot for "Copy Diagnostics" menu item.
+ func diagnostics() -> String {
+ var lines: [String] = []
+ lines.append("Kapture diagnostics")
+ for (i, s) in NSScreen.screens.enumerated() {
+ let scale = s.backingScaleFactor
+ let cgID = (s.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? NSNumber)?.uint32Value ?? 0
+ lines.append("screen[\(i)]: frame=\(s.frame) scale=\(scale) backingSize=\(s.frame.width*scale)x\(s.frame.height*scale) cgID=\(cgID)")
+ }
+ if #available(macOS 14.0, *) {
+ Task {
+ if let content = try? await SCShareableContent.current {
+ for (i, d) in content.displays.enumerated() {
+ lines.append("SCDisplay[\(i)]: frame=\(d.frame) width=\(d.width)x\(d.height) id=\(d.displayID)")
+ }
+ } else {
+ lines.append("SCShareableContent: unavailable (no Screen Recording permission?)")
+ }
+ let text = lines.joined(separator: "\n")
+ let pb = NSPasteboard.general
+ pb.clearContents()
+ pb.setString(text, forType: .string)
+ }
+ } else {
+ let text = lines.joined(separator: "\n")
+ let pb = NSPasteboard.general
+ pb.clearContents()
+ pb.setString(text, forType: .string)
+ }
+ return lines.joined(separator: "\n")
+ }
+
func begin() {
guard !isSelecting else { return }
guard PermissionManager.isGranted else {
diff --git a/build-app.sh b/build-app.sh
index 93a1f8a..3180131 100755
--- a/build-app.sh
+++ b/build-app.sh
@@ -108,9 +108,9 @@ cat > "$APP/Contents/Info.plist" <<'PLIST'
CFBundleIconFile
Icon
CFBundleShortVersionString
- 1.1.5
+ 1.1.6
CFBundleVersion
- 15
+ 16
LSUIElement
NSHighResolutionCapable