Close WindowController Without loosing Data in objective c - objective-c

So i have a windowController which i pop up using NSApp this window is called from mainWindowController.
ScriptSettingWindowController *mySettings = [[ScriptSettingWindowController alloc]initWithWindowNibName:#"ScriptSettingWindowController" owner:self];
[NSApp runModalForWindow:[mySettings window]];
There are other UIElements which gets displayed only when using Owner:self. When using owner:self it takes over mainWindowController.
enter image description here
When i close the NSApp The control returns to the mainWindowController. But ends up crashing the application. I believe the control has to be returned back to mainWindowController before closing the NSApp.
To close the modal i use
[NSApp stopModal];
[NSApp orderOut:self];
[NSApp close];
but they do not close the popup.
[[self window] close];
[[self window] close]; this does close the window along with some variables being cleared and crashing the app.
Im dealing with an old project here and have no clue about mac development. Any help would be appreciated. thanks in advance

Related

Fullscreen (kiosk) NSWindowController with WebView need click first before been able to click on any links

I am creating an application which have a kiosk web browser as one of its features.
The web browser is in a NSWindowController and a strange thing is happening: when the NSWindowController is loaded i set the WebView url to a default one and start loading the page.
Everything loads fine etc, but i can't interact with the WebView (ie. click on a link in the loaded page) before i have clicked anywhere on the window. After that everything is working fine. Looks like the window is missing 'focus' and after clicking on the window it gets focus and i see the cursor changing when hovering over links etc...
This is not an issue when i don't use [[self.window contentView] enterFullScreenMode:[NSScreen mainScreen] withOptions:nil];
There are couple of buttons in the window too, but they just work on the first click without the focusing.
Anyway here is the code that do most of the job:
NSApplicationPresentationOptions options =
NSApplicationPresentationHideMenuBar|NSApplicationPresentationHideDock|
NSApplicationPresentationDisableHideApplication|
NSApplicationPresentationDisableProcessSwitching|
NSApplicationPresentationDisableAppleMenu| NSApplicationPresentationDisableForceQuit;
[NSApp setPresentationOptions:options];
[[self.window contentView] enterFullScreenMode:[NSScreen mainScreen] withOptions:nil];
[self.webView setFrameLoadDelegate:self];
[self.webView setPolicyDelegate:self];
NSString *url = [[NSString alloc] initWithString:#"https://www.google.com"];
[[self.webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];
I assume that your webView is not the first responder before you click on it.
You can change this by using
[[self window] makeFirstResponder:webView];
Also [self.window makeKeyAndOrderFront:self]; or [NSApp activateIgnoringOtherApps:YES]; could make a change dependent on the situation. If this will not help you may need to make the call with delay dependent when its initially used.
[self performSelector:#selector(myDelayedActivateFunction) withObject:nil afterDelay:0.0];

NSPopover loses first responder

I have a NSPopover in my application with various buttons. One button allows the user to tweet using the NSSharingService:
NSArray* array = #[ #"Tweet something"];
NSSharingService* sharingServiceFB = [NSSharingService sharingServiceNamed:NSSharingServiceNamePostOnTwitter];
[sharingServiceFB performWithItems:array];
This works well, but when the tweet has been sent or cancelled, the focus is returned to the main application (main window) and not the NSPopover. How can I return focus to the NSPopover?
My initial approach was to observe NSWindowDidBecomeKeyNotificationwhich calls a method when notification has been received that does the following
if (self.sheetPopover!=nil){
[self.sheetPopover becomeFirstResponder];
}
However, this did not work as expected and I still have to click twice on the NSPopover to regain focus. Any suggestions as to how to fix this? Thanks.
I found a solution that worked for me. I made my NSPopover a delegate of NSSharingServiceDelegate, and implemented two of the delegate methods where I reset the first responder when the twitter view had closed. Here, self is the NSPopover view.
- (void)sharingService:(NSSharingService *)sharingService didShareItems:(NSArray *)items
{
[self becomeFirstResponder];
[[self window] becomeKeyWindow];
[[self window] becomeMainWindow];
}
- (void)sharingService:(NSSharingService *)sharingService didFailToShareItems:(nonnull NSArray *)items error:(nonnull NSError *)error
{
[self becomeFirstResponder];
[[self window] becomeKeyWindow];
[[self window] becomeMainWindow];
}
Comments as to whether this is the best approach are very welcome.

Objective-C: How to hold the thread until the NSSheet is closed?

I am opening an NSWindow as NSSheet and I want to hold the thread until the NSSheet is closed.
_license = [[LicenseArgWindow alloc] initWithWindowNibName:#"LicenseArgWindow"];
[self.window beginSheet:self.license.window completionHandler:^(NSModalResponse returnCode) {}];
[NSApp beginSheet: _license
modalForWindow: _window
modalDelegate: self
didEndSelector: nil
contextInfo: nil];
///here is the problem
///the thread reaches here wheather the nswindow is closed or not
BOOL isAgreed = _license.isAgreed;
How to stop the thread at NSSheet launch and the thread should not pass until the NSWindow is closed
Please help. Many Thanks
Set the didEndSelector parameter in:
[NSApp beginSheet: _license
modalForWindow: _window
modalDelegate: self
didEndSelector: #selector(didEndSheet:returnCode:contextInfo:)
contextInfo: nil];
and have that do the "accepted license" bit:
- (void)didEndSheet:(NSWindow *)sheet
returnCode:(NSInteger)returnCode
contextInfo:(void *)contextInfo
{
[sheet orderOut:self];
BOOL isAgreed = _license.isAgreed;
}
Here is a guide from Apple.
The whole point of sheets is that they are modal for just the one window. The rest of the app has to continue to function. The user can work with other windows or do global actions like open a new file, etc. To block the whole app's execution waiting for the sheet is entirely against the purpose of sheets as a UI mechanism.
If you want an app-modal dialog, run the dialog as a modal window (not sheet). You can either use an NSAlert which has a runModal method, or you can use an arbitrary window using -[NSApplication runModalForWindow:].

How do I quit a mac application programmatically?

I need to add a quit-button to my application that runs from the menubar in mac.
How do I programmatically quit an application in mac?
There is a simpler form to quit from code:
[NSApp terminate:self];
But as you're adding a button, all you have to do is to control drag from your button to the Application icon and connect the method terminate:.
[[NSApplication sharedApplication] terminate:self];
Try the following:
[NSApp terminate: nil];
In some case you cannot close app when call [NSApp terminate:self];. Like when showing NSAlert as sheet on the doc window (NSAlert -beginSheetModalForWindow:completionHandler:) ...
You can close all window and alert before call terminate, like following code:
for (NSWindow *window in [NSApplication sharedApplication].windows) {
[window close];
}
[NSApp terminate:self];

Can't open a sheet on a window twice

I'm opening a sheet on a window , the first time the sheet opens
correctly, but if I close it, and try to open again it doesn't work, I
just get the system alert sound.
- (IBAction) showSpeedSheet:(id)sender
{
[NSApp beginSheet:addEditPackagePanel
modalForWindow:[[NSApp delegate] window]
modalDelegate:nil
didEndSelector:nil
contextInfo:nil];
}
-(IBAction)endSpeedSheet:(id)sender
{
[NSApp endSheet:addEditPackagePanel];
[addEditPackagePanel orderOut:sender];
}
I can't find what's wrong, the app doesn't print any error on the log.
A delegate is not required.
The beep occurs because the system believes there is already a sheet open on the window (whether or not that sheet is technically visible). It's not the greatest error reporting, but that's what it is.
In my code sheets have window controllers and I do both of the following steps in every action that is attached to a sheet-closing button:
[NSApp endSheet:[windowController window]];
[windowController close];
With these steps, subsequent sheets are able to display without beeping.
I think you may need to implement the modal delegate and didEndSelector. The orderOut should be called from the did-end selector.
[NSApp beginSheet:addEditPackagePanel
modalForWindow:[[NSApp delegate] window]
modalDelegate: self
didEndSelector: #selector(didEndSheet:returnCode:contextInfo:)
contextInfo: nil];
and
- (void)didEndSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void*)contextInfo
{
[sheet orderOut:self];
}
I believe control is sent to the did-end selector has soon as endSheet is called.