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 () ,@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) &allow-other-keys) &body body) "Wrap BODY in with-ltk unless a connection already exists." (declare (ignore debug)) (let ((fname (gensym))) `(flet ((,fname () ,@body)) (if (wish-stream *wish*) (,fname) (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.
;;; CAUTION ;; http://sourceforge.net/tracker/index.php?func=detail&aid=219967&grou... ;; 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...
Later, Daniel