----------------------------------------------------------------------------
-- |
-- Module      :  XMonad.Actions.WindowMenu
-- Description :  Display window management actions in the center of the focused window.
-- Copyright   :  (c) Jan Vornberger 2009
-- License     :  BSD3-style (see LICENSE)
--
-- Maintainer  :  jan.vornberger@informatik.uni-oldenburg.de
-- Stability   :  unstable
-- Portability :  not portable
--
-- Uses "XMonad.Actions.GridSelect" to display a number of actions related to
-- window management in the center of the focused window. Actions include: Closing,
-- maximizing, minimizing and shifting the window to another workspace.
--
-- Note: For maximizing and minimizing to actually work, you will need
-- to integrate "XMonad.Layout.Maximize" and "XMonad.Layout.Minimize" into your
-- setup.  See the documentation of those modules for more information.
--
-----------------------------------------------------------------------------

module XMonad.Actions.WindowMenu (
                             -- * Usage
                             -- $usage
                             windowMenu
                              ) where

import XMonad
import qualified XMonad.StackSet as W
import XMonad.Actions.GridSelect
import XMonad.Layout.Maximize
import XMonad.Actions.Minimize
import XMonad.Prelude (fi)

-- $usage
--
-- You can use this module with the following in your @xmonad.hs@:
--
-- >    import XMonad.Actions.WindowMenu
--
-- Then add a keybinding, e.g.
--
-- >    , ((modm,               xK_o ), windowMenu)

colorizer :: a -> Bool -> X (String, String)
colorizer :: forall a. a -> Bool -> X (String, String)
colorizer a
_ Bool
isFg = do
    String
fBC <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks (forall (l :: * -> *). XConfig l -> String
focusedBorderColor forall b c a. (b -> c) -> (a -> b) -> a -> c
. XConf -> XConfig Layout
config)
    String
nBC <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks (forall (l :: * -> *). XConfig l -> String
normalBorderColor forall b c a. (b -> c) -> (a -> b) -> a -> c
. XConf -> XConfig Layout
config)
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ if Bool
isFg
                then (String
fBC, String
nBC)
                else (String
nBC, String
fBC)

windowMenu :: X ()
windowMenu :: X ()
windowMenu = (Window -> X ()) -> X ()
withFocused forall a b. (a -> b) -> a -> b
$ \Window
w -> forall a. (Display -> X a) -> X a
withDisplay forall a b. (a -> b) -> a -> b
$ \Display
d -> Display -> Window -> (WindowAttributes -> X ()) -> X ()
withWindowAttributes Display
d Window
w forall a b. (a -> b) -> a -> b
$ \WindowAttributes
wa -> do
    [String]
tags <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks (forall (l :: * -> *). XConfig l -> [String]
workspaces forall b c a. (b -> c) -> (a -> b) -> a -> c
. XConf -> XConfig Layout
config)
    let Rectangle Position
x Position
y Dimension
wh Dimension
ht = WindowAttributes -> Rectangle
getSize WindowAttributes
wa
    Rectangle Position
sx Position
sy Dimension
swh Dimension
sht <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall a b. (a -> b) -> a -> b
$ ScreenDetail -> Rectangle
screenRect forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall i l a sid sd. Screen i l a sid sd -> sd
W.screenDetail forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall i l a sid sd. StackSet i l a sid sd -> Screen i l a sid sd
W.current forall b c a. (b -> c) -> (a -> b) -> a -> c
. XState -> WindowSet
windowset
    let originFractX :: Double
originFractX = (forall a b. (Integral a, Num b) => a -> b
fi Position
x forall a. Num a => a -> a -> a
- forall a b. (Integral a, Num b) => a -> b
fi Position
sx forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fi Dimension
wh forall a. Fractional a => a -> a -> a
/ Double
2) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fi Dimension
swh
        originFractY :: Double
originFractY = (forall a b. (Integral a, Num b) => a -> b
fi Position
y forall a. Num a => a -> a -> a
- forall a b. (Integral a, Num b) => a -> b
fi Position
sy forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fi Dimension
ht forall a. Fractional a => a -> a -> a
/ Double
2) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fi Dimension
sht
        gsConfig :: GSConfig a
gsConfig = (forall a. (a -> Bool -> X (String, String)) -> GSConfig a
buildDefaultGSConfig forall a. a -> Bool -> X (String, String)
colorizer)
                    { gs_originFractX :: Double
gs_originFractX = Double
originFractX
                    , gs_originFractY :: Double
gs_originFractY = Double
originFractY }
        actions :: [(String, X ())]
actions = [ (String
"Cancel menu", forall (m :: * -> *) a. Monad m => a -> m a
return ())
                  , (String
"Close"      , X ()
kill)
                  , (String
"Maximize"   , forall a. Message a => a -> X ()
sendMessage forall a b. (a -> b) -> a -> b
$ Window -> MaximizeRestore
maximizeRestore Window
w)
                  , (String
"Minimize"   , Window -> X ()
minimizeWindow Window
w)
                  ] forall a. [a] -> [a] -> [a]
++
                  [ (String
"Move to " forall a. [a] -> [a] -> [a]
++ String
tag, (WindowSet -> WindowSet) -> X ()
windows forall a b. (a -> b) -> a -> b
$ forall a s i l sd.
(Ord a, Eq s, Eq i) =>
i -> StackSet i l a s sd -> StackSet i l a s sd
W.shift String
tag)
                    | String
tag <- [String]
tags ]
    GSConfig (X ()) -> [(String, X ())] -> X ()
runSelectedAction forall {a}. GSConfig a
gsConfig [(String, X ())]
actions

getSize :: WindowAttributes -> Rectangle
getSize :: WindowAttributes -> Rectangle
getSize WindowAttributes
wa =
  let x :: Position
x = forall a b. (Integral a, Num b) => a -> b
fi forall a b. (a -> b) -> a -> b
$ WindowAttributes -> CInt
wa_x WindowAttributes
wa
      y :: Position
y = forall a b. (Integral a, Num b) => a -> b
fi forall a b. (a -> b) -> a -> b
$ WindowAttributes -> CInt
wa_y WindowAttributes
wa
      wh :: Dimension
wh = forall a b. (Integral a, Num b) => a -> b
fi forall a b. (a -> b) -> a -> b
$ WindowAttributes -> CInt
wa_width WindowAttributes
wa
      ht :: Dimension
ht = forall a b. (Integral a, Num b) => a -> b
fi forall a b. (a -> b) -> a -> b
$ WindowAttributes -> CInt
wa_height WindowAttributes
wa
   in Position -> Position -> Dimension -> Dimension -> Rectangle
Rectangle Position
x Position
y Dimension
wh Dimension
ht