window 从状态栏取消隐藏和激活应用程序时按钮变灰

window buttons are greyed when unhide and active the app from status bar

我的应用程序在状态栏上有 NSStatusBarButton(时间、wifi 等) 用户可以点击 show/hide 应用程序。

隐藏:

[[NSApplication sharedApplication] hide:self];
[[NSApplication sharedApplication] deactivate];

显示:

[self.windowController.window makeKeyAndOrderFront:self];
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];

问题是当我显示应用程序时,window 按钮(关闭、最大化)的颜色在闪烁,然后变成灰色。 我可以在事件日志中看到应用程序处于活动状态并且它响应鼠标滚动。

只有当我用鼠标激活其他应用程序并return回到我的应用程序时,按钮才会激活并显示颜色(红色和绿色)

更多信息:
1.应用程序是在主菜单.xib.
旁边的代码(不是故事板)中创建的 2. 当我点击图像菜单状态栏以取消隐藏应用程序时,在调试模式=打开时,代码因以下错误而中断:

”错误:执行被中断,原因:EXC_BAD_ACCESS(代码=1,地址=0x4e47432b2b00)。 进程已 return 进入表达式评估前的状态。"

有什么可以从这里继续的想法吗?

这里是 AppDelegate 从头开始​​创建的项目。 XIB 文件没有被修改。 StatusBar 的所有操作都在这里。

注意:使用提供的代码快照

没有观察到crash/exception

在演示过程中,只需点击几次添加的 X 状态栏按钮:

更新:添加了带有控制器的变体 & window 以编程方式创建,除了 XIB 中留下的主菜单外什么都没有...测试正常。 Xcode 11.2 / macOS 10.15 卡特琳娜

#import "AppDelegate.h"

@interface AppDelegate ()

@property (strong) NSWindowController *controller;
@property (strong) NSStatusItem *statusItem;
@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

    NSWindow *window = [[NSWindow alloc] initWithContentRect:
         NSMakeRect(0, 0, 480, 300) 
         styleMask:(NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable) 
         backing:NSBackingStoreBuffered defer:NO];
    [window setFrameAutosaveName:@"MyWindow"];
    [window setTitle:@"Testing hide-unhide"];

    self.controller = [[NSWindowController alloc] initWithWindow:window];
    [self.controller showWindow:nil];
    [self.controller.window center]; // << for simplicity


    // Insert code here to initialize your application
    NSStatusBar *statusBar = [NSStatusBar systemStatusBar];
    self.statusItem = [statusBar statusItemWithLength:16];

    NSStatusBarButton *button = self.statusItem.button;
    [button setTitle:@"X"];
    [button setTarget:self];
    [button setAction:@selector(hideUnhide:)];
}

- (void)hideUnhide:(id)sender
{
  if([[NSApplication sharedApplication] isHidden])
  {
      [NSApp activateIgnoringOtherApps:true];
      [self.controller.window makeKeyAndOrderFront:nil];
  } else {
      [self.controller.window orderOut:nil];
      if (NSApp.isActive) {
          [NSApp deactivate];
      }
      [NSApp hide:nil];
  }
}

@end

项目模板在 XIB 中创建的 window 变体

#import "AppDelegate.h"

@interface AppDelegate ()

@property (weak) IBOutlet NSWindow *window;
@property (strong) NSStatusItem *statusItem;
@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Insert code here to initialize your application
    NSStatusBar *statusBar = [NSStatusBar systemStatusBar];
    self.statusItem = [statusBar statusItemWithLength:16];

    NSStatusBarButton *button = self.statusItem.button;
    [button setTitle:@"X"];
    [button setTarget:self];
    [button setAction:@selector(hideUnhide:)];

}

- (void)hideUnhide:(id)sender
{
    [self.window orderOut:nil]; // drops current window state
    // [self.window resignKeyWindow]; // << also works
    if (NSApp.isActive) {
        [NSApp deactivate];
        [NSApp hide:nil];
    } else {

        [NSApp activateIgnoringOtherApps:true];
        [self.window makeKeyAndOrderFront:nil];
    }
}

@end

感谢Asperi的帮助,创建示例代码来缩小差异, 问题是启用此覆盖:

-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
{
    return YES;
}
  1. 禁用它,然后我可以 unhide/hide 应用程序的 3 个按钮被激活并使用它们的颜色。

  2. 这个 [window orderOut] 也是一个重要的电话。