Top Left Menu Bar Is Frozen when Main Window Shows Up - objective-c

I build a Menu Bar App. When I click on a menu item. Main Window will shows up in the center on the screen. The problem is every first time main window shows up, the top left menus including file, edit, help, etc (including the Apple Icon). It's just frozen.
I can't click on any of the menu items. Until I click other app and then click my app's main window again, the top left menus will be clickable.
My users are not very happy about it, they want me to fix on the next release. Here is the code to show my app's main window.
- (void)showWindow {
[self.window makeKeyAndOrderFront:self];
[NSApp activateIgnoringOtherApps:YES];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
}
Given that self is my App Delegate and window is a instance NSWindow(my main window). A little help here please?

I had the same issue and tried many things. The answer was to add
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
into AppDelegate's
applicationWillFinishLaunching
Found the answer from this question Cocoa application menu bar not clickable

Related

NSPopover crashes on segue triggered programmatically, OSX, Xcode 8.2

I have a simple setup (OSX not iOS):
Two windows A and B. Window A is a splash screen, window B the main screen.
Flow is like this -> Window A on app start, opens window B on "New Project" button click.
Window B contains a button. Button is setup in IB to open a view within a popover (via segue). Segue on button click works as expected.
On some place i trigger that segue programatically (performSegueWithIdentifier) to open the same popover attached to the button. This works as expected.
[self performSegueWithIdentifier:#"showSHImportCSVPrefsViewController" sender:nil];
But: if i close window B which returns to window A and open window B again ("New project") the popover throws an error when triggered programatically even if the manual button click still works... im so confused...
[NSPopover showRelativeToRect:ofView:preferredEdge:]: view has no window. You must supply a view in a window.'
After going through the whole code it turned out it was an observer not killed.
So when i closed window B and re-opened it, the same observer was created again, triggering the programmatically segue call twice, leading to the above described situation.
Solution: removeObserver on - (void)dealloc

OS X Menubar application: How to bring window to front

I am developing a menubar-only application for OS X and I am struggeling to get a settings window to show up in front of other apps.
App setup
"Menubar-only application" means:
I removed the "Is Initial Controller" from the NSWindowController in the main storyboard file. The main storyboard's window is not used in my app
I added an NSMenu to the "Application Scene" in the main storyboard. This will become my menubar menu
I set LSUIElement to YES to hide the dock icon
I set LSBackgroundOnly to NO (see NSWindow makeKeyAndOrderFront makes window appear, but not Key or Front)
When the app starts, I create an NSStatusItem and add the NSMenu from the storyboard as its menu. This all works fine - the app starts, shows no window and no dock icon but a menubar item that contains the menu from the storyboard.
Settings window
I now wanted to add a settings window that is shown when a menubar entry is clicked. I therefore:
Created a new .xib-file and added an NSWindow to it
Created a custom NSWindowController that connects the outlets and actions
Instantiated the custom NSWindowController using initWithNibNamed: on app launch
When the "Settings"-entry from the menu is clicked, I then try to bring the settings window to front using:
[self.settingsWindowController.window center];
[self.settingsWindowController.window showWindow:self];
[self.settingsWindowController.window makeKeyAndOrderFront:NSApp];
The window is shown, but not brought to the front but rather hidden behind other apps.
Any ideas how to solve this? Thanks!
You need to call:
[NSApp activateIgnoringOtherApps:YES];
(This is one of the rare occasions where it's correct to pass YES to that method.)
For Swift you can use
NSApp.activate(ignoringOtherApps: true)
I know you're asking for obj-c and already received an answer, but just incase anyone is Googling for Swift 4 implementation.
In your class that extends NSWindowController define the function:
func bringToFront() {
self.window?.center()
self.window?.makeKeyAndOrderFront(nil)
NSApp.activate(ignoringOtherApps: true)
}
Then whenever you wanna bring it up, call bringToFront().

Cocoa HUD panel shows again after calling orderOut:

I'm using a NSPanel with HUD style to display some information.
There's a button inside the HUD panel, when the user clicks the button, I'll open a new window by calling:
[anotherWindowController showWindow:self];
[anotherWindowController.window makeKeyAndOrderFront];
And I want the panel disappear when the window shows, so I set the delegate of the main window, and in the windowDidResignMain callback, I called [hudPanel orderOut:nil].
The HUD panel did disappear (I can see it), but right after it closed, it reopens.
I've checked all possible orderFront: code, and none of them get called. So my hands are really tied. Is this a system level behaviour? Can anyone guide me through this?
EDIT:
I forgot to mention that, the button resides in a NSPopover. So, basically, there's a NSButton in the HUD panel. When user clicks the button, a NSPopover will show up, inside which, there's the button to bring up the new window.
Big thanks!
I had the problem. The following solved it:
[NSApp endSheet:yourPanel];
[yourPanel orderOut:self];
Use
[hudPanel performClose:nil]
(in Swift I have to use self instead of nil). I had a problem using orderOut with a popover and it was solved by using the above method.
Please add [hudPanel close] after [hudPanel orderOut:nil]
swift: hudPanel.close()
from the apple docs:
If the window is the key or main window, the window object immediately behind it is made key or main in its place. Calling orderOut(_:) causes the window to be removed from the screen, but does not cause it to be released. See the close() method for information on when a window is released.
Sometimes the window reappears during window controller inner logic, I think. I have an issue when long pressing keyboard button kills window, but shot keyDown event only hides it on the split second. After using close all goes smoothly.

Disabling Window Behind

These days, I develop iPad applications. Since I've run out of subjects to work on, I'm working on a simple OS X application to see how far I can go.
Anyway, what I want to do is show a Preferences window (PrefWindowController). It has a separate xib (PrefWindowController.xib) from MainMenu.xib. When it appears, I want the main window to go behind it. The following is what I have.
// AppDelegate.m
- (void)preferencesClicked:(id)sender {
if (!preferencesWindow) {
preferencesWindow = [[PrefWindowController alloc] initWithWindowNibName:#"PrefWindowController"];
}
[preferencesWindow showWindow:self];
}
// PrefWindowController.m
- (void)windowDidLoad {
[super windowDidLoad];
[NSApp runModalForWindow:self.window];
NSLog(#"Hello!?");
}
- (IBAction)closeClicked:(id)sender {
[NSApp stopModal];
[self close];
}
So I've learnt that I can use runModalForWindow to put the current window on top of the main window. The problem that I have is that this preferences window will reopen when I click on the close button (closeClicked). If I click on it again, it will close. If I open Preferences and click on the same button, it won't reopen. An interesting thing is that the application won't read NSLog(#"Hello!?") when the Preferences window first opens. It does when I clicked on the close button. Do you know what I'm doing wrong?
Thank you for your help.
Modal doesn't mean display on top. Modal means stop the user interacting with anything else other than this. It does this by creating a new run loop, which means that anything after runModelForWindow won't happen till after the modal window is closed. Exactly what you are seeing with the NSLog.
You probably don't want to use a modal window for preferences. The convention for OSX is that the main app window stays active when a preferences window is open.
If you just want to bring the window to the front, and don't care if the user later clicks on the main window to bring it to the front, then use -makeKeyAndOrderFront on the window you have. If on the other hand you want this preferences window to always be in front, then make it an NSPanel rather than an NSWindow.

how to make a window visible after close it?

My app is menu status bar app, I mean the app contains icon in menu status bar and a window. The icon in dock is hidden. what I need to implement is that after the user click the status bar icon, the app window shows up, but I don't know how to make a window visible programmingly. may be I have to use code like
[self.window show]
in my application delegate?
Try
[self.window makeKeyAndOrderFront:sender];
If you are calling from any action use sender.
In your case put nil in place of sender.