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

Reply via email to