aboutsummaryrefslogtreecommitdiffstats
path: root/XMonad/Actions/AfterDrag.hs
diff options
context:
space:
mode:
Diffstat (limited to 'XMonad/Actions/AfterDrag.hs')
-rw-r--r--XMonad/Actions/AfterDrag.hs71
1 files changed, 71 insertions, 0 deletions
diff --git a/XMonad/Actions/AfterDrag.hs b/XMonad/Actions/AfterDrag.hs
new file mode 100644
index 0000000..261ea91
--- /dev/null
+++ b/XMonad/Actions/AfterDrag.hs
@@ -0,0 +1,71 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module : XMonad.Actions.AfterDrag
+-- Copyright : (c) 2014 Anders Engstrom <ankaan@gmail.com>
+-- License : BSD3-style (see LICENSE)
+--
+-- Maintainer : Anders Engstrom <ankaan@gmail.com>
+-- 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