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

A more complete fix to per-monitor DPI issues #326

Merged
merged 4 commits into from
Feb 12, 2022

Conversation

rwg0
Copy link
Contributor

@rwg0 rwg0 commented Jan 28, 2022

#321

This now covers all cases that I can find. There are still issues if the application does not declare per-monitor DPI awareness and the docking host window is split over two monitors with different DPIs, but these existed already, and I don't think it is possible to solve that sort of issue without being per monitor DPI aware.

A number of changes are needed, largely taking into account the fact that a floating window can have a different DPI to the main docking window in a per-monitor DPI aware application:

  • The drag service needs to work in raw screen co-ordinates and let each window it hit tests do its own conversion into DPI scaled co-ordinates, since the conversion may be different on a per window basis. I renamed HitTest() to HitTestScreen to reflect this and added a TransformToDeviceDPI to IDropArea to support this
  • The overlay windows must be owned by the thing they are sitting over, rather than the thing being dragged, to get the right DPI. Otherwise they show in the wrong place. Also, caching the overlay window by detaching the owner and then re-using later is bad, since while the window is cached, the owner may change DPI, which the overlay window will not reflect when it is re-used. I have changed the code to stop caching them to avoid this
  • When a LayoutFloatingWindow control is shown for the first time, setting its position may cause it to be on a different screen, which can change its DPI, which in turn moves the position a long way from the mouse. We cannot use the DPIChangedEvent to detect this, since it is not present in net40. Instead I measure the screen size of the window before/after setting the position. If the size changes, presumably the DPI has changed, and I re-do the position calculations in the new DPI. This makes the window drag away from the docking area correctly even if it drags straight onto a different DPI screen

I have tested on Win10 (21H1) with the TestApp set to each of

*PerMonitor V2 DPI Awareness
*PerMonitor DPI Awareness
*System DPI Awareness
*No DPI Awareness

The first two seem to work correctly in all cases (docking window on high DPI, floating on low, vice versa, docking window split across high and low, floating on either high or low). The last two still have issues, but the same issues are seen with the code before my changes.

Win8 and earlier did not have per-monitor DPI, so any changes made here should have no effect on them (because the DPI would always be the same for all windows).

…er placement on high dpi monitor, incorrect docking overlay placement on high dpi monitor, window undocked by dragging does not show until drag complete on high dpi monitor
…he dragging window. This ensures the DPIs match. Destroy and recreate rather than stash them, as otherwise DPI can get mixed up if you move parent to different DPI monitor
…hanges DPI because it is on a different screen
@Dirkster99 Dirkster99 merged commit 3308372 into Dirkster99:master Feb 12, 2022
@Skaptor
Copy link
Contributor

Skaptor commented Mar 1, 2022

Setting the overlay window owner causes the "unloaded" event of the docking manager to not be called. thus, breaking any attached behavior that saves the docking manager layout on the unloaded event.

@Skaptor
Copy link
Contributor

Skaptor commented Mar 1, 2022

What can be causing this? If the line is commented everything works normally.

The attached behavior that breaks (which is an article written by @Dirkster99) can be found here

image

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.

None yet

3 participants