Fix initial scale of wxGLCanvas under EGL/Wayland

The scale of the canvas was set up correctly only once we received
"size-allocate" signal from GTK, but this doesn't necessarily happen
when the window is first shown and after its scale factor is actually
known.

Ensure that we use the correct scale by catching the notification about
its change too. This makes buffer scale factor correct from the very
beginning, without having to wait for a resize.

See #23733, #25465.
This commit is contained in:
Vadim Zeitlin
2025-11-26 20:33:55 +01:00
parent dac1996ebe
commit 036087097b
2 changed files with 27 additions and 8 deletions
+1 -1
View File
@@ -148,7 +148,7 @@ private:
static EGLConfig ms_glEGLConfig;
friend void wxEGLUpdatePosition(wxGLCanvasEGL* win);
friend void wxEGLSetScale(wxGLCanvasEGL* win, int scale);
friend void wxEGLUpdateGeometry(GtkWidget* widget, wxGLCanvasEGL* win);
};
// ----------------------------------------------------------------------------
+26 -7
View File
@@ -436,9 +436,17 @@ void wxEGLUpdatePosition(wxGLCanvasEGL* win)
wl_subsurface_set_position(win->m_wlSubsurface, x, y);
}
// Helper declared as friend in the header and so can access m_wlSurface.
void wxEGLSetScale(wxGLCanvasEGL* win, int scale)
// Helper declared as friend in the header and so can access member variables.
//
// Used when size or scale factor changes
void wxEGLUpdateGeometry(GtkWidget* widget, wxGLCanvasEGL* win)
{
int scale = gtk_widget_get_scale_factor(widget);
wl_egl_window_resize(win->m_wlEGLWindow, win->m_width * scale,
win->m_height * scale, 0, 0);
wxEGLUpdatePosition(win);
wl_surface_set_buffer_scale(win->m_wlSurface, scale);
}
@@ -497,12 +505,14 @@ static void gtk_glcanvas_size_callback(GtkWidget *widget,
GtkAllocation *,
wxGLCanvasEGL *win)
{
int scale = gtk_widget_get_scale_factor(widget);
wl_egl_window_resize(win->m_wlEGLWindow, win->m_width * scale,
win->m_height * scale, 0, 0);
wxEGLUpdateGeometry(widget, win);
}
wxEGLUpdatePosition(win);
wxEGLSetScale(win, scale);
static void gtk_glcanvas_scale_factor_notify(GtkWidget* widget,
GParamSpec*,
wxGLCanvasEGL *win)
{
wxEGLUpdateGeometry(widget, win);
}
} // extern "C"
@@ -574,8 +584,17 @@ bool wxGLCanvasEGL::CreateSurface()
// Not unmapping the canvas as soon as possible causes problems when reparenting
g_signal_connect(m_widget, "unmap",
G_CALLBACK(gtk_glcanvas_unmap_callback), this);
// We connect to "size-allocate" to update the position of the
// subsurface when the toplevel window is moved, which also updates the
// scale as a side effect, but we need to also separately connect to
// "notify::scale-factor" to catch scale changes, which is especially
// important initially, as we don't get a "size-allocate" with the
// correct scale when the window is created.
g_signal_connect(m_widget, "size-allocate",
G_CALLBACK(gtk_glcanvas_size_callback), this);
g_signal_connect(m_widget, "notify::scale-factor",
G_CALLBACK (gtk_glcanvas_scale_factor_notify), this);
}
#endif