Have you looked at the custom widget example in the gtkmm tutorial?
https://developer.gnome.org/gtkmm-tutorial/stable/sec-custom-widgets.html.en
https://git.gnome.org/browse/gtkmm-documentation/tree/examples/book/custom/custom_widget/mywidget.cc
Two differences between your code and the custom widget example strike me.
1. In on_realize() you have set_window(get_parent_window()) instead of set_window(_event_window).
2. In on_unrealize() you have set_realized(false) where the custom widget example has Gtk::Widget::on_unrealize().
Gtk::Widget::on_unrealize() calls gtk_widget_real_unrealize() which among other things calls gdk_window_destroy().
The custom widget example is written for gtkmm3. I don't know if some details are different in gtkmm2.
This bug discusses the warning that you get: https://bugzilla.gnome.org/show_bug.cgi?id=606903
I have written some of the comments in that bug, but I don't remember all the details now.
Kjell
2013-04-17 23:01, Виталий Кирсанов skrev:
Please call me an earth worm if I'm using this mailing list inapropriately. But maybe somebody can help me.
Status quo: I have a custom widget (MyWidget) with an event window.
Problem: if I create, show and then, later, hide and destroy the widget I get the following message from the application:
Gdk-WARNING **: losing last reference to undestroyed window
What I've found out: I've had a look in
gdkwindow.c
file and this message is reported whenGDK_WINDOW_DESTROYED(window) == FALSE
. So the thing I do not understand is how I should destroy my window correctly so that eventuallygdk_window_destroy()
function is called. I thought that the best place to call it was theGdk::~Window()
destructor. But it's empty. And moreovergdk_window_destroy()
is absent ingdkwindow.cc
file at all.The
on_realize()
andon_unrealize()
call-backs are below.class MyWidget : public Gtk::Widget { ... private: Glib::RefPtr<Gdk::Window> _event_window; ... }; void Gtk::MyWidget::on_realize() { GdkWindowAttr attributes; const Allocation & allocation = get_allocation(); attributes.event_mask = GDK_BUTTON_PRESS_MASK; attributes.x = allocation.get_x(); attributes.y = allocation.get_y(); attributes.width = allocation.get_width(); attributes.height = allocation.get_height(); attributes.wclass = GDK_INPUT_ONLY; attributes.window_type = GDK_WINDOW_CHILD; _event_window = Gdk::Window::create(get_parent_window(), &attributes, GDK_WA_X | GDK_WA_Y); _event_window->set_user_data(Widget::gobj()); set_window(get_parent_window()); set_realized(); }
void Gtk::MyWidget::on_unrealize() { _event_window->set_user_data(NULL); _event_window.reset(); set_realized(false); }
Best regards,Vitaly KirsanovICQ: 193259120