From: Norbert Z. <nz...@cs...> - 2010-08-29 17:57:17
|
Hi folks, I'm completely new to gtk2hs and am a bit lost with the following issue. I've written a small test application with a main window and a canvas in it. My first attempt at this had the following code in it to make the application exit when the main window closes: onDestroyEvent mainWin mainQuit This worked beautifully, but the documentation says that onDestroyEvent is deprecated. So I replaced it with the following, similar to some code snippets I found in the documentation: mainWin `on` destroyEvent $ liftIO $ do mainQuit return True Problem is it doesn't do anything. I also added putStrLn "Quitting" hFlush stdout before the mainQuit to see whether the do-block gets executed at all. I never saw any output. So I suspect that, for some reason, my event handler is never run. Can anybody enlighten me as to what I'm doing wrong? Thanks, Norbert -- () ascii ribbon campaign - against html e-mail /\ www.asciiribbon.org - against proprietary attachments |
From: Andy S. <laz...@gm...> - 2010-08-30 02:05:36
|
Norbert Zeh <nz...@cs...> writes: > Hi folks, > > I'm completely new to gtk2hs and am a bit lost with the following issue. > I've written a small test application with a main window and a canvas in > it. My first attempt at this had the following code in it to make the > application exit when the main window closes: > > onDestroyEvent mainWin mainQuit > > This worked beautifully, but the documentation says that onDestroyEvent > is deprecated. So I replaced it with the following, similar to some > code snippets I found in the documentation: > > mainWin `on` destroyEvent $ liftIO $ do > mainQuit > return True > > Problem is it doesn't do anything. I also added > > putStrLn "Quitting" > hFlush stdout > > before the mainQuit to see whether the do-block gets executed at all. I > never saw any output. So I suspect that, for some reason, my event > handler is never run. Can anybody enlighten me as to what I'm doing > wrong? There have two way to use destroy signal: mainWin `onDestroy` mainQuit mainWin `on` destroyEvent $ tryEvent mainQuit If you use EventM module, you should use tryEvent wrap your handler. tryEvent catches pattern match exceptions and returns False. If the signal successfully runs to its end, it returns True. Use EventM monad, you don't need return True or False, tryEvent will handle those. Cheers, -- Andy |
From: Norbert Z. <nz...@cs...> - 2010-08-30 11:03:18
|
Andy Stewart [2010.08.30 1001 +0800]: > There have two way to use destroy signal: > > mainWin `onDestroy` mainQuit > > mainWin `on` destroyEvent $ tryEvent mainQuit Actually, I did try that before and just did again. It makes no difference. Program still doesn't exit after closing the window. Moreover, I still need to use liftIO because mainQuit has type IO (). Cheers, Norbert -- () ascii ribbon campaign - against html e-mail /\ www.asciiribbon.org - against proprietary attachments |
From: Brandon S A. K. <al...@ec...> - 2010-08-30 14:57:47
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 8/30/10 07:03 , Norbert Zeh wrote: >> mainWin `on` destroyEvent $ tryEvent mainQuit > > Actually, I did try that before and just did again. It makes no > difference. Program still doesn't exit after closing the window. > Moreover, I still need to use liftIO because mainQuit has type IO (). You want deleteEvent. destroyEvent is triggered when the widget is actually deallocated, which happens only after the deleteEvent is processed --- but the default deleteEvent calls exitProcess, so the main loop will never regain control. - -- brandon s. allbery [linux,solaris,freebsd,perl] al...@kf... system administrator [openafs,heimdal,too many hats] al...@ec... electrical and computer engineering, carnegie mellon university KF8NH -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkx7xuIACgkQIn7hlCsL25V+gQCfUyU76RWi7VlCzuORvoYOAR3s g6kAn1KTDkPMzBmNZCybKE2S2T/w5LoY =QzSI -----END PGP SIGNATURE----- |
From: Brandon S A. K. <al...@ec...> - 2010-08-30 15:10:34
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 8/30/10 10:57 , Brandon S Allbery KF8NH wrote: > On 8/30/10 07:03 , Norbert Zeh wrote: >>> mainWin `on` destroyEvent $ tryEvent mainQuit > >> Actually, I did try that before and just did again. It makes no >> difference. Program still doesn't exit after closing the window. >> Moreover, I still need to use liftIO because mainQuit has type IO (). > > You want deleteEvent. destroyEvent is triggered when the widget is actually > deallocated, which happens only after the deleteEvent is processed --- but > the default deleteEvent calls exitProcess, so the main loop will never > regain control. And reading the other messages in this thread, the above is unclear. The deleteEvent is triggered when the window manager sends WM_DELETE_WINDOW; you can use this to autosave documents or even abort the close (usually to display a "You have unsaved changes" dialog). The destroyEvent is triggered by the actual closing of the window, and at this point there is no way to abort the process; the actual X11 window is gone. objectDestroy (formerly onDestroy) is triggered when the GTK+ object is freed, which is at too low a level for pretty much anything you might want to do in addition to being even later than the destroyEvent. Pedantry: I believe destroyEvent is invoked from the Haskell finalizer, and objectDestroy from the C finalizer. Assume both of these happen during garbage collection. deleteEvent is invoked from the mainLoop. It is possible that the old onDestroy signal was triggered synchronously, in which case it could have done mainQuit (assuming the old onDelete code permitted; I think the rules were looser in older versions but this was fragile) but pretty much nothing else. - -- brandon s. allbery [linux,solaris,freebsd,perl] al...@kf... system administrator [openafs,heimdal,too many hats] al...@ec... electrical and computer engineering, carnegie mellon university KF8NH -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkx7yd0ACgkQIn7hlCsL25XiVACeOtSDHTw3196eBiJiqM4+PJCV /ZcAnA5VD7MLOjjPXeM3bYcjr2shU//r =c4SY -----END PGP SIGNATURE----- |
From: Norbert Z. <nz...@cs...> - 2010-08-30 19:05:19
|
Brandon S Allbery KF8NH [2010.08.30 1110 -0400]: > The deleteEvent is triggered when the window manager sends WM_DELETE_WINDOW; > you can use this to autosave documents or even abort the close (usually to > display a "You have unsaved changes" dialog). The destroyEvent is triggered > by the actual closing of the window, and at this point there is no way to > abort the process; the actual X11 window is gone. objectDestroy (formerly > onDestroy) is triggered when the GTK+ object is freed, which is at too low a > level for pretty much anything you might want to do in addition to being > even later than the destroyEvent. Thanks, Brandon. This makes things *much* clearer for me. Cheers, Norbert |
From: Axel S. <Axe...@in...> - 2010-08-31 07:13:52
|
Hi Brandon et al., On 30.08.2010, at 17:10, Brandon S Allbery KF8NH wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > On 8/30/10 10:57 , Brandon S Allbery KF8NH wrote: >> On 8/30/10 07:03 , Norbert Zeh wrote: >>>> mainWin `on` destroyEvent $ tryEvent mainQuit >> >>> Actually, I did try that before and just did again. It makes no >>> difference. Program still doesn't exit after closing the window. >>> Moreover, I still need to use liftIO because mainQuit has type IO >>> (). >> >> You want deleteEvent. destroyEvent is triggered when the widget is >> actually >> deallocated, which happens only after the deleteEvent is processed >> --- but >> the default deleteEvent calls exitProcess, so the main loop will >> never >> regain control. > > And reading the other messages in this thread, the above is unclear. > > The deleteEvent is triggered when the window manager sends > WM_DELETE_WINDOW; > you can use this to autosave documents or even abort the close > (usually to > display a "You have unsaved changes" dialog). The destroyEvent is > triggered > by the actual closing of the window, and at this point there is no > way to > abort the process; the actual X11 window is gone. objectDestroy > (formerly > onDestroy) is triggered when the GTK+ object is freed, which is at > too low a > level for pretty much anything you might want to do in addition to > being > even later than the destroyEvent. > Yes, I think this is a nice summary. > Pedantry: I believe destroyEvent is invoked from the Haskell > finalizer, and > objectDestroy from the C finalizer. Assume both of these happen > during > garbage collection. deleteEvent is invoked from the mainLoop. It is > possible that the old onDestroy signal was triggered synchronously, > in which > case it could have done mainQuit (assuming the old onDelete code > permitted; > I think the rules were looser in older versions but this was > fragile) but > pretty much nothing else. > Finalizers that can emit signals (i.e. potentially all Gtk+ finalizers) are actually run in the main loop now which fixes some threading issues. So while the above isn't quite correct, I don't think there's an observable difference from within Haskell: You were never able to run Haskell code while the GC is running, so it calling something in Haskell from the GC created a suspended thread in old GHC run-times. Cheers, Axel > - -- > brandon s. allbery [linux,solaris,freebsd,perl] al...@kf... > system administrator [openafs,heimdal,too many hats] al...@ec... > electrical and computer engineering, carnegie mellon university > KF8NH > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v2.0.10 (Darwin) > Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ > > iEYEARECAAYFAkx7yd0ACgkQIn7hlCsL25XiVACeOtSDHTw3196eBiJiqM4+PJCV > /ZcAnA5VD7MLOjjPXeM3bYcjr2shU//r > =c4SY > -----END PGP SIGNATURE----- > > ------------------------------------------------------------------------------ > Sell apps to millions through the Intel(R) Atom(Tm) Developer Program > Be part of this innovative community and reach millions of netbook > users > worldwide. Take advantage of special opportunities to increase > revenue and > speed time-to-market. Join now, and jumpstart your future. > http://p.sf.net/sfu/intel-atom-d2d > _______________________________________________ > Gtk2hs-users mailing list > Gtk...@li... > https://lists.sourceforge.net/lists/listinfo/gtk2hs-users |
From: Axel S. <Axe...@in...> - 2010-08-30 06:33:24
|
Hi Norbert, On 29.08.2010, at 19:57, Norbert Zeh wrote: > Hi folks, > > I'm completely new to gtk2hs and am a bit lost with the following > issue. > I've written a small test application with a main window and a > canvas in > it. My first attempt at this had the following code in it to make the > application exit when the main window closes: > > onDestroyEvent mainWin mainQuit > > This worked beautifully, but the documentation says that > onDestroyEvent > is deprecated. So I replaced it with the following, similar to some > code snippets I found in the documentation: > It's only deprecated because you should use the `on` destroyEvent syntax. > mainWin `on` destroyEvent $ liftIO $ do > mainQuit > return True > > Problem is it doesn't do anything. I also added > > putStrLn "Quitting" > hFlush stdout > > before the mainQuit to see whether the do-block gets executed at > all. I > never saw any output. So I suspect that, for some reason, my event > handler is never run. Can anybody enlighten me as to what I'm doing > wrong? Judging from the documentation, we are wrong in using 'destroyEvent' in our examples. This only works when the associated widget has a 'DrawWindow' which is an area to draw on. Some widgets do not have such a window but draw on their parent's DrawWindow. If you connect to such a widget's destroyEvent, it will never be triggered because it indicates that the widget's DrawWindow is destroyed. Correctly, one should always connect to 'deleteEvent' which will close the window by default (unless you return True from this handler). So this should always work: mainWin `on` deleteEvent $ \_ -> mainQuit >> return False Hope this helps, Axel |
From: Norbert Z. <nz...@cs...> - 2010-08-30 11:07:18
|
Axel Simon [2010.08.30 0833 +0200]: > Hi Norbert, [...] > Judging from the documentation, we are wrong in using 'destroyEvent' in > our examples. This only works when the associated widget has a > 'DrawWindow' which is an area to draw on. Some widgets do not have such a > window but draw on their parent's DrawWindow. If you connect to such a > widget's destroyEvent, it will never be triggered because it indicates > that the widget's DrawWindow is destroyed. Correctly, one should always > connect to 'deleteEvent' which will close the window by default (unless > you return True from this handler). > > So this should always work: > > mainWin `on` deleteEvent $ \_ -> mainQuit >> return False This does work indeed. I'm still a bit confused as to why onDestroyEvent works, while `on` destroyEvent does not. In particular, this suggests that it can't be the above explanation because the widget (which is a top-level window and, thus, I believe should have an associated DrawWindow) reacts to onDestroyEvent and, thus, seems to receive the signal. Any more ideas? Thanks, Norbert -- () ascii ribbon campaign - against html e-mail /\ www.asciiribbon.org - against proprietary attachments |
From: Axel S. <Axe...@in...> - 2010-08-30 11:19:33
|
Hi Norbert, On 30.08.2010, at 13:07, Norbert Zeh wrote: > Axel Simon [2010.08.30 0833 +0200]: >> Hi Norbert, > > [...] > >> Judging from the documentation, we are wrong in using >> 'destroyEvent' in >> our examples. This only works when the associated widget has a >> 'DrawWindow' which is an area to draw on. Some widgets do not have >> such a >> window but draw on their parent's DrawWindow. If you connect to >> such a >> widget's destroyEvent, it will never be triggered because it >> indicates >> that the widget's DrawWindow is destroyed. Correctly, one should >> always >> connect to 'deleteEvent' which will close the window by default >> (unless >> you return True from this handler). >> >> So this should always work: >> >> mainWin `on` deleteEvent $ \_ -> mainQuit >> return False > > This does work indeed. I'm still a bit confused as to why > onDestroyEvent works, while `on` destroyEvent does not. In > particular, > this suggests that it can't be the above explanation because the > widget > (which is a top-level window and, thus, I believe should have an > associated DrawWindow) reacts to onDestroyEvent and, thus, seems to > receive the signal. Any more ideas? Ok, so 'destroyEvent' is the new name for 'onDestroyEvent'. 'onDestroy' is not an event (i.e. does not have an EventM handler, just a normal IO handler) and is called when the object is destroyed. This handler is also deprecated and now lives in 'Object' as 'objectDestroy'. This is confusing and we should change our examples since obviously we are confused about this too. Axel |
From: Norbert Z. <nz...@cs...> - 2010-08-30 14:00:44
|
Axel Simon [2010.08.30 1319 +0200]: [...] > Ok, so 'destroyEvent' is the new name for 'onDestroyEvent'. > 'onDestroy' is not an event (i.e. does not have an EventM handler, just a > normal IO handler) and is called when the object is destroyed. This > handler is also deprecated and now lives in 'Object' as 'objectDestroy'. > This is confusing and we should change our examples since obviously we > are confused about this too. I thought I was using onDestroyEvent before, but I certainly did use onDestroy. onDestroyEvent doesn't do anything for me, just as `on` destroyEvent, while onDestroy showed me the desired behaviour. I'm still a bit curious as to why a main window does not receive a destroy event, but at least the behaviour between the old and new API is consistent. So, for now, thanks a lot for helping me sort this out. Cheers, Norbert -- () ascii ribbon campaign - against html e-mail /\ www.asciiribbon.org - against proprietary attachments |