Window-less event injection into wxWigets event loop using wxHaskell

108 Views Asked by At

Another take on Haskell-way multithreading and wxWidgets.

I see https://stackoverflow.com/a/12596595/4095104 as a nice hack to run code in the wx event loop, but it requires me to create a window in start/run first and return from it so the event loop may run its course, while my application is essentially window-less and may create windows on demand from the internal (multithreaded) logic. Is there a good way to create a new event in the loop that is not bound to any pre-existing wxWidgets objects?

Edit: the code example:

import Graphics.UI.WX as WX
import Graphics.UI.WXCore as WXCore
import Control.Concurrent

-- | cf. http://snipplr.com/view/17538/
myEventId :: Int
myEventId = WXCore.wxID_HIGHEST+100
    -- the custom event ID, avoid clash with Graphics.UI.WXCore.Types.varTopId

-- | the custom event is registered as a menu event
createMyEvent :: IO (WXCore.CommandEvent ())
createMyEvent =
   WXCore.commandEventCreate WXCore.wxEVT_COMMAND_MENU_SELECTED myEventId

registerMyEvent :: WXCore.EvtHandler a -> IO () -> IO ()
registerMyEvent win io =
   WXCore.evtHandlerOnMenuCommand win myEventId io


doesntwork = do
    handler <- newEmptyMVar
    start $ do
        app <- wxcAppGetApp
        event <- createMyEvent
        mvar <- newEmptyMVar
        registerMyEvent app $ do
            str <- takeMVar mvar
            putStrLn str
        putMVar handler (app, event, mvar)
    (app, event, mvar) <- takeMVar handler
    putMVar mvar "hack"
    WXCore.evtHandlerAddPendingEvent app event
    threadDelay 10000000000

works = do
    handler <- newEmptyMVar
    start $ do
        app <- wxcAppGetApp
        event <- createMyEvent
        mvar <- newEmptyMVar
        registerMyEvent app $ do
            str <- takeMVar mvar
            putStrLn str
        putMVar handler (app, event, mvar)
        putMVar mvar "hack"
        WXCore.evtHandlerAddPendingEvent app event
    (app, event, mvar) <- takeMVar handler
    threadDelay 10000000000

main = doesntwork
1

There are 1 best solutions below

0
On

At C++ level you could just use wxEventLoop class directly, but I don't know if it's properly wrapped by wxHaskell.