diff options
Diffstat (limited to '')
-rw-r--r-- | XMonad/Actions/AfterDrag.hs | 71 | ||||
-rw-r--r-- | XMonad/Actions/FloatSnap.hs | 26 |
2 files changed, 89 insertions, 8 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 diff --git a/XMonad/Actions/FloatSnap.hs b/XMonad/Actions/FloatSnap.hs index 3597254..baf511f 100644 --- a/XMonad/Actions/FloatSnap.hs +++ b/XMonad/Actions/FloatSnap.hs @@ -21,18 +21,21 @@ module XMonad.Actions.FloatSnap ( snapShrink, snapMagicMove, snapMagicResize, - snapMagicMouseResize) where + snapMagicMouseResize, + afterDrag, + ifClick, + ifClick') where import XMonad import Control.Applicative((<$>)) import Data.List (sort) import Data.Maybe (listToMaybe,fromJust,isNothing) import qualified XMonad.StackSet as W +import qualified Data.Set as S import XMonad.Hooks.ManageDocks (calcGap) import XMonad.Util.Types (Direction2D(..)) - -import qualified Data.Set as S +import XMonad.Actions.AfterDrag -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@: @@ -53,17 +56,24 @@ import qualified Data.Set as S -- For detailed instructions on editing your key bindings, see -- "XMonad.Doc.Extending#Editing_key_bindings". -- --- And possibly add an appropriate mouse binding, for example: +-- And possibly add appropriate mouse bindings, for example: -- --- > , ((modm, button1), (\w -> focus w >> mouseMoveWindow w >> snapMagicMove (Just 50) (Just 50) w)) --- > , ((modm .|. shiftMask, button1), (\w -> focus w >> mouseMoveWindow w >> snapMagicResize [L,R,U,D] (Just 50) (Just 50) w)) --- > , ((modm, button3), (\w -> focus w >> mouseResizeWindow w >> snapMagicResize [R,D] (Just 50) (Just 50) w)) +-- > , ((modm, button1), (\w -> focus w >> mouseMoveWindow w >> ifClick (snapMagicMove (Just 50) (Just 50) w))) +-- > , ((modm .|. shiftMask, button1), (\w -> focus w >> mouseMoveWindow w >> ifClick (snapMagicResize [L,R,U,D] (Just 50) (Just 50) w))) +-- > , ((modm, button3), (\w -> focus w >> mouseResizeWindow w >> ifClick (snapMagicResize [R,D] (Just 50) (Just 50) w))) -- -- For detailed instructions on editing your mouse bindings, see -- "XMonad.Doc.Extending#Editing_mouse_bindings". -- -- Using these mouse bindings, it will not snap while moving, but allow you to click the window once after it has been moved or resized to snap it into place. --- Note that the order in which the commands are applied in the mouse bindings are important. +-- Note that the order in which the commands are applied in the mouse bindings are important. Snapping can also be used together with other window resizing +-- functions, such as those from "XMonad.Actions.FlexibleResize" +-- +-- An alternative set of mouse bindings that will always snap after the drag is: +-- +-- > , ((modm, button1), (\w -> focus w >> mouseMoveWindow w >> afterDrag (snapMagicMove (Just 50) (Just 50) w))) +-- > , ((modm .|. shiftMask, button1), (\w -> focus w >> mouseMoveWindow w >> afterDrag (snapMagicResize [L,R,U,D] (Just 50) (Just 50) w))) +-- > , ((modm, button3), (\w -> focus w >> mouseResizeWindow w >> afterDrag (snapMagicResize [R,D] (Just 50) (Just 50) w))) -- -- Interesting values for the distance to look for window in the orthogonal axis are Nothing (to snap against every window), Just 0 (to only snap -- against windows that we should collide with geometrically while moving) and Just 1 (to also snap against windows we brush against). |