有什么办法可以解决这个 NSTrackingArea 怪癖吗?

发布于 2024-10-19 10:17:33 字数 1736 浏览 1 评论 0原文

我这里有问题。我正在创建一个像这样的 NSTrackingArea

NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:[self frame] options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways owner:self userInfo:nil];
[self addTrackingArea:area];
[area release];

这工作得很好。然而,这里有一个问题。我将其设置如下:

-(void)mouseEntered:(NSEvent *)event {
    [self toggleDetail];
}
-(void)mouseExited:(NSEvent *)event {
    [self toggleDetail];
}

toggleDetail 基本上是这样的:

- (void)toggleDetail {
if (!attachedWindow) {
    NSPoint buttonPoint = NSMakePoint(NSMidX([conditionImage frame]),
                                      NSMidY([conditionImage frame]));
    attachedWindow = [[MAAttachedWindow alloc] initWithView:view 
                                            attachedToPoint:buttonPoint 
                                                   inWindow:[self window] 
                                                     onSide:12
                                                 atDistance:10.0];
    //config removed because of irrelevance
    [[self window] addChildWindow:attachedWindow ordered:NSWindowAbove];
} else {
    [[self window] removeChildWindow:attachedWindow];
    [attachedWindow orderOut:self];
    [attachedWindow release];
    attachedWindow = nil;
}

}

现在这是我的问题。当我的 MAAttachedWindow 关闭时,我将鼠标移到窗口上,它就会打开。花花公子。但是,只有当我将鼠标远离 MAAttachedWindow 时,它才有用。一旦我将鼠标移到它上面(仍然在主窗口上),它就开始猛烈地打开和关闭 MAAttachedWindow

原因如下:窗口一打开,跟踪区域就认为我的鼠标不再位于窗口上方,因为弹出窗口位于窗口前面。然而,一旦它删除弹出窗口,它就会认为我的鼠标再次位于它上面,从而再次创建并显示弹出窗口。因此这是一个无限循环。

我的问题是是否有办法解决这个问题,除非我的鼠标位于窗口和弹出窗口或类似窗口之外,否则它无法关闭窗口。有办法做到这一点吗?

I've got a problem here. I'm creating a NSTrackingArea like this:

NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:[self frame] options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways owner:self userInfo:nil];
[self addTrackingArea:area];
[area release];

This works quite fine. However, here's a problem. I have it set up like this:

-(void)mouseEntered:(NSEvent *)event {
    [self toggleDetail];
}
-(void)mouseExited:(NSEvent *)event {
    [self toggleDetail];
}

And toggleDetail is basically like this:

- (void)toggleDetail {
if (!attachedWindow) {
    NSPoint buttonPoint = NSMakePoint(NSMidX([conditionImage frame]),
                                      NSMidY([conditionImage frame]));
    attachedWindow = [[MAAttachedWindow alloc] initWithView:view 
                                            attachedToPoint:buttonPoint 
                                                   inWindow:[self window] 
                                                     onSide:12
                                                 atDistance:10.0];
    //config removed because of irrelevance
    [[self window] addChildWindow:attachedWindow ordered:NSWindowAbove];
} else {
    [[self window] removeChildWindow:attachedWindow];
    [attachedWindow orderOut:self];
    [attachedWindow release];
    attachedWindow = nil;
}

}

Now here's my problem. When my MAAttachedWindow is closed, and I move my mouse over the window, it opens. Dandy. However, it's only good when I keep my mouse away from the MAAttachedWindow. As soon as I move my mouse over it (while still over the main window) it starts to violently open and close the MAAttachedWindow.

Here's why: As soon as the window opens, the tracking area believes that my mouse isn't over the window anymore because the popup is in front of it. However, as soon as it removes the popup, then it thinks that my mouse is over it again, thus creating and showing the popup once more. Thus it's an endless loop.

My question is if there's a way around this, where it can not close the window unless my mouse is outside both the window and the popup or something similar. Is there a way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

作业与我同在 2024-10-26 10:17:33

请参阅-[NSWindow setIgnoresMouseEvents:]。

顺便说一句,使用覆盖窗口时要非常小心。它们的困难在于,您必须在创建它时为其提供绝对坐标,并且存在一个小竞争 - 父窗口可以在您获取其框架的时间和创建子窗口的时间之间移动。窗口移动由 Window Server 完成,并且可以独立于应用程序完成(这就是为什么您可以在应用程序进行沙滩球运动时移动窗口)。现在,这种问题很少见,但有可能而且很难正确解决。如果您在父窗口调整大小时尝试调整或移动子窗口,则问题更大。

现在我意识到这些都可能不适用于您,但如果适用,并且您可以想到使用子窗口的替代方法,我建议您使用它。

See -[NSWindow setIgnoresMouseEvents:].

By the way, be very careful with overlay windows. The difficulty with them is that you have to give it absolute coordinates when you create it and there’s a small race—the parent window can be moved between the time that you get its frame, and the time that you create the child window. Window moving is done by the Window Server and can be done independently of the application (that's why you can move a window when the application is beach balling). Now it’s very rare that this would be an issue, but it is possible and quite hard to fix it properly. It’s more of a problem if you’re trying to resize or move a child window when the parent window resizes.

Now I realise that none of this might apply to you, but if it does, and you can think of an alternative to using child windows, I would advise you to go with it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文