[cl-gtk2-devel] gtk_widget_destroy

Peter Keller psilord at cs.wisc.edu
Fri Mar 4 08:38:49 UTC 2011


On Fri, Mar 04, 2011 at 06:52:33AM +0300, Kalyanov Dmitry wrote:
> Gtk+ does not do any cleanup on gtk_main_quit - it just ends its event
> loop. Windows are destroyed by X11 server beacuse socket is closed by
> the OS when process quits. To properly close all windows, you have to
> something like this:
> 
> (gtk:within-main-loop (loop for w in (gtk:gtk-window-list-toplevels) do
> (gtk:object-destroy w)))
> 
> You can use the gtk_quit_add_full function to register cleanup callback;
> but cl-gtk2 does not have bindings for it.
> 
> You should also note that cl-gtk2 will use background thread for Gtk+
> main event loop (if your lisp supports threads); (gtk:gtk-main) starts
> the background thread and returns.
> 

What I ended up doing was this. It waits until the gtk main loop has
exited by joining with it, then cleans up the top-level I created. This
seems to work over and over again without corrupting SBCL or causing GTK
to emit assertion failures. The lisp style of my test code is nasty and
just makes me think I'm doing it wrong.

(defun clicked-callback (w)
  (declare (ignore w))
  (format t "Quitting~%")
  (gtk:gtk-main-quit))

(defun doit ()
  (let (top-level)
    (gtk:within-main-loop
     (let ((builder (make-instance 'gtk:builder)))
       (gtk:builder-add-from-file builder "./hello.xml")
       (gtk:builder-connect-signals-simple
        builder `(("quit_button_clicked" ,#'clicked-callback)))

       (setf top-level (gtk:builder-get-object builder "top_level"))
       (format t "Created toplevel ~A~%" top-level)

       (gtk:widget-show top-level :all t)))

    (gtk:join-gtk-main)

    (gtk:within-main-loop
     (gtk:object-destroy top-level))))

I found that when I used your loop based toplevel closing code, I closed
more toplevels than I created(!?!) even in a brand new SBCL image where
I've run (doit) exactly once. It also put gtk into a bad state where
gtk itself would emit assertion failures and eventually the SBCL image
would corrupt itself and wedge.

The draft manual has some pretty vague documentation in the GTK+
Main Loop section (like it states that gtk-main starts and waits in
its own main loop until gtk-main-quit is called, but you say gtk-main
starts the background thread and immediately returns, but in testing,
the former seems to be what happens). The lisp-ish control forms around
the gtk main loop idea are relatively confusing in the manual. Also,
in the manual JOIN-MAIN-THREAD should be JOIN-GTK-MAIN.

I would be interested in helping you expand your tutorial and manual
if you have the time to answer (probably many) questions and help me
understand things.

Thank you.

-pete






More information about the cl-gtk2-devel mailing list