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.

[1] http://www.gnu.org/software/guile-gnome/docs/gdk/html/Threads.html

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?

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)


To give you an idea where things are going, here's a short write-up of the status quo. Test-gtk works perfectly. 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)

(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.


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



_______________________________________________
cells-gtk-devel site list
[email protected]
http://common-lisp.net/mailman/listinfo/cells-gtk-devel

Reply via email to