Merge branch 'msw-dpi-handling-fixes'

Fixes to make processing wxEVT_DPI_CHANGED work better.

See #23510.
This commit is contained in:
Vadim Zeitlin 2023-05-02 18:01:06 +01:00
commit 26d342cb05
9 changed files with 52 additions and 6 deletions

View file

@ -3129,7 +3129,12 @@ public:
// Scale the value by the ratio between new and old DPIs carried by this
// event.
wxPoint Scale(wxPoint pt) const;
wxSize Scale(wxSize sz) const;
wxRect Scale(wxRect r) const
{
return wxRect(Scale(r.GetPosition()), Scale(r.GetSize()));
}
int ScaleX(int x) const { return Scale(wxSize(x, -1)).x; }
int ScaleY(int y) const { return Scale(wxSize(-1, y)).y; }

View file

@ -131,6 +131,8 @@ protected:
virtual void DoGetClientSize(int *width, int *height) const override;
virtual void DoSetClientSize(int width, int height) override;
virtual void MSWBeforeDPIChangedEvent(const wxDPIChangedEvent& event) override;
#if wxUSE_MENUS_NATIVE
// perform MSW-specific action when menubar is changed
virtual void AttachMenuBar(wxMenuBar *menubar) override;

View file

@ -123,8 +123,8 @@ protected:
WXHBRUSH DoMSWControlColor(WXHDC pDC, wxColour colBg, WXHWND hWnd) override;
virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI) override;
virtual void MSWBeforeDPIChangedEvent(const wxDPIChangedEvent& event) override;
void OnDPIChanged(wxDPIChangedEvent& event);
// the labels windows, if any
wxSubwindows *m_labels;

View file

@ -605,6 +605,15 @@ protected:
// controls. The default version updates m_font of this window.
virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI);
// Also called from MSWUpdateOnDPIChange() but, unlike the function above,
// this one is called after updating all the children and just before
// letting the application handle the given wxDPIChangedEvent (whose
// Scale() functions may be useful for the overridden versions).
virtual void
MSWBeforeDPIChangedEvent(const wxDPIChangedEvent& WXUNUSED(event))
{
}
// this allows you to implement standard control borders without
// repeating the code in different classes that are not derived from
// wxControl

View file

@ -3475,10 +3475,19 @@ public:
For example, the returned value will be twice bigger than the original
one when switching from normal (96) DPI to high (2x, 192) DPI.
The overloads taking wxPoint and wxRect are only available in wxWidgets
3.3.0 and later.
@since 3.1.6
*/
wxSize Scale(wxSize sz) const;
/// @overload
wxPoint Scale(wxPoint pt) const;
/// @overload
wxRect Scale(wxRect rect) const;
/**
Rescale horizontal component to match the new DPI.

View file

@ -915,6 +915,11 @@ wxHelpEvent::Origin wxHelpEvent::GuessOrigin(Origin origin)
// wxDPIChangedEvent
// ----------------------------------------------------------------------------
wxPoint wxDPIChangedEvent::Scale(wxPoint pt) const
{
return wxRescaleCoord(pt).From(m_oldDPI).To(m_newDPI);
}
wxSize wxDPIChangedEvent::Scale(wxSize sz) const
{
return wxRescaleCoord(sz).From(m_oldDPI).To(m_newDPI);

View file

@ -947,3 +947,15 @@ wxPoint wxFrame::GetClientAreaOrigin() const
return pt;
}
void wxFrame::MSWBeforeDPIChangedEvent(const wxDPIChangedEvent& WXUNUSED(event))
{
#if wxUSE_STATUSBAR
// If this frame uses a status bar, we need to adjust its height here
// before executing the user-defined wxEVT_DPI_CHANGED handler which may
// want to change the client size of the frame (e.g. using wxSizer::Fit()),
// because otherwise this wouldn't work correctly because the status bar
// would still have its old height, corresponding to the old DPI.
PositionStatusBar();
#endif // wxUSE_STATUSBAR
}

View file

@ -184,8 +184,6 @@ bool wxSlider::Create(wxWindow *parent,
SetSize(size);
}
Bind(wxEVT_DPI_CHANGED, &wxSlider::OnDPIChanged, this);
return true;
}
@ -649,13 +647,14 @@ void wxSlider::MSWUpdateFontOnDPIChange(const wxSize& newDPI)
}
}
void wxSlider::OnDPIChanged(wxDPIChangedEvent& event)
void wxSlider::MSWBeforeDPIChangedEvent(const wxDPIChangedEvent& event)
{
// We need to update the thumb before processing wxEVT_DPI_CHANGED in the
// user code, as it may update the slider size, which wouldn't work
// correctly if it still used the old thumb length.
int thumbLen = GetThumbLength();
SetThumbLength(event.ScaleX(thumbLen));
event.Skip();
}
// ----------------------------------------------------------------------------

View file

@ -5030,6 +5030,11 @@ wxWindowMSW::MSWUpdateOnDPIChange(const wxSize& oldDPI, const wxSize& newDPI)
wxDPIChangedEvent event(oldDPI, newDPI);
event.SetEventObject(this);
// Another hook to give the derived window a chance to update itself after
// updating all the children, but before the user-defined event handler.
MSWBeforeDPIChangedEvent(event);
return HandleWindowEvent(event);
}