Skip to content

Conversation

v1ne
Copy link
Contributor

@v1ne v1ne commented Jun 5, 2018

This change adds basic support for per-window DPI awareness v2, introduced with Windows 10 1703.
In the long run, this enables mintty to use WM_GETDPISCALEDSIZE to resize the window pixel-perfectly when the pixel density changes so that the terminal's size in rows×cols stays constant.

For the moment, the basic support gets rid of mintty's window flipping back and forth between different screens A↔B if I drag it from a screen A onto a screen B with a different pixel density.

@mintty
Copy link
Owner

mintty commented Jun 6, 2018

Thanks for this contribution which will need careful inspection.

Will this mitigate any of #695, #696, #697, maybe about the flipping effect?

About terminal size, please outline any benefit, also "in the long run", as compared to the current handling.

@mintty
Copy link
Owner

mintty commented Jun 6, 2018

Also (and this is actually one of the reasons of the project's "no unsolicited pull requests" policy), if this were a normal issue, its discussion would be more visible among the public issues. Should this be getting more complex, let's consider to move discussion to another issue.

@mintty
Copy link
Owner

mintty commented Jun 6, 2018

Ah, the context menu and the Options dialog scale properly, finally!

@Biswa96
Copy link
Contributor

Biswa96 commented Jun 6, 2018

Does this affect any old Windows versions?

@mintty
Copy link
Owner

mintty commented Jun 7, 2018

@Biswa96: I've tested it on Windows 7 and Windows XP, no side effects.

@v1ne: The names DPI_PROCESS_DPI_AWARE and DPI_PER_WINDOW_AWARE_V2 seem misleading to me. The previous mode (per_monitor_dpi_aware == true) was a per-monitor awareness, not per-process; also, checking https://msdn.microsoft.com/en-us/library/windows/desktop/mt791579%28v=vs.85%29.aspx, this and the new mode are both called PER_MONITOR, not per window.
Also, can we use #defines instead of enum Dpi_Awareness and stay with the name per_monitor_dpi_aware for now, so there are fewer or no changes in other functions and files in the first version? I've manually patched as attached, leaving in some old code (per #ifdef); after further evaluation and clean-up, I'd provide that again and give you the opportunity to submit a rebased patch if you desire (for the credits).

winmain.c.txt

@mintty
Copy link
Owner

mintty commented Jun 7, 2018

Not yet tested, but I assume the shortcut of win_fix_position is not proper; this function serves other purposes than DPI adjustment.

@mintty
Copy link
Owner

mintty commented Jun 7, 2018

Did you consider that some of the code you changed is disabled anyway?
when WM_DPICHANGED:
#ifdef handle_dpi_on_dpichanged
...
#endif

@mintty
Copy link
Owner

mintty commented Jun 7, 2018

New integration proposal as attached, plus one "bool" -> "int" in winpriv.h
Evaluation of win_fix_position pending.
winmain.c.txt

@mintty
Copy link
Owner

mintty commented Jun 7, 2018

I misinterpreted the win_fix_position patch, it only returns during the WM_DPICHANGED processing.
Still need to find a multi-monitor Windows 10 system for final testing.

@mintty
Copy link
Owner

mintty commented Jun 10, 2018

This is my cleaned-up proposal to integrate DPI handling V2.
I've tweaked the option HandleDPI so that you can enforce V2 (or nothing) but still use values 1 or true for backward compatibility.
Please resubmit as a (squashed) single-commit pull request. Alternatively, I may commit it next week.
dpiv2.zip

@mintty
Copy link
Owner

mintty commented Jun 12, 2018

@v1ne, last reminder to resubmit the consolidated patch I uploaded, or reveal what I should use for commit --author="...". Thanks a lot already for this contribution.

This enables the user to drag mintty from one screen to another screen with
a different pixel density without any fluttering.

Unfortunately, the size of the terminal (rows, cols) still changes when the
pixel density changes. The suggested way to fix this properly is to handle
WM_GETDPISCALEDSIZE and return the desired window dimensions. This means that
we have to compute the new window dimensions in terms of the old dimensions,
which requires a way to transform dim -- old dpi -> (rows, cols) -- new dpi
--> dim', including the old and new size of the search and scroll bar.

But this change already makes the options dialog pop up at the right size.
Previously, it was always unscaled on my HiDPI screen.
@v1ne v1ne force-pushed the dpi-awareness-pmv2 branch from 7482fbd to 3090e45 Compare June 12, 2018 12:11
@v1ne
Copy link
Contributor Author

v1ne commented Jun 12, 2018

Hi. Sorry for the late reply. And sorry for the unsolicited PR. I'll stick to the policy in the future, sure!

I'm certain that this change fixes #695 and #696, which I experienced on a daily basis in my setup. I'm uncertain about #697.

Thank you for your helpful comments! I took your zip file and put it into the single commit. Indeed, this way I don't need to change unrelated files.

The benefit of using WM_GETDPISCALEDSIZE is that it allows mintty to maintain its size when the pixel density changes: Currently, if I move a 78×24 character terminal from my HiDPI to my LoDPI screen, it ends up at 81×26 characters. Without this message, it is difficult to achieve this without reintroducing the window flutter. At least from my experience of introducing HiDPI support in a major commercial application on Windows. But there, I have the advantage of not having to support HiDPI on Windows <10. ;)

If there's any other change you want, please tell me.

@mintty mintty merged commit ef4cfcd into mintty:master Jun 12, 2018
mintty added a commit that referenced this pull request Jun 12, 2018
@mintty
Copy link
Owner

mintty commented Jun 12, 2018

You had dropped the man page from the commit, I've added that.
I would not have included the notes about possible future handling of WM_GETDPISCALEDSIZE in the commit message, but alright; do you have any specific idea how to make use of that?
Thanks again. If I had a name, I would list you on the credits page...

@v1ne
Copy link
Contributor Author

v1ne commented Jun 13, 2018

Thanks for merging! I don't use my name here on Github, sorry. 0:-)

I tried the following scheme:
WM_GETDPISCALEDSIZE with old dimensions → transform to rows×cols with current font (cell_width, cell_height) → use win_init_fonts to set new font, calculate new dimensions from rows×cols → hand new dimensions to Windows.
Unless the size of a cell changes linearly with the pixel density, I'd have to use the mechanism behindwin_init_fonts to determine the new cell_width, cell_height. But I found the side effects of wind_init_fonts hard to control and didn't get an easy win this way.

Also, the size of the window decoration, search bar and maybe scroll bar have to be taken into account when calculating the window dimensions. I'd have to further look into how mintty's scroll and search bar are positioned to give this a second try.

@mintty
Copy link
Owner

mintty commented Jul 1, 2018

Released 2.9.0.

@mintty
Copy link
Owner

mintty commented Nov 1, 2018

Actually, it's just this change that causes DPI change handling to fail if the DPI of a monitor is changed,
even with option HandleDPI=1. Haven't compared with actual movement between monitors (because I don't have two at my Windows 10 system).
You noted in your commit message that something would still need to be done. Can we get this sorted out?

@v1ne
Copy link
Contributor Author

v1ne commented Nov 8, 2018

Can you give me a bit more context?

What I referred to is that on DPI changes, the new window size is currently computed only approximately, resulting in the window losing or gaining rows and columns.

@mintty
Copy link
Owner

mintty commented Nov 8, 2018

What I saw is: change DPI of the current (or only) monitor, and the terminal size jumps e.g. from 33x80 to 26x63, then after resetting DPI back to 32x79.
This is more than an approximate size.
Not yet tested whether it's the same when moving the window between monitors.
However, the fix is simply to maintain the terminal size by setting it to the previous one in the new DPI context, no need to precalculate it during WM_GETDPISCALEDSIZE. You may checkout the commit diff.

@mintty
Copy link
Owner

mintty commented Nov 10, 2018

Released 2.9.4.

@mintty
Copy link
Owner

mintty commented Jul 7, 2019

See #890 about reintroducing the manifest section <dpiAware>true</dpiAware> to support DPI scaling in Windows 7. This has become possible after introducing DPI awareness mode V2.

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.

3 participants