haskellmouse-cursorgloss

How to hide the mouse cursor in Haskell Gloss


Is it possible to hide the cursor using Gloss in Haskell? We want to replace the player with the mouse position.


Solution

  • This functionality isn't exposed by gloss: it would be more easily achievable if the Internal modules were exposed (by using eg. playWithBackendIO and some custom instances of Backend to hide the cursor). If you really want this functionality, it'd be best to fork the project and add the functionality you want.


    There are workarounds without modifying the original package though: when using any of the ...IO functions, we can perform arbitrary IO actions inside the functions we pass in, which allows us to modify the state of the backend.

    I'm going to use displayIO here for simplicity, but this works for any of the modes like playIO etc.

    import Prelude hiding (init)
    import Control.Monad
    import Data.IORef
    import Data.StateVar
    import Graphics.Gloss
    import Graphics.Gloss.Interface.IO.Display
    import qualified Graphics.UI.GLUT.Window as Glut
    
    init :: IO ()
    init = Glut.cursor $= Glut.None
    
    render :: IORef Bool -> IO Picture
    render doneInit = do
        needsInit <- not <$> readIORef doneInit
        when needsInit $ do
            init
            writeIORef doneInit True
        return $ color white $ circle 30
    
    controllerCallback :: Controller -> IO ()
    controllerCallback _ = return ()
    
    main :: IO ()
    main = do
        let disp = InWindow "test" (800, 600) (0, 0)
        initVar <- newIORef False
        displayIO disp black (render initVar) controllerCallback
    

    The vital piece is Glut.cursor $= Glut.None, which sets GLUT's cursor value using StateVar's $= function and automatically updates the glut context. We only want to run this once, so we use an IORef to keep track of whether we've run it before.

    Finally, this doesn't work for the GLFW backend. gloss uses a very old version of GLFW-b which doesn't support anything to do with cursor modes. More modern versions do, but I've not been able to find a way to get the Window instance as Gloss just discards it.