xmonad-contrib/XMonad/Actions/TiledWindowDragging.hs
Tony Zorman b1b3c4c469 ~/.xmonad/xmonad.hs -> xmonad.hs
With XDG support so firmly ingrained now, it's about time we stop
hard-coding the configuration path in the docs.
2023-12-22 18:17:17 +01:00

93 lines
3.4 KiB
Haskell

-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.TiledWindowDragging
-- Description : Change the position of windows by dragging them.
-- Copyright : (c) 2020 Leon Kowarschick
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Leon Kowarschick. <thereal.elkowar@gmail.com>
-- Stability : unstable
-- Portability : unportable
--
-- Provides an action that allows you to change the position of windows by dragging them around.
--
-----------------------------------------------------------------------------
module XMonad.Actions.TiledWindowDragging
(
-- * Usage
-- $usage
dragWindow
)
where
import XMonad
import XMonad.Prelude
import qualified XMonad.StackSet as W
import XMonad.Layout.DraggingVisualizer
-- $usage
-- You can use this module with the following in your @xmonad.hs@:
--
-- > import XMonad.Actions.TiledWindowDragging
-- > import XMonad.Layout.DraggingVisualizer
--
-- then edit your 'layoutHook' by adding the draggingVisualizer to your layout:
--
-- > myLayout = draggingVisualizer $ layoutHook def
--
-- Then add a mouse binding for 'dragWindow':
--
-- > , ((modMask .|. shiftMask, button1), dragWindow)
--
-- For detailed instructions on editing your mouse bindings, see
-- "XMonad.Doc.Extending#Editing_mouse_bindings".
-- | Create a mouse binding for this to be able to drag your windows around.
-- You need "XMonad.Layout.DraggingVisualizer" for this to look good.
dragWindow :: Window -> X ()
dragWindow window = whenX (isClient window) $ withDisplay $ \dpy ->
withWindowAttributes dpy window $ \wa -> do
focus window
(offsetX, offsetY) <- getPointerOffset window
let (winX, winY, winWidth, winHeight) = getWindowPlacement wa
mouseDrag
(\posX posY ->
let rect = Rectangle (fi (fi winX + (posX - fi offsetX)))
(fi (fi winY + (posY - fi offsetY)))
(fi winWidth)
(fi winHeight)
in sendMessage $ DraggingWindow window rect
)
(sendMessage DraggingStopped >> performWindowSwitching window)
-- | get the pointer offset relative to the given windows root coordinates
getPointerOffset :: Window -> X (Int, Int)
getPointerOffset win = do
(_, _, _, oX, oY, _, _, _) <- withDisplay (\d -> io $ queryPointer d win)
return (fi oX, fi oY)
-- | return a tuple of windowX, windowY, windowWidth, windowHeight
getWindowPlacement :: WindowAttributes -> (Int, Int, Int, Int)
getWindowPlacement wa = (fi $ wa_x wa, fi $ wa_y wa, fi $ wa_width wa, fi $ wa_height wa)
performWindowSwitching :: Window -> X ()
performWindowSwitching win = do
root <- asks theRoot
(_, _, selWin, _, _, _, _, _) <- withDisplay (\d -> io $ queryPointer d root)
ws <- gets windowset
let allWindows = W.index ws
when ((win `elem` allWindows) && (selWin `elem` allWindows)) $ do
let allWindowsSwitched = map (switchEntries win selWin) allWindows
(ls, t : rs) <- pure $ break (== win) allWindowsSwitched
let newStack = W.Stack t (reverse ls) rs
windows $ W.modify' $ const newStack
where
switchEntries a b x | x == a = b
| x == b = a
| otherwise = x