Am I able to refer to a display by its ID instead of First, Main, Second in Move and Resize Front Window action?
I use an iPad with duet display as a fourth monitor, but I don't always have it connected. Using it changes the display hierarchy, messing up certain window macros. Is there a way that I can tell KBM to refer to a specific screen and have it perform actions on that screen no matter what displays are connected?
I'm not trying to argue with you, I'm just trying to understand what you want.
When you say "refer to a display by its ID," what is the ID of a display? In KM, the only ID that it uses is a sequence number starting from left and going to right (top to bottom if they share the same left value.) What is your definition of a display's ID? If I have two 4K monitors, what is the ID for each monitor? When I look at the details of my 4K monitor, I don't see any unique ID number. How is KM supposed to assign IDs to monitors that don't have IDs?
Also, it's not 100% clear whether your phrase "messing up certain window macros" refers to private macros that only you are using, or refers to macros available on this website, or refers to window-related actions available in KM. If you are talking about your own macros, there may be ways to fix that to account for the display changes you are triggering.
I'm just trying to help. My heart is in the right place. Basically, if you want KM to be able to address specific screens by name, there has to be a naming scheme, and I can't see what that scheme could be.
The display's number changes when the iPad is plugged in. Referring to the second display when the iPad is connected does not refer to the same display when the iPad is disconnected. So it messes up macros that perform actions like move a window to the right side of the second display. It would move the window to the display that Keyboard Maestro currently sees as the second display instead of the one that it saw as the second display when the iPad was plugged in.
I am trying to figure out if there's a more robust way of telling Keyboard Maestro to position windows. The "Main" command always refers to the main display no matter what, is there a way I can always refer to specific displays no matter how many monitors I connect or disconnect? Can I ensure that my macros will always work if the displays change?
I'm sure that there is a better way to make this macro, what it does is swap the position of the two most recently accessed apps on a certain display. Or depending on what I'm using it for it will put the two most recent apps into position on that display. I would like to be able to do this with two windows of the same app but I haven't figured out how to do that yet.
But even if I can figure out a better way to execute this macro, it would still be nice to know if I can be sure that the macro will always position the window on the display I intend.
Thanks again, sorry for the poor explanation above.
In my last post I pointed out that there was no unique ID for monitors. Since that's the case, how would you propose that KM specify monitors for you? How do you want KM to distinguish between two monitors if MacOS doesn't have distinguishing names for them? It seems that KM has resolved this problem by giving monitors a number starting from the left/top and going to the right/bottom. That seems reasonable. But if you don't like that method, then what do you propose? If there's no way to name monitors uniquely, how do you propose KM deal with that?
Moving apps across monitors is an extremely difficult process to define, since monitors come in different shapes and sizes. There is a thread about this topic somewhere on this website. I think there are also macros on this website that attempt to deal with that problem.
Nevertheless I have an idea. If your monitors all have unique sizes, then you can use their sizes as their name. That will give you the unique ID to tell which monitor is which.
I wouldn't know about Moom, but many utilities don't hesitate to use undocumented APIs in MacOS, whereas KM refuses to do that. Typically this makes other utilities more powerful than KM, but at the expense of breaking every time MacOS gets upgraded. KM 3.0 still runs on MacOS because it won't use undocumented APIs. Anyway, I don't really know why Moom can do it. But that might explain it.
When you add the iPad, how exactly does it mess up your screen order? KM orders screens from left to right. If you add an iPad in the middle, that will indeed mess up the order of the monitors. But your code can account for that because your iPad has a unique resolution. I can imagine how you could fix your code to work correctly by recognizing the iPad's existence by noticing its unique screen resolution. But if you don't want to update your code to account for that, I understand completely.
That's where I place my iPad too. So I think I have a plan here.
What you could do, I think, is determine if your iPad exists by going through all the screen sizes and checking if any of the screens have the resolution of your iPad. I think you can do this with the WINDOWCOUNT() and WINDOW() functions.
If it exists, then you can take that into account. I presume it's the only "moveable"/"disappearable" monitor in your setup. If the iPad doesn't exist your monitors will exist in some fixed order like 1,2,3,4 but if your iPad is inserted it will exist in some order which I will call 1,2,5,3,4 where 5 is your iPad. (But KM will renumber them as 1,2,3,4,5.)
So does this set your sails in the right direction? You need the WINDOW() function to determine if you have an iPad, and you need the knowledge of your monitors to otherwise know the rest of your arrangement. Does this make sense? I'm trying my best to come up with a solution for you.
You have to decide what you want your macro to do in all the different situations your macro might run.
Screens are numbered left to right, so if you have your iPad below your Main screen, and a screen to the right, the iPad would be number 2 (after the Main screen as number 1 (also 0 or Main)). If you had a screen to the left, your iPad would be number 3 (after the left screen as number 1, and the Main screen as number 2 (also 0 or Main)).
If the only change to your screen setup is whether or not your iPad is connected as a screen, then you can use the SCREENCOUNT function to determine whether it is connected, and adjust your chosen screen appropriately.
You could, for example, use the ternary operator like this:
(SCREENCOUNT() == 3) ? 2 : 0
That would be screen 2 if there are three screens and screen 0 otherwise.
If your screens' arrangement can't be guaranteed then you'll have to derive the current arrangement somehow and then work from there. One way would be to use resolutions -- I've a suspicion that %ScreenResolution%All%is buggy, but you can build your own list.
I've used the nominal resolutions (set in the macro's first Action), searching for those in the generated list. The number of lines up to and including the found text is the screen index of the iPad and if it isn't connected then the search errors and the variable Local_iPadIndex is empty.
Does that reference a screen, or just detect that it is connected? Also, going through system_profiler -- and especially wrapping that shell script in an AppleScript -- is relatively slow so not something you'd want to do in a frequently-used window positioning macro, for example. It is a useful method and I've used it a couple of times since you showed me it, but I don't think it fits here.
Because, importantly -- a Sidecar-connected iPad doesn't seem to have a serial number:
iMac-8382:~ nigel$ system_profiler SPDisplaysDataType
Graphics/Displays:
...
Displays:
iMac:
...
BenQ PD2710QC:
...
Sidecar Display:
Resolution: 2032 x 1620
UI Looks like: 1016 x 810 @ 60.00Hz
Framebuffer Depth: 24-Bit Color (ARGB8888)
Mirror: Off
Connection Type: AirPlay
iMac-8382:~ nigel$
If that's guaranteed the only display without a serial number you'll ever connect you might be able to do something -- but iPad nominal/actual display resolutions are different enough to "proper" screens that resolution will probably be enough of a distinguisher.
I use it to i) detect whether a screen is present ii) match it to a screen number / position and then use the traditional screen references (i.e., 0,1, etc.).
It is more the method I was highlighting as the first AppleScript provides numerous parameters you could match on (i.e., name, resolution, serial number, etc.).
I do not own an iPad or use Sidecar so I cannot test that. If it has a name or a resolution (which is does) then teh approach can be used as i) AppleScript 1 provides the details of each display and ii) AppleScript 2 is easily adjusted to change the criteria from serial number to name, resolution, or other.
I would use teh resolution which is easily extracted from the sample output using a RegEx, here is a sample.
Can you explain how you do these bits? Neither of your scripts do the first, and the second seems non-trivial (to say the least!).
If you can show how to get the index of the Dell in your listing by using the spsdisplays_resolution of 2560 x 1440, that'll be easy to speed test against my version.
I use these tools to determine which display is the main and which display is not the main with sample output as follows where 0 is the main display (lunar also supports terms main, secondary, etc.):
I will note that I have at most two displays so I do not know whether this approach works for 3 or more displays. If you are interested I can test this during the day by adding my travel display.
It is also possible to do this with UID, serial #, etc. as Lunar supports these as well.
To date this has worked well though it does misfire from time to time.
Worth noting:
-- You can simply use this to pull display names / attributes as well with the caveat that I use the AppleScript to do this as it is easier to write to a Keyboard Maestro variable.
-- You can also have different macros for different screen configurations that simply test what screens are connected and then there is no need to assign / test screens. This is the route I ultimately went as it was easier to code and use!
Happy to provide further info should you wish.
PS. I will investigate ways to speed up the AppleScript.
At the moment you seem to be limited to "This is the main display, so this other one isn't". I'm still not seeing how you get to KM screen indexes from that -- in a 2-display setup the "Main" display is index 0 and also either index 1 or 2. How do you work out which?
The problem is that when you connect an iPad via Sidecar (and I'm assuming from the OP that Duet Display is the same) that the iPad will appear at an inconsistent position, so if you already have displays A and B with indexes i1 and i2 respectively:
A_i1 B_i2
...and connect iPad P, you might get any of
P_i1 A_i2 B_i3
or
A_i1 P_i2 B_i3
or
A_i1 B_i2 P_i3
...so it isn't enough to know that the iPad is connected, you also have find out the current arrangement.
(I suspect, from very brief testing, it isn't random but that the host Mac is using radio position detection to work out where the iPad is in relation to itself and trying to set the arrangement accordingly.)
You need to get from system_profiler or lunar output to those KM indices, and I'm not seeing how you do that.