polygon icon indicating copy to clipboard operation
polygon copied to clipboard

feat: Add Maximize, Almost Maximize, Next Monitor and Previous Monitor

Open shaqaruden opened this issue 1 year ago • 16 comments

✅ Maximize ✅ Almost Maximize 🚧 Next Monitor 🚧 Previous Monitor

❌ Run Thorough tests

shaqaruden avatar Nov 30 '23 19:11 shaqaruden

I have no previous experience with AutoHotKey Script. Everything I have written either borrows from what is already there or from reading the docs so if there are issues with the code itself or better ways to do something, please bring it up.

shaqaruden avatar Nov 30 '23 19:11 shaqaruden

@thesobercoder I'm not sure if you have a mac or not but I do so I will bring it in to work tomorrow and try out Rectangle functionality on my monitors (2 Landscape & 1 Portrait)

shaqaruden avatar Nov 30 '23 21:11 shaqaruden

@thesobercoder Ok so this is what Rectangle does with Windows in different scenarios.

Window Almost Maximized moved from Macbook display to portrait display Full Width/Maintain Height

Window Almost Maximized moved from portrait display to Macbook display Maintain Width/Full Height

Window Maximized moved from Macbook display to portrait display Full Width/Full Height or Full Width/Maintain Height

Window Maximized moved from portrait display to Macbook display Full Width/Full Height

Window Top-Right Quarter moved from Macbook display to portrait display Maintains Width/Maintains Height

Window Top-Right Quarter moved from portrait display to Macbook display Maintains Width/Maintains Height

In all scenarios, the window was positioned in the center of the display.

So it looks like the rule is, if the width or height is greater than the width or height of the display it is moving to it is resized to fit the full width or height of the display.

Another thing I thought of was, how does AutoHotkey handle different resolutions?

shaqaruden avatar Dec 01 '23 21:12 shaqaruden

@thesobercoder Ok so this is what Rectangle does with Windows in different scenarios.

Window Almost Maximized moved from Macbook display to portrait display Full Width/Maintain Height

Window Almost Maximized moved from portrait display to Macbook display Maintain Width/Full Height

Window Maximized moved from Macbook display to portrait display Full Width/Full Height or Full Width/Maintain Height

Window Maximized moved from portrait display to Macbook display Full Width/Full Height

Window Top-Right Quarter moved from Macbook display to portrait display Maintains Width/Maintains Height

Window Top-Right Quarter moved from portrait display to Macbook display Maintains Width/Maintains Height

In all scenarios, the window was positioned in the center of the display.

So it looks like the rule is, if the width or height is greater than the width or height of the display it is moving to it is resized to fit the full width or height of the display.

Another thing I thought of was, how does AutoHotkey handle different resolutions?

@shaqaruden I think the Rectangle layout logic you laid out above makes complete sense. To your second question, I think AutoHotkey itself doesn't handle resolution by itself and calls underlying Win32 APIs to get the job done. So Windows is in control of repainting the GUI to match the resolution.

thesobercoder avatar Dec 02 '23 07:12 thesobercoder

@shaqaruden I think the Rectangle layout logic you laid out above makes complete sense. To your second question, I think AutoHotkey itself doesn't handle resolution by itself and calls underlying Win32 APIs to get the job done. So Windows is in control of repainting the GUI to match the resolution.

I will begin to implement this behavior

shaqaruden avatar Dec 02 '23 16:12 shaqaruden

Quick update on this. I have been pretty busy the last couple weeks I haven't had a chance to work on this until today. Next and Previous monitor are almost ready, just bugs related to high res displays.

I came across, when moving a window from my portrait display to a landscape display the CheckWindowWithinMonitor() function not working. I did not see this function used anywhere so I rewrote this function as GetActiveWindowMonitorNumber(). This new method returns the monitor the provided window is on. It take into account a window being across multiple displays as well. If a window is 30% on monitor 1 and 70% on monitor 2, it will return monitor 2. If a window is 51% on monitor 1 and 49% on monitor 2 it will return monitor 1. It calculates the area of each monitor the monitor covers.

I also implemented the Rectangle app logic when moving a oversized window (w or h) and I added this method that displays monitor info. This will likely be deleted before this PR is merged

shaqaruden avatar Dec 21 '23 20:12 shaqaruden

I came across, when moving a window from my portrait display to a landscape display the CheckWindowWithinMonitor() function not working. I did not see this function used anywhere so I rewrote this function as GetActiveWindowMonitorNumber().

The main function GetWindowRectEx() which is used on all layouts uses the CheckWindowWithinMonitor() function. If you're going to replace it, please run thorough tests before raising the PR.

thesobercoder avatar Dec 22 '23 11:12 thesobercoder

The main function GetWindowRectEx() which is used on all layouts uses the CheckWindowWithinMonitor() function. If you're going to replace it, please run thorough tests before raising the PR.

I have added this to my list

shaqaruden avatar Dec 22 '23 12:12 shaqaruden

I have been dog fooding my changes for a while now and I have noticed that if I go between using just my high dpi laptop display and my desktop monitors I need to restart the script to get proper sizing again. I'm guessing this is due to the AHK only retrieving display details on initial load.

I also noticed that when running my laptop display with a single external display and my laptop display, I also have issues with the script working on both displays (works on which ever display I have set as main but the other does the same as if I had switched between using just my laptop display and using just my desktop displays.

shaqaruden avatar Feb 14 '24 13:02 shaqaruden

One thing I forgot to mention is with using both my laptop display and 1 or more of my desktop displays. The original released version does not do anything on the laptop display but works fine on the desktop display(s). So I believe this is one thing I have "improved" with my update to GetActiveWindowMonitorNumber though now the issue I talked about in my last comment now exists.

Any ideas on how we could solve this? Maybe this is something that needs to be lived with due to a limitation of AHK?

shaqaruden avatar Feb 14 '24 13:02 shaqaruden

Any ideas on how we could solve this? Maybe this is something that needs to be lived with due to a limitation of AHK?

It indeed might be a limitation with AHK. I haven't had an opportunity to look at it recently. The DPI thing is really an issue with AHK. At one point, I was tempted to rewrite Polygon in Rust, but I just don't have enough knowledge of the Windows API.

thesobercoder avatar Feb 16 '24 15:02 thesobercoder

I kind of had the same thought that maybe it should be written as a native windows app but I also lack the knowledge required for that.

I was to come across this in the documentation

https://www.autohotkey.com/docs/v2/misc/DPIScaling.htm

On Windows 10 version 1607 and later, the SetThreadDpiAwarenessContext system function can be used to change the program's DPI awareness setting at runtime. For instance, enabling per-monitor DPI awareness disables the scaling performed by the system, so built-in functions such as WinMove and WinGetPos will accept or return coordinates in pixels, untouched by DPI scaling. However, if a GUI is sized for a screen with 100 % DPI and then moved to a screen with 200 % DPI, it will not adjust automatically, and may be very hard to use.

Theoretically we could get the new scale when called the shortcuts which I think should place allow the windows to be placed correctly and as long as all windows are moved using the defined keyboard shortcuts and not the mouse there shouldn't be an issue with enabling per-display dpi scaling.

Unless I'm not fully understanding what I read, thoughts?

shaqaruden avatar Feb 16 '24 17:02 shaqaruden

Theoretically we could get the new scale when called the shortcuts which I think should place allow the windows to be placed correctly and as long as all windows are moved using the defined keyboard shortcuts and not the mouse there shouldn't be an issue with enabling per-display dpi scaling.

Unless I'm not fully understanding what I read, thoughts?

This might be my lack of knowledge, but let's say we call the SetThreadDpiAwarenessContext, what would that do differently than what we're doing now? Should this function be called before we get the position for a window?

thesobercoder avatar Feb 18 '24 16:02 thesobercoder

This might be my lack of knowledge, but let's say we call the SetThreadDpiAwarenessContext, what would that do differently than what we're doing now? Should this function be called before we get the position for a window?

My thought is between SetThreadDpiAwarenessContext and A_ScreenDPI we should be able to keep windows resizing correctly in virtually every scenario.

A_ScreenDPI should get the DPI of the primary display when switching between laptop and desktop modes when the resolutions is different.

Then with SetThreadDpiAwarenessContext we should be able to allow each display to size windows independent of the primary displays DPI.

I would need to play around with them and confirm my thoughts.

shaqaruden avatar Feb 18 '24 19:02 shaqaruden

Today I am playing around with using Swift to build a Windows app, might be able to use that to do this properly

shaqaruden avatar Mar 06 '24 16:03 shaqaruden

Today I am playing around with using Swift to build a Windows app, might be able to use that to do this properly

Interesting. Excited to see how it turns out.

thesobercoder avatar Mar 07 '24 03:03 thesobercoder