First of all, thanks for gtk2hs. It's already awesome. There are a number of improvements I would suggest and I may even be willing to work on if I can find the time.
#1: This one is a 10-second programming effort and is really necessary, I think.
The current definition of EventM is
type EventM t a = ReaderT (Ptr t) IO a
This is unfortunate because it prevents users from wrapping this in a monad transformer, for example to carry application state around. For example, if I were to try to define an action
doSomething :: StateT MyState (EventM any) Bool
the compiler complains because EventM expects two type arguments and was given only one. The fix is simple: Change the definition of EventM to
type EventM t = ReaderT (Ptr t) IO.
(Arguably, the plumbing should be hidden and EventM should be a newtype, but that would be more effort because it probably requires changes elsewhere in the gtk2hs code base.)
#2: MonadIO and type classes for EventM and Render
Let me start by saying that I am not sure how hard this is to do, but it would help users a lot. Again, the motivation is that applications often use monad transformers to carry state around, so the main monad may not be IO but something like StateT MyState IO. Now using pretty much all the standard gtk functions requires cluttering the code with lots of calls to liftIO. Changing the type signature of all gtk2hs functions as illustrated here for buttonNew would solve this: Currently, the type of buttonNew is
buttonNew :: IO Button
Can't we make it
buttonNew :: MonadIO m => m Button ?
This would eliminate the need for lifting in the user code. The same reasoning applies to Render and EventM, except that it requires more effort because one would have to define type classes such as MonadEventM and MonadRender. The lack of this approach for EventM is quite a bit more annoying than the need to sprinkle liftIO's throughout the code because passing an event handler wrapped in a StateT transformer or similar to "on" explicitly requires packing and unpacking the state.
Let me close by saying once more that I am happy gtk2hs exists because, even though I say "annoying" above, it would be more annoying not to have gtk2hs for GUI development in Haskell. Thanks for your efforts, guys.