----------------------------------------------------------------------------- -- | -- Module : XMonad.Actions.AfterDrag -- Copyright : (c) 2014 Anders Engstrom -- License : BSD3-style (see LICENSE) -- -- Maintainer : Anders Engstrom -- Stability : unstable -- Portability : unportable -- -- Perform an action after the current mouse drag is completed. ----------------------------------------------------------------------------- module XMonad.Actions.AfterDrag ( -- * Usage -- $usage afterDrag, ifClick, ifClick') where import XMonad import System.Time -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@: -- -- > import XMonad.Actions.AfterDrag -- -- Then add appropriate mouse bindings, for example: -- -- > , ((modm, button3), (\w -> focus w >> mouseResizeWindow w >> ifClick (windows $ W.float w $ W.RationalRect 0 0 1 1))) -- -- This will allow you to resize windows as usual, but if you instead of -- draging click the mouse button the window will be automatically resized to -- fill the whole screen. -- -- For detailed instructions on editing your mouse bindings, see -- "XMonad.Doc.Extending#Editing_mouse_bindings". -- -- More practical examples are available in "XMonad.Actions.FloatSnap". -- | Schedule a task to take place after the current dragging is completed. afterDrag :: X () -- ^ The task to schedule. -> X () afterDrag task = do drag <- gets dragging case drag of Nothing -> return () -- Not dragging Just (motion, cleanup) -> modify $ \s -> s { dragging = Just(motion, cleanup >> task) } -- | Take an action if the current dragging can be considered a click, -- supposing the drag just started before this function is called. -- A drag is considered a click if it is completed within 300 ms. ifClick :: X () -- ^ The action to take if the dragging turned out to be a click. -> X () ifClick action = ifClick' 300 action (return ()) -- | Take an action if the current dragging is completed within a certain time (in milliseconds.) ifClick' :: Int -- ^ Maximum time of dragging for it to be considered a click (in milliseconds.) -> X () -- ^ The action to take if the dragging turned out to be a click. -> X () -- ^ The action to take if the dragging turned out to not be a click. -> X () ifClick' ms click drag = do start <- io $ getClockTime afterDrag $ do stop <- io $ getClockTime if diffClockTimes stop start <= noTimeDiff { tdPicosec = fromIntegral ms * 10^(9 :: Integer) } then click else drag