Date: Thu, 30 Nov 2006 14:19:38 +0100 From: Maxence Guesdon To: "Olivier Andrieu" Cc: lablgtk at math.nagoya-u.ac.jp Subject: Re: strange behaviour of GMain.Main.main / GMain.Main.quit Message-ID: <20061130141938.3d823177 at cayuga.inria.fr> In-Reply-To: <41636.213.30.139.86.1164878208.squirrel at webmail.nerim.net> References: <20061129150731.3660ab96 at tintin.inria.fr> <17773.54865.833705.129071@karryall.dnsalias.org> <20061130092041.1d52a40d@tintin.inria.fr> <41636.213.30.139.86.1164878208.squirrel@webmail.nerim.net> Organization: INRIA Mime-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII Content-Length: 3652 On Thu, 30 Nov 2006 10:16:48 +0100 (CET) "Olivier Andrieu" wrote: > > On Wed, 29 Nov 2006 19:49:53 +0100 > > Olivier Andrieu wrote: > > > >> Salut Maxence, > > > > Salut Olivier, > > > >> Maxence Guesdon [Wednesday 29 November 2006] : > >> > > >> > Hello, > >> > > >> > I'm experiencing problems while using GMain.Main.main and > >> > GMain.Main.quit. Here is a program to reproduce the problem. It > >> > creates a window. When "Return" is pressed, the nb_waits counter in > >> > incrementend, then GMain.Main.main is called to wait for a > >> > GMain.Main.quit, then "pop!" is displayed (that is, when > >> > GMain.Main.main returns). When "Escape" is pressed, GMain.Main.quit > >> is > >> > called nb_waits times. I thought that then all waiting "pop!" would > >> be > >> > displayed one after the other but it works only when there is only > >> one > >> > GMain.Main.main waiting. Is this a bug or a feature ? > >> > >> It's not a bug, that's just how the glib event loop API works. A > >> GMainLoop has a is_running boolean flag. g_main_loop_run basically > >> does a: > >> while (loop->is_running) process_events (loop); > >> and g_main_loop_quit simply sets loop->is_running to FALSE. > >> > >> To get this multiple level of loops, you'd need to create a new loop > >> object or something (but lablgtk doesn't wrap all the necessary > >> functions). > > > > Looking at the code in GtkMain, I see: > > let loops = ref [] > > let default_main () = > > let loop = (Main.create true) in > > loops := loop :: !loops; > > while Main.is_running loop do Main.iteration true done; > > if !loops <> [] then loops := List.tl !loops > > let main_func = ref default_main > > let main () = !main_func () > > let quit () = if !loops <> [] then Main.quit (List.hd !loops) > > > > So it seems that when I call GMain.Main.main () a new loop is created > > and it is destroyed when I call GMain.Main.quit (). Am I missnig > > something ? What happens to the code after the call to GMain.Main.main > > () in my example ? > > Oh right, I forgot lablgtk was doing its own thing with loops rather than > wrapping g_main_loop run. > > Well what's happening in your code is that you're repeatedly calling > GtkMain.Main.quit() in a for loop, but that turns into repeated calls to > Glib.Main.quit() to the *same* loop object on top of the loops "stack". As > you can see in the code above, loops are not pop'ed by GtkMain.Main.quit() > but when GtkMain.Main.main() returns. I understand now. For information, below is a new program doing as expected. The important thing is in the wait function: After returning from the GMain.Main.main (), it triggers another GMain.Main.quit if there are other "waiters" remaining. Doing so, each GMain.Main.quit impacts the correct event loop. Merci Olivier ;-) ========= GMain.Main.init ();; let w = GWindow.window ~title:"test" ~width: 600 ~height: 400 ();; let nb_waits = ref 0;; let wait () = incr nb_waits; prerr_endline (Printf.sprintf "nb_waits is now %d" !nb_waits); GMain.Main.main (); if !nb_waits > 0 then begin decr nb_waits; GMain.Main.quit () end let cb ev = let key = GdkEvent.Key.keyval ev in if key = GdkKeysyms._Return then begin wait (); prerr_endline "pop!" end else ( if key = GdkKeysyms._Escape then ( decr nb_waits; GMain.Main.quit (); ) ); true ;; ignore (w#event#connect#key_press ~callback: cb);; w#show ();; GMain.Main.main () ====== -- Maxence Guesdon http://yquem.inria.fr/~guesdon/ http://devel.inria.fr/rocq/