Baffling failure of move app to built-in display macro

I typically use my MacBook attached to a dock that connects it to an external display. My display setup includes the built-in display and the external display as a single Space. I always want my email program (MailMate) to appear on the built-in display, never on the external display. But the KM macro I've created to ensure this doesn't work the first time the app is launched (after login or wake), when the app appears on the external monitor and stays there until the macro is triggered again. The problem isn't with the body of the macro, which works on subsequent runs, but appears to be with the macro triggers. For some reason the triggers don't seem to register in some situations.

To work around this, I've tried putting variations on the macro in various places: not just in the KM folder for my mail app, but in the app launchers folder, and in the Global Macro Group. But nothing seems to work.

Here's my current macro setup for moving the app. If you can suggest what might be going wrong, I'd receive it gratefully. Hopefully, it's just a failure of logic on my part that I can learn from.

(Once again, the steps to move the app work correctly, because when manually run, they work flawlessly. The problem only occurs when the app launches, either via KM or via a non-KM method.)

Global Macro Group (available in all applications):

Triggered by any of the following:

-At System Unlock
-At System Wake
-At Login
-Application “MailMate” launches
-The Display Layout Changed

Will execute the following actions:

If All Conditions Met

-The calculation “SCREENCOUNT() > 1” returns true (non-zero)
-Application “MailMate” is running

Execute the Following Actions:

-Move and Resize Front Window
In MailMate
To: (664,1692, 1680,1050)
Notify on failure.
Otherwise, Execute the Following Actions:

-Move and Resize Front Window
In MailMate

To: (SCREENVISIBLE(Main,Left),SCREENVISIBLE(Main,Top), SCREENVISIBLE(Main,Width),SCREENVISIBLE(Main,Height))

Notify on failure.

It's probably trying to move the window before the window has appeared -- you can test that by putting a long "Pause" at the start of the macro.

If that doesn't help then please upload your actual macro (you'll find instructions at How to Post/Upload your Macros and Scripts) so people can take a proper look -- there's lots of action options that don't show up in your listing that may be important.

1 Like

The pause works well, thanks very much. I kept it at the default 1.5 seconds, but it occurs less than half a second after the window appears on launch, confirming that the macro was triggering before the window was fully drawn.

Pauses can be good solutions. But sometimes it's better to write code that WAITs for a certain condition (like an app being up front, or a menu item becoming available) and THEN takes the necessary action. It's more reliable and runs faster to do it that way.

Well, I admit I assumed that a macro that's triggered when an application launches would wait for that app to launch.

Sorry, I know that the code condition for an app launching may not coincide with my human condition for the same. I've replaced the "app is running" condition in the macro with the "front window exists" condition and we'll see how that does.

An app can be launched with or without a window. You seem to be thinking that "a window" is synonymous with an "app." They are not the same thing. You can have apps with 0, 1 or 100 windows.

So that's the troubleshooting done. Now for the improvements :wink:

KM is told that the app has launched. But it isn't told when the app has finished launching. As @Airy says, the solution is to WAIT for a certain condition to be true -- in this case, that MailMate has a window. This doesn't just make your macro run more briskly, it also prevents errors those times when the delay is longer than you pause allows for.

KM has the "Pause Until..." action for this (change "Finder" to "MailMate"):

image

...and I'd also use the action's "Settings" cog-wheel to "Set Action Timeout...":

...for those times when MailMate is running but doesn't have a window open.

That probably won't work reliably. Your first attempt was failing because the window wasn't there when the "Move" action executed. You're now testing for the presence of the window even earlier in the macro so there's still no window, the Condition will evaluate to false, the "otherwise" block will be executed, and the macro will fail to resize the non-existent window to the visible size of your main screen.

1 Like

These are great improvements. Thank you for the clear tutorial!