robot 1.2 → 1.3
raw patch · 4 files changed
+72/−21 lines, 4 filesdep +exceptions
Dependencies added: exceptions
Files
- Test/Robot.hs +13/−2
- Test/Robot/Connection.hs +35/−0
- Test/Robot/Internal.hs +21/−18
- robot.cabal +3/−1
Test/Robot.hs view
@@ -5,7 +5,6 @@ -- * Running your robot Robot() -- hide implementation , runRobot- , runRobotWithConnection -- * Key and button constants , module Test.Robot.Types@@ -18,14 +17,17 @@ -- * Miscellaneous , sleep+ , module Test.Robot.Connection ) where import Control.Applicative import Control.Concurrent (threadDelay)+import Control.Monad.Catch import Control.Monad.IO.Class +import Test.Robot.Connection import Test.Robot.Internal import Test.Robot.Types @@ -54,7 +56,7 @@ -- of an exception. -- hold :: x -> Robot a -> Robot a- hold = bracketRobot_ <$> press <*> release+ hold = bracket_ <$> press <*> release instance Pressable Key where press = keyboard True@@ -93,6 +95,15 @@ -- | Press the argument, then release it.+--+-- Note that the underlying events are fired very quickly; much faster+-- than some applications (such as Xmonad) can handle. If this becomes+-- an issue, you may introduce a delay using 'sleep':+--+-- @+-- slowTap x = x \`hold\` sleep 0.1+-- @+-- tap :: Pressable x => x -> Robot () tap = (`hold` return ())
+ Test/Robot/Connection.hs view
@@ -0,0 +1,35 @@+-- | Functions for managing connections manually.++module Test.Robot.Connection+ (+ -- * Managing connections+ -- $connections+ runRobotWith+ , connect++ ) where+++import Test.Robot.Internal+++-- $connections+--+-- 'runRobot' opens a new connection every time it is called. If you+-- call it too many times, it will exhaust the connection pool, causing+-- a \"maximum number of clients reached\" error.+--+-- This module lets you avoid this error by handling the connection+-- manually.+--+-- Example:+--+-- @+-- main = do+-- Just conn <- 'connect'+-- replicateM_ 500 $ do+-- 'runRobotWith' conn $ tap _A+-- putStrLn \"Ducks!\"+-- @+--+--
Test/Robot/Internal.hs view
@@ -8,13 +8,11 @@ -- * The Robot monad Robot(..) , runRobot- , runRobotWithConnection+ , runRobotWith+ , connect , mkRobot , mkRobot' - -- * Exception safety- , bracketRobot_- -- * Synthesizing events , keyboard , button@@ -24,45 +22,50 @@ import Control.Applicative-import Control.Exception (bracket_)+import Control.Monad.Catch import Control.Monad.IO.Class import Control.Monad.Trans.Reader import Data.Map (Map) import qualified Data.Map as M -import Graphics.XHB+import Graphics.XHB hiding (connect)+import qualified Graphics.XHB as X import qualified Test.Robot.Internal.XTest as X import Test.Robot.Types --- | The Robot monad: a reader monad over IO.+-- | A @Robot@ is a program that interacts with the GUI.+--+-- Use 'runRobot' to execute your Robot, and 'liftIO' to perform+-- arbitrary I/O.+-- newtype Robot a = Robot { unRobot :: ReaderT (Connection, Map KEYSYM KEYCODE) IO a }- deriving (Functor, Applicative, Monad, MonadIO)+ deriving (Functor, Applicative, Monad, MonadIO, MonadCatch, MonadMask, MonadThrow) -- | Run the robot, connecting to the display automatically. runRobot :: Robot a -> IO a runRobot m = do- Just c <- connect- runRobotWithConnection m c+ c <- connect+ runRobotWith c m -- | Run the robot using an existing connection.-runRobotWithConnection :: Robot a -> Connection -> IO a-runRobotWithConnection (Robot m) c = do+runRobotWith :: Connection -> Robot a -> IO a+runRobotWith c (Robot m) = do keymap <- X.getKeysymMap c runReaderT m (c, keymap) +-- | Connect to the X11 server.+connect :: IO Connection+connect = do+ Just c <- X.connect+ return c+ mkRobot :: ((Connection, Map KEYSYM KEYCODE) -> IO a) -> Robot a mkRobot = Robot . ReaderT mkRobot' :: (Connection -> IO a) -> Robot a mkRobot' = mkRobot . (. fst)---bracketRobot_ :: Robot a -> Robot z -> Robot r -> Robot r-bracketRobot_ (Robot before) (Robot after) (Robot middle)- = mkRobot $ \env -> let run = flip runReaderT env- in bracket_ (run before) (run after) (run middle) keyboard :: Bool -> Key -> Robot ()
robot.cabal view
@@ -1,5 +1,5 @@ Name: robot-Version: 1.2+Version: 1.3 Synopsis: Simulate keyboard and mouse events Homepage: https://github.com/lfairy/robot License: OtherLicense@@ -21,6 +21,7 @@ Library Exposed-Modules: Test.Robot+ Test.Robot.Connection Test.Robot.Internal Test.Robot.Internal.XTest Test.Robot.Types@@ -31,6 +32,7 @@ Build-Depends: base == 4.* , containers+ , exceptions == 0.6.* , transformers , xhb