Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3078713f8f |
@@ -14,9 +14,9 @@ final class CaptureController: NSObject {
|
||||
// Selection state (driven by the event tap; AppKit global coordinates)
|
||||
private var marqueeStart: NSPoint?
|
||||
private(set) var marqueeRect: NSRect?
|
||||
private(set) var hoverWindow: (id: CGWindowID, frame: NSRect)?
|
||||
private(set) var hoverWindow: (id: CGWindowID, frame: NSRect, pid: Int)?
|
||||
var hoverFrame: NSRect? { hoverWindow?.frame }
|
||||
private var trackedWindows: [(id: CGWindowID, frame: NSRect)] = []
|
||||
private var trackedWindows: [(id: CGWindowID, frame: NSRect, pid: Int)] = []
|
||||
private var lastWindowScan = Date.distantPast
|
||||
private var eventTap: CFMachPort?
|
||||
|
||||
@@ -105,13 +105,17 @@ final class CaptureController: NSObject {
|
||||
|
||||
/// A window was picked from hover — capture it directly (real rounded
|
||||
/// corners come from the window's own alpha).
|
||||
private func finishWindowPick(_ windowID: CGWindowID, _ rect: NSRect) {
|
||||
private func finishWindowPick(_ windowID: CGWindowID, _ rect: NSRect, ownedRisk: Bool) {
|
||||
let ids = overlayIDs
|
||||
hideOverlays()
|
||||
isSelecting = false
|
||||
restorePreviousApp()
|
||||
DispatchQueue.main.async { [self] in
|
||||
capture(rect, excludingWindowIDs: ids, windowID: windowID)
|
||||
if ownedRisk {
|
||||
capture(rect, excludingWindowIDs: ids, roundedCorners: true)
|
||||
} else {
|
||||
capture(rect, excludingWindowIDs: ids, windowID: windowID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,11 +223,12 @@ final class CaptureController: NSObject {
|
||||
) as? [[String: Any]] else { trackedWindows = []; return }
|
||||
|
||||
let ownIDs = Set(overlayIDs)
|
||||
var found: [(id: CGWindowID, frame: NSRect)] = []
|
||||
var found: [(id: CGWindowID, frame: NSRect, pid: Int)] = []
|
||||
for info in list {
|
||||
guard let cid = info[kCGWindowNumber as String] as? CGWindowID,
|
||||
let bounds = info[kCGWindowBounds as String] as? [String: CGFloat],
|
||||
let layer = info[kCGWindowLayer as String] as? Int,
|
||||
let pid = info[kCGWindowOwnerPID as String] as? Int,
|
||||
layer == 0
|
||||
else { continue }
|
||||
if ownIDs.contains(Int(cid)) { continue }
|
||||
@@ -235,7 +240,7 @@ final class CaptureController: NSObject {
|
||||
)
|
||||
guard cgRect.width >= 80, cgRect.height >= 60 else { continue }
|
||||
let rect = Self.cgToAppKit(rect: cgRect)
|
||||
found.append((cid, rect))
|
||||
found.append((id: cid, frame: rect, pid: pid))
|
||||
}
|
||||
trackedWindows = found
|
||||
}
|
||||
@@ -248,7 +253,7 @@ final class CaptureController: NSObject {
|
||||
return NSRect(x: rect.origin.x, y: y, width: rect.width, height: rect.height)
|
||||
}
|
||||
|
||||
private func topmostWindowContaining(_ appKitPoint: NSPoint) -> (id: CGWindowID, frame: NSRect)? {
|
||||
private func topmostWindowContaining(_ appKitPoint: NSPoint) -> (id: CGWindowID, frame: NSRect, pid: Int)? {
|
||||
for entry in trackedWindows {
|
||||
if entry.frame.contains(appKitPoint) {
|
||||
return entry
|
||||
@@ -321,8 +326,14 @@ final class CaptureController: NSObject {
|
||||
CaptureController.log("tap: marquee complete \(rect)")
|
||||
finishSelection(rect)
|
||||
} else if let hover = hoverWindow {
|
||||
CaptureController.log("tap: window pick id=\(hover.id) \(hover.frame)")
|
||||
finishWindowPick(hover.id, hover.frame)
|
||||
// An overlapping window from the same app means this is an
|
||||
// owned popup — desktopIndependentWindow would composite the
|
||||
// parent too, so capture the screen crop instead.
|
||||
let ownedRisk = trackedWindows.contains {
|
||||
$0.id != hover.id && $0.pid == hover.pid && $0.frame.intersects(hover.frame)
|
||||
}
|
||||
CaptureController.log("tap: window pick id=\(hover.id) pid=\(hover.pid) ownedRisk=\(ownedRisk) \(hover.frame)")
|
||||
finishWindowPick(hover.id, hover.frame, ownedRisk: ownedRisk)
|
||||
} else {
|
||||
CaptureController.log("tap: click with no hover/marquee — cancel")
|
||||
cancelSelection()
|
||||
|
||||
+2
-2
@@ -108,9 +108,9 @@ cat > "$APP/Contents/Info.plist" <<'PLIST'
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>Icon</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.8.1</string>
|
||||
<string>1.8.2</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>81</string>
|
||||
<string>82</string>
|
||||
<key>LSUIElement</key>
|
||||
<true/>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
|
||||
Reference in New Issue
Block a user