SUBMACRO: sm.𝗽𝗮𝗹𝗲𝘁𝘁𝗲⇾MoveMouseToPalette, v4.0

Mouse Move


PURPOSE

This submacro, when run asynchronously immediately before the Show Palette of Macros action, will move the mouse to the upper-left corner of the palette, offset by a specified amount. If the Mouse Offset is specified as two numbers ( X,Y ) the offsets are in pixels. If one or both of the numbers is followed by a percent sign, the number is in percentage of palette width or height. For example 50%,10 would move the mouse to the middle of the palette, 10 pixels from the top.


SETTINGS

local_MouseOffset : If the calling macro does not supply the Mouse Offset via the With Parameter, this variable defines the value that will be used. The default is 10,10 which positions the mouse over the X that can be clicked to close the palette.


CREATING A CALLING MACRO

If this submacro is executed from the Keyboard Maestro Editor using the Run button, a dialog will appear that presents an option to create a calling macro. The dialog will prompt for the Mouse Offset.


RELATED MACRO

Macros that call this macro, via the Execute a Macro action, will include a Show Palette of Macros action. Macros can be manually added to the SPoM action, however, the process can be tedious. For an automated method, see a macro shared by @noisneil: Show a Palette of Macros - Auto-Create and Populate. After using that macro, copy the SPoM action that it creates to the macro that calls this macro.


PROTECTING CALLING MACROS

The first Group action in this macro includes a call to a subroutine (s.𝗸𝗺⇾CheckSubUUID) that will help ensure that current calling macros will work with this and future versions of this submacro.

If an upgraded version of this macro is installed before deleting the previous version (or if this submacro is duplicated), the upgraded version (or duplicate) submacro will display a warning and instructions for repair.

If the import-before-deletion (or duplication) was intended, the warning can be stopped two ways:

  1. The OriginalUUID within the first group action can be modified to match the UUID of the newly imported (or duplicated) submacro.

  2. The first group action can be deleted. If this is done, however, new calling macros will not be protected.

WARNING: If either of these changes is made, old calling macros will no longer refer to this submacro.

For more information (including a download link for s.𝗸𝗺⇾CheckSubUUID), refer to this Keyboard Maestro Forum Tutorial: Avoiding Upgrade Issues with Submacros and Subroutines


UPGRADING THIS MACRO

If upgrading from an earlier version of this submacro, it is imperative to first delete the older version prior to importing this version into Keyboard Maestro. Note that calling macros do not need to be deleted.


TESTED WITH

• Keyboard Maestro 11.0.1
• Sonoma beta 14.2 (23C5030f)/MacBookPro16,1
• Mojave 10.14.16/Macmini6,2
• High Sierra 10.13.6/iMac11,1445


VERSION HISTORY

( expand / collapse )

1.0 initial version

2.0 The Mouse Offset can now be expressed in percentage of palette width or height. For example 50%,10 would move the mouse to the middle of the palette, 10 pixels from the top.

3.0
a) Streamlined the logic in the first Group action. This group includes logic to protect old calling macros by confirming that this macro was properly upgraded.

b) Bug fix: When I created Version 1 of this submacro, I began by downloading and modifying a similar macro by @noisneil. In hindsight, that was a big mistake because Version 1 (and Version 2) of this submacro shared the same UUID as @noisneil's submacro. That causes problems that I won't detail here; but the issue has been resolved with Version 3+. There is one upgrade complication, however (only for Version 3): calling macros to Version 1 or Version 2 will need to be repaired: the Execute a Macro actions will need to be modified to refer to this Version 3. Alternatively, Version 3+ could be run from the Keyboard Maestro Editor to create a new caller and the Execute a Macro action from the new caller could be copied to the old callers.

3.1 No functional change; just minor changes to the dialog messages in the first Group action: To protect old callers, confirm that the macro was properly upgraded.

4.0
a) For the Group action ‘To protect old callers, confirm that the macro was properly upgraded’ moved the logic to a subroutine (s.𝗸𝗺⇾CheckSubUUID).
b) Updated the TECHNICAL NOTE section.
c) Bug fix: If there was an active Keyboard Maestro Search (top-right), the icon intended for the new calling macro was applied to the enclosing macro group.


If upgrading from an earlier version of this submacro, it is imperative to first delete the older version prior to importing this version into Keyboard Maestro. Note that calling macros do not need to be deleted.


Download: sm.𝗽𝗮𝗹𝗲𝘁𝘁𝗲⇾MoveMouseToPalette.kmmacros (138 KB)

Macro-Image


Macro-Notes
  • Macros are always disabled when imported into the Keyboard Maestro Editor.
    • The user must ensure the macro is enabled.
    • The user must also ensure the macro's parent macro-group is enabled.

System Information
  • macOS 14.2 (23C5030f) PRE-RELEASE SEED SOFTWARE
  • Keyboard Maestro v11.0.1

Note that sm.𝗽𝗮𝗹𝗲𝘁𝘁𝗲⇾MoveMouseToPalette calls a subroutine named s.𝗸𝗺⇾CheckSubUUID. This subroutine is optional, but recommended. If it is download and installed, the feature discussed in the header comment (section PROTECTING CALLING MACROS) of sm.𝗽𝗮𝗹𝗲𝘁𝘁𝗲⇾MoveMouseToPalette will be provided.

For more information (including a download link for s.𝗸𝗺⇾CheckSubUUID), refer to this Keyboard Maestro Forum Tutorial: Avoiding Upgrade Issues with Submacros and Subroutines


If sm.𝗽𝗮𝗹𝗲𝘁𝘁𝗲⇾MoveMouseToPalette is executed from the Keyboard Maestro Editor using the Run button, it can create its own calling macros.


Here's an example...

2 Likes

Hi, @peternlewis. In the above submacro, I use the following AppleScript to get the position of a palette created with the Show Palette of Macros action.

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

I tried to retrieve the bounds, but got these errors:

  • 2023-11-17 10:01:54 Action 15394072 failed: Execute an AppleScript failed with script error: text-script:109:115: execution error: System Events got an error: Can’t get bounds of window 1 of process "Keyboard Maestro Engine". (-1728)

When I look at the Keyboard Maestro Engine AppleScript Dictionary it seems that bounds should be available. What am I missing? TIA


I was hoping to get the bounds so that offset could be defined as a percentage of palette width and palette height. In the above macro, I resorted to using absolute pixels from the palette top-left.


2023-11-18 12:4619 EST Update: I discovered that I can return the size, so I can achieve my objective.

tell application "System Events"
	tell process "Keyboard Maestro Engine"
		tell window 1
			set lstPosition to position
			set lstSize to size
			return lstPosition & lstSize
		end tell
	end tell
end tell

However, I still don't understand why bounds seems to be invalid.

This is a really nice touch, and something I think might be applicable in quite a few scenarios. Well done @_jims !

I wonder if perhaps our two approaches could be combined, to give the user the option to:

  • move the palette to the mouse or
  • move the mouse to a position on the palette or
  • both

Also, it would be quite slick if we could add an action group to the submacro that, if enabled, will prompt the user to click (or press a modifier) at the position on the palette that they would like the mouse to arrive at. The offset coordinates would then be displayed in a window, ready to be pasted. This may be overkill, as it's not hard to use the screenshot tool to see x,y, but it did occur to me.

2 Likes

Sure, why not?

As written, by using the Mouse Absolute Offset it can be moved within the palette. (It would be nice to have the capability to specify a percent x & y, but I don't know how to retrieve the palette bounds–see post above.) Am I missing your point?

both as in either or? Or do you want them to both move and split the difference? Or move to some fixed coordinates not related to either?

Sounds pretty cool, but seems like you would always want that group enabled; it would be activated based on some passed value via the With Parameter. Thoughts?

1 Like

I meant that the palette could appear at the mouse position and the mouse could move to a predetermined position relative to it. Kind of what I did in my version but with your finessed approach.

Possibly, if you wanted to move the mouse as part of the subroutine. If a palette is small, you may only wish to have it appear next to the mouse.

If you are able to position the palette at the current mouse position and also position the mouse relative to the palette's corner, then all bases are covered.

Yes, it would be nice to get the width of the palette so that the mouse could programmatically centered horizontally on the palette if desired.

1 Like

Shouldn't that be "via the Execute Macro action..."

Great macro - very useful to me. Thank you.

1 Like

Yes, my mistake. Thanks for pointing that out. :grinning: I will fix that note soon. I’m working on Version 2 that will accept percentage offsets as well as absolute offsets.

1 Like

I've updated the OP with Version 2.0 of sm.𝗽𝗮𝗹𝗲𝘁𝘁𝗲⇾MoveMouseToPalette:

  • The Mouse Offset can now be expressed in percentage of palette width or height. For example 50%,10 would move the mouse to the middle of the palette, 10 pixels from the top.
2 Likes

It does not appear to be complaining about accessing bounds, it is complaining that it “Can’t get window 1”.

I tried your script and had no problem.

The palette of macros will not stay on the screen if you do much of anything, so are you sure the palette is not closing?

Sorry, @peternlewis, originally I put the wrong error from Engine.log in the post. I've corrected it above.

The script works for me when I combine position & size, but not when I attempt to use bounds. I'll send you a DM which will better demonstrate the issue. Thanks!

Email would be better. support@stairways.com

I had sent a DM before I saw this, but I also sent the content via email (just now).

Your script is not accessing the Keyboard Maestro at all, the Keyboard Maestro Engine’s dictionary is irrelevant because your script is not asking Keyboard Maestro for any information.

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

is not using Keyboard Maestro Engine’s dictionary, or talking to the Keyboard Maestro Engine at all.

It is talking to the System Events application. And it is asking System Events about its process named Keyboard Maestro Engine, and is asking System Events about that processes window.

And System Events sdef does not have bounds

This might take a few messages back and forth. I’ll send you a DM.

Bingo!

Thanks for not starting the sentence as, "Hey dummy, your script is not..."

Sometimes when I'm in amongst trees, I miss the forest. :disappointed_relieved:

1 Like

I've updated the OP with Version 3.0 of sm.𝗽𝗮𝗹𝗲𝘁𝘁𝗲⇾MoveMouseToPalette:

  • Streamlined the logic in the first Group action. This group includes logic to protect old calling macros by confirming that this macro was properly upgraded.

  • Bug fix: When I created Version 1 of this submacro, I began by downloading and modifying a similar macro by @noisneil. In hindsight, that was a big mistake because Version 1 (and Version 2) of this submacro shared the same UUID as @noisneil's submacro. That causes problems that I won't detail here; but the issue has been resolved with Version 3+. There is one upgrade complication, however (only for Version 3): calling macros to Version 1 or Version 2 will need to be repaired: the Execute a Macro actions will need to be modified to refer to this Version 3. Alternatively, Version 3+ could be run from the Keyboard Maestro Editor to create a new caller and the Execute a Macro action from the new caller could be copied to the old callers.

1 Like

I've updated the OP with Version 3.1 of sm.𝗽𝗮𝗹𝗲𝘁𝘁𝗲⇾MoveMouseToPalette:

  • No functional change; just minor changes to the dialog messages in the first Group action: To protect old callers, confirm that the macro was properly upgraded.
1 Like

I've updated the OP with Version 4.0 of sm.𝗽𝗮𝗹𝗲𝘁𝘁𝗲⇾MoveMouseToPalette:

  • For the Group action ‘To protect old callers, confirm that the macro was properly upgraded’ moved the logic to a subroutine (s.𝗸𝗺⇾CheckSubUUID).*

  • Bug fix: If there was an active Keyboard Maestro Search (top-right), the icon intended for the new calling macro was applied to the enclosing macro group. (Thanks to @noisneil for reporting the issue.)

*For more information, refer to this Keyboard Maestro Forum Tutorial: Avoiding Upgrade Issues with Submacros and Subroutines

Hey Jim. I haven't had oodles of time the last couple of days, so I'm sorry I haven't been brilliantly responsive.

1 Like