'Gtk::DrawingArea's size_allocate signal not captured

I want to code a hand-free drawing soft using gtkmm. So I derive the Gdk::DrawingArea class and override it's on_size_allocate() function to initialize the surface for drawing.

    class MyDrawing : public Gtk::DrawingArea
    {
    public:
      MyDrawing();
      virtual ~MyDrawing();
      Cairo::RefPtr<Cairo::Surface>  surface;
    
    protected:
      void on_size_allocate(Gtk::Allocation& );
      bool on_draw(const Cairo::RefPtr<Cairo::Context>&);
    };
    
    MyDrawing::MyDrawing() : surface (NULL)
    {
      set_size_request (200, 200);
    }
    
    MyDrawing::~MyDrawing()
    {
    }
    
    bool MyDrawing::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
    {
      if (!surface)
        return FALSE;
    
      cr->set_source (surface, 0, 0);
      cr->paint();
      return TRUE;
    }
    
    void MyDrawing::on_size_allocate(Gtk::Allocation& allocation)
    {
      g_print ("init the surface, w: %d, h: %d\n", get_allocated_width(), get_allocated_height());
      surface = get_window()->create_similar_surface (Cairo::CONTENT_COLOR,
                                                      get_allocated_width (),
                                                      get_allocated_height ());
      g_print ("init ok\n");
    }

Then I create an application and an window, add a MyDrawing instance to the window and run the application. Everything is ok, except the surface isn't initialized.

What could be the problem?

I am using gtkmm-3.0 on Debian GNU/Linux 10.



Solution 1:[1]

It would be better if you could show the code, but I think you forgot to add the widget to the window, and because of this the widget is never drawn which explains why no size is allocated:

class MyWindow : public Gtk::Window
{

public:

MyWindow()
{
    add(m_drawing);
    show_all();
}

private:

    MyDrawing m_drawing;
};

You could also have forgotten to show the window, but in that case no window would have been drawn... In my case, when adding your widget to the window (Gtkmm 3.24.20), I get the following error:

init the surface, w: 1, h: 1
Segmentation fault (core dumped)

So you handler is called, but the program then segfaults. If I comment out the surface creation call, I get:

init the surface, w: 1, h: 1
init ok

which means the way you are creating your surface is not valid.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1