[ltk-user] ensure-ltk ?

Daniel Herring dherring at tentpost.com
Sun Jan 3 03:42:31 UTC 2010

On Fri, 1 Jan 2010, Daniel Herring wrote:

> What's the proper idiom when writing a function that might start wish or
> might be called inside another with-ltk?
> For example,
> (defun some-window ()
>   (ensure-ltk ()
>     ...))
> Where some-window could be called from a REPL or from a tk callback? Is
> there already a way to do this in ltk, or should I define a macro
> something like the following seemingly broken code?
> (defmacro ensure-ltk ((&rest options) &body body)
>   (let ((fname (gensym)))
>     `(labels ((,fname () , at body))
>        (if (wish-stream *wish*)
>            (,fname)
>            (with-ltk ,options (,fname))))))

Here's my current macro.  Could it be added to ltk.lisp?

(defmacro ensure-ltk ((&rest options &key (debug 2)
                       &body body)
   "Wrap BODY in with-ltk unless a connection already exists."
   (declare (ignore debug))
   (let ((fname (gensym)))
     `(flet ((,fname () , at body))
        (if (wish-stream *wish*)
            (with-ltk ,options (,fname))))))

It turns out that both ensure-ltk macros work.  However care must be 
exercised; my first use triggered Tk bug #219967.  My distilled Ltk sample 
appears below.

;; This can freeze a graphical window manager.
;; To run on linux and recover:
;; - log into a text console (e.g. Ctrl-Alt-F2)
;; - switch graphical (Ctrl-F7) and run the bomb
;; - switch back to text and `killall wish`
;; - watch `top` until things calm down
(defun bomb ()
   (with-ltk ()
     (pack (make-instance 'treeview))
     ;; commenting out the sleep might save your window manager
     (sleep 1) ; just to let the treeview appear
     (grid (make-instance 'label :master nil) 0 0)))

Even without this Tk bug, its probably a good idea to always pass a proper 
:master to other functions which create widgets...


More information about the ltk-user mailing list