Skip to content

Commit ed2538a

Browse files
committed
Fix: Refine logic for right-click paste and left-click copy actions
1 parent e241718 commit ed2538a

1 file changed

Lines changed: 9 additions & 20 deletions

File tree

src/MouseInterceptor.swift

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,13 @@ func eventTapCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent,
6767
}
6868
}
6969
}
70-
7170
return false
7271
}
7372

7473
// 1. Handle Right Click -> Paste (Cmd+V)
7574
if type == .rightMouseDown {
76-
// Check Setting
7775
if UserDefaults.standard.bool(forKey: "pasteOnRightClick") {
78-
// Only paste if click is strictly on a Terminal window (not obscured by Dock)
76+
// Only paste if click is strictly on a Terminal window
7977
if !isClickInTerminalWindow(event.location) {
8078
if isDebug { print("DEBUG: Right click outside/obscured, ignoring.") }
8179
return Unmanaged.passUnretained(event)
@@ -102,52 +100,43 @@ func eventTapCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent,
102100

103101
// 2. Track Mouse Down
104102
if type == .leftMouseDown {
105-
// Only track if click is actually in Terminal window
106103
if isClickInTerminalWindow(event.location) {
107104
lastMouseDownPoint = event.location
108105
} else {
109-
lastMouseDownPoint = .zero // Reset to prevent false triggers
106+
lastMouseDownPoint = .zero
110107
}
111108
return Unmanaged.passUnretained(event)
112109
}
113110

114111
// 3. Handle Left Mouse Up -> Copy (Cmd+C)
115112
if type == .leftMouseUp {
116-
// Check Setting
117113
if !UserDefaults.standard.bool(forKey: "copyOnSelect") {
118114
return Unmanaged.passUnretained(event)
119115
}
120116

121-
// Only copy if release is in Terminal window
122-
if !isClickInTerminalWindow(event.location) {
123-
return Unmanaged.passUnretained(event)
124-
}
117+
// FIX: Removed the check !isClickInTerminalWindow(event.location)
118+
// If the drag started inside the terminal (lastMouseDownPoint != .zero),
119+
// we should respect the selection even if the mouse release happens outside.
125120

126-
// Skip if mouse down was outside Terminal (lastMouseDownPoint was reset)
127121
if lastMouseDownPoint == .zero {
128122
return Unmanaged.passUnretained(event)
129123
}
130124

131125
let currentPoint = event.location
132-
// Calculate drag distance
133126
let dist = hypot(currentPoint.x - lastMouseDownPoint.x, currentPoint.y - lastMouseDownPoint.y)
134-
135-
// Get Click Count (1 = single, 2 = double, 3 = triple)
136127
let clickCount = event.getIntegerValueField(.mouseEventClickState)
137128

138-
// Trigger Copy if:
139-
// A) User dragged more than 5 pixels (Manual selection)
140-
// B) User Double-clicked (Word selection) or Triple-clicked (Line selection)
129+
// Reset lastMouseDownPoint to avoid stale state
130+
lastMouseDownPoint = .zero
131+
132+
// Trigger Copy if dragged > 5px OR Double/Triple Click
141133
if dist > 5.0 || clickCount >= 2 {
142134

143135
if isDebug {
144136
print("DEBUG: Selection Detected (Drag: \(Int(dist))px, Clicks: \(clickCount)). Queuing Copy...")
145137
}
146138

147-
// Wait 0.01s (reduced from 0.25s) for Terminal to finalize the visual selection
148-
// This ensures it feels "instant" (10ms) but is reliably processed after selection logic.
149139
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
150-
// Ensure Terminal is still focused
151140
if NSWorkspace.shared.frontmostApplication?.bundleIdentifier == "com.apple.Terminal" {
152141

153142
let source = CGEventSource(stateID: .hidSystemState)

0 commit comments

Comments
 (0)