Display a sheet but still let my main app do work - objective-c

The loadFile method starts a NSTimer to load an process a file over time without blocking the application in a while loop. This timer is not firing with the first bit of code, and is with the second bit. The issue is the second bit shows the sheet as a panel style window, not as a sheet.
How do I get a sheet that can still do work?
Show Sheet but no work is done
[self.sheetView loadFile:filename];
[[NSApplication sharedApplication] beginSheet: self.sheetView
modalForWindow: self.window
modalDelegate: self
didEndSelector: nil
contextInfo: nil];
[[NSApplication sharedApplication] runModalForWindow: self.sheetView];
Show window and work is done
NSModalSession session = [NSApp beginModalSessionForWindow:self.sheetView];
NSInteger result = NSRunContinuesResponse;
[self.sheetView loadFile:filename];
// Loop until some result other than continues:
while (result == NSRunContinuesResponse)
{
// Run the window modally until there are no events to process:
result = [NSApp runModalSession:session];
// Give the main loop some time:
[[NSRunLoop currentRunLoop] limitDateForMode:NSDefaultRunLoopMode];
}
[NSApp endModalSession:session];

Is there a reason why NSThread can't be used? That's the obvious answer ...

Related

Close WindowController Without loosing Data in 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

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:].

Closing OSX window on load

I have come up with a taskbar program that is able to shut and close a window. Key code being:
-(void) openWindow{
NSLog(#"Opening Window");
//put infront of all other apps
[NSApp activateIgnoringOtherApps:YES];
//show window
[[_myView window] orderFront:self];
}
-(void) closeWindow{
NSLog(#"Closing Window");
//hide window
[[_myView window] orderOut:self];
}
This is working perfectly.
The only issue is, I now want the program to start off with the window closed but when I set this:
- (void)viewDidLoad {
[super viewDidLoad];
[self closeWindow];
}
Nothing happens and the window stays open?? And before you ask - Yes 'Visible At Launch' is switched off! Haha
If I add a 0.001 second delay in the view did load it works!!
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.001 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self closeWindow];
});
but then there is a horrible flicker...
If there is a viewWillAppear method, try to put your [self closeWindow] in.
Or maybe you try to close the window before she is visible so the code to show window is executed after your call to closeWindow.
Put some breakpoints if needed to see the order of the methods's execution.

Make window & application key then instantly return it to previous

I've been trying to make a WebKit WebView receive mouse moved & enter events when the window and application aren't key or active. I've spent weeks trying different methods and the only way I can make work is by using an NSTrackingArea to activate the application and make the window key, send the event to the WebView then switch back to the old application.
I've looked through the WebView (specifically WebHTMLView which handles the mouse events) source code and it appears that due to something to do with scroll bars it flat out won't accept mouse moved events when the window is not key. So, really, this basically seems the only way.
This works. However, there is a delay between when my application becomes active and the other application becomes active again. This creates a bad repeated flickering of the window frame as controls as it changes from the active style to inactive style.
This is from my WebView subclass:
-(void)awakeFromNib{
[[self mainFrame]loadRequest:[NSURLRequest requestWithURL: [NSURL URLWithString: #"file:///..."]]];
NSTrackingArea* trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] options: (NSTrackingMouseMoved | NSTrackingActiveAlways) owner:self userInfo:nil];
[self addTrackingArea:trackingArea];
[[self window] makeKeyWindow];
}
-(void)mouseMoved:(NSEvent *)theEvent{
if(![NSApp isActive]){
NSRunningApplication *app = [[NSWorkspace sharedWorkspace] frontmostApplication];
if (app != NSApp) {
oldApp = app;
}
[NSApp activateIgnoringOtherApps:YES];
}
[super mouseMoved:theEvent];
if(oldApp){
[oldApp activateWithOptions:NSApplicationActivateIgnoringOtherApps];
}
}
Is there anything I can do to make this switch instant, not draw or, even better, another way to achieve what I want?

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.