将鼠标保持在 Swift 范围内
Keep mouse within area in Swift
我试图阻止鼠标光标离开屏幕的特定区域。我找不到执行此操作的本机方法,所以我尝试手动执行此操作。
到目前为止我有这个:
NSEvent.addGlobalMonitorForEvents(matching: [.mouseMoved, .leftMouseDragged], handler: {(event: NSEvent) in
let x = event.locationInWindow.flipped.x;
let y = event.locationInWindow.flipped.y;
if (x <= 100) {
CGWarpMouseCursorPosition(CGPoint(x: 100, y: y))
}
})
// elsewhere to flip y coordinates
extension NSPoint {
var flipped: NSPoint {
let screenFrame = (NSScreen.main?.frame)!
let screenY = screenFrame.size.height - self.y
return NSPoint(x: self.x, y: screenY)
}
}
这会阻止光标离开 X 轴。伟大的。 但是它也会阻止光标在 X=100 处沿 y 轴滑动。
所以我尝试添加增量:
NSEvent.addGlobalMonitorForEvents(matching: [.mouseMoved, .leftMouseDragged], handler: {(event: NSEvent) in
let x = event.locationInWindow.flipped.x;
let y = event.locationInWindow.flipped.y;
let deltaY = event.deltaY;
if (x <= 100) {
CGWarpMouseCursorPosition(CGPoint(x: 100, y: y + deltaY))
}
})
现在它确实沿 Y 轴滑动。但是加速还差得远,太快了。我没有得到的是,如果我尝试做 y - deltaY
它会像我预期的那样滑动,但是 reversed:
NSEvent.addGlobalMonitorForEvents(matching: [.mouseMoved, .leftMouseDragged], handler: {(event: NSEvent) in
let x = event.locationInWindow.flipped.x;
let y = event.locationInWindow.flipped.y;
let deltaY = event.deltaY;
if (x <= 100) {
CGWarpMouseCursorPosition(CGPoint(x: 100, y: y - deltaY))
}
})
现在光标以适当的加速度沿 X=100 处的 Y 轴滑动(就像在屏幕边缘滑动光标),但它是相反的。向上移动鼠标,向下移动光标。
如何在我的自定义区域的边缘以正确的方向正确平滑地滑动光标?
或者是否有更好的方法来实现我想要做的事情?
我明白了。我需要减去之前的增量。
所以现在我有了这个:
var oldDeltaX: CGFloat = 0;
var oldDeltaY: CGFloat = 0;
NSEvent.addGlobalMonitorForEvents(matching: [.mouseMoved, .leftMouseDragged, .rightMouseDragged], handler: {(event: NSEvent) in
let deltaX = event.deltaX - oldDeltaX;
let deltaY = event.deltaY - oldDeltaY;
let x = event.locationInWindow.flipped.x;
let y = event.locationInWindow.flipped.y;
let window = (NSScreen.main?.frame.size)!;
let width = CGFloat(1920);
let height = CGFloat(1080);
let widthCut = (window.width - width) / 2;
let heightCut = (window.height - height) / 2;
let xPoint = clamp(x + deltaX, minValue: widthCut, maxValue: window.width - widthCut);
let yPoint = clamp(y + deltaY, minValue: heightCut, maxValue: window.height - heightCut);
oldDeltaX = xPoint - x;
oldDeltaY = yPoint - y;
CGWarpMouseCursorPosition(CGPoint(x: xPoint, y: yPoint));
});
public func clamp<T>(_ value: T, minValue: T, maxValue: T) -> T where T : Comparable {
return min(max(value, minValue), maxValue)
}
extension NSPoint {
var flipped: NSPoint {
let screenFrame = (NSScreen.main?.frame)!
let screenY = screenFrame.size.height - self.y
return NSPoint(x: self.x, y: screenY)
}
}
这会将鼠标限制在 1920x1080 的显示区域中。
我发现 Godot 的源代码是很好的资源:https://github.com/godotengine/godot/blob/51a00c2855009ce4cd6475c09209ebd22641f448/platform/osx/display_server_osx.mm#L1087
这是最好的或最有效的方法吗?我不知道,但它有效。
我试图阻止鼠标光标离开屏幕的特定区域。我找不到执行此操作的本机方法,所以我尝试手动执行此操作。
到目前为止我有这个:
NSEvent.addGlobalMonitorForEvents(matching: [.mouseMoved, .leftMouseDragged], handler: {(event: NSEvent) in
let x = event.locationInWindow.flipped.x;
let y = event.locationInWindow.flipped.y;
if (x <= 100) {
CGWarpMouseCursorPosition(CGPoint(x: 100, y: y))
}
})
// elsewhere to flip y coordinates
extension NSPoint {
var flipped: NSPoint {
let screenFrame = (NSScreen.main?.frame)!
let screenY = screenFrame.size.height - self.y
return NSPoint(x: self.x, y: screenY)
}
}
这会阻止光标离开 X 轴。伟大的。 但是它也会阻止光标在 X=100 处沿 y 轴滑动。
所以我尝试添加增量:
NSEvent.addGlobalMonitorForEvents(matching: [.mouseMoved, .leftMouseDragged], handler: {(event: NSEvent) in
let x = event.locationInWindow.flipped.x;
let y = event.locationInWindow.flipped.y;
let deltaY = event.deltaY;
if (x <= 100) {
CGWarpMouseCursorPosition(CGPoint(x: 100, y: y + deltaY))
}
})
现在它确实沿 Y 轴滑动。但是加速还差得远,太快了。我没有得到的是,如果我尝试做 y - deltaY
它会像我预期的那样滑动,但是 reversed:
NSEvent.addGlobalMonitorForEvents(matching: [.mouseMoved, .leftMouseDragged], handler: {(event: NSEvent) in
let x = event.locationInWindow.flipped.x;
let y = event.locationInWindow.flipped.y;
let deltaY = event.deltaY;
if (x <= 100) {
CGWarpMouseCursorPosition(CGPoint(x: 100, y: y - deltaY))
}
})
现在光标以适当的加速度沿 X=100 处的 Y 轴滑动(就像在屏幕边缘滑动光标),但它是相反的。向上移动鼠标,向下移动光标。
如何在我的自定义区域的边缘以正确的方向正确平滑地滑动光标?
或者是否有更好的方法来实现我想要做的事情?
我明白了。我需要减去之前的增量。
所以现在我有了这个:
var oldDeltaX: CGFloat = 0;
var oldDeltaY: CGFloat = 0;
NSEvent.addGlobalMonitorForEvents(matching: [.mouseMoved, .leftMouseDragged, .rightMouseDragged], handler: {(event: NSEvent) in
let deltaX = event.deltaX - oldDeltaX;
let deltaY = event.deltaY - oldDeltaY;
let x = event.locationInWindow.flipped.x;
let y = event.locationInWindow.flipped.y;
let window = (NSScreen.main?.frame.size)!;
let width = CGFloat(1920);
let height = CGFloat(1080);
let widthCut = (window.width - width) / 2;
let heightCut = (window.height - height) / 2;
let xPoint = clamp(x + deltaX, minValue: widthCut, maxValue: window.width - widthCut);
let yPoint = clamp(y + deltaY, minValue: heightCut, maxValue: window.height - heightCut);
oldDeltaX = xPoint - x;
oldDeltaY = yPoint - y;
CGWarpMouseCursorPosition(CGPoint(x: xPoint, y: yPoint));
});
public func clamp<T>(_ value: T, minValue: T, maxValue: T) -> T where T : Comparable {
return min(max(value, minValue), maxValue)
}
extension NSPoint {
var flipped: NSPoint {
let screenFrame = (NSScreen.main?.frame)!
let screenY = screenFrame.size.height - self.y
return NSPoint(x: self.x, y: screenY)
}
}
这会将鼠标限制在 1920x1080 的显示区域中。
我发现 Godot 的源代码是很好的资源:https://github.com/godotengine/godot/blob/51a00c2855009ce4cd6475c09209ebd22641f448/platform/osx/display_server_osx.mm#L1087
这是最好的或最有效的方法吗?我不知道,但它有效。