LeifUK / OpenControls.Wpf

The OpenControl.Wpf project is a library of useful WPF controls. They are free to use and distribute but please add my name and a link to this page to your application credits page.
77 stars 39 forks source link

FloatingPaneManager doesn't work well with high dpi displays #1

Closed Algorithman closed 3 years ago

Algorithman commented 3 years ago

First: Nice work. Thanks.

But now for the issue: For example https://github.com/LeifUK/OpenControls.Wpf/blob/9ae8ceb384c602ed686cbc524479acbd57a2a4b4/OpenControls.Wpf.DockManager/FloatingPaneManager.cs#L214 you have to consider the scaling (probably everywhere where PointToScreen is involved).

If i don't divide topLeftPanePoint by 1.5 (my monitor's scaling factor) i end up with a displaced FloatingPaneManager.

Second scaling issue: GetCursorPos also does not account for scaling, so undocking a window can displace it outside the monitor space.

Algorithman commented 3 years ago

A good method seems to be something like this:

                        if ((paneType == pane.GetType()) || ((pane is DocumentPanel) && (sender is FloatingDocumentPaneGroup)))
                        {
                            _windowLocationPane = new WindowLocationPane();
                            _windowLocationPane.AllowsTransparency = true;
                            if (SelectedPane is DocumentPanel)
                            {
                                _windowLocationPane.ShowIcons(WindowLocation.Middle);
                            }
                            Point topLeftPanePoint = pane.PointToScreen(new Point(0, 0));
                            PresentationSource source = PresentationSource.FromVisual((UIElement)pane);
                            double dpix = source.CompositionTarget.TransformToDevice.M11;
                            double dpiy = source.CompositionTarget.TransformToDevice.M22;
                            _windowLocationPane.Left = topLeftPanePoint.X/dpix;
                            _windowLocationPane.Top = topLeftPanePoint.Y/dpiy;
                            _windowLocationPane.Width = SelectedPane.ActualWidth;
                            _windowLocationPane.Height = SelectedPane.ActualHeight;
                            _windowLocationPane.Show();
                        }

By using the values of the translation matrix you should be on the safe side.

LeifUK commented 3 years ago

Thank you for fixing this issue. I have merged your code changes into the main branch. Much appreciated.