Skip to content

Commit df485cb

Browse files
Track Mouse Drag Outside View (#108)
### Description Fixes a bug that didn't allow the view to track drags outside it's bounds. Users can now drag selections over other views and outside the window. ### Related Issues * closes #100 * closes CodeEditApp/CodeEditSourceEditor#316 ### Checklist - [x] I read and understood the [contributing guide](https://github.com/CodeEditApp/CodeEdit/blob/main/CONTRIBUTING.md) as well as the [code of conduct](https://github.com/CodeEditApp/CodeEdit/blob/main/CODE_OF_CONDUCT.md) - [x] The issues this PR addresses are related to each other - [x] My changes generate no new warnings - [x] My code builds and runs on my machine - [x] My changes are all related to the related issue above - [x] I documented my code ### Screenshots https://github.com/user-attachments/assets/ffbad5bf-5a56-4ef8-91f7-c5a9bb725208
1 parent 3f96de5 commit df485cb

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

Sources/CodeEditTextView/TextView/TextView+Mouse.swift

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,19 +87,27 @@ extension TextView {
8787
return
8888
}
8989

90+
// We receive global events because our view received the drag event, but we need to clamp the potentially
91+
// out-of-bounds positions to a position our layout manager can deal with.
92+
let locationInWindow = convert(event.locationInWindow, from: nil)
93+
let locationInView = CGPoint(
94+
x: max(0.0, min(locationInWindow.x, frame.width)),
95+
y: max(0.0, min(locationInWindow.y, frame.height))
96+
)
97+
9098
if mouseDragAnchor == nil {
91-
mouseDragAnchor = convert(event.locationInWindow, from: nil)
99+
mouseDragAnchor = locationInView
92100
super.mouseDragged(with: event)
93101
} else {
94102
guard let mouseDragAnchor,
95103
let startPosition = layoutManager.textOffsetAtPoint(mouseDragAnchor),
96-
let endPosition = layoutManager.textOffsetAtPoint(convert(event.locationInWindow, from: nil)) else {
104+
let endPosition = layoutManager.textOffsetAtPoint(locationInView) else {
97105
return
98106
}
99107

100108
let modifierFlags = event.modifierFlags.intersection(.deviceIndependentFlagsMask)
101109
if modifierFlags.contains(.option) {
102-
dragColumnSelection(mouseDragAnchor: mouseDragAnchor, event: event)
110+
dragColumnSelection(mouseDragAnchor: mouseDragAnchor, locationInView: locationInView)
103111
} else {
104112
dragSelection(startPosition: startPosition, endPosition: endPosition, mouseDragAnchor: mouseDragAnchor)
105113
}
@@ -197,9 +205,7 @@ extension TextView {
197205
}
198206
}
199207

200-
private func dragColumnSelection(mouseDragAnchor: CGPoint, event: NSEvent) {
201-
// Drag the selection and select in columns
202-
let eventLocation = convert(event.locationInWindow, from: nil)
203-
selectColumns(betweenPointA: eventLocation, pointB: mouseDragAnchor)
208+
private func dragColumnSelection(mouseDragAnchor: CGPoint, locationInView: CGPoint) {
209+
selectColumns(betweenPointA: mouseDragAnchor, pointB: locationInView)
204210
}
205211
}

0 commit comments

Comments
 (0)