summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Main.hs65
-rw-r--r--W.hs31
2 files changed, 55 insertions, 41 deletions
diff --git a/Main.hs b/Main.hs
index 7cf9858..3974467 100644
--- a/Main.hs
+++ b/Main.hs
@@ -67,7 +67,9 @@ keys =
[ (mod1Mask .|. shiftMask, xK_Return, spawn "xterm")
, (mod1Mask, xK_p, spawn "exe=`dmenu_path | dmenu` && exec $exe")
, (controlMask, xK_space, spawn "gmrun")
- , (mod1Mask, xK_Tab, switch)
+ , (mod1Mask, xK_Tab, focus 1)
+ , (mod1Mask, xK_j, focus 1)
+ , (mod1Mask, xK_k, focus (-1))
, (mod1Mask .|. shiftMask, xK_q, io $ exitWith ExitSuccess)
]
@@ -112,63 +114,50 @@ handle _ = return ()
-- ---------------------------------------------------------------------
-- Managing windows
--- | Modify the current window list with a pure funtion, and refresh
-withWindows :: (Windows -> Windows) -> W ()
-withWindows f = do
- modifyWindows f
- refresh
-
--- | Run an action on the currently focused window
-withCurrent :: (Window -> W ()) -> W ()
-withCurrent f = do
- ws <- gets windows
- case ws of
- [] -> return ()
- (w:_) -> f w
-
--
-- | refresh. Refresh the currently focused window. Resizes to full
-- screen and raises the window.
--
refresh :: W ()
-refresh = withCurrent $ \w -> do
- d <- gets display
- sw <- gets screenWidth
- sh <- gets screenHeight
- io $ do moveResizeWindow d w 0 0 (fromIntegral sw) (fromIntegral sh)
- raiseWindow d w
+refresh = do
+ ws <- gets windows
+ case ws of
+ [] -> return ()
+ (w:_) -> do
+ d <- gets display
+ sw <- liftM fromIntegral (gets screenWidth)
+ sh <- liftM fromIntegral (gets screenHeight)
+ io $ do moveResizeWindow d w 0 0 sw sh
+ raiseWindow d w
+
+-- | Modify the current window list with a pure funtion, and refresh
+withWindows :: (Windows -> Windows) -> W ()
+withWindows f = do
+ modifyWindows f
+ refresh
---
-- | manage. Add a new window to be managed
---
manage :: Window -> W ()
manage w = do
trace "manage"
d <- gets display
- withWindows $ \ws -> if w `elem` ws then ws else w:ws -- a set
+ withWindows (nub . (w :))
io $ mapWindow d w
---
-- | unmanage, a window no longer exists, remove it from the stack
---
unmanage :: Window -> W ()
unmanage w = do
dpy <- gets display
- io $ grabServer dpy
- modifyWindows (filter (/= w))
- io $ sync dpy False
- io $ ungrabServer dpy
- refresh
+ io $ do grabServer dpy
+ sync dpy False
+ ungrabServer dpy
+ withWindows $ filter (/= w)
---
--- | switch. switch focus to next window in list.
+-- | focus. focus to window at offset 'n' in list.
-- The currently focused window is always the head of the list
---
-switch :: W ()
-switch = withWindows rotate
+focus :: Int -> W ()
+focus n = withWindows (rotate n)
---
-- | spawn. Launch an external application
---
spawn :: String -> W ()
spawn = io_ . runCommand
diff --git a/W.hs b/W.hs
index 88af0d3..cf1c1fb 100644
--- a/W.hs
+++ b/W.hs
@@ -29,6 +29,14 @@ data WState = WState
, windows :: !Windows
}
+--
+-- Multithreaded issues:
+--
+-- We'll want a status bar, it will probably read from stdin
+-- but will thus need to run in its own thread, and modify its status
+-- bar window
+--
+
type Windows = [Window]
-- | The W monad, a StateT transformer over IO encapuslating the window
@@ -74,6 +82,23 @@ forever a = a >> forever a
snoc :: [a] -> a -> [a]
snoc xs x = xs ++ [x]
--- | Rotate a list one element
-rotate [] = []
-rotate (x:xs) = xs `snoc` x
+-- | Rotate a list by 'n' elements.
+--
+-- for xs = [5..8] ++ [1..4]
+--
+-- rotate 0
+-- [5,6,7,8,1,2,3,4]
+--
+-- rotate 1
+-- [6,7,8,1,2,3,4,5]
+--
+-- rotate (-1)
+-- [4,5,6,7,8,1,2,3]
+--
+rotate n xs = take l . drop offset . cycle $ xs
+ where
+ l = length xs
+ offset | n < 0 = l + n
+ | otherwise = n
+
+