show/hide app

My brother and I are working on an app that organizes macros and assigns them to letters on the left hand. It’s called the Hotkey-Grid (github: https://github.com/jsphweid/hotkey-grid, more info here: http://ahkscript.org/boards/viewtopic.php?f=6&t=9128). Basically, you hit a button and it runs a specified applescript or autohotkey script. The buttons are laid out visually on a grid and buttons can be moved around and moved to different tabs to make it easy to change which key does what.

The driving mechanic is being able to show/hide the app quickly when CAPS is pressed and this works very fluidly in Windows (easy to do with AHK). However, in the mac version we’ve run into roadblocks.

  1. Taking control of CAPS to show/hide the app is difficult (in AHK, you just run a simple script that binds the key while the script is running to do whatever you want).

  2. Using Applescript to show / hide is slow. Or at the least, to bring the window to the front and push it to the back. It doesn’t happen instantly. I think the code that we are currently using to do this is:

tell application "Hotkey Grid"
	if it is running then
		tell application "Finder"
			set isHotkeyGridVisible to visible of process "Hotkey Grid"
		end tell
		if isHotkeyGridVisible is true then
			tell application "Finder"
				set visible of process "Hotkey Grid" to false
			end tell
		else
			tell application "Hotkey Grid" to activate
		end if
	else
		tell application "Hotkey Grid" to activate
	end if
end tell

As I said, the performance is not good. What is the fastest way to do this? And if you have any ideas on getting CAPS to execute this process, let me know.

As I don’t own your app, I tested with Mail.

When I executed your script, I got these events log :
s

tell application "Finder"
	get visible of process "Mail"
end tell
tell application "System Events"
	get visible of process "Mail"
end tell
tell application "Finder"
	set visible of process "Mail" to false
end tell
tell application "System Events"
	set visible of process "Mail" to false
end tell

tell application "Finder"
	get visible of process "Mail"
end tell
tell application "System Events"
	get visible of process "Mail"
end tell
tell application "Mail"
	activate
end tell

So it was clear that the first thing to do is to replace “Finder” by “System Events” in your code.
This time the events log are:

tell application "System Events"
	get visible of process "Mail"
	set visible of process "Mail" to false
end tell
tell application "System Events"
	get visible of process "Mail"
end tell
tell application "Mail"
	activate
end tell

I wish to add that, if you are working under Yosemite, we all know that activate is slow under this OS.
I guess that it will be faster under El Capitan.

Yvan KOENIG running Yosemite 10.10.4 in French (VALLAURIS, France) samedi 8 août 2015 10:56:42

You might find this easier to write:


try
	tell application "System Events" to set visible of process "Hotkey Grid" to ¬
		not visible of process "Hotkey Grid"
on error
	tell application "Hotkey Grid" to activate
end try

Thanks for your answers.

Any advice on binding CAPS to perform this action or is this probably extremely impractical? Or maybe you know of another community that would know the answer better?

Thanks for this. Unfortunately though, it activates the window quickly but it doesn’t make it the front-most window. If you call the script with a hotkey and say, for instance, chrome is active at the time. Chrome will be the front-most window, “Hotkey Grid” will be the 2nd front most. Additionally, if “Hotkey Grid” IS in fact the “active” front-most window, it does not seem to want to make it invisible. Any suggestions?

Perhaps something like this:


tell application "System Events"
	tell application process "Hotkey Grid"
		set visible to true
		set frontmost to true
	end tell
end tell


Chris


{ MacBookPro6,1 · 2.66 GHz Intel Core i7 · 8GB RAM · OSX 10.11.1 }
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

I wonder why that script doesn’t work with my app. I have no explanation. I just doesn’t bring it all the way to the front. It’s always behind the frontmost by 1. I don’t get it.

I also don’t get why the reaction is so slow when it is bound to a keyboard shortcut and ran as a service as opposed to simply run in a script editor (which evidently is a long-running problem).

Is there any other way around this that one can think of? I even made a service that runs an applescript, writes a file of most active window, then applied a “launch application” in the workflow which kind of forces it to become frontmost (and even this doesn’t work all the time), then runs another applescript that reads the previous file and determines whether it should hide Hotkey Grid if it previous wrote it was active. But this bugs out once Hotkey Grid is active for some reason.

Maybe it can be done via shell or javascript? I notice these are also possibilities for Services…?

Each day I begin to more fully understand this maybe. Here is an example:

This brings the window to the front.

do shell script "open -a Terminal"

This does not for some reason. It show/hides but it does not bring it ALL THE WAY to the front, at least on my 10.11 El Capitan macbook pro.


try
    tell application "System Events" to set visible of process "Terminal" to not visible of process "Terminal"
on error
    do shell script "open -a Terminal"
end try

Likewise. This script in an isolated way works:


tell application "System Events"
   tell application process "Hotkey Grid"
       set visible to true
       set frontmost to true
   end tell
end tell

But not in a conditional / try statement…


try
    tell application "System Events" to set visible of process "Terminal" to not visible of process "Terminal"
on error
   tell application "System Events"
      tell application process "Hotkey Grid"
         set visible to true
         set frontmost to true
      end tell
   end tell
end try

I assume this is by design?

ALRIGHT.

AFTER ALL THIS.

This guy had it figured out all along.

http://brettterpstra.com/2011/01/22/quick-tip-applescript-application-toggle/

Also, using FastScripts, the latency when executing is almost nothing as opposed to using Automater… Thank GOD.

I think this solves all of my problems… for now.