3

enter image description here My app has NSStatusBarButton on status bar (where the time, wifi etc) The user can tap to show/hide the app.

to hide :

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

to show :

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

The problem is when I show the app, the window buttons (close, maximise ) are flickering their colour, then turn gray. I can see in logs of events the application is active and it responds to mouse scroll.

Only if I activate OTHER app with the mouse and return back to my app, the buttons will be active with there colour (red and green)

More info :
1. the app is created in code (not storyboard) besided the mainMenu.xib.
2. when I tap the image menu status bar to UNHIDE the app, in debug mode=on, the code is break with this error :

"error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x4e47432b2b00). The process has been returned to the state before expression evaluation."

Any ideas where to continue from here ?

user1105951
  • 2,259
  • 2
  • 34
  • 55

2 Answers2

2

Thanks to the help of Asperi, the create sample code to narrow the diffrences, the problem was enabling this override :

-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
{
    return YES;
}
  1. disable it and I could unhide/hide the app with the 3 buttons being activated with their color.

  2. also this [window orderOut] was important call.

user1105951
  • 2,259
  • 2
  • 34
  • 55
0

Here is AppDelegate from project created from scratch. XIB file was not modified. All manipulations with StatusBar is here.

Note: no crash/exception is observed with provided code snapshot

During demo just clicked several times on added X status bar button:

Activate/Deactivate on NSStatusBarButton click

Update: added variant with controller & window created programmatically, nothing except main menu left in XIB... Tested as worked. Xcode 11.2 / macOS 10.15 Catalina

#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

Variant with window created in XIB by project template

#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
  • 228,894
  • 20
  • 464
  • 690
  • thanks for the help. In my case I'm using NSWindowController. calling [self.windowController.window orderOut:nil]; will quit the app. I tried to override windowShouldClose but it's not called. – user1105951 Jan 06 '20 at 15:31
  • I cannot test now, but try resignKeyWindow. – Asperi Jan 06 '20 at 15:48
  • I've tested `resignKeyWindow`, as well as with `NSWindowController` and it works. Probably you've configured to close the app on last window close, because I do not observe such behaviour. Actually, `orderOut` should not quit application... – Asperi Jan 06 '20 at 16:13
  • 1. my app not quit when pressing the x button ( I return "NO" when using NSWindowController delegate windowShouldClose). 2. Can you explain where to test the resignKeyWindow ? tnx – user1105951 Jan 06 '20 at 16:29
  • I updated my code above, you can replace `[self.windowController.window orderOut:nil]`, with `[self.windowController.window resignKeyWindow]`. – Asperi Jan 06 '20 at 16:31
  • have the same problem. when UNHide, this line "[NSApp activateIgnoringOtherApps:true];" make exception. I have no idea how to debug it. but If try to guess, its something the different from the normal way. I'm building the window, window controller and nsviewcontroller in code. – user1105951 Jan 06 '20 at 16:40
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/205458/discussion-between-asperi-and-user1105951). – Asperi Jan 06 '20 at 16:41
  • the exception break only when Xcode debug is on. and when the window is shown, the 3 buttons are gray. – user1105951 Jan 06 '20 at 16:41
  • Updated with only programmatic creation. Pay attention on window styles, they are important. That's it. – Asperi Jan 06 '20 at 17:06