gpt4 book ai didi

objective-c - 在显示弹出窗口时保持 NSStatusBarButton 突出显示

转载 作者:太空狗 更新时间:2023-10-30 03:50:27 30 4
gpt4 key购买 nike

实际上所有 NSStatusItem 都已在 10.10 中弃用,底层 NSStatusBarButton 的行为似乎令人困惑。

目前我正在开发一个菜单栏应用程序。当用户单击应用程序的菜单栏图标时,我的应用程序委托(delegate)中的一个方法将通过目标操作调用,该方法显示带有一些信息的 NSPopover(如果它已经可见,则将其关闭)。

通常情况下,如果您已经将 NSMenu 与 NSStatusItem 相关联,那么当用户单击菜单栏图标时,该图标将一直突出显示为蓝色,直到菜单关闭。类似地,单击系统音量图标会弹出一个 slider 并将其图标突出显示为蓝色,直到包含该 slider 的 View 消失。

但是,由于我是打开 NSPopover 的人,系统反而会在鼠标按下时突出显示图标为蓝色,然后在调用我的方法后在鼠标抬起时将其恢复为正常。这意味着我似乎无法在该循环上做任何事情来保持高光。我希望图标在鼠标抬起时继续突出显示,并且只有在我告诉它时(即当我关闭弹出窗口时)才恢复正常。

我不知道该怎么做。我试过使用

[self.statusItem.button setHighlighted: YES];
//or [self.statusItem.button highlight: YES];

当我在我的应用委托(delegate)中收到鼠标弹起事件并打开弹出窗口时。问题是系统仍然有它,显然,从较早的鼠标按下时突出显示此帧/循环,并且在我将其设置为突出显示后,由于鼠标抬起,它立即将其设置为未突出显示。我可以通过将其封装在一个方法中并稍后使用计时器或延迟选择器运行该方法来解决这个问题。这允许我保持图标突出显示但引入了闪烁;当鼠标向下移动时,图标会自动突出显示,当鼠标向上移动时,它会在一帧内取消突出显示,然后我的方法会重新突出显示它。

我还想也许我可以使用已弃用的 setHighlightMode: 并将其设置为 NO 以防止图标在单击时自动突出显示,然后使用 setHighlighted :/highlighted: 手动设置它,但这也不起作用。同样,我想也许这也行得通:

 NSButtonCell* cell = (NSButtonCell*)self.statusItem.button.cell;
cell.highlightsBy = NSNoCellMask;

但无论点击它会自动突出显示图标,并在调用我的方法后立即取消突出显示。

基本上:

  1. The undesirable automatic highlighting behavior of NSStatusBarButton interferes with manually setting the highlight state, unless I delay manually setting it which introduces a short flicker.
  2. The only thing that seems to successfully disable this automatic behavior is the deprecated setHighlightMode:, but this seems to prevent all highlighting, manual or not.
  3. The only work around seems to be to add a subview to the NSButtonCell, add an event listener for mouse up and then set the highlight state of the superview as per here: NSStatusBarButton keep highlighted but I would think there'd be a simpler way to just... disable the automatic highlighting altogether.

tl;dr:有没有一种方法可以让我轻松地完全控制何时以及何时不突出显示我的菜单栏图标,以便我可以在显示 NSPopover 时让它自然突出显示?

最佳答案

我最终通过不设置 NSStatusItem 的操作选择器属性解决了这个问题。相反,我使用了 NSEventaddLocalMonitorForEventsMatchingMask:handler:。在处理程序 block 中,我检查 event.locationInWindow 是否在我的状态项的 .bounds 内。如果是这样,我发送 .action 将手动发送的消息,然后返回 nil 以防止事件被传递。如果它不在状态图标的范围内,我将返回 event 以便它正常传递。在我的点击处理方法中,当我的弹出窗口显示/关闭时,我使用 [self.statusItem.button highlight: YES/NO]

长话短说:

applicationDidFinishLaunching:

__block AppDelegate* appDelegate = self;
[NSEvent addLocalMonitorForEventsMatchingMask: NSEventMaskFromType(NSLeftMouseDown) handler:^NSEvent* (NSEvent* event){
if (NSPointInRect(event.locationInWindow, appDelegate.statusItem.button.bounds)){
[appDelegate clickedMenuBarIcon: event];
return nil;
}
return event;
}];

clickedMenuBarIcon: 中,我可以设置高亮状态。由于我在我的处理程序 block 中返回了 nil,它阻止了事件的传递,因此自动突出显示永远不会发生,我可以手动完成。


如果有任何与此相关的错误,我将不胜感激任何建议。

关于objective-c - 在显示弹出窗口时保持 NSStatusBarButton 突出显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31495755/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com