fix(image): don't crash at startup when the widget isn't realized yet

The HiDPI code path builds a cairo surface from the pixbuf via
Gdk::Cairo::create_surface_from_pixbuf(pixbuf, scale, image_.get_window()),
which requires a realized Gtk::Image. During startup an image module can
run its first update() before the widget is realized, so get_window()
returns a null Gdk::Window and that path aborts before anything is
logged. The more image modules are configured, the more likely at least
one updates before realization, which is why >2 images reliably kills
startup.

Guard on get_window(): only take the surface path when a window is
available, otherwise fall back to image_.set(pixbuf) (the pre-HiDPI
behavior). This keeps HiDPI crispness once realized and never crashes at
startup.

Fixes #5051.
This commit is contained in:
Alex
2026-07-05 09:47:47 +02:00
parent 93cabeefc2
commit 0729823c13
+13 -3
View File
@@ -265,9 +265,19 @@ void SingleImageStrategy::update() {
}
if (pixbuf) {
auto surface = Gdk::Cairo::create_surface_from_pixbuf(pixbuf, image_.get_scale_factor(),
image_.get_window());
image_.set(surface);
// Building a HiDPI-aware cairo surface requires a realized widget: it reads the
// GdkWindow and its scale factor. During startup update() can run before the
// Gtk::Image is realized, in which case get_window() is null; feeding that path a
// null window aborts startup. Fall back to setting the pixbuf directly while the
// widget is unrealized, and use the crisp surface path once a window is available.
auto window = image_.get_window();
if (window) {
auto surface =
Gdk::Cairo::create_surface_from_pixbuf(pixbuf, image_.get_scale_factor(), window);
image_.set(surface);
} else {
image_.set(pixbuf);
}
image_.show();
if (hasTooltip_ && !tooltip_.empty()) {