aboutsummaryrefslogtreecommitdiffstats
path: root/ManageDocks.hs
blob: 2f702e8aed4f1427f73c01dc342649adbef6eb65 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
-----------------------------------------------------------------------------
-- |
-- Module       : XMonadContrib.ManageDocks
-- Copyright    : (c) Joachim Breitner <mail@joachim-breitner.de>
-- License      : BSD
--
-- Maintainer   : Joachim Breitner <mail@joachim-breitner.de>
-- Stability    : unstable
-- Portability  : unportable
--
-- Makes xmonad detect windows with type DOCK and does not put them in
-- layouts. It also detects window with STRUT set and modifies the
-- gap accordingly.
--
-- Cheveats:
--
--  * Only acts on STRUT apps on creation, not if you move or close them
--
--  * To reset the gap, press Mod-b twice and restart xmonad (Mod-q)
-----------------------------------------------------------------------------
module XMonadContrib.ManageDocks (
	-- * Usage
	-- $usage
	manageDocksHook
	) where

import Control.Monad.Reader
import XMonad
import Operations
import qualified StackSet as W
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
import Data.Word

-- $usage
-- Add the imports to your configuration file and add the mangeHook:
--
-- > import XMonadContrib.ManageDocks
--
-- > manageHook w _ _ _  = manageDocksHook w

-- %import XMonadContrib.ManageDocks
-- %def -- comment out default manageHook definition above if you uncomment this:
-- %def manageHook _ _ _ = manageDocksHook w


-- |
-- Detects if the given window is of type DOCK and if so, reveals it, but does
-- not manage it. If the window has the STRUT property set, adjust the gap accordingly.
manageDocksHook :: Window -> X (WindowSet -> WindowSet)
manageDocksHook w = do
	hasStrut <- getStrut w
	maybe (return ()) setGap hasStrut

	isDock <- checkDock w
	if isDock then do
		reveal w
		return (W.delete w)
	      else do
	        return id

-- |
-- Checks if a window is a DOCK window
checkDock :: Window -> X (Bool)
checkDock w = do
	a <- getAtom "_NET_WM_WINDOW_TYPE"
	d <- getAtom "_NET_WM_WINDOW_TYPE_DOCK"
	mbr <- getProp a w
	case mbr of 
		Just [r] -> return (r == d)
		_        -> return False

-- | 
-- Gets the STRUT config, if present, in xmonad gap order
getStrut :: Window -> X (Maybe (Int, Int, Int, Int))
getStrut w = do 
	a <- getAtom "_NET_WM_STRUT"
	mbr <- getProp a w
	case mbr of 
		Just [l,r,t,b] -> return (Just (
					fromIntegral t,
					fromIntegral b,
					fromIntegral l,
					fromIntegral r))
		_              -> return Nothing

-- |
-- Helper to read a property
getProp :: Atom -> Window -> X (Maybe [Word32])
getProp a w = withDisplay $ \dpy -> io $ getWindowProperty32 dpy a w

-- |
-- Modifies the gap, setting new max
setGap :: (Int, Int, Int, Int) -> X ()
setGap gap = modifyGap (\_ -> max4 gap)

-- |
-- Piecewise maximum of a 4-tuple of Ints
max4 :: (Int, Int, Int, Int) -> (Int, Int, Int, Int) -> (Int, Int, Int, Int) 
max4 (a1,a2,a3,a4) (b1,b2,b3,b4) = (max a1 b1, max a2 b2, max a3 b3, max a4 b4)