StatusItem menu blocks main thread when it's opened. Workaround? - objective-c

I've written an app for the Mac that is designed as a status bar item. However, when a user opens its menu from the status bar, the main run loop is blocked until it's closed. Since this app responds to messages on a socket, it's a problem that it can't do anything while the menu is open.
I've tried setting the status item from a separate thread and scheduling the socket on a different thread, but no dice. Is there a good way to deal with this?
UPDATE:
I've resolved this now. I was using the NetSocket socket wrapper and its asynchronous nature made it very difficult to open and watch on a different thread. I switched to SmallSockets (another Objective-C socket wrapper) and because it is synchronous, I was able to open a socket and just watch it directly on a separate thread.

While the user is interacting with a menu the run loop runs in the event tracking mode. Attach your sockets to the NSEventTrackingRunLoopMode mode too and they continue to run while the user interacts with the menu.
But putting the sockets on another thread should work too. If this did not work for you, you probably did something wrong, but without seeing the code I can't say.

Related

Running winforms app from debugger disables alt-tab switching to form

I have a Winforms app with a main form where a multiline text box is updated during a long running process.
I would like to be able to use the ALT-TAB facility of Windows to switch away from the Visual Studio 2012 IDE to watch the form being updated as the app runs.
Is there some option that controls this? If I have other apps running such as Notepad I can toggle away from the IDE but navigating in this way to the running Winforms app seems to be disabled.
Last time I debugged an app like this I recall this sort of switching worked but sometimes there was a lag in the rendering of the screen.
The winforms app is not multithreaded.
Any ideas?
The winforms app is not multithreaded.
Which means you're doing all your lengthy processing on the UI thread. And that, in turn, means that during that processing, your app is ignoring all the messages Windows is sending it, like the "hey, somebody just Alt+Tabbed to you, so bring yourself to the front" message.
You either need to sprinkle your code with frequent calls to Application.DoEvents (not recommended, but could work if you don't intend to maintain this app long-term), or move your long-running logic into a background thread so your UI thread can stay responsive to messages.

Is there a way of restarting an app when coming back from background?

I want to be able to restart the app when coming back from background. So if the user selects the app again it should start as if it were the first time it's open. I've been googling but couldn't find a way of doing this.
I was thinking in just add the main view of the app in applicationWillEnterForeground, but It would be great if I can deallocate resources.
You can't restart an app. What you can do is disable background support, so your app always completely terminates when closing.
"...you can explicitly opt out of the
background execution model by adding
the UIApplicationExitsOnSuspend key to
your application’s Info.plist file and
setting its value to YES."
Source: Opting Out of Background Execution.

NSAlertPanel problems

I am designing an application to connect remotely to another computer. I want to display an NSAlertPanel on connecting however it is 'blocking' the remote side from continuing with the session until OK is pressed with the usual NSAlertPanel setup.
Is there a way to have an NSAlertPanel which is non-blocking? Thanks.
When you run your alert panel modally, you block the run loop of the associated thread, which is the main thread in this case.
To display a window on connection, you can use custom sheets. It's easy to use and explained in the documentation page below:
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Sheets/Tasks/UsingCustomSheets.html
However, if you need to run your alert modally, an alert that is blocking interactions with the whole application, you may need to move your connection part to another thread, which is a good practice in both cases.

Is it okay to continuously hook and unhook keyboard?

I have an issue with WindowsHookEx in vb.net. If my pc is overloaded especially from 3D rendering, windows automatically disconnects my keyboard hook and my hotkeys stop working. I searched around and it seems that there is no way to detect whether a hook is active or disconnected. So I tried this method presented by "moodforaday"
Is it possible to detect when a low-level keyboard hook has been automatically disconnected by Windows?
hook-has-been-automatically-d
He states that using GetLastInputInfo periodically and store GetLastInputInfo to another variable when a key is used and compare the results. If the tick is much newer than your older variable then its likely that its disconnected. Its a great method but the ticks can go up from other things like the mouse. In my Hook class there is no Mouse hook therefore I cannot store a variable of the tick count when the mouse is moved. So now I ended up having it create a new instance of the hook class and hook again. It checks every second if the stored tick is older than new tick by 10000 ticks.
Is it alright to keep creating new instances of Hooks? It will keep Hooking/Unhooking constantly and I'm wondering if that is going to be a problem for Windows.
Also if anyone has another method to detect if a hook is disconnected please let me know would fix this whole hassle.
Do your 3D rendering in a background thread. Use Control.Invoke only for code where you directly access UI controls.
Alternately, you could split the rendering into very small pieces and post them to yourself as messages, to be handled on the main thread. This way you will be able to handle both internal and external messages.
In both cases, your application will be responding in a timely fashion, Windows will have no reason to consider it non-responding, and your keyboard shortcuts will stay in place.

Program locking when performing some tasks

I have a program that has the option to create a restore point...
My problem is that when you click on it to do so, the program just locks up until it's finished creating the restore point.
I have put a seperate form on the program and it has a Marquee Progress Bar Control which I downloaded, so the idea is...
User clicks "Create Restore Point"
frmRestore.show
Marquee Progress Bar goes on and on while the restore point is created
Restore point is done
frmRestore.hide
The thing is, when you click create restore point, the form shows and the program just locks up, onces the restore point is created the form hides again.
Could this problem be solved with a Background worker? To be honest I'm not completely sure what it does, I mucked around with the controls but can't seem to find anything useful.
Thanks
You need to put the restore procedure in separate thread. If your program is not multi-threaded then it will work linear and lock until it will finish the task it is doing.
The program is locked up because you are doing something intensive on the main thread.
It goes like this in a GUI application:
// do some stuff
// respond to system and redraw gui
// do some stuff
// respond to system and redraw gui
And when you block "// do some stuff" the program won't be able to respond and redraw the gui untill do some stuff is done.
What you need to do is either use a secondary thread or using a background worker like you said. A thread is like, you can do stuff in it without blocking the system or the GUI
hope this helps
I've never seriously used VB, but I think the same concepts apply to Qt (begin rant about Qt being better here).
I'm not sure if VB uses a GUI thread or just one unified one, but I think your problem is that the GUI thread is performing long non-gui operations which cause it to "lock". When it "locks", the program is waiting for the tasks to finish, and hence not letting you interact with it.
Use a separate thread...