"Manipulate a Window" onto a Second Display with Custom Resize Math (Ventura 2023)

Hi, I'm looking for a more up-to-date solution for this:

My issue is that when the window jumps to the other screen, the coordinates are mixed up. It manages to almost work, though! The math seems to not work right when it tries to move the window. I guess there might have been changes in MacOS or KM since this was posted.

I'm using a 5K retina iMac with a 4K monitor beside it. With the help of the forum silently, I've figured out which screen to put the window on, and other parts of the story include a toggle to move a window back and forth with the cursor and one shortcut keystroke.

I also relied on this:

and

Mixed up how?

First step is to define what you want to do -- and the first obvious question (assuming you have the same requirements as the OP in that first linked post) is "what do you mean by 'same position' when the monitors have different resolutions?".

And it's always worth re-stating your problem, including start and desired end points, in your own words and without reference to other posts. You'll often find that they very act of trying to explain things will lead to your own "lightbulb" moment!

Thank you.

I approached my problem with new thoughts this morning. Thanks for the pointers.

So, first step:
I want to be able to execute a macro that moves the front and active window to my other screen and carries the mouse cursor with it. By 'same position,' I mean roughly the same percentage of x and y that the window inherits from one screen and passes to the next.

For the record, my resolutions are nearly the same, but the coordinates differ due to some probably noteworthy differences.

For instance, %ScreenVisible% Top is -114 on the external screen and 25 on the internal screen.
The width of each screen is 2560 and the height is about 1400. It is the height that is giving me the most issues now.

When I run the script, it seems that SCREEN(External) works just as expected. However, SCREEN(Internal) works essentially, but moves the window up (about 114 give or take 25 px I could guess!)

I think I want to add or subtract a consistent amount to make the percentage more accurate, but I'm unsure what I should modify. It's almost a math issue, and I pretty much understand the task I am trying to implement.

One thing I had to fix today was the issue that the external display counts its x-coordinate from negative 2560 to zero!

Thanks, @Nige_S


Phew! Finally came up with Math on the window coordinates which worked for me. My windows, if they are moving, and moving very slowly each move. That's suitable enough!

My approach kept getting out-of-proportion results. I tried to do the math initially based on individual input and output pixel values. That was a flawed approach because (I think due to menu height and the lack of Dock on extended display) the heights of the screens were not the same. I might experiment with %Screen% instead of %ScreenVisible%, but things are working for now. Most of my windows would be "in" the set of expected cases.

Using the different heights, the percentage or pixel value calculations were failing. When I solved that inconsistency, instead of windows floating by varied amounts off target, different one way than the other, suddenly they were flawless every time and now not moving seemingly at all.

Interesting process to go through!

That's how coordinates across the whole display area (all screens) works -- (0,0) is at the top-left corner of the primary display, and any point to the left or above that corner has a negative value.

Easiest way to visualise this is to look at the arrangement in System Settings->Displays, where you can see which is your "primary" display and the logical arrangement (which is not the same as the physical arrangement on your desk!). The arrangement is probably the source of your "top" offset too -- I'm guessing you don't have the top of the displays lined up and the external screen's top is slightly above the internal's. You don't have to arrange them aligned at the top, but it certainly makes the maths easier!

Yes, different SCREENVISIBLEs on your primary and secondary displays will make things tricky. You now have a design decision -- near enough all the time, or perfect most of the time but broken on edge cases. Only you can answer that one!

If you are going to post a macro, please post the actual thing and not just images of parts. A solution that people have to squint at, re-type (and get wrong!), and don't have complete information about (what "is 1" in the condition at the top?) isn't very usable.

1 Like

Here is the Macro is exported following directions shared by Nige_S:

Download: Move-window-left-or-right.kmmacros (9.8 KB)

I should have added "...and include any sub-macros, or at least a description of what they do and the values returned in each case". I'll take a guess that this one uses front window frame and screen sizes to return which display the window is on, 1 or 2. That possibly isn't necessary -- take a look at the Front parameter for the SCREENINDEX() function.

I'm still not entirely sure what you are doing, but my feeling is that things are... overcomplicated. That's probably because I'm a bit confused by your calculations -- what, for example, does this do? (The first case of your "Switch`, some spaces added for clarity.)

When Instance__FrontScreenIndex is 1, move the left border of the window to:

SCREEN(Internal,Left, ( (ExternalScreen.Width+W1.Left) /ExternalScreen.Width*100.000 )%)

Hi,

I attached the subroutine in my very first message. You asked for more info.

Since I gave it already, attaching the subroutine is already done.

You mentioned and others on the related posts that screens can be idiosyncratic.

Since I finished what I wanted, and reported success, you may be the one overcomplicating by asking extra questions.

I definitely appreciate the support. Your questions helped me figure out a better approach. So I thank you, but I'm done with the issue by now. I'm just new to this forum, not getting help in general. I got your help! Thanks!

Apologies -- I hadn't realised that you'd linked to the post with the sub-macro in your OP. Should have checked more carefully.

I usually do :wink:

But you don't need that sub-macro. It was necessary in 2016, but KM has had a couple of major revisions since then and there is now SCREENINDEX(Front).

Indeed, since you are only moving (and not resizing) the window you can reduce the whole macro to two actions:

Move-window-left-or-right copy.kmmacros (3.1 KB)

Image

The calculations are a bit long-winded so you might want to separate them out, calculating your variables then using them in the "Move" action -- I'd certainly do that if, for example, I was applying coordinate offsets depending on which screen was frontmost.

Thanks for explaining! Yes, I realized I was mixing some old and new code, but in the end it worked perfectly.

The main issue I had was moving the window without resizing it because the available screen dimensions were off by less than a couple hundred pixels. On screens with thousands of pixels, they would move close to the intended spot (ratio-specific, not pixel-specific), but then, moving a window back and forth between screens, they would migrate up or down by a set amount.

Because my setup is very static, with the iMac and a set display, I didn't look for a more generalized solution, and the old macro was helpful in generation "1" and "2," which were just my index for the IF conditions. That's the only part I would be interested in swapping out of my macro, because I understand my calculation and it works, two important things for me working on the macro.

Can you tell me more about how I would use SCREENINDEX(Internal) and SCREENINDEX(External)? Just going from (Front) I thought wouldn't work for me, because either display might have the window in focus I want to move.

Don't worry if you have more important things to do! Right now, it's working perfectly as desired for me.

And that's the important bit. Nice one!

IMO they aren't that useful in your situation. Because you have a static setup, your internal (iMac) and external (monitor) indexes will always be the same numbers -- 2 and 1 respectively, because screens are indexed left-to-right, top-to-bottom as shown in "Displays". So you could hard-code those numbers -- if the sub macro returns 2 the active window is on your iMac's screen.

But SCREENINDEX(Front) returns the index of the screen currently containing "the most" of the frontmost window of the frontmost app -- the screen you want to move the window from. In a 2-screen setup like yours, SCREENINDEX(Back) will always return the index of the "non-active" screen, the one you want to move the window to.

So our two macros differ in approach more than anything. Yours has calculations for both possible cases and chooses between them based on which screen has the active window, mine has one calculation that references the current state.

The calculation itself isn't difficult -- for the x coordinate, find the % inset of the left edge of the window from the left edge of the current screen, calculate the equivalent-% coordinate on the other. Do similar for the y. As you've found, the complicated bit is that the coordinate space spans all screens, with 0,0 at the top-left of the Main I did it the long way round to show how to reference the left (or top) edge of each screen, while you used the "% offset" format.

That's tricky to solve without playing around, as it's likely particular to your setup and requirements. You'll have to try combinations of SCREEN and SCREENVISIBLE, depending on your setup, maybe including a MENUBARHEIGHT() offset and even a fiddle-factor number. My calculation will bounce the window from screen to screen without a change of position on a particular screen, but that's not the same as being in the "same" position on both screens!