Show/Hide window when app is in background

I’ve got an app that doesn’t use a dock item or menu item on OS X. It’s only supposed to show if 1) it receives a packet from a server or 2) the user requests it with a keystroke (cmd-F5). When the app is running and in the foreground, this works as expected. When the app is in the background, any other app is in the foreground, then the keystroke does not show the window.
I’m currently using a timer action to listen for a keystroke to show/hide the window, which is of the Global Floating Window type. This was developed by someone else and I now need to update it for the latest Xojo and macOS builds. I’m currently testing with Xojo 2015 Release 3 and macOS 10.12.6. Is this functionality still possible?


if Keyboard.ControlKey And Keyboard.AsyncKeyDown(&h60) then if self.Left < 0 then ShowWindow AddMessage(highlightOff, "Show KeyStrokeHit") else HideWindow AddMessage(highlightOff, "Hide KeyStrokeHit") end if end if


if (me.Left+me.Width)<0 then // beep me.Left = me.Left + windowDisplayOffset AddMessage(highlightOff, "ShowWindow: " + str( me.Left)) end if


if (me.Left+me.Width)>0 then me.Left = me.Left - windowDisplayOffset AddMessage(highlightOff, "HideWindow: " + str( me.Left)) else AddMessage(highlightOff, "DONT HideWindow: " + str( me.Left)) end if

When looking for a solution for OSX, you may get better results by posting in the Targets > macOS subforum.

I’d suggest you look at the Global Hotkey program from MBS.

I use a similar solution in CharMenu, and it works flawlessly. I don’t see why you should change that code.

How is your timer configured?

mTimer.Mode = ? mTimer.Period = ?

In CharMenu, I use multiple period 100, which is amply sufficient to monitor the keyboard. Anything shorter is a waste, since the keyboard is in fact a very slow peripheral.

My timer is configured the same way, multiple with a period of 100. This (mostly) works when the application is in the foreground, but not when it’s in the background. I’ve updated the target to macOS, thanks for the suggestion. I believe this may have something to do with the cocoa/carbon switch. I suspect carbon allowed for apps to listen for keystrokes while in the background, but Cocoa does not.

Are you sure this is working on Mac OS? I can’t recreate your success without plugins in a simple test project with 2017r2.

This could also quite possibly be the culprit. I believe there is a non-applscript MBS plugin that will help.

You probabky need to set the timer to much less. Like 10 instead of 100. It works here that way.

I am holding the keys down, not just pressing them. The background app is not receiving the keys.
If you have it working in a test project, why not post that and I’ll give it a go.

This unreliability of it working for everyone should be a huge red flag to this method of shortcut capturing.

My app has always been Cocoa, and has been in the MAS since July 2016. I never observed any issue with the key trigger. There may be something else here.

Where is your timer ? If it is on a window, that may explain. Mine is in app.

Ah! That’s the trick! I have it working here now.
I’ll clean up my test project, and post it a little later.

RegisterEventHotKey seems to still be the right way to do this and NOT burn a pile of CPU

Here’s the global hotkey test project I got working: global_hotkey_test.xojo_binary_project

Norman is right though. I saw this eating up 5% of the CPU during a keycombo hold.

Since Xojo does not support natively the RegisterEventHotKey why beat on programmers that use the resources at their disposal ?

doing it in a really short period timer may get your app marked as burning excessive CPU

and users freak out when the OS warns them about stuff like this

I think at one time there was a sample that demo’d how to do this

Thanks, everyone. My timer was on the window, not the app. I’m considering just moving to a menu item instead of forcing a command-keystroke to present the window. I’m testing @Tim Parnell’s project now, but I suspect that’ll solve this question.

CharMenu shows 0.5 %CPU while not called upon. I would not label that as burning excessive CPU.

Move the timer to app and it will react as expected.