Moving/Resizing Application Windows & Positioning/Sizing Keyboard Maestro GUI Elements With WindowArgs, v3.0

WindowArgs


Keyboard Maestro Version 11+ Required


BACKGROUND

Keyboard Maestro includes actions, functions, and tokens that can be used to move and resize existing application windows. A similar action can be used to position and, in some cases, size Keyboard Maestro GUI elements (a.k.a. engine windows). The latter includes Display Text windows, Prompt For User Input dialogs, Prompt With List lists, and Custom HTML Prompt windows.

The action menus include some presets that can be selected to automatically enter X, Y, Width, and Height for common positions and sizes.

If one of those presets meets your needs, then this forum post is likely moot!


INTRODUCTION TO WINDOWARGS

The purpose of this forum post is to share a method to easily leverage the power of the native Keyboard Maestro window-related actions and functions using a simple text string that includes five arguments (four required, the fifth optional). This text string, dubbed WindowArgs, has the following characteristics and capability:

  • Window positions and sizes can be specified using:

    • Screen Percentages
    • Screen Points (Points == Density-Independent Pixels)
    • Units can be mixed; for example, width could be in points and height in percent of screen height.
  • Only considers the visible section of the screen; this excludes the menu bar and the Dock, that is, if they are not hidden.

  • Windows can be left-, top-, right- and/or bottom-justified.

  • Windows can be centered and mixed with justification. For example, a window could be centered horizontally and bottom-justified.

  • Centered windows can be offset from the center by a fixed number of points or a percentage of the visible screen dimension. Right- and bottom-justified windows can be offset from the respective edges, leftward and upward, respectively.

  • Positions of the macOS menu bar and Dock are considered when centering and justifying windows.

  • Can be used to position and size application windows and Keyboard Maestro GUI elements, i.e., Display Text windows, Prompt For User Input dialogs, Prompt With List lists, and Custom HTML Prompt windows.

  • Can correct an inconsistency with Custom HTML Prompt (Has Title checked) window positioning and sizing. For more information, see Position & Size of 'Custom HTML Prompt' Windows Measure Differently Than Other Windows.

  • Window size and position are automatically constrained to remain fully within the visible screen area, i.e., a window can never be placed partially or fully outside this area.


QUICK START

A WindowArgs string is a compact way to describe a window's position and size relative to the visible screen area (SCREENVISIBLE), automatically accounting for the macOS menu bar and any visible Dock.

Each WindowArgs string consists of four required arguments and one optional argument: X Y W H F

Argument Meaning
X Horizontal position
Y Vertical position
W Window width
H Window height
F Optional title bar compensation flag (must be the fifth and final argument, if present)

For example: >2% =-10 850 40%

means:

  • Position the window 2% of the screen width left of the right edge.
  • Position the window 10 points of the screen height above centered vertically.
  • Make the window 850 points wide.
  • Make the window 40% of the screen height.

See the subsequent sections for the complete WindowArgs reference.


WINDOWARGS SYNTAX

WindowArgs include four required and one optional arguments: X Y W H F

All position and size values are relative to SCREENVISIBLE, the usable screen area which excludes the menu bar and Dock (if they are not hidden).


X – horizontal position:

       Syntax            Meaning    
n Left edge n pts from left
m% Left edge at m% of width from left
| Centered horizontally within area
|n, |m% Centered horizontally + offset rightward n pts or m% of width
|-n, |-m% Centered horizontally − offset leftward n pts or m% of width
> Right edge flush with right
>n, >m% Right edge inset (i.e., leftward) n pts or m% of width

Y – vertical position:

       Syntax            Meaning    
n Top edge n pts from top
m% Top edge at m% of height from top
= Centered vertically within the visible area (preferred)
=n=m% Centered vertically + offset downward n pts or m% of height
=-n, =-m% Centered vertically − offset upward n pts or m% of height
v Bottom edge flush with bottom
vn, vm% Bottom edge inset (i.e., upward) n pts or m% of height from bottom
- Centered vertically (deprecated; use = instead; offset not supported when using -)

W – window width:

       Syntax            Meaning    
n n pts wide
m% m% of width

H – window height (or with Custom HTML Prompt window, the height of the content area):

       Syntax            Meaning    
n n pts tall
m% m% of height

Size constraint: W and H are constrained before position is resolved. Width cannot exceed visible width; height cannot exceed visible height (minus 19 pts when Has Title is checked). Values less than 1 pt are treated as 1 pt. The constrained size is used when computing all centered and edge-flush positions, so the window is always correctly placed relative to its actual dimensions.


F – optional title bar flag for Custom HTML Prompt (Has Title is checked) windows when using the action code to position the window:

       Syntax            Meaning    
absent, blank, or 0 No title bar compensation; output is x,y,w,h
+1 Apply 19 pt title bar compensation; output is x,y,w,h,1
x or any non-zero value other than the literal +1 Apply 19 pt title bar compensation; output is x,y,w,h

1 and +1 are not the same value here. Both apply title bar compensation, but only the literal +1 produces the 5-value x,y,w,h,1 output; a plain 1 (or x, or any other non-zero value) produces the 4-value x,y,w,h output. Use +1 specifically when you need the trailing ,1 flag for downstream code.

The trailing ,1 can be used to indicate to Custom HTML Prompt action code that Has Title position compensation was used by WindowArgs when generating local_WF.

Position constraint: After X and Y are resolved, the final position is constrained so the window remains fully within the visible area. The left edge cannot be less than visible left, the top edge cannot be less than visible top, the right edge cannot exceed visible right, and the bottom edge cannot exceed visible bottom. This means an offset or absolute position that would push the window partially off screen is automatically pulled back to keep it fully visible.


INCONSISTENCY WHEN POSITIONING CUSTOM HTML PROMPT WINDOWS

When using the Set Next Engine Window action, Custom HTML Prompt windows can be positioned like all other, i.e., Display Text windows, Prompt For User Input dialogs, Prompt With List lists. However, when Custom HTML Prompt windows are positioned via the action code using data-kmwindow or KMWindow(), the Y coordinate is always relative to the top edge of the content, even if the window has a title bar (Has Title is checked in the action gear menu).

For example, if one wanted to position a Custom HTML Prompt window 5 points to the right of the left edge of the display and 5 points below the macOS menu bar, then the following X,Y would be required:

  • 5,36 if Has Title is unchecked
  • 5,55 if Has Title is checked

5 points == specified offset
31 points == height of macOS menu bar
19 points == height of window title bar

With WindowArgs, this shift can be triggered by setting the optional fifth argument, F (to any value except 0). Note that F is purely a position correction; it does not affect the content area height.

If Has Title is not checked, this flag should not be set. And even if Has Title is checked, the flag should not be set if the Set Next Engine Window action is used to position the Custom HTML Prompt.


EXAMPLE WINDOWARGS

        WindowArgs         Description
0 0 50% 75% Top-left corner; 50% width; 75% height
10% 20 1000 90% 10% from left; 20 pts from top; 1000 pts wide; 90% height
| = 60% 700 Centered horizontally and vertically; 60% width; 700 pts tall
| =20 800 500 Centered horizontally; centered vertically 20 pts down; 800×500 pts
| =-10% 800 500 Centered horizontally; centered vertically 10% height upward; 800×500 pts
|50 = 600 400 Centered horizontally 50 pts rightward; centered vertically; 600×400 pts
|-20% = 600 400 Centered horizontally 20% width leftward; centered vertically; 600×400 pts
> = 50% 60% Right-justified; centered vertically; 50% width; 60% height
> v 850 40% Right-justified; bottom-justified; 850 pts wide; 40% height
>50 v 850 40% Right edge inset 50 pts leftward from right; bottom-justified; 850 pts wide; 40% height
> v20% 850 40% Right-justified; bottom edge inset 20% height upward from bottom; 850 pts wide; 40% height
> v 850 40% x Right-justified; bottom-justified; 850 pts wide; 40% height; Has Title compensation applied → output x,y,w,h
> v 850 40% +1 Right-justified; bottom-justified; 850 pts wide; 40% height; Has Title compensation applied → output x,y,w,h,1
> v 850 40% 0 Right-justified; bottom-justified; 850 pts wide; 40% height; 0 = no compensation → output x,y,w,h

WINDOWARGS DOWNLOADS

Upgrade Instructions: If you have previously installed the following subroutines, delete them before installing the versions below.* Any macros calling the WindowArgs subroutines can be retained and should function as expected with the updated subroutines below.

To use the WindowArgs logic described in the sections above, download and install the following:

Download: WindowArgs Subroutines.kmmacros (34.2 KB)

The above download includes two WindowArgs subroutine macros. The subsection below describes each.

Download: WindowArgs Macros.kmmacros (194.8 KB)

The above download includes two Application Window macros*, six Keyboard Maestro GUI macros, and five Window Tool macros. The subsections below describe each component found in the download.

*If you are curious why previous versions must be deleted before installing new versions, refer to Avoiding Upgrade Issues with Submacros and Subroutines. To find the old version of the subroutines and all callers, search using the noted UUID's below.


WindowArgs Subroutines

s.𝘄𝗶𝗻𝗱𝗼𝘄⇾WindowArgs X Y W H F to WindowFrame

UUID: 229A6201-8F48-4664-98C3-88F05847D7FD

This primary subroutine includes the main logic which converts a WindowArgs string to a WindowFrame. This subroutine can be used in several ways which are demonstrated in the two subsections below.

Subroutine-Image


s.𝘄𝗶𝗻𝗱𝗼𝘄⇾WindowArgs X Y F + WindowFrame W H to Adjusted WindowFrame

UUID: 2F54F591-0716-4437-ABB2-D053301B7EB5

The second subroutine is more specialized. Its function is described in the next subsection.

Subroutine-Image


Application Window Macros

The two macros in this subsection demonstrate how Application Windows can be moved and resized using the WindowAgrs subroutine(s).

Move & Resize a Window using WindowArgs X Y W H

This macro includes a group that can be added to the Favorite Actions (Action > Add to Favorites). This group calls the primary subroutine listed in the subsection above, and also calls WT 0–Get Window Absolute WindowFrame to display the window's resulting position and size in a dialog for confirmation.

Implementation is straightforward: simply insert the groups after the macro action(s) that create a window (e.g., a Finder window; a browser window) and then change the WindowArgs arguments based on the desired requirements.

Macro-Image


Move & Resize a Window using WindowArgs X Y W H (w/ check+correction)

This second macro includes a group that includes calls to both subroutines. The second subroutine includes logic to handle situations when the width and/or height within the WindowArgs are not achievable because the window being resized has some built-in constraints (e.g., minimum width and/or minimum height). For example, the Keyboard Maestro editor window has a minimum width and height.

Like the macro above, this one also calls WT 0–Get Window Absolute WindowFrame to display the window's resulting position and size in a dialog for confirmation.

Note that neither of groups in the two macros above will have any effect on Display Text windows, Prompt For User Input dialogs, Prompt With List lists, and Custom HTML Prompt windows because the Keyboard Maestro Manipulate a Window action does not recognize these as windows. To apply WindowArgs to these Keyboard Maestro GUI elements, see the subsection below.

Macro-Image


Keyboard Maestro GUI ( KMG ) Macros

The six macros in this subsection demonstrate how Keyboard Maestro GUI elements can be positioned and sized using the primary WindowAgrs subroutine.

KMG 1–Display Text [position/size via WindowArgs → Set Next Engine Window]

  • The WindowArgs subroutine computes a frame saved to local_WF.
  • local_WF is then used within a Set Next Engine Window action to preset the position and size of a Display Text action window.
Macro-Image


KMG 2–Prompt for User Input [position via WindowArgs → Set Next Engine Window]

  • The width and height of a Prompt for User Input dialog cannot be set by a KM action because both dimensions are determined intrinsically based on the dialog content. Thus, the Set Next Engine Window action can only preset the position of the dialog.
  • For centered, right-, or bottom-aligned dialogs (|, >, =, v), WindowArgs requires the actual W and H to properly compute the position. By setting WindowArgs to 0 0 0 0, the dialog can be rendered and its width and height displayed using the WT 2–Get Prompt for User Input Dialog Absolute WindowFrame macro. WindowArgs can then be set to the desired X and Y with the measured W and H.
  • From the calculated local_WF, the position is used in a Set Next Engine Window action preceding the Prompt for User Input action.
Macro-Image


KMG 3–Prompt With List [position via WindowArgs → Set Next Engine Window]

  • The width and height of a Prompt With List list cannot be set by a KM action–both dimensions depend on gear settings and/or list content. Thus, the Set Next Engine Window action can only preset the position of the list.
  • For centered, right-, or bottom-aligned windows (|, >, =, v), WindowArgs requires the actual W and H to properly compute the position. By setting WindowArgs to 0 0 0 0, the list can be rendered and its width and height displayed using the WT 3–Get Prompt with List Absolute WindowFrame macro. WindowArgs can then be set to the desired X and Y with the measured W and H.
  • From the calculated local_WF, the position is used in a Set Next Engine Window action preceding the Prompt With List action.
Macro-Image


KMG 4–Custom HTML Prompt [position via WindowArgs → data-kmwindow]

  • The width and height of a Custom HTML Prompt window cannot be set by a KM action when no size is specified within the HTML because both dimensions are determined intrinsically based on the content. Thus, the Set Next Engine Window action can only preset the position of the window.
  • For centered, right-, or bottom-aligned windows (|, >, =, v), WindowArgs requires the actual W and H to properly compute the position. By setting WindowArgs to 0 0 0 0, the window can be rendered and its width and height displayed using the WT 4–Get Custom HTML Prompt Absolute WindowFrame macro. WindowArgs can then be set to the desired X and Y with the measured W and H.
  • Unlike KMG 5 and KMG 6, no title bar compensation is needed because the Set Next Engine Window action automatically detects whether Has Title is checked in the Custom HTML Prompt action and adjusts accordingly.
Macro-Image


KMG 5–Custom HTML Prompt [position/size via WindowArgs → data-kmwindow]

  • Unlike KMG 4, title bar compensation is needed because the Custom HTML Prompt is positioned via the action code (see data-kmwindow). If Has Title is checked, WindowArgs will properly compensate if the fifth argument, F, is set (to any value except 0). Conversely, if Has Title is not checked, F should not be set (or set to 0).
  • Because data-kmwindow is parsed from static HTML at load time and KM variables cannot be resolved at that point, the HTML is first stored in local_HTML via a Set Variable to Text action, which resolves local_WF values at that stage. The Custom HTML Prompt action then contains only document.write(GetVariable('local_HTML')) to inject the pre-resolved HTML.
Macro-Image


KMG 6–Custom HTML Prompt [position/size via WindowArgs → KMWindow()]

  • Unlike KMG 4, title bar compensation is needed because the Custom HTML Prompt is positioned via the action code (see KMWindow()). If Has Title is checked, WindowArgs will properly compensate if the fifth argument, F, is set (to any value except 0). Conversely, if Has Title is not checked, F should not be set (or set to 0).
  • A key advantage over data-kmwindow (used in KMG 5) is that KM variables can be read directly at execution time inside KMWindow(), so no Set Variable to Text pre-resolution step or document.write indirection is needed.
Macro-Image


Window Tools ( WT )

The macros in the above subsections use the following utility macros.

WT 0–Get Window Absolute WindowFrame

Macro-Image


WT 1–Get Display Text Absolute WindowFrame

Macro-Image


WT 2–Get Prompt for User Input Dialog Absolute WindowFrame

Macro-Image


WT 3–Get Prompt with List Absolute WindowFrame

Macro-Image


WT 4–Get Custom HTML Prompt Absolute WindowFrame

Macro-Image


WINDOW-RELATED FORUM THREADS

The forum includes several other threads related to this topic. This is far from exhaustive, but here are a few that you might find helpful. Please comment below if there are others that you would like to share.

5 Likes

This looks great! My tool has been feeling a bit unresponsive recently. I’m looking forward to trying yours. Thanks for such a detailed write up.

1 Like

I've updated the OP with Version 2.0 for two of the downloads:

  1. Move & Resize a Window using WindowArgs X Y W H, and

  2. Move & Resize a Window using WindowArgs X Y W H (w/ check+correction)

To help circumvent a well-known macOS issue with window positioning and resizing, added a repeat to enclose the Manipulate a Window action. For more information, see: Bug report: Window positioning + resize failing in KM11, by @cdthomer.

2 Likes

Thanks for this macro. I just started using it for my claude generated html prompts. I pasted your comment for the macro description into claude and told it to follow your instruction when giving me a new html prompt. It now produces html that works with your s.𝘄𝗶𝗻𝗱𝗼𝘄⇾WindowArgs X Y W H F to WindowFrame macro. Nice.

1 Like

Keyboard Maestro Version 11+ Required

I've updated the OP with Version 3.0:

  1. Enhanced X and Y syntax for greater flexibility

    • X
      • | (center horizontally) now supports offsets: |n or |m% (rightward) and |-n or |-m% (leftward).
      • > (right-justify) now supports insets: >n or >m% (move leftward from right edge).
    • Y
      • = is now the preferred vertical center operator (replaces deprecated -) and supports offsets: =n or =m% (downward) and =-n or =-m% (upward).
      • v (bottom-justify) now supports insets: vn or vm% (move upward from bottom).
        The old - operator is retained for backward compatibility but is deprecated.
  2. Improved size handling (constraints)
    Width and height are now automatically constrained to the visible screen area before position calculations. Oversized values are reduced accordingly, and values < 1 pt are treated as 1 pt.

  3. Improved position handling (constraints)
    Final window position is now automatically constrained so the window stays fully within the visible screen area regardless of offsets or absolute coordinates.

  4. F flag / title bar compensation enhancements
    When the optional fifth argument F is set to literal +1 the subroutine now returns a 5-value string x,y,w,h,1. The trailing ,1 can serve as an flag for Custom HTML Prompt code indicating that title bar compensation was applied. For backward compatibility, any non-zero value will trigger shifting for title bar compensation.

The trailing ,1 flag will be used in a future tutorial to demonstrate detecting manual moves/resizes of Custom HTML Prompt windows. This will include conditionally restoring the user-adjusted position and size.

  1. Documentation & examples overhaul
    • Expanded tables with clearer syntax explanations, more examples (including new offset/inset cases).
    • Better coverage of Custom HTML Prompt title bar behavior and when to use F.
    • Added upgrade note: Delete previous subroutine versions before importing new ones (with link to the avoiding-upgrade-issues thread).
    • Refined macro descriptions and Window Tools section.

These changes make WindowArgs more powerful while maintaining full backward compatibility for existing callers.