此应用程序的目的是在24/7后台运行,并将鼠标锁定在屏幕中央。它与一系列Flash程序配合使用,以模拟鼠标的操纵杆式运动。我已经尝试使用内置在Cocoa / Quartz中的其他方法来实现此目的,但是这些方法都没有达到我的目的,因此这就是我必须这样做的方法。
我一直试图弄清楚为什么在看似随机的时间之后,该程序只是停止限制鼠标。该程序没有给出错误或类似信息,只是停止工作。强制退出屏幕的确说“无响应”,但是,我的许多鼠标修改脚本(包括该脚本)始终显示为“无响应”,并且它们可以正常运行。
这是代码:
code removed, check below for updated code.
最终更新
Ken Thomases给了我正确的答案,我已根据他的建议更新了代码。
这是我可以正常工作的最终代码(在我手动停止运行之前,该代码运行了12多个小时没有遇到任何麻烦):
#import <Cocoa/Cocoa.h>
#import <CoreMedia/CoreMedia.h>
int screen_width, screen_height;
struct event_tap_data_struct {
CFMachPortRef event_tap;
float speed_modifier;
};
CGEventRef
mouse_filter(CGEventTapProxy proxy, CGEventType type, CGEventRef event, struct event_tap_data_struct *);
int
screen_res(int);
int
main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
screen_width = screen_res(0);
screen_height = screen_res(1);
CFRunLoopSourceRef runLoopSource;
CGEventMask event_mask = kCGEventMaskForAllEvents;
CGSetLocalEventsSuppressionInterval(0);
CFMachPortRef eventTap;
struct event_tap_data_struct event_tap_data = {eventTap,0.2};
eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 0, event_mask, mouse_filter, &event_tap_data);
event_tap_data.event_tap = eventTap;
if (!eventTap) {
NSLog(@"Couldn't create event tap!");
exit(1);
}
runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, event_tap_data.event_tap, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
CGEventTapEnable(event_tap_data.event_tap, true);
CFRunLoopRun();
CFRelease(eventTap);
CFRelease(runLoopSource);
[pool release];
exit(0);
}
int
screen_res(int width_or_height) {
NSRect screenRect;
NSArray *screenArray = [NSScreen screens];
unsigned screenCount = (unsigned)[screenArray count];
for (unsigned index = 0; index < screenCount; index++)
{
NSScreen *screen = [screenArray objectAtIndex: index];
screenRect = [screen visibleFrame];
}
int resolution_array[] = {(int)CGDisplayPixelsWide(CGMainDisplayID()),(int)CGDisplayPixelsHigh(CGMainDisplayID())};
if(width_or_height==0){
return resolution_array[0];
}else {
return resolution_array[1];
}
}
CGEventRef
mouse_filter(CGEventTapProxy proxy, CGEventType type, CGEventRef event, struct event_tap_data_struct *event_tap_data) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
if (type == kCGEventTapDisabledByTimeout || type == kCGEventTapDisabledByUserInput) {
CGEventTapEnable(event_tap_data->event_tap,true);
return event;
} else if (type == kCGEventMouseMoved || type == kCGEventLeftMouseDragged || type == kCGEventRightMouseDragged || type == kCGEventOtherMouseDragged){
CGPoint point = CGEventGetLocation(event);
NSPoint old_point;
CGPoint target;
int tX = point.x;
int tY = point.y;
float oX = screen_width/2;
float oY = screen_height/2;
float dX = tX-oX;
float dY = tY-oY;
old_point.x = floor(oX); old_point.y = floor(oY);
dX*=2, dY*=2;
tX = round(oX + dX);
tY = round(oY + dY);
target = CGPointMake(tX, tY);
CGWarpMouseCursorPosition(old_point);
CGEventSetLocation(event,target);
}
[pool release];
return event;
}
(第一)更新:
该程序仍然崩溃,但是我现在已经将其作为可执行文件运行,并收到错误代码。
终止时,控制台将记录“ Segmentation Fault:11”。
我一直在尝试发现这意味着什么,但是这似乎是一个令人印象深刻的名词,而且我还没有磨练出一些有用的东西。
这是我正在使用的新代码:
#import <Cocoa/Cocoa.h>
#import <CoreMedia/CoreMedia.h>
int screen_width, screen_height;
struct event_tap_data_struct {
CFMachPortRef event_tap;
float speed_modifier;
};
CGEventRef
mouse_filter(CGEventTapProxy proxy, CGEventType type, CGEventRef event, struct event_tap_data_struct *);
int
screen_res(int);
int
main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
screen_width = screen_res(0);
screen_height = screen_res(1);
CFRunLoopSourceRef runLoopSource;
CGEventMask event_mask;
event_mask = CGEventMaskBit(kCGEventMouseMoved) | CGEventMaskBit(kCGEventLeftMouseDragged) | CGEventMaskBit(kCGEventRightMouseDragged) | CGEventMaskBit(kCGEventOtherMouseDragged);
CGSetLocalEventsSuppressionInterval(0);
CFMachPortRef eventTap;
CFMachPortRef *eventTapPtr = &eventTap;
struct event_tap_data_struct event_tap_data = {*eventTapPtr,0.2};
eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 0, event_mask, mouse_filter, &event_tap_data);
if (!eventTap) {
NSLog(@"Couldn't create event tap!");
exit(1);
}
runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
CGEventTapEnable(eventTap, true);
CFRunLoopRun();
CFRelease(eventTap);
CFRelease(runLoopSource);
[pool release];
exit(0);
}
int
screen_res(int width_or_height) {
NSRect screenRect;
NSArray *screenArray = [NSScreen screens];
unsigned screenCount = (unsigned)[screenArray count];
for (unsigned index = 0; index < screenCount; index++)
{
NSScreen *screen = [screenArray objectAtIndex: index];
screenRect = [screen visibleFrame];
}
int resolution_array[] = {(int)CGDisplayPixelsWide(CGMainDisplayID()),(int)CGDisplayPixelsHigh(CGMainDisplayID())};
if(width_or_height==0){
return resolution_array[0];
}else {
return resolution_array[1];
}
}
CGEventRef
mouse_filter(CGEventTapProxy proxy, CGEventType type, CGEventRef event, struct event_tap_data_struct *event_tap_data) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
if (type == kCGEventTapDisabledByTimeout || type == kCGEventTapDisabledByUserInput) {
CGEventTapEnable(event_tap_data->event_tap,true);
}
CGPoint point = CGEventGetLocation(event);
NSPoint old_point;
CGPoint target;
int tX = point.x;
int tY = point.y;
float oX = screen_width/2;
float oY = screen_height/2;
float dX = tX-oX;
float dY = tY-oY;
old_point.x = floor(oX); old_point.y = floor(oY);
dX*=2, dY*=2;
tX = round(oX + dX);
tY = round(oY + dY);
target = CGPointMake(tX, tY);
CGWarpMouseCursorPosition(old_point);
CGEventSetLocation(event,target);
[pool release];
return event;
}
最佳答案
您需要在事件抽头收到kCGEventTapDisabledByTimeout
或kCGEventTapDisabledByUserInput
时重新启用它。
更新:这是您的台词以及它们的工作方式(失败):
CFMachPortRef eventTap; // uninitialized value
CFMachPortRef *eventTapPtr = &eventTap; // pointer to eventTap
struct event_tap_data_struct event_tap_data = {*eventTapPtr,0.2}; // dereferences pointer, copying uninitialized value into struct
eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 0, event_mask, mouse_filter, &event_tap_data); // sets eventTap but has no effect on event_tap_data
关于objective-c - 分割故障11 | CGEventTap应用程序将在任意时间后停止处理鼠标事件。,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10365487/