NSWindow Modal Problems - objective-c

I'm running a modal window in my application, which works fine. The problem however seems to be dismissing the window.
While the window closes, it takes at least 20 seconds for the application to continue (I show the modal window at startup), but it will continue instantly if I click on its dock icon.
Here's how I close the modal window:
[NSApp stopModal];
[updaterWindow orderOut:self];
[updaterWindow close];
I've tried various things to get the Application to continue faster, such as manually switching to the main run loop and speaking to the main window directly (asking it to become the key window), which all did not work. Same as before, 20 seconds wait or instant load when clicking on the dock icon.
What can cause something like this? I'm really baffled.
Edit:
My modal window is actually created in a really simple way. I run my window as modal:
[NSApp runModalForWindow:updaterWindow];
When I am done with things, I close it:
[NSApp stopModal];
[updaterWindow orderOut:self];
[updaterWindow close];
The window goes away, but it needs a click to the dock icon or anywhere on the screen for the app to continue.

I'm doing something similar in my app at the moment: I have an IBAction method that calls the modal window:
-(IBAction)showMyModalWindow:(id)sender {
[theModalWindow makeKeyWindow];
NSInteger retVal = [NSApp runModalForWindow:theModalWindow];
[theModalWindow close];
//continue and do somethin according the value in retVal
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
}
In this case theModalWindow is in it's own nib file has an NSObject in it that deals with the ok and cancel button to dismiss theWindow, by way of example here's the cancel button callback:
-(IBAction)cancelButton:(id)sender
{
[NSApp stopModalWithCode:errAuthorizationCanceled];
}
The last line in showMyModalWindow: method seems to be what's needed in my case by sending the app forward... Hope that's of some use!
Todd.

Related

Opening a modal dialog (modal window or sheet) from another modal dialog

I need to open a modal window, which can open another modal window (or sheet). First window works fine, but second behaves strange.
This is how I open first window:
RegisterDialog * registerDialog=[[RegisterDialog alloc] initWithWindowNibName:#"RegisterDialogMac"];
NSWindow* window = [registerDialog window];
[NSApp runModalForWindow:window];
This window behaves properly and responds to any buttons, I just added a bit of code to stop modal event loop after pressing on a red button:
- (void)windowWillClose:(NSNotification *)notification {
[[NSApplication sharedApplication] stopModal];
}
Ok. Now I am opening the second dialog window if user press the "Register" button:
-(IBAction)registerPressed:(id)sender {
RegistrationDialogMac* registrationDialog=[[RegistrationDialogMac alloc] initWithWindowNibName:#"RegistrationDialogMac"];
NSWindow* window = [registrationDialog window];
[NSApp runModalForWindow:window];
}
This second dialog window works fine too, but is closed only if to press red button.
This is how "Cancel" button is processed:
-(IBAction)cancelPressed:(id)sender {
[NSApp stopModal];
[[self window] close];
}
After pressing it modal event loop is stopped, first dialog window becomes active, but second window still remains here. It is closed only if I press the red button. This is strange, as the first modal window is closed properly by the same code.
Ok. I tried to go different route and run the second dialog window as a sheet:
-(IBAction)registerPressed:(id)sender {
RegistrationDialogMac* registrationDialog=[[RegistrationDialogMac alloc] initWithWindowNibName:#"RegistrationDialogMac"];
NSWindow* window = [registrationDialog window];
[self.window beginSheet: window
completionHandler:^(NSModalResponse returnCode) { }
];
}
(I turned off "Visible at launch" to correctly draw this sheet attached to the first dialog window)
This way the second dialog window is drawn, but ignores all button presses. Graphically buttons are pressed, but aren't processed. This code:
-(IBAction)cancelPressed:(id)sender {
NSLog(#"!");
[[self window] close];
//[NSApp endSheet:[self window]]; // may be this would be correct way to close sheet? Don't know as this method isn't run anyway
}
isn't executed at all, there is no a single "!" character in the log.
So I am doing something wrong. I actually almost have no any Mac coding experience, only Windows.
Found that [self window] of the second dialog was nil, so it couldn't respond to close. Checked the .xib - and, yes, I forgot to connect the window outlet to the window itself. Fixed, and the window is closed correctly now.
This doesn't fix the problem of unresponding buttons when this second dialog is drawn as Sheet though.

setActivationPolicy to Regular and openWindow

On applicationDidFinishLaunching application activationPolicy is set to Prohibited (to hide the dock icon).
I have a method that sets it to NSApplicationActivationPolicyRegular (to be able to open and focus the window) then opens the window, but I have to run it twice to work. The set policy doesn't affect the openWindow: method.
- (void)openWindow {
[NSApp activateIgnoringOtherApps:YES];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
[NSApp openWindow:window];
}
Do I need to delay the openWindow:?
When do you call openWindow? Maybe you should place the calling after the applicationDidFinishLaunching.
By the way, if you want to hide the dock icon and be able to focus on the window, you should try NSApplicationActivationPolicyAccessory other than NSApplicationActivationPolicyProhibited.

App stuck on runModalForWindow

I'm trying to display a modal dialog on top of my app but it's blocking my main app window when it closes. Here's my code:
TutorialWindowController* pTutorialController = [[TutorialWindowController alloc] initWithWindowNibName:#"TutorialWindow"];
NSWindow* pTutorialWindow = [pTutorialController window];
DDLogInfo(#"Tutorial window opening...");
[NSApp runModalForWindow: pTutorialWindow];
DDLogInfo(#"Tutorial window closed!"); // CODE NEVER GETS HERE
[NSApp endSheet: pTutorialWindow];
[pTutorialWindow orderOut: self];
In the modal dialog, my Close button runs this:
- (IBAction)closeButtonPressed:(id)sender {
[NSApp stopModal];
}
The modal dialog displays fine. However, when I click the Close button, the dialog disappears and my app's main window isn't responsive. I hear the bonk every time I try clicking. I'm pretty sure this is because the code never continues after runModalForWindow. Same thing happens if I close the modal dialo using the red X.
What am I doing wrong?
After ordering out the tutorial window, try doing a
[window makeKeyAndOrderFront:self];
on your main window.
You should call [pTutorialWindow orderOut:nil] first.
Not sure about the closeButtonPressed handler. But try adding to the delegate:
- (void) windowWillClose:(NSNotification *)notification
{
// ...
// In there, you should verify that you are calling:
[NSApp stopModal]
}
Adding the stopModal call solved the issue for me.
Verify that the Window delegate in the Interface Editor's Connection Inspector is connected to the File's Owner.
I had several modal dialogues working correctly except for one, and the missing connection was the only difference. Making the connection fixed the problem.

Opening a new window and waiting for it to close

I have a Mac OS X app written in objetive-c Cocoa. You can see most of the code in this previous question. Essentially you click a button on the main window (the app delegate) and it opens another window where the user can enter information.
In the following code (that gets called when the user press the button in the app's main window)
- (IBAction)OnLaunch:(id)sender {
MyClass *controllerWindow = [[MyClass alloc] initWithWindowNibName:#"pop"];
[controllerWindow showWindow:self];
NSLog(#"this is a log line");
}
The NSLog line gets printer immediately after I called showWindow. Is there any way to wait until controllerWindow is closed to continue with the NSlog?
The reason for this is that the user set's a value on the new window I opened and I need to collect that value on the same OnLaunch so I need to wait.
I know that modal windows are bad form in Mac, but I have no control over this feature.
I've tried with
[NSApp runModalForWindow:[controllerWindow window]];
and then setting the popup window to
[[NSApplication sharedApplication] runModalForWindow:popupwin];
and it works but then the focus never gets passed to the main window anymore
Thanks!
If you want the window to be modal for your application, use a sheet: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Sheets/Tasks/UsingCustomSheets.html
However, there is no way to suspend execution of a method while the sheet is displayed, this would be tantamount to blocking the current run loop. You would have to break you code into the begin and end methods as described in the linked documentation.
Here are the steps you need to follow:
In TestAppAppDelegate create an NSWindow outlet to hold your sheet and an action to dismiss the sheet
Create a nib with an NSWindow as the root object. I think you already have this in "pop". Set the Visible at Launch option to NO (this is very important)
Set the file's owner of this nib to TestAppAppDelegate and connect the window to your new outlet, and the close button to your new action
In your method to launch the sheet (OnLaunch), use the following code:
(ignore this it's to make the code format properly!)
if(!self.sheet)
[NSBundle loadNibNamed:#"Sheet" owner:self];
[NSApp beginSheet:self.sheet
modalForWindow:self.window
modalDelegate:self
didEndSelector:#selector(didEndSheet:returnCode:contextInfo:)
contextInfo:nil];
Your close button action should be [NSApp endSheet:self.sheet];
Your didEndSheet: method should be [self.sheet orderOut:self];
You can use UIVIew method animateWithDuration:delay:options:animations:completion: to accomplish this.
You said you want the next line to execute once the window is closed, rather than after it is opened. In any case, you may end the OnLaunch method this way:
- (IBAction)OnLaunch:(id)sender {
MyClass *controllerWindow = [[MyClass alloc] initWithWindowNibName:#"pop"];
[controllerWindow animateWithDuration:someDelay:options: someUIAnimationOption
animations:^{
[controllerWindow showWindow:self]; // now you can animate it in the showWindow method
}
completion:^{
[self windowDidFinishShowing]; // or [self windowDidFinishDisappearing]
}
}
- (void) windowDidFinishShowing {
NSLog(#"this is a log line");
}

NSWindow not closing

Hey, SO, minor issue: I have an NSWindow I am using to report exceptions that works pretty well. I give the user the option to quit the application or continue running in an uncertain state with a "Continue" button. The "Continue" button is supposed to simply close the window, however it does not work. Here is the code:
- (IBAction) continueOperation:(id)sender
{
[[self window] performClose:self];
}
If the user presses the close X in the upper left corner, the window closes correctly, but the code does not do the trick. Any ideas what I might be doing wrong? Thanks!
Are you sure that [self window] is returning the window that you think it is?