From 8c57d383a08a3dec19c39473dc3127f560508f7f Mon Sep 17 00:00:00 2001 From: "l.mai" Date: Fri, 29 Jun 2007 19:10:38 +0200 Subject: flexible resizing for floating windows The default resize handler for floating windows warps the mouse pointer to the bottom right corner of the window (fixing the opposite, upper left, corner). This extension lets you use any of the four window corners as grabbing points, allowing more flexible resizing. darcs-hash:20070629171038-42ea9-1a2b98ca2071dd5988e529b8395148b6a838ba9b.gz --- FlexibleResize.hs | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 FlexibleResize.hs diff --git a/FlexibleResize.hs b/FlexibleResize.hs new file mode 100644 index 0000000..9d5d098 --- /dev/null +++ b/FlexibleResize.hs @@ -0,0 +1,63 @@ +----------------------------------------------------------------------------- +-- | +-- Module : XMonadContrib.FlexibleResize +-- Copyright : (c) Lukas Mai +-- License : BSD3-style (see LICENSE) +-- +-- Maintainer : +-- Stability : unstable +-- Portability : unportable +-- +-- Lets you resize floating windows from any corner. +-- +----------------------------------------------------------------------------- + +module XMonadContrib.FlexibleResize ( + -- * Usage + -- $usage + XMonadContrib.FlexibleResize.mouseResizeWindow +) where + +import XMonad +import Operations +import Graphics.X11.Xlib +import Graphics.X11.Xlib.Extras +import Foreign.C.Types + +-- $usage +-- Put something like this in your Config.hs file: +-- +-- > import qualified XMonadContrib.FlexibleResize as Flex +-- > mouseBindings = M.fromList +-- > [ ... +-- > , ((modMask, button3), (\w -> focus w >> Flex.mouseResizeWindow w)) ] + +mouseResizeWindow :: Window -> X () +mouseResizeWindow w = whenX (isClient w) $ withDisplay $ \d -> do + io $ raiseWindow d w + wa <- io $ getWindowAttributes d w + sh <- io $ getWMNormalHints d w + (_, _, _, _, _, ix, iy, _) <- io $ queryPointer d w + let + [pos_x, pos_y, width, height] = map (fromIntegral . ($ wa)) [wa_x, wa_y, wa_width, wa_height] + west = firstHalf ix width + north = firstHalf iy height + (cx, fx, gx) = mkSel west width pos_x + (cy, fy, gy) = mkSel north height pos_y + io $ warpPointer d none w 0 0 0 0 cx cy + mouseDrag $ \(_, _, _, ex, ey, _, _, _, _, _) -> do + wa' <- getWindowAttributes d w + let [px, py] = map (fromIntegral . ($ wa')) [wa_x, wa_y] + moveResizeWindow d w (fromIntegral $ fx px ex) (fromIntegral $ fy py ey) + `uncurry` applySizeHints sh (gx ex, gy ey) + float w + where + firstHalf :: CInt -> Position -> Bool + firstHalf a b = fromIntegral a * 2 <= b + cfst = curry fst + csnd = curry snd + mkSel :: Bool -> Position -> Position -> (Position, a -> a -> a, CInt -> Dimension) + mkSel b k p = + if b + then (0, csnd, fromIntegral . max 1 . ((k + p) -) . fromIntegral) + else (k, cfst, fromIntegral . max 1 . subtract p . fromIntegral) -- cgit v1.2.3