From 88a39aa6f8fa6ce766e099eb9e63ce5625953963 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 6 Nov 2023 22:44:54 +0100 Subject: [PATCH] Implement wxEVT_DPI_CHANGED generation for wxGTK Just check if the scale factor has changed when getting a "configure" event for a TLW as we're guaranteed to get one when the scale factor does change, according to GTK documentation (and it does seem to work). Closes #19290. --- include/wx/gtk/toplevel.h | 5 +++++ interface/wx/event.h | 3 +++ src/gtk/toplevel.cpp | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/include/wx/gtk/toplevel.h b/include/wx/gtk/toplevel.h index f35562777d..9aff64dd21 100644 --- a/include/wx/gtk/toplevel.h +++ b/include/wx/gtk/toplevel.h @@ -190,6 +190,11 @@ private: bool m_updateDecorSize; bool m_deferShowAllowed; + +#ifdef __WXGTK3__ + // last known scale factor value + double m_scaleFactor; +#endif // __WXGTK3__ }; #endif // _WX_GTK_TOPLEVEL_H_ diff --git a/interface/wx/event.h b/interface/wx/event.h index f781f0223e..1096d48f12 100644 --- a/interface/wx/event.h +++ b/interface/wx/event.h @@ -3439,6 +3439,9 @@ public: "Application Manifests" documentation for more details). + This event is generated by wxGTK when using GTK 3.10 or later and only + since wxWidgets version 3.3.0. + @beginEventTable{wxDPIChangedEvent} @event{EVT_DPI_CHANGED(func)} Process a @c wxEVT_DPI_CHANGED event. diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp index 13b1857c6b..590dd7543f 100644 --- a/src/gtk/toplevel.cpp +++ b/src/gtk/toplevel.cpp @@ -339,6 +339,21 @@ gtk_frame_configure_callback( GtkWidget*, void wxTopLevelWindowGTK::GTKConfigureEvent(int x, int y) { +#ifdef __WXGTK3__ + // First of all check if our DPI has changed. + const auto newScaleFactor = GetContentScaleFactor(); + if ( newScaleFactor != m_scaleFactor ) + { + const auto oldScaleFactor = m_scaleFactor; + + // It seems safer to change it before generating the events to avoid + // any chance of reentrancy. + m_scaleFactor = newScaleFactor; + + WXNotifyDPIChange(oldScaleFactor, newScaleFactor); + } +#endif // __WXGTK3__ + wxPoint point; #ifdef GDK_WINDOWING_X11 if (gs_decorCacheValid) @@ -709,6 +724,16 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, g_object_ref(m_widget); } +#ifdef __WXGTK3__ + // This value may be incorrect as here it's just set to the scale factor of + // the primary monitor because the widget is not realized yet, but it's + // better than setting it to 1, as chances are that the window will be + // created on the primary monitor or, maybe, the other monitors use the + // same scale factor anyhow. And if this isn't the case, we will set it to + // the correct value when we get "configure-event" from GTK later. + m_scaleFactor = GetContentScaleFactor(); +#endif // __WXGTK3__ + wxWindow *topParent = wxGetTopLevelParent(m_parent); if (topParent && (((GTK_IS_WINDOW(topParent->m_widget)) && (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)) ||