macos - 自定义 NSStatusItem 和 NSView 无法可靠地接收 NSTrackingEvents

标签 macos cocoa mouseevent nsstatusitem nstrackingarea

我有一个仅状态栏项目的应用程序,我试图在鼠标悬停时显示面板。我已经连接了自定义状态项(和关联的 View )并正在工作,但跟踪矩形仅在每十几次启动时接收事件。这让我相信某个地方发生了竞争条件,但我找不到它。在我的自定义状态栏项目 View 中:

- (id)initWithStatusItem:(NSStatusItem *)statusItem {
    CGFloat itemWidth = [statusItem length];
    CGFloat itemHeight = [[NSStatusBar systemStatusBar] thickness];
    NSRect itemRect = NSMakeRect(0.0, 0.0, itemWidth, itemHeight);
    NSLog(@"itemRect: %@", NSStringFromRect(itemRect));

    if ((self = [super initWithFrame:itemRect])) {
        _statusItem = statusItem;
        _statusItem.view = self;

        NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveAlways;
        NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:itemRect
                                                                    options:options
                                                                      owner:self
                                                                   userInfo:nil];
        [self addTrackingArea:trackingArea];

        [self.window setIgnoresMouseEvents:NO];
        [self.window setAcceptsMouseMovedEvents:YES];

        self.wantsLayer = YES;
    }
    return self;
}

- (void)mouseEntered:(NSEvent *)theEvent {
    [[NSNotificationCenter defaultCenter] postNotificationName:UAStatusItemMouseEnteredNotification object:nil];
}

- (void)mouseExited:(NSEvent *)theEvent {
    [[NSNotificationCenter defaultCenter] postNotificationName:UAStatusItemMouseExitedNotification object:nil];
}

在大多数启动中,应用程序不会响应跟踪鼠标事件,但时常会正确、完整地调用 mouseEntered:mouseExited: 方法让我困惑。这是怎么回事,我做错了什么?




编辑 2012 年 7 月 17 日
我根据@Streams的答案更改了代码,但看到了同样的问题:

- (id)initWithStatusItem:(NSStatusItem *)statusItem {
    CGFloat itemWidth = [statusItem length];
    CGFloat itemHeight = [[NSStatusBar systemStatusBar] thickness];
    NSRect itemRect = NSMakeRect(0.0, 0.0, itemWidth, itemHeight);
    NSLog(@"itemRect: %@", NSStringFromRect(itemRect));

    if ((self = [super initWithFrame:itemRect])) {
        _statusItem = statusItem;
        _statusItem.view = self;            

        [self updateTrackingAreas];

        [self.window setIgnoresMouseEvents:NO];
        [self.window setAcceptsMouseMovedEvents:YES];

        self.wantsLayer = YES;
    }
    return self;
}

- (void)updateTrackingAreas {

    if (self.trackingArea)
        [self removeTrackingArea:self.trackingArea];

    [super updateTrackingAreas];

    self.trackingArea = [[NSTrackingArea alloc] initWithRect:CGRectZero
                                                     options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingInVisibleRect | NSTrackingActiveAlways
                                                       owner:self
                                                    userInfo:nil];
    [self addTrackingArea:self.trackingArea];
}




编辑 2012 年 7 月 18 日
这是准系统sample project它使用一个众所周知的 github 项目(由 @Stream 编写)来显示问题。它无法可靠地接收鼠标悬停事件(如果有的话)。

最佳答案

我提出了 DTS 请求,让 Apple 查看此内容。以下是回复:

...you are using full screen in Xcode when starting your app. I wasn't doing this [before], but I now can reproduce the issue. From what I can tell it only happens when your app is started from full screen mode in Xcode. Your users won't be starting the app this way. This is a problem with AppKit's fullScreen mode, and not necessarily with your code.

关于macos - 自定义 NSStatusItem 和 NSView 无法可靠地接收 NSTrackingEvents,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11525426/

相关文章:

macos - 在 Mac OS X 10.6.3 下保存 PDF 时应用 Quartz 滤镜

objective-c - NSTextFieldCell 委托(delegate)?

java - 如何使MouseClicked事件在java中工作

javascript - 有没有办法触发mousemove并获取event.pageX,event.pageY?

javascript - d3.js voronoi 事件。当光标正好位于点上方时,鼠标悬停似乎消失

macos - PostreSQL93 + postgis2 使用 MacPorts

macos - 重命名子目录中的文件名

Python dateutil rrule错误

objective-c - 添加方法后应用程序无法启动(Xcode 7.2)

objective-c - 如何取消选择 cocoa 中的单选按钮