MBS + frontmost appsication

Once in a blue moon, when logging back into my Mac, my menubar application has an unhandled exception from the following code:

Var t as String
Dim w As New NSWorkspaceMBS
Dim n As NSRunningApplicationMBS = w.frontmostApplication
t = n.localizedName

It’s caused by w.frontmostApplication returning nil

My workaround is to check if w, or n = nil, and returning if it is.

This method is called by a timer every .3 seconds, and sends a shell command if the user has switched applications.

Is there a way to tell if the user is logged out or the Mac is locked so the menubar app doesn’t check which app is frontmost?

Well, you can check the notifications sent to NSWorkSpaceMBS class.

Also don’t check every 300ms. The user doesn’t switch apps that fast. It may be enough to check every 2 seconds.
And if it is w, you may be in some state with no front app, e.g. screen saver takes over.

I’ll have to look into NSWorkSpace Notifications - it might be exactly what I need instead of a timer. I only need to find out what the frontmost app is when the user changes apps.

I switch back and forth between apps very frequently sometimes, so the timer needs to be fast. I have got the app down to 0.2% cpu usage, so I can leave the timer as it is.

if w ever equals NIL, you have bigger problems to worry about!
The NSWorkspace class should not be possible to be NIL, except maybe a bug in the plugin.

Yes, NSWorkspace notifications will tell you when the user switches applications. For the time being you can get that application info, however I don’t know if this is possible in the App Sandbox or allowed on the Mac App Store, and it may not be possible in the future, you know for security purposes…

It’s not w that’s nil, it’s w.frontmostApplication that returns nil.

It only happens if my Mac is waking up, or being logged into, but I can’t reliably reproduce it as it doesn’t happen often.

I only just figured out how to add exception handling, and have combined nil checks with with message boxes to let me know when a nil is found while the app is running.

for now, I’m using this to get around that:

Dim n As NSRunningApplicationMBS = w.frontmostApplication

While n is nil
  n  = w.frontmostApplication

I would recommend against that approach, for two reasons.

  1. NSWorkspace Notifications will tell you when the user switches applications, no need for polling or loops. This will have th minimum benefit that it will make your application more energy efficient.
  2. It is entirely possible that w.frontmostapplication may never be valid, at which point your application deadlocks. While I would encourage you to adopt the notifications, if you don’t want to do so, at least add a timeout to the loop, just incase Apple introduce a bug or decide that your application no longer is able to access the front most application information.

I removed the while/wend loop and switched it back to a notification that I’ll remove after more testing. I’ve been using this particular app for about a year or so?

It works with a keyboard remapper. The remapper doesn’t automatically change profiles when you change applications. It does accept terminal commands, so my app sends those commands whenever the frontmost application changes.

I’m pretty sure Apple wouldn’t allow it in the App Store as it only works if you have the remapper. I do plan to sell it online eventually, but it’s such a niche app I’m not even sure it’s beer money.

It does make the comic book work I do in Photoshop and Clip Studio Paint so much faster and easier with the one handed keyboard since I no longer have to manually change profiles when I switch back and forth between apps.

1 Like