On Tuesday 04 December 2007 09:57, Peter Hildebrandt wrote: > Peter, > > thanks for your reply. I've made some progress, but before > suggesting a patch I'd like to verify a few internals. > > The GTK/GDK doc says, that you're fine as long as you use gdk/gtk > only in callback functions such as on-click-handlers. These > callbacks are apparently run within the lock we supply for > gtk-main. However in "Idles, timeouts, and input functions" [1] > you'd need to sorround calls to gtk/gdk with the equivalent of > with-gdk-threads.
I see that the entire main loop in gtk-app is surrounded in with-gdk-threads, but nothing on a finer grain. Is this the problem? > [1] > http://www.gnu.org/software/guile-gnome/docs/gdk/html/Threads.html I recall reading this page after struggling with the behavior in the Win32 port of my program. It has been about a year since I've worked with cells-gtk (Not that I don't like it, or have given up on it. I'm just busy with some server stuff and hunchentoot). > Now I have poked around the code for a while, and did not find any > of those. Does cells-gtk use "Idles, timeouts, and input > functions"? If yes, where? I did a quick tutorial at http://www.gtk.org/tutorial1.2/gtk_tut-17.html fgrep timeout `find . -name \*.lisp` ... widgets.lisp timeout-add. This is used in test-gtk/test-display... In fact I have noted that this test doesn't work in some lisps! I don't see in my notes where though. Under lispworks, gtk-app does a process-wait-with-timeout. Grep on idle and input doesn't show anything. > > My second question: Is there somewhere a list of all windows that > have been created using to-be? Or will I have to hack my own using > :after methods? (for details why I need this, see below) Maybe Kenny Tilton could answer that one. > > > To give you an idea where things are going, here's a short write-up > of the status quo. Test-gtk works perfectly. Including the pulse behavior in test-display? > If you have loaded > test-gtk and changed into the package, > > (start-app-in-thread 'test-gtk) > > starts the sample app and returns right away to the REPL. > > A typical example how this facility would be used is along these > lines: > > ;; create a hello-world app > (defmodel app (gtk-app) > ((label :accessor label :initform (c-in "") :initarg :label)) > (:default-initargs > > :title "TestApp" > :kids (list > > (mk-label :text (c? (label (upper self))))))) > > ;; run the app > (start-app-in-thread 'app) > > ;; modify a slot in the app instance and watch cells(-gtk) > propagate the change > (setf (label (gtk-current-app)) "Hallo Welt") > > Once the app is running, you can create further windows > > (to-be (mk-window :title "a window")) > > and also instances of the application > > (to-be (make-instance 'app)) > > I love interactive programming :-) > > Three limitations apply: > > (1) To maintain compatibility with start-app's behavior, the window > started by start-app-in-thread serves as the applications main > window -- gtk-main will exit, when this one is closed. The > application (or the developer at the REPL) has to make sure all > windows created by to-be are closed using not-to-be before the main > window exits. If he doesn't, they will remain inactive, until a > new application is started. (This is where a list of all open > windows would come in handy, the solution being only a mapcar away) This may resolve the problem I've seen where I'd have to restart lisp to get cells-gtk unstuck after breaking (e.g. in debugger) and quitting. That would be marvelous! > > (2) If start-app-in-thread is called while an application is still > running, it will schedule the request and return immediately. The > new application is opened once the previous one is closed. This > limitation appears to be necessary to prevent hassle with > applications that are not thread-safe and thus do not like being > execute several times within the same lisp process. If you really > want to run your application in parallel, use (to-be (make-instance > 'app)) or (make-be 'app). > > (3) For technical reasons, you CANNOT use start-app and > start-app-in-thread from the same lisp session (i.e., if you have > used one, you will have to RESTART your lisp session before you can > use the other) > > In other words, (start-app-in-thread) behaves just like > (start-app), the only difference being, that it returns > immediately, running gtk in the background. > > Comments are welcome. If this behavior seems to be ok, I will > factor out the relevant changes against the current cvs version and > provide a patch for testing. This could be a patch that might really improve matters. Go for it! > > > Here's a little write up of the technical details involved. > > The major issue appears to be that GTK expects gtk-main to be > called only once for every given process. If it is called > repeatedly, gtk plays along nicely, if the call comes from the same > thread as before, otherwise it does not signal an error, but simply > discards any screen output. > > Interestingly, g-thread-init and gdk-thread-init may well be called > from a different thread. However, once gtk-main has been called, > our process is doomed to use the same thread for subsequent calls > to gtk-main. I did not find this behavior documented anywhere, but > I have come to believe that it simply reflects the C programming > style of compile-link-run -- hence it did not occur to anyone that > this might be a problem. > > As long as you run gtk-main directly from your lisp session, it is > not a problem either, since it is always the same caller as well. > However, once you try to spawn a thread every time you launch > gtk-main, things inevitably break. > > Therefore, my code creates one thread dedicated to running > gtk-main. This thread is fired up the first time > start-app-in-thread is called and should remain alive throughout > the lisp session. Subsequent calls to start-app-in-thread use a > mutex to communicate start-app requests to the running thread. > > Regards, > Peter > > > On Mon, 03 Dec 2007 13:29:59 +0100, Peter Denno > <[EMAIL PROTECTED]> > > wrote: > > On Monday 03 December 2007 06:50, Peter Hildebrandt wrote: > >> I've been trying for a while to launch a gtk application in a > >> distinct thread (using sbcl): > >> > >> (sb-thread:make-thread (lambda () (cells-gtk-init) (start-app > >> 'my-app))) > >> > >> The thread appears to runs fine up to the point where (gtk-main) > >> is called, however no window is ever being displayed. > > > > I ran in to this problem. I don't think I resolved it. It may > > well be the case that I still don't understand restarts > > completely. The code to look at is probably start-app in > > gtk-app.lisp. > > > > If you typically run under slime, just for experimentation, try > > running from a command prompt instead. > > > >> The objective is to launch a GUI in the background, then return > >> back to the REPL (with the GUI still runnning in the > >> background), and modifying the underlying data structures > >> directly, while the GUI visualizes the results. For another app > >> I have this up and running with cl-glut, but here I'd like to > >> have (cells-)gtk for various reasons. > >> > >> Did anybody ever encounter this issue, or has any ideas how to > >> work around it? > >> > >> Help is highly appreciated, > >> > >> Peter > >> > >> > >> _______________________________________________ > >> cells-gtk-devel site list > >> [email protected] > >> http://common-lisp.net/mailman/listinfo/cells-gtk-devel -- Best regards, - Peter _______________________________________________ cells-gtk-devel site list [email protected] http://common-lisp.net/mailman/listinfo/cells-gtk-devel
