我正尝试使用以下方式将LeftMouse重新映射为CTRL
:CGPoint mouseFlip( CGPoint pt ) {
return CGPointMake(pt.x, [NSScreen mainScreen].frame.size.height - pt.y);
}
_eventTap = CGEventTapCreate(
kCGHIDEventTap,
kCGHeadInsertEventTap,
kCGEventTapOptionDefault,
CGEventMaskBit(NSEventTypeMouseMoved) | CGEventMaskBit(NSEventTypeFlagsChanged),
(CGEventTapCallBack)_tapCallback,
(__bridge void *)(self)
);
:
CGEventRef _tapCallback(
CGEventTapProxy proxy,
CGEventType type,
CGEventRef event,
Intercept* listener
)
{
//Do not make the NSEvent here.
//NSEvent will throw an exception if we try to make an event from the tap timout type
@autoreleasepool {
if( type == kCGEventTapDisabledByTimeout ) {
NSLog(@"event tap has timed out, re-enabling tap");
[listener tapEvents];
return nil;
}
if( type != kCGEventTapDisabledByUserInput ) {
return [listener processEvent:event];
}
}
return event;
}
- (CGEventRef)processEvent:(CGEventRef)cgEvent
{
NSEvent* event = [NSEvent eventWithCGEvent:cgEvent];
switch( event.type ) {
case NSEventTypeMouseMoved:
CGPoint prev_mouse = [NSEvent mouseLocation];
int64_t dx = CGEventGetIntegerValueField(cgEvent, kCGMouseEventDeltaX);
int64_t dy = CGEventGetIntegerValueField(cgEvent, kCGMouseEventDeltaY);
CGPoint new_mouse = {
prev_mouse.x + dx,
prev_mouse.y - dy
};
:
/* awkward multi-screen bounds checking here */
:
CGEventRef dragEvent = CGEventCreateMouseEvent(
NULL,
kCGEventLeftMouseDragged, mouseFlip(new_mouse),
0
);
CGEventPost(kCGHIDEventTap, dragEvent);
CFRelease(dragEvent);
break;
:
在大多数情况下这是可行的。但是,我经常注意到鼠标滑行/滑行,就像在冰上行走一样。性能略有下降。
有人愿意批评这种方法吗?
我想知道dx
,dy
中是否存在一些细微的四舍五入问题。或者,如果事件以某种方式迷失了。
从prev_mouse
获取[NSEvent mouseLocation]
也许是不安全的?
我无法获得当前的鼠标位置有点烦人。我猜想[NSEvent mouseLocation]
仅在NSEventTypeMouseMoved
事件完成后得到更新。如果我只能访问新的当前位置,则可以省去/* awkward multi-screen bounds checking here */
。
另一种方法是执行以下操作的定期计时器:
timer = [NSTimer scheduledTimerWithTimeInterval: .01f
repeats: YES
block:
^(NSTimer *timer) {
if( ! self->ctrl_is_down )
return;
CGEventRef dragEvent = CGEventCreateMouseEvent(
NULL,
kCGEventLeftMouseDragged,
mouseFlip( [NSEvent mouseLocation] ),
0
);
CGEventPost(kCGHIDEventTap, dragEvent);
CFRelease(dragEvent);
}];
可以将这种方法提炼成可用的东西吗?
什么是正确的方法?
(也发布在Apple Dev Forums上)