Skipping past any details of error-checking etc, you could write:
tell application "System Events"
set procKME to first application process where name = "Keyboard Maestro Engine"
tell front window of procKME to return {title, position, size}
end tell
or
tell application "System Events"
set procKME to first application process where name = "Keyboard Maestro Engine"
set lst to {}
set lstWins to windows of procKME
repeat with oWin in lstWins
set end of lst to {title, position, size} of oWin
end repeat
return lst
end tell
I want to position a palette next to a Finder window, like this:
I'm using your 2 macros - the "Get palette position" and the "Set palette position". If you just think about it for a minute, you'll see why I'm posting this.
Right now I have to call "Get palette position" twice, so I can calculate the width of the palette, so I can position it properly.
I can think of several ways you could modify either or both of your plugins to better accommodate this. You with me?
Let me know if this is something you want to tackle. It's OK if not - I just wanted to check with you. Thanks!
Yeah, theyāre in JXA, and itās taxing my brain to figure it out. I can do it, but itāll take time. Thereās so many syntactical elements Iām unfamiliar with (theyāre not incomprehensible, I just have to think a littleā¦). Iāve seen them all before, but itās not a native language for me, soā¦
Couldnāt you just do it in C#? Then Iād understand it in no time!!
Iāve got an AS version working, so I may just go with that. Weāll see.
tell application "System Events"
set _kme to first application process where name = "Keyboard Maestro Engine"
set _palette to first window of _kme where name = "_Sandbox"
set _size to the size of _palette
return item 1 of _size
end tell
Fāing AS. Took me forever to find the correct syntax for each property. Yeah, just ātellā me these things - only I have to guess the exact wording because God forbid you understand things like Window.Title, Window.Position and Window.Size. And code completion? Naw, thatās too 1990ās.
And I refuse to think about error checking. Honestly, with no defined mechanism for returning exit statuses to KM, it doesnāt really matter. If it doesnāt work, display the results in a window, and Bobās your uncle.
Not exactly rock solid, but if I wanted that, I should have stayed with Windows (HA!).
OK, letās start at the top and work our way down, little by little, a few questions at a time.
Please remember - nothing I say is intended as criticism - this is just how I learn.
I notice that you start the function with some statements, then you have some embedded functions, then some more statements following them. Am I reading that correctly - that JS lets you stick embedded functions anywhere? And assuming Iām correct, why did you structure it that way?
The whole thing is wrapped as an anonymous function (you could also call it function run() { ā¦}) because that avoids pollution of the (overpopulated) global namespace, and, above all, means that your own local variables appear grouped in a separate panel of the the Safari JavaScript debugger.
(Wrapping in an anonymous function to get a local namespace sometimes gets called āthe module patternā in discussions of Javascript)
The name rebindings at the start are a fairly traditional way of ensuring default fall-back values for the arguments of the main function. Have to say that Iām moving away from that now ā prefer to avoid mutation and use fresh names, lower down, that take values from the arguments if they are provided.
JavaScript functions are nestable objects like any other object (you can convert them to strings, use them as values in records, etc etc). Given the āmodule patternā of an outermost anonymous function, you will tend to see some function definitions at the top of the module. (The compiler lifts them there anyway if you place them further down).
One use of the module pattern in OS X scripting is that the arguments to the outer (anonymous) function can be an interface to some broader context. If you are running the JavaScript in a shell script, they might be bash variables bound to KM variable values.
Wanting to play with AppleScript myself I tried to use your code. I get an error when I try...
activate "Mail"
tell application "System Events"
set _kme to first application process where name = "Keyboard Maestro Engine"
set _palette to first window of _kme where name = "Email Palette"
set _size to the size of _palette
return item 1 of _size
end tell
Error:
System Events got an error: Canāt get window 1 of application process "Keyboard Maestro Engine" whose name = "Email Palette". Invalid index.
I took it that your _Sandbox what the name of your palette, is that correct?
My guess is your palette hasn't been displayed yet, after activating Mail. Try putting a delay in, although I'm not sure how to do that in AppleScript. You could activate it in KM and use a KM pause, then run your AppleScript, and see if that's what's wrong.
Ultimately you can trigger your macro when Mail becomes active - the palette will have been displayed by then (I think).
Also, have you seen:
If you download the action (you don't need to install it unless you want to), unzip it and look in the script file, it has all sorts of AppleScript window position stuff in it.
Hereās how I do diagnostics on those sorts of things.
This script is in document 1 of the Script Editor.app (or Script Debugger).
tell application "System Events"
tell application process "Keyboard Maestro Engine"
return properties of windows
end tell
end tell
Then I switch to the app where the palette appears and run this from a Keyboard Maestro macro:
tell application "Script Editor"
tell document 1 to execute
delay 0.25
activate
end tell
That way I get a properly formatted AppleScript record in an AppleScript editor.
I can write any arbitrary code in my AppleScript editor and execute it remotely, and that comes in handy when I need another application to be frontmost for context.
How do I use this? I find installation instructions but no how to use instructions. The Wiki article on Plug In Actions https://wiki.keyboardmaestro.com/manual/Plug_In_Actions doesn't help either. Any other resources to check?
Does anyone already have a KM macro that "memorizes" the position of a given application's KM palettes and can restore them to their memorized position (in case the user has inadvertently moved them)?
In other words, a KM macro that is something like [Desktop Icon Manager] for KM palettes.
Hey there, recording and then setting palettes positions is very doable with AppleScript. Iām not at my computer right now but when I am Iāll share something with you to get you started.
Hi Barry, unless I misunderstood you post, this shouldnāt be an issue. Finder does have AppleScript support, but in this case it's irrelevant since what I understand you want to record is a palette's size/position which is part of the Keyboard Maestro Engine app, not Finder.
EDIT: Hey @BF-H, here is a simple macro that uses AppleScript to record the front palette's position, and then compiles the XML to insert a new AppleScript that will position that palette to wherever it was when the macro was triggered. If you're like me, once you have your palettes positioned where you like them, it's unlikely you'll need to change that from time to time. So I have a variety of macros that position my open apps and palettes for me, and this macro can be used to build another macro designed to position your palettes. It is not designed to record a palette's position, and then restore that later on. It's designed to store the position insert that into the macro that is currently being edited.