dispatch_sync_f blocks window fullscreen operation - objective-c

I am writing an application that does a blocking operation on the main thread using dispatch_sync_f when toggled (input from keyboard). I have a while loop inside the function that was passed to dispatch_sync_f that performs some routines. To ensure window events are processed while in this loop, I wrote the following and pass it along.
event = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:nil
inMode:NSDefaultRunLoopMode
dequeue:YES];
[NSApp sendEvent:event]
However, when I try to go fullscreen (green button) it is stuck until this blocking function is untoggled. I thought I was passing along all events any keyboard/mouse input to the window is processed. But going fullscreen may not have been an event in this case. Is there a way to detect fullscreen event and pass it to the window while the main thread is blocked?

Related

How to change visual state of stackpanel from a keyboard event

In a C++/winrt app I am able to handle a click in a stackpanel and respond by changing the background of the panel. But if I call the same method from the KeyDown event handler for the main page the appearance of the panel does not change. Both calls to the panel's background change are happening on one of the SHCore.dll threads, and I wonder why they are not on the "Main Thread." Using the dispatcher as follows still leaves me on the SHCore thread:
Window::Current().Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, [this, theKey,&handled]
{
handled = PressLetterKey(theKey);
});
As there is no visible effect from triggering the change within the keydown handler I begin to wonder if this is a thread issue. Yet the thread does appear to the same one in both the functional and the non-functional cases, and both the clickhandler and the keydown handler are calling the same method on the stackpanel - Could the thread here be the problem, or is there some other reason why the panel does not show its change in appearance when triggered by a keydown?
The triggering doesn't have to be a keydown, of course - I'm really just asking if the stackpanel's appearance can be toggled programmatically...for instance if one wanted to blink a button.
OK, once again I've just made a dumb error, but what can be salvaged here is an answer to the threading question. Yes, the SHCore thread is the UIThread, at least here. The "Main Thread" is something else. Any click event or keydown event arrives on the UI thread ready for action, there's no need to call dispatcher. In my case, I was triggering changes in one of a large series of stack panels and - the one I thought I was triggering was actually not the correct one; the triggered item was simply offscreen... so there you have it!

How to wait for window to close inside a framework?

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.

Custom modal dialog and background operations

I have a Cocoa app with a custom, multi-step account setup that I implemented as a custom modal dialog with a set of views.
The problem is that the background operations (fetching a URL) seem to get stuck. I assume that this is because the application is in a modal mode.
Here the code to start the modal dialog:
[NSApp beginSheet:accountSetupController.window modalForWindow:self.window
modalDelegate:nil didEndSelector:NULL contextInfo:NULL];
[accountSetupController beginAccountSetup]; // this later launches the background operation
[NSApp runModalForWindow:accountSetupController.window];
NSApp endSheet:accountSetupController.window];
First of all, is my assumption correct? Is there a way to have the background operation proceed even if the application is running modal?
The actual background operation is not under my control. It is an external API that takes a completion block.
Take a look at the "discussion" section of your call to [NSApplication beginSheet: modalForWindow: ...]:
Discussion
This method runs the modal event loop for the specified sheet
synchronously. It displays the sheet, makes it key, starts the run
loop, and processes events for it. While the application is in the run
loop, it does not respond to any other events (including mouse,
keyboard, or window-close events) unless they are associated with the
sheet. It also does not perform any tasks (such as firing timers) that
are not associated with the modal run loop. In other words, this
method consumes only enough CPU time to process events and dispatch
them to the action methods associated with the modal window.
To me, this means that background threads and tasks aren't running while this modal session is going. I've run into this problem before with my own modal dialogs trying to access web servers (for registration purposes, if I remember correctly).
The best solution is to not use modal dialogs if you need to talk to a server asynchronously. If you must use modal dialogs, try to do your communication between modal sheets (i.e. when the user hits "submit", end the sheet and do the server chatting, then bring up the next sheet for the next step).

How to make NSWindow accept mouseMove events immediately after opening?

I am writing an application using cocoa which, in some point (surprise), opens window.
There is a "Hover" functionality in this window, and for that I need to accept mouseMoved events. I managed to activate this functionality using
[[newView window] setAcceptsMouseMovedEvents:YES];
call, however, it only starting to work after I touch the opened window, actually activating it this way. I am interested for it to work right away, without clicking on it.
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
does not seem to be working since only mouseDown or mouseDragged events activate it. Apparently mouseMoved event does not.
In other words, mouseMoved event only start to work after mouseDown or mouseDragged event has been called.
Are you using an NSTrackingArea to handle this? Have you passed in the NSTrackingActiveAlways option?

Creating a parenet less modal dialog or MessageBox or alert Sheets in cocoa?

Issue1:
I want to show an alert window or message box before the Main Window of the Application is launched. When im using the NSRunAlertPanel() it is not showing the alert window.It is directly launching the Application's Main Window.
Issue2:
I want to create an Modal (login dialog) and message boxes in an thread spanned from the main thread.
Its urgent
So, Kindly reply soon...
Thank You Pradeep.
Issue2: I want to create an Modal (login dialog) and message boxes in an thread spanned from the main thread.
In Cocoa, nearly all UI code must run on the main thread. There are a few limited, well-defined exceptions (e.g., the opt-in threaded drawing introduced in Snow Leopard), but the general rule is to not run UI code on another thread.
Besides, you don't need a thread anyway. It's not like the modal dialog is going to be computationally intensive.
Send NSApp a runModalForWindow: message, passing the dialog. This will run the dialog on the main thread, blocking the rest of your UI. If you don't want to block the UI (and you generally shouldn't), just make it key and order it front, like usual.
What you can do is:
uncheck the "Visible at launch" option for your main window in Interface Builder.
start your application as usual
decide whether or not to show the modal dialog
invoke "orderFront:" message of the main window.