-SendEvent的行为与预期不符

时间:2013-08-03 21:48:10

标签: macos cocoa nswindow nsapplication nsevent

我有一个全屏透明窗口,显示在我的应用程序的主菜单上方。它ignoresMouseEvents设置为NO。尽管如此,为了接收鼠标点击,我添加了以下代码:

[NSEvent addLocalMonitorForEventsMatchingMask:NSLeftMouseDownMask handler:^(NSEvent *event) {
    [self click:event];
    return event;
}];

每当用户点击我的应用处于活动状态时,就会调用方法click

- (BOOL)click:(NSEvent *)event {
    NSPoint coordinate = [event locationInWindow];
    float ycoord = coordinate.y;
    float menuheight = [[NSApp mainMenu] menuBarHeight];
    float windowheight = [[NSApp mainWindow] frame].size.height;
    if (ycoord >= windowheight - menuheight && ![[NSApp mainWindow] ignoresMouseEvents]) {
        [[NSApp mainWindow] setIgnoresMouseEvents:YES];
        [NSApp sendEvent:event];
        NSLog(@"click");
        [[NSApp mainWindow] setIgnoresMouseEvents:NO];
        return YES;
    }
    return NO;
}

正如您所看到的,如果点击位于主菜单栏上,它会将主窗口的ignoresMouseEvents属性更改为YES,然后在sendEvent:中调用NSApplication。最后,它将主窗口的ignoresMouseEvents属性更改回NO。

但是,即使单击主菜单栏时日志确实显示“单击”,单击也无效。例如,如果单击菜单项(例如“文件”菜单项),则不会打开相应的菜单(在本例中为文件菜单)。

我做错了什么?

1 个答案:

答案 0 :(得分:2)

在您的应用甚至收到它之前,窗口服务器会决定事件所针对的窗口。在致电-sendEvent:时尚未决定。 -setIgnoresMouseEvents:的主要作用是通知窗口服务器,而不是Cocoa的内部,如何发送鼠标事件。

除了事件点击之类的东西,一旦你收到一个事件,重新定位就太晚了。

请注意,例如,NSEvent在您致电-window之前已经有关联的-sendEvent:-sendEvent:只是用它来发送它。

如果您想允许菜单栏中的点击,您应该调整窗口大小,使其不与菜单栏重叠,或者您应将其窗口级别设置为菜单栏后面。