Thank you, Kjell. Frankly speaking I do not remember why I made my widget pretend windowless. I've changed the code according to the examples and everything seems to work now.
But it's really very strange to have such an API. I can think at least of two issues about it. First is what if a custom widget has more than one window? It can set one of them as the widget's window with Widget::set_window() and then when it's time to unrealise the resources it will be destroyed by Widget::unrealize() function. But what about the others? Does the user have to destroy them with direct gdk_window_destroy() call? The other thought is about the symmetry of the API. The user herself creates the window with Gdk::Window::create() but then it is supposed to be destroyed implicitly. It's really not obvious from the documentation. Also there is a pitfall in GTK+ docs. Although it is not stated in the API description gtk_widget_realize() and gtk_widget_unrealize() are not really complete antagonists. I mean if you want to call Gtk::Widget::realize() (or gtk_widget_realize(), doesn't matter) from you custom widget's on_realize() method then you can do this only if your widget is windowless. But unlike realize method it appears that you *have *to call Gtk::Widget::unrealize() if your widget is both window or no-window widget. This is just thinking out loud. Maybe GTK+/gtkmm developers will pay attention to this. С уважением, Кирсанов Виталий ICQ: 193259120 2013/4/18 Kjell Ahlstedt <[email protected]> > 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 eventually gdk_window_destroy() function is called. I thought that > the best place to call it was the Gdk::~Window() destructor. But it's > empty. And moreovergdk_window_destroy() is absent in gdkwindow.cc file at > all. > > The on_realize() and on_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 Kirsanov > ICQ: 193259120 > > >
_______________________________________________ gtkmm-list mailing list [email protected] https://mail.gnome.org/mailman/listinfo/gtkmm-list
