How to wait for window to close inside a framework? - objective-c

I have to create a function into a framework which opens a window with a radio group and a button on it. When I click the button, the function should print out which radio was selected. I´m using a NSWindowController with xib file to show the Form.
The problem is, that the code continues running after showing the window.
So I tried a while loop with a property in my window which is set when I click the button.
But it does not work because I think the window is running in the same thread.
MyWindowController windowController = [[MyWindowController alloc initWithWindowNibName:#"MyWindow"];
[windowController showWindow:self];
while([windowController buttonClicked] == 0);
NSLog("Radio %# is selected!", [windowController selectedRadio]);
Do you have any idea how to wait for the window to close and than read out the data?
I hope you can help me.

You can add your self as delegate tao the window and listen for windowWillClosenotifications. That way you get informed when the windows is getting closed.
Note that you are not "waiting" on the window toi close, that wouldn't work without blocking the runloop, but you just sit idle until the delegate method is called. Also note that the window controller should be automatically a delegate to the window and thus could also be used for this.

Related

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.

Show a second window from a second .xib file in Xcode?

I am a complete noob with Xcode, but I am trying to make a small Mac application.
What I want happen, is that I press a button in the main window, and another window opens on top of that main window.
As I said, I am a complete noob, so I would prefer a step by step guide :)
It is quite simple, first of all you have to create a window with Xcode, then a WindowController after that you can link the Controller with your view(the Xib).
Then to open up a new window (lets say your window controller is called YourWindowController) just insert this code in the IBAction method that get fired by your button :
YourWindowController *controllerWindow =
[[YourWindowController alloc] initWithWindowNibName:#"You_Window_XIB"];
[controllerWindow showWindow:self];

close event NSWindow

I have an application, where a second NSWindow is opened by pressing a button. This new window is opened using [NSApp runModalForWindow:<myWindow>]. I want to be able to determine if the user closes the second window, in order to stop the modal.
There are several ways to be notified when a window closes.
You can observe NSWindowWillCloseNotification notifications from the second NSWindow object.
You can implement NSWindowDelegate methods windowShouldClose: or windowWillClose:.
You can subclass NSWindow and override the performClose: method.
You can add a Close button to the window, and connect it to an action.
Without more information, it's hard to advise which of these or other options would work best for you.

Message when a WebView's window is closed?

In my program I have an NSPanel containing a web view appear to a user to have them authenticate on a web page. I want to monitor if the user is closing the WebView before the authentication is complete.
I looked for messages in the WebFrameLoadDelegate protocol but I couldn't seem to find any message that would fire when the user clicks the close button for the NSPanel and only when the user clicks the close button.
I looked at subclassing NSWindowController and overriding the close method. Perhaps I did it wrong, because even when I removed the [super close] call, the panel still closed.
So, what is the correct procedure for executing extra code when the NSPanel containing the WebView closes?
If you want to stop the user from closing a window, you need to set the window's style mask to one that doesn't include NSCloseableWindowMask. This will disable the window's close button, so that it can only be closed programmatically. In the simplest case, you can just do [panel setStyleMask:[panel styleMask] ^ NSCloseableWindowMask].
Also, if you want to override a window's closing behavior, you either need to override NSWindow's (not NSWindowController's) close method, or implement windowShouldClose: on the window's delegate. I think the second way is better. At any rate, -[NSWindowController close] is just a convenience method to close the window. It isn't what's normally invoked when a window closes.