On Thu, 06 Dec 2007 16:38:11 +0100, Ken Tilton <[EMAIL PROTECTED]>
wrote:
Peter Hildebrandt wrote:
On Tue, 04 Dec 2007 23:48:07 +0100, Ken Tilton
<[EMAIL PROTECTED]> wrote:
I just glanced at the GTk doc and did not see anything that would
support such a safety net, so you are probably on the right track
rolling one into Cells-Gtk. One might check with the GTk mailing list
to see if we are missing something. Basically the Prime Directive in
these GUI wrapper deals is to use the C library wherever possible.
Thanks for the hint. Indeed there is a way to do this with GTK.
Actually, there is two: The good people at
[EMAIL PROTECTED] pointed me to gtk_quit_add [1] and
gtk_quit_add_destroy [2].
Cool.
They are part of my patch to cells-gtk I just mailed out.
The former registers a callback which is called once gtk-main quits,
while the latter simply schedules a window for destruction upon
quitting the main app (as I learned, this was discussed on the GTK
mailing list in February 1999 [3]).
http://mail.gnome.org/archives/gtk-list/1999-February/msg00577.html
[1]
http://library.gnome.org/devel/gtk/2.12/gtk-General.html#gtk-quit-add
[2]
http://library.gnome.org/devel/gtk/2.12/gtk-General.html#gtk-quit-add-destroy
[3] http://mail.gnome.org/archives/gtk-list/1999-February/msg00577.html
I assume what we want is the former, that is code it along these lines
- upon creation of a window we register a callback to dispose of the
window once the app is closed (either md-awaken :after or
make-instance :after -- which one is more appropriate? I'd go with
the former, since this is the point in time where the window actually
shows up on the screen)
I think we want to register the callback as soon as possible so we do
not miss any action the GTk side -- I am imagining a sequence where
something goes wrong during window instantiation and GTk snuffs a window
while we are still going about building it from the Lisp side. Of course
Gtk would complain about continued attempts to build a snuffed window,
but things might go more neatly if we avoid that by getting the callback
set up ASAP.
Yep, it's part of make-instance ((self window)) now.
In the latest Cells (not yet pulled into Cells-GTk) there is an
elaborate scheme for handling such matters -- wherever messages get
prepped for Gtk they would get enqueued, not actually sent. Then Cells
allows the application to specify a custom handler for this queue, which
handler can sort the messages so they happen in just the right order. In
this case we would tag the creation message with :win-make and tag the
callback registration with :win-quit-cb-register and sort them to run
back to back. And in case anyone is thinking ahead, I believe there is
enough state information on the Lisp side to handle gracefully "snuff"
notifications that come in during window creation.
Well, of course that'd be a great project. That would put us in a
position to handle threading properly by wrapping the execution of the
command queue win with-gdk-threads and thus be truly thread-safe in gdk
terms.
Right now we ignore this issue more or less since it does not seem to be a
problem. (At least I haven't seen anything bad happen despite of some
rigorous testing on test-gtk). Maybe after all lisp does not really
process stuff from the repl while in a C callback?
- in the callback we finally call not-to-be on self to properly
dispose of the window.
Is there anything wrong with hooking into md-awaken/not-to-be? I
put the following in my code:
(let ((open-windows nil))
(defmethod md-awaken :after ((self window))
(pushnew self open-windows))
(defmethod not-to-be :before ((self window))
(setf open-windows (delete self open-windows )))
(defun not-to-be-all ()
(mapcar #'not-to-be open-windows)
(setf open-windows nil)))
where not-to-be-all is called when the user closes the main window.
Appears to be working perfectly. Am I missing something?
Anyone?
It'd like to hear some comments, too.
It's a toss-up. The above has a slight "backdoor" feel to it, but
that might be the right way to go.
It is definitely a hack.
:) I did not mean anything disparaging by "backdoor". Indeed, we are at
the very boundary between C and Lisp "Gtks" where we might very much
/want/ to step out of the Cells machinery (but so far it looks like we
can stay within, if only because Cells does allow one to play with
md-awaken and not-to-be and get a c little closer to the action when
needed).
Well, actually it turned out that this way I might be messing with cells
too much. The mapcar #'not-to-be appears to be somewhat radical compared
to a modest (not-to-be self) in the gtk-quit callback.
That's why I'm discussing this issue with you guys before publishing
a patch.
Some background: Cells is all about making sure everything gets done
and in the right order when things change. But because the Cells
engine is ordering operations, interesting code is almost compelled
to play within the Cells framework, or it misses out on vital action
(does not learn about change) or at best runs at the wrong time.
I think I understand.
If you creat a class called gtk-application and hang windows off that
as kids of an instance of that, then you can just not-to-be that
instance and have all windows tended to. Use of this instance gets
enforced simply by having the md-awaken method merely enforce that
with a helpful error message telling the developer the right way to
make a window (push a new instance onto the kids of a gtk-application
instance.
Well, the problem is that gtk-app is derived from window, hence its
kids are the widgets to be displayed within it. As I mentioned
before, I'd like to maintain compatibility, thus I'd rather leave this
as it is. My suggestion:
We introduce a new class, gtk-application, which so far does nothing
but keep track of all windows opened by the app in its kids slots.
<g> That is what I meant by gtk-app, which I did not know existed. <g>
Now we have a global variable *system*, and every window pushes itself
open creation into the kids of *system*. There is a function called
(open-windows) that returns those kids which currently have a gtk
representation. (It appears I am not capable of removing a window from
the kids of *system* without causing some cells havoc). Still a hack, but
closer to the Right Thing. And once I figure it out, I can change it all
internally wihtout modifying the interface.
Is this the Windows model where a window (or the prime window) is the
same as an application? I grew up developing on the mac where one could
close all the windows and still have the app and its menu bar available.
Thanks for pointing that out. Indeed I had the windowsy idea of a main
window being equivalent to the app in mind (which seems to match the gtk
philosophy). Of course there is no point why a GUI toolkit should dictate
this view. The version I mailed out earlier today allows you work either
way.
- Have a main app thread that is independent of any specific window and
close it down at its on discretion (maybe a menu command or the like)
- Have a main window, closing which will result in closing all the other
windows.
My current version supports only one app per image in the later model,
whereas you can run several applications of the former kind within the
same lisp image.
Since not-to-be will remove them properly (and will be called either
by the user or through the callback), we do not have to keep track of
that. All that's left to do is register new instances -- which I'd do
within the md-awaken method, so that instances are registered with the
application object at the same time the callback is registered.
That would work. I do not mean to confuse things -- I think registering
for quits is still The Right Way meaning that is how windows would get
managed, but I might /still/ have gtk-application to support things like
my imagined menu of windows, drag/drop between windows, etc etc.
Yep, this is how it is done now. gtk-quit closes windows if you want
that, and (open-windows) gives you a list of all open instances of window
(or its subclass gtk-app).
Anyway, sounds like you are doing pretty good sorting this out, just
throwing thoughts over the wall.
Thanks!
Regards,
Peter
cheers, ken
_______________________________________________
cells-gtk-devel site list
[email protected]
http://common-lisp.net/mailman/listinfo/cells-gtk-devel