linebender/druid · error

create_similar_surface failed

Error message

create_similar_surface failed

What it means

Error in resize_surface on GTK: w.create_similar_surface(cairo::Content::...) returned None, so a new cairo backing surface matching the drawing area's window could not be allocated at the requested size. It fires on window resize when cairo cannot create a similar surface for the given visual/size, typically due to resource exhaustion or an invalid window/visual.

Solutions

  1. Retry the surface creation with a smaller or current widget allocation
  2. Verify drawing_area.window() is valid and realized before creating the surface
  3. Recreate the surface on the next expose/configure event instead of failing hard
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at druid-shell/src/backend/gtk/window.rs:862 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of linebender/druid@0f8b1195e4 (2026-09-10). Data as JSON: /api/errors/1bffddd6db2c366c. Report an issue: GitHub.

Appendix: source

Thrown at druid-shell/src/backend/gtk/window.rs:862

        let mut surface = self.surface.borrow_mut();
        let mut cur_size = self.surface_size.get();
        let (width, height) = (next_size(width), next_size(height));
        if surface.is_none() || cur_size != (width, height) {
            cur_size = (width, height);
            self.surface_size.set(cur_size);
            if let Some(s) = surface.as_ref() {
                s.finish();
            }
            *surface = None;

            if let Some(w) = self.drawing_area.window() {
                if self.is_transparent.get() {
                    *surface = w.create_similar_surface(cairo::Content::ColorAlpha, width, height);
                } else {
                    *surface = w.create_similar_surface(cairo::Content::Color, width, height);
                }
                if surface.is_none() {
                    return Err(anyhow!("create_similar_surface failed"));
                }
            } else {
                return Err(anyhow!("drawing area has no window"));
            }
        }
        Ok(())
    }

    /// Queues a call to `prepare_paint` and `paint`, but without marking any region for
    /// invalidation.
    fn request_anim_frame(&self) {
        if self.in_draw.get() {
            self.request_animation.set(true);
        } else {
            self.drawing_area.queue_draw()
        }
    }

View on GitHub (pinned to 0f8b1195e4)