Multiple Mice - How To Recognize Mice Separately And Their Button Clicks

Trying to assign keyboard keys to mouse button clicks. We have multiple mice plugged into the computer and it works great to assign one mouse’s buttons to trigger keyboard keys through the “This Device Key” trigger. Our problem is that we have multiple mice and want to assign them separate keys for each of their buttons. Example, mouse one left click triggers keyboard key “A” and right click triggers keyboard key “S”. Mouse two left click triggers keyboard key “J” and right click triggers keyboard key “K”.

Our basic goal is to use multiple mice to play local co-op games with them. Some of the games are preset keyboard assignments and it’s very difficult to have four people on one keyboard. We thought assigning our mice to the keys could help with the small space of the keyboard we have been trying to play on.

USB Device Key triggers can tell the devices apart only if they are different devices. So if you get an Apple Mouse and a Microsoft Mouse, you probably can use different buttons. If you have multiple identical mice, Keyboard Maestro cannot tell them apart.

You might also want to use devices like the XK-24 or such.

I have multiple mice that are different brands/makes. All of them are identified in KM as USB Optical Mouse. Maybe I need to look into renaming or changing the system recognition of them?
The reason we are using mice is because they are inexpensive. That XK-24 is rather pricey and way beyond what we would ever need.

Well, if they all report the same USB Device Key name, then you’re out of luck I’m afraid.

I'm trying to get the time (MILIISECONDS()) of a mouse click. Generally using AppleTrackpad, but I'd like it to be general.

I can't seem to set the field in "this device key" ... is pressed. How do I enter "Apple Trackpad" in that field?

IdleClickCounter.kmmacros (1.6 KB)

The USB Device Key trigger can only detect USB device buttons, and only then if the button sends a single bit on and then off, and if the device is not captured exclusively by a driver. It is likely that Apple captures the inbuilt trackpad exclusively, and also possible that the trackpad does not operate via USB, either of which would make it impossible to detect the click I'm afraid.

The primary goal is to get a "good enough" replacement for IDLE(), which seems to reset. I've come up with an approximation, but it doesn't take into account mouse clicks. I really would like to capture when a mouse click happens. That being said, this is a close approximation.
IdleEventCounter.kmmacros (8.5 KB)

I ran a simple test. IDLE() gets reset after my KM DeskTop Wallpaper kicks in (set to run every X minutes, in my case X=30). In those macros, I use the KM action to type a key, ^0 or ^1 to get to a specific screen. So, there is a high likelihood that that action resets the internal timer IDLE() uses. Is there any way around this? It's possible there are some other actions those macros do that also does the reset.

Not a high likelihood -- a certainty!

IDLE() is based on the HID system, so any keypress or mouse action -- actual or simulated -- will reset the timer.

Yes, but no keys were pressed, or mice buttons clicked.

Only the KM ACTIONS for them were performed. There is a difference! If a human presses a key, that’s one thing. If a program invokes an action that simulates it, that’s a different thing.

No -- as far as the HID system is concerned, it's the same thing. If you think they should be treated differently, complain to Apple!

I hope you'll acknowledge that your point is debatable. Apple didn't write the KM IDLE() function.

And I'm not sure what your point is -- KMIDLE() queries the OS to find the current idle time, so is totally dependent on what the OS decides is an idle-breaking event.

Unless you're suggesting that KME should do its own monitoring of all events and maintain its own idle timer, separate from the system's? That sounds like a huge overhead for a very small gain.

Well, maybe a little filtering is in order.

Which got me thinking -- maybe you could get close to this yourself...

What's your purpose? Why does it matter whether an "activity" is actual or simulated? That would inform any route to a solution.

Within KM, if all you are interested in is "what's the idle time excluding resets from KM macros?" then you might be able to:

  1. Maintain a global variable Global_KMIdleTime
  2. Have a periodic macro running, say, every minute that resets Global_KMIdleTime to 0 if IDLE < 60
  3. For every macro containing idle-breaking actions that runs, add IDLE() to Global_KMIdleTime

Then, at any time, your "adjusted idle time" would be IDLE() + Global_KMIdleTime. Resource impact would be directly related to required time resolution.

Totally spit-balling and needs a lot of fleshing-out, but it might give you some ideas on how to approach this from another direction...

I like this idea. I think it’s better than the solution I found. I’ll try it out.

You might also want to look into MetaGrid and build a console on an iPhone or iPad that triggers KM Macros. It's like a Streamdeck without the limitation of a set number of buttons.

I worked on this for nearly 6 hours. Although your suggestion had a lot of merit, implementing it is very difficult, and I was not comfortable with the reliability of the result.

The problem is this: There are too many code paths to identify and get to a complete set of idle-breaking (I like that term by the way). The principle issue is the “type a key” action, which are sprinkled liberally throughout my code. Why?

Keys are the way to navigate spaces. It’s not just the hot key to get to the first space on screen 1 or the first space on screen 2. It’s also the way one scrolls among spaces.

You ask what the purpose is. I’ve written a very sophisticated wallpaper management subsystem during the pandemic. Magazines, museums, newspapers, and more have released a lot of high quality jpegs during the pandemic, and I have a large collection of them. No, I don’t distributed them, but the software to manage them is posted in the KM Forum. From there, It was easy to develop a screensaver.

I also wrote a macro to manually turn off the screen to save energy.

The problem was when I combined the two I started running into a lot of complexity. The Idle trigger was insufficient, since IDLE() was being reset by the screensaver. I did work out a system that works that looked at USB device keys, and window change events, and then wrote a system to trim the logs, since they were getting pretty large (type a key, type a left or right shift, left or right option, page up and down, etc. This worked but as you might imagine it generated too many events, and I was concerned about the overhead.

So, I backed out of it for now. If I want to turn off the screen, I have a hot key trigger. It will do for now.

Again, thanks for trying to help.

Frankly -- as a Spaces user, you're stuffed so long as Apple leaves that unscriptable. Not using Spaces myself I don't know if you can get round it (if you activate a window with eg KM or AppleScript, does the OS switch to that Space?) or whether you'll be left hanging until someone in the Shortcuts team takes an interest and argues the Spaces team into adding the necessary hooks.