Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
wants to merge 4 commits into from

Conversation

shaqaruden
Copy link

@shaqaruden shaqaruden commented Nov 30, 2023

✅ Maximize
✅ Almost Maximize
🚧 Next Monitor
🚧 Previous Monitor

❌ Run Thorough tests

@shaqaruden
Copy link
Author

shaqaruden commented Nov 30, 2023

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
Copy link
Author

shaqaruden commented Nov 30, 2023

@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)

@thesobercoder thesobercoder self-requested a review December 1, 2023 08:53
@thesobercoder thesobercoder linked an issue Dec 1, 2023 that may be closed by this pull request
@shaqaruden
Copy link
Author

shaqaruden commented Dec 1, 2023

@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?

@thesobercoder
Copy link
Owner

thesobercoder commented Dec 2, 2023

@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.

@shaqaruden
Copy link
Author

@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

- Improve logic to find current window. Now takes into account how much a window covers a differenent monitors. Monitor with most coverage is used
- Next Monitor does not crash when on a monitor of higher DPI
- Add Previous Monitor

Note: One issue remains with Next/Previous Monitor. High DPI monitors still mess with positioning and sizing of the window.
@shaqaruden
Copy link
Author

shaqaruden commented Dec 21, 2023

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

@thesobercoder
Copy link
Owner

thesobercoder commented Dec 22, 2023

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.

@shaqaruden
Copy link
Author

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
Copy link
Author

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
Copy link
Author

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?

@thesobercoder
Copy link
Owner

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.

@shaqaruden
Copy link
Author

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?

@thesobercoder
Copy link
Owner

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?

@shaqaruden
Copy link
Author

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
Copy link
Author

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

@thesobercoder
Copy link
Owner

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.

Repository owner deleted a comment from DavideStagni Mar 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Move Window to next Monitor/Maximize/Almost Maximize
2 participants