Arbitrary number of child windows

View: New views
11 Messages — Rating Filter:   Alert me  

Arbitrary number of child windows

by Holger Berndt :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I've been giving gtkmm a look lately, and so far, I am impressed by the
nice design of the language bindings.

I have however one pretty basic problem with window creation. I
have a main window, and I want to be able to create an arbitrary number
of non-blocking child windows for it. The child windows should be
destroyed together with the main window, and should also destroy
themselves (and free all memory) when they are closed individually.

As an example: Say I have a long list of items in a tree view in my
main window. Whenever I activate an item, I want a window popping up
with further details. It should be possible to display multiple such
windows at the same time, even multiple detail views on the same data,
so I don't want to reuse the former windows. In order for the child
windows not to leak memory on closing, I don't want them to just hide,
but destroy themselves.

As far as I can see, I can't archieve that with any of the memory
management methods described in the gtkmm-book. I have found an older
mailing list post at
http://osdir.com/ml/gnome.gtkmm/2003-03/msg00067.html
that tries to solve the very same problem. I am however a bit sceptic
on the frequent use of "delete this;" in member functions. As far as I
know, "delete this;" itself is valid, but any other statement, even a
return statement, is undefined behaviour. I might be wrong about that
though.

Another possibility that I can see is to keep track of all open windows
in the main window class in a list, connect the child window's delete
event signal to a member function of the main window to remove the
window and delete all its memory resources, using the window pointer in
the GdkEventAny structure argument. The disadvantage of this
however is that still a higher instance needs to keep track of the
childs, they are not easy-to-use fire-and-forget self-destructing
windows.

Another possibility would be something along Qt's QObject::deleteLater()
function to not actually do a "delete this;" but schedule an object for
deletion in the event loop. That sounds more well-defined than a "delete
this", but I haven't found an equivalent in gtkmm.

How do other people write their self-destructing child windows?

Holger
_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Arbitrary number of child windows

by Paul Davis :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Fri, 2008-05-09 at 19:28 +0200, Holger Berndt wrote:

>
> Another possibility would be something along Qt's QObject::deleteLater()
> function to not actually do a "delete this;" but schedule an object for
> deletion in the event loop. That sounds more well-defined than a "delete
> this", but I haven't found an equivalent in gtkmm.
>
> How do other people write their self-destructing child windows?

template<class T> bool idle_deleter (T* ptr) { delete ptr; return
false; }

Glib::signal_idle.connect (sigc::bind (sigc::ptr_fun
(idle_deleter<Window>), aWindow);

done.


_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Arbitrary number of child windows

by Holger Berndt :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sa, 10.05.2008 17:11, Paul Davis wrote:

>> How do other people write their self-destructing child windows?
>
>template<class T> bool idle_deleter (T* ptr) { delete ptr; return
>false; }
>
>Glib::signal_idle.connect (sigc::bind (sigc::ptr_fun
>(idle_deleter<Window>), aWindow);
>
>done.

Very good idea indeed! Thanks, Paul.

Holger
_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Arbitrary number of child windows

by Chris Vine :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> I am however a bit sceptic
> on the frequent use of "delete this;" in member functions. As far as I
> know, "delete this;" itself is valid, but any other statement, even a
> return statement, is undefined behaviour. I might be wrong about that
> though.

Yes, you are wrong.  Provided that no members of the object in question
are operated on after 'delete this', then it is fine.  A return
statement is entirely unproblematic.

Calling 'delete this' does not often represent the correct approach, but
one notable exception is objects which are self owning and control their
own lifetime by reference to user input.  Non-modal (non-blocking)
dialogs are an example of a such a type of object.

Handing it off to some other handler, such as an idle handler, does
exactly the same as 'delete this' but at some indeterminate time later.
It is better to do it directly and call 'delete this'.

Make sure that the destructor is virtual though.

Chris


_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Arbitrary number of child windows

by Paul Davis :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Mon, 2008-05-12 at 20:26 +0100, Chris Vine wrote:

>
> Handing it off to some other handler, such as an idle handler, does
> exactly the same as 'delete this' but at some indeterminate time later.
> It is better to do it directly and call 'delete this'.

if you're in a signal handling call stack, i can't agree with this. you
have no idea which, if any, members of a Glib::Object and all of its
derived classes might still be accessed after your handler method
returns.


_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Arbitrary number of child windows

by Chris Vine :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, 2008-05-12 at 16:34 -0400, Paul Davis wrote:
> if you're in a signal handling call stack, i can't agree with this. you
> have no idea which, if any, members of a Glib::Object and all of its
> derived classes might still be accessed after your handler method
> returns.

Can you unpack that for me?  I have never had any problems
destroying/finalising GObject objects in a signal hander.  (I am not
asserting there can't be problems, but I have not come across them - or
is this specific to glibmm?)

Chris


_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Arbitrary number of child windows

by Paul Davis :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Mon, 2008-05-12 at 22:16 +0100, Chris Vine wrote:

> On Mon, 2008-05-12 at 16:34 -0400, Paul Davis wrote:
> > if you're in a signal handling call stack, i can't agree with this. you
> > have no idea which, if any, members of a Glib::Object and all of its
> > derived classes might still be accessed after your handler method
> > returns.
>
> Can you unpack that for me?  I have never had any problems
> destroying/finalising GObject objects in a signal hander.  (I am not
> asserting there can't be problems, but I have not come across them - or
> is this specific to glibmm?)

well, things may have gotten much better than they were (much of my
experience here was rooted in gtkmm 1.2), but basically destroying a
widget while inside a method connected to a signal (on some other
widget) was an invitation to disaster. random disaster, of course,
because of the delightful way that memory allocation on *nix systems
works. it still seems a bit rude to me to say:

   foo.signal_bar().connect (mem_fun (*objptr,
Object::do_something_then_delete_me));

i think that in general, signal_bar() would like to know that the
handlers it is calling do not destroy the objects they are invoked
upon.

maybe these assumptions are all gone now.



_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Arbitrary number of child windows

by Chris Vine :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, 2008-05-12 at 18:23 -0400, Paul Davis wrote:

> well, things may have gotten much better than they were (much of my
> experience here was rooted in gtkmm 1.2), but basically destroying a
> widget while inside a method connected to a signal (on some other
> widget) was an invitation to disaster. random disaster, of course,
> because of the delightful way that memory allocation on *nix systems
> works. it still seems a bit rude to me to say:
>
>    foo.signal_bar().connect (mem_fun (*objptr,
> Object::do_something_then_delete_me));
>
> i think that in general, signal_bar() would like to know that the
> handlers it is calling do not destroy the objects they are invoked
> upon.
>
> maybe these assumptions are all gone now.

At the C/GTK+ level this is OK.  The OP was concerned with dialogs, and
the destructor of Gtk::Window (via Gtk::Window::destroy_() and
Gtk::Window::destroy_c_instance_()) will call gtk_window_destroy() on
the underlying GtkWindow/GtkDialog object, which is fine, as it will
correctly finalise all its contained widgets and its own underlying
GObject.

I do recall a problem with libsigc++ 1.2 at < 1.2.3 blowing up if a slot
method deleted the object of which it was a method but that was
corrected in version 1.2.3 (and never affected 1.0 or 2.0/2.2); that did
prevent calling 'delete this' in the circumstances you describe:

2002-12-11  Tim Shead  <tshead@...>

        * sigc++/signal.cc: Fix segfault when a signal observer deletes
        itself from within its signal handler.

Chris


_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Arbitrary number of child windows

by Chris Vine :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, 2008-05-13 at 00:01 +0100, Chris Vine wrote:
> At the C/GTK+ level this is OK.  The OP was concerned with dialogs, and
> the destructor of Gtk::Window (via Gtk::Window::destroy_() and
> Gtk::Window::destroy_c_instance_()) will call gtk_window_destroy() on
                                                ^^^^^^^^^^^^^^^^^^^^

gtk_object_destroy().

Chris



_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Arbitrary number of child windows

by Murray Cumming :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, 2008-05-12 at 18:23 -0400, Paul Davis wrote:
> i think that in general, signal_bar() would like to know that the
> handlers it is calling do not destroy the objects they are invoked
> upon.

I believe that fixing that was a design aim for libsigc++ 2, which we
are now using. I believe it works. I personally avoid it, however, just
to keep things simple.

--
Murray Cumming
murrayc@...
www.murrayc.com
www.openismus.com


_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Arbitrary number of child windows

by Chris Vine :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, 2008-05-13 at 11:17 +0200, Murray Cumming wrote:
> On Mon, 2008-05-12 at 18:23 -0400, Paul Davis wrote:
> > i think that in general, signal_bar() would like to know that the
> > handlers it is calling do not destroy the objects they are invoked
> > upon.
>
> I believe that fixing that was a design aim for libsigc++ 2, which we
> are now using. I believe it works. I personally avoid it, however, just
> to keep things simple.

It was fixed from libsigc++-1.2.3 onwards.  As it happens, it also
worked with libsigc++-1.0.

Chris

_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list