Find coordinates of front most window, including alerts, dialog window, etc

Sometimes I want to set a very specific position for an alert, dialog window, etc.
Using the window tokens and trying to guess their values is always a big confusing to me and something that seems very slow.

I was trying to find a way to have an AppleScript that gets the X and Y values of the frontmost window (which I will drag to the desired position), relative to the top left corner of the screen and then save those values to the clipboard, but no matter what I do, I can't make it work.

For example this script gets the coordinates of Keyboard Maestro's Editor window, but not a dialog box that I "triggered" from a different macro, even when I click it to make it the focus (and frontmost) window:

tell application "System Events"
	set frontApp to first application process whose frontmost is true
	tell front window of frontApp
		set windowPosition to position
	end tell
end tell

It seems that the script is ignoring the dialog as the frontmost window.

I then went to Activity Monitor and saw that I have 3 "osascript" processes running and when I close the dialog window I triggered, I get 2, so that tells me that the process I need to target is osascript so I used:

tell application "System Events"
	tell front window of "osascript"
		set windowPosition to position
	end tell
end tell

but since I have 3, how would it know which to target?
So I get this error, not sure if it's related?
2024-06-08 09:46:32 Action 15910677 failed: Execute an AppleScript failed with script error: text-script:91:99: execution error: The variable position is not defined. (-2753)

So how could I target the frontmost window of the osascript window?

I even tried an IF THEN action with a condition to check the title of the dialog window, but that doesn't work either. It always shows me a "false" result.
image

When I hover over the dialog window using UI Browser I get that the application is osascript and it's window 1. Those are the only 2 things in UI Browser

After some research it seems that a dialog window isn't a "normal" window (I can't explain it in a more basic way than this). It seems that a dialog box can't be easily manipulated via AppleScript (I was trying to add the coordinates on the AppleScript itself, but it wasn't working either).

Even the Set Next Engine Window Position, Center Next Engine Window and Move Last Engine Window to Position actions weren't working, so I guess I will have to deal with the fact that I won't be able to move a dialog window.

This just sucks, because if I have 2 or more dialog window being open (I have these because I need multiple messages to show in the morning) they just overlap.

If you open a Keyboard Maestro Alert, you can run this AppleScript in another Macro to get its position:

tell application "System Events"
	tell application process "Keyboard Maestro Engine"
		get position of window "Keyboard Maestro Alert"
	end tell
end tell

This assumes the Alert has the default name "Keyboard Maestro Alert"

The below works for me:

1 Like

Yes, with Alerts it does work, but not with a Dialog window created via AppleScript (via display dialog)

An AppleScript dialog isn't a window, and can't be manipulated like one. And it isn't a KM Engine Window, so none of those actions will work.

If you want that sort of control over dialog/alerts you'll have to either use KM's (including Custom HTML Prompts) or try something else -- take a look at swiftDialog.

Building on @Zabobon's script (through trial and error, and LLM support), here's a script that returns the position and size of the last window from the Keyboard Maestro Engine (not needing to reference the window name):


tell application "System Events" to tell process "Keyboard Maestro Engine"
      return {position of last window, size of last window}
end tell

And one that sets the window's position and size, from "x,y,width,height" values set from KM local variable "local__windowFrame":


set instanceID to system attribute "KMINSTANCE"

tell application "Keyboard Maestro Engine"
      set windowData to getvariable "local__windowFrame" instance instanceID
end tell

set AppleScript's text item delimiters to {","}
set {x, y, width, height} to text items of windowData

tell application "System Events" to tell process "Keyboard Maestro Engine"
      set position of last window to {x as integer, y as integer}
      set size of last window to {width as integer, height as integer}
end tell

"last window" seems to consistently reference any recently spawned Engine window from my testing, but referencing front window also works, and might make sense in some situations.

Both scripts seem to work well with all Keyboard Maestro Engine Windows: Alert, Display Text in Window, Display Progress, Prompt for User Input, Prompt With List, Prompt for Snippet, Display System Clipboard. Even windows like: Prompt for File, Applications Palette, Active Macro Groups Window, and the Debugger Window – windows that are not manipulatable through actions like the Move Last Engine Window – seem to play well with these AppleScripts!


Note that some windows, the Alert and the Prompts, as well as the Debugger (and display dialog windows from an AppleScript), control the flow of the executing macro. So if you'd like to use these scripts to interact with these, you'd have to do so from a separate asynchronously run macro.

Something like this (using the setting position of a display dialog window from an AppleScript, from the post below, as an example):

TEST Set position of Applescript Dialog Macros.kmmacros (4.7 KB)
(KM v11.0.3)

Macro Images

1 Like

As noted by @alltiagocom, windows displayed from display dialog in an AppleScript need to be referenced as an osascript window (not a Keyboard Maestro Engine window) even when the AppleScript is run from an action in KM. So to return or set the position of a display dialog window, you'd have to swap out Keyboard Maestro Engine for osascript, as the process.

Like this to return the position and size of the last osascript window:


tell application "System Events" to tell process "osascript"
      return {position of last window, size of last window}
end tell

And this to set the position of the last osascript window (display dialog windows are not resizable, but the script runs all the same even if "local__windowFrame" also holds values for sizing):


set instanceID to system attribute "KMINSTANCE"

tell application "Keyboard Maestro Engine"
      set windowData to getvariable "local__windowFrame" instance instanceID
end tell

set AppleScript's text item delimiters to {","}
set {x, y} to text items of windowData

tell application "System Events" to tell process "osascript"
      set position of last window to {x as integer, y as integer}
end tell


Someone better at AppleScripting than me could build the logic to tell System Event to tell osascript to return position of last window if there were no KM Engine window, or vice versa. However, as these simple scripts simply fail if there are no KM Engine or osascript windows to be found, the scripts can be combined in KM through Try/Catch logic, like this (getting quite close to OP's original request):

Keyboard Maestro Export


Lastly, window coordinates are returned from AppleScript with spaces after each comma, as opposed to comma-only delimited values, as from KM tokens like %WindowFrame%1%. The calculation fields in KM actions have no problem interpreting these coordinates with added spaces — however, before I realized this, I made this Shell script running the AppleScript with a translate at the end, deleting any whitespace character.

So, if you want coordinates without spaces, here you go:

osascript -e 'tell application "System Events" to tell process "osascript" to return {position of front window, size of front window}' | tr -d ' '