From 125172361e1eef9d922ba541751c3a0a503daef7 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Mon, 1 Nov 2021 11:04:29 -0600 Subject: add passmenu --- src/Internal/PassMenu.hs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/Internal/PassMenu.hs (limited to 'src') diff --git a/src/Internal/PassMenu.hs b/src/Internal/PassMenu.hs new file mode 100644 index 0000000..7374bed --- /dev/null +++ b/src/Internal/PassMenu.hs @@ -0,0 +1,15 @@ +module Internal.PassMenu where + +import XMonad +import XMonad.Util.Run +import Control.Monad + +runPassMenu :: X () +runPassMenu = void $ + safeSpawn "passmenu" [ + "-p", "Password ", + "-l", "12", + "-dim", "0.4", + "-sb", "#f54245", + "-nf", "#f54245" ] + -- cgit From 1e38cda801d91f39ffe0eeb9808afb32f300098d Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Mon, 1 Nov 2021 13:59:03 -0600 Subject: Add more DMenu integration & Add ability to change the spacing with Mod+Shift+[]. --- src/Internal/DMenu.hs | 29 +++++++++++++++++++++++++++++ src/Internal/Keys.hs | 11 +++++++++-- src/Internal/Lib.hs | 31 ++++++++++++++++++++----------- 3 files changed, 58 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/Internal/DMenu.hs b/src/Internal/DMenu.hs index c5cac49..d91c7ba 100644 --- a/src/Internal/DMenu.hs +++ b/src/Internal/DMenu.hs @@ -1,10 +1,39 @@ module Internal.DMenu where +import XMonad.Util.Dmenu import XMonad import XMonad.Util.Run import Control.Monad +import Data.Map (Map) +import qualified Data.Map as Map +import XMonad.Util.Run +import Data.List (intercalate) + +data Colors = + Colors { + fg :: String, + bg :: String + } | DefaultColors runDMenu :: X () runDMenu = void $ safeSpawn "/usr/bin/dmenu_run" [ "-p", "Execute ", "-l", "12", "-dim", "0.4"] + +runDMenuPrompt :: String -> Maybe String -> [String] -> X String +runDMenuPrompt prompt color select = + let realColor = maybe [] (\c -> ["-sb", c, "-nf", c]) color + in + runProcessWithInput "/home/rahm/.local/bin/dmenu_debug.sh" ([ + "-p", prompt, + "-l", "12", + "-dim", "0.4" ] ++ realColor) (intercalate "\n" select) + + +runDMenuPromptWithMap :: String -> Maybe String -> Map String a -> X (Maybe a) +runDMenuPromptWithMap prompt color map = do + let realColor = maybe [] (\c -> ["-sb", c, "-nf", c]) color + menuMapArgs "dmenu"([ + "-p", prompt, + "-l", "12", + "-dim", "0.4" ] ++ realColor) map diff --git a/src/Internal/Keys.hs b/src/Internal/Keys.hs index 91d033d..c97736f 100644 --- a/src/Internal/Keys.hs +++ b/src/Internal/Keys.hs @@ -4,6 +4,7 @@ module Internal.Keys where import Graphics.X11.ExtraTypes.XorgDefault import System.Process import XMonad.Util.Ungrab +import XMonad.Layout.Spacing import Internal.XPlus import Data.Maybe (isJust) import Debug.Trace @@ -65,6 +66,10 @@ click = do (_, _, window, _, _, _, _, _) <- io $ queryPointer dpy root focus window +modifyWindowBorder :: Integer -> SpacingModifier +modifyWindowBorder i = ModifyWindowBorder $ \(Border a b c d) -> + (Border (a + i) (b + i) (c + i) (d + i)) + newKeys :: MarkContext -> IO (KeyMap l) newKeys markContext = return $ \config@(XConfig {modMask = modm}) -> @@ -102,8 +107,10 @@ newKeys markContext = mapNumbersAndAlpha 0 ( runXPlus markContext config . swapWorkspace))) - , ((modm .|. shiftMask, xK_bracketleft), sendMessage (IncMasterN (-1))) - , ((modm .|. shiftMask, xK_bracketright), sendMessage (IncMasterN 1)) + , ((modm, xK_minus), sendMessage (IncMasterN (-1))) + , ((modm, xK_plus), sendMessage (IncMasterN 1)) + , ((modm .|. shiftMask, xK_bracketleft), sendMessage (modifyWindowBorder (-1))) + , ((modm .|. shiftMask, xK_bracketright), sendMessage (modifyWindowBorder 1)) , ((modm, xK_bracketleft), sendMessage ShrinkZoom) , ((modm, xK_bracketright), sendMessage ExpandZoom) diff --git a/src/Internal/Lib.hs b/src/Internal/Lib.hs index e0b78c5..feb5f26 100644 --- a/src/Internal/Lib.hs +++ b/src/Internal/Lib.hs @@ -3,6 +3,7 @@ module Internal.Lib where import Prelude hiding ((!!)) +import XMonad.Util.Run import XMonad.Prompt import XMonad.Prompt.Input import XMonad.Prompt.Shell @@ -19,6 +20,7 @@ import Text.Printf import XMonad hiding (workspaces, Screen) import XMonad.StackSet hiding (filter, focus) import qualified Data.Map as Map +import Internal.DMenu type WorkspaceName = Char newtype Selector = Selector (forall a. (Eq a) => a -> [a] -> a) @@ -123,15 +125,22 @@ windowJump = do windowTitlesToWinId <- withWindowSet $ \ss -> Map.fromList <$> mapM (\wid -> (,) <$> getString wid <*> return wid) (allWindows ss) - mkXPrompt - WinPrompt - xpConfig - (\input -> return $ filter (fuzzyCompletion input) (Map.keys windowTitlesToWinId)) $ - \str -> do + windowId <- runDMenuPromptWithMap "Window" (Just "#f542f5") windowTitlesToWinId + + case windowId of + Nothing -> return () + Just wid -> do saveLastMark markContext - case Map.lookup str windowTitlesToWinId of - Just w -> focus w - Nothing -> - case filter (fuzzyCompletion str) (Map.keys windowTitlesToWinId) of - [s] -> mapM_ focus (Map.lookup s windowTitlesToWinId) - _ -> return () + focus wid + -- mkXPrompt + -- WinPrompt + -- xpConfig + -- (\input -> return $ filter (fuzzyCompletion input) (Map.keys windowTitlesToWinId)) $ + -- \str -> do + -- saveLastMark markContext + -- case Map.lookup str windowTitlesToWinId of + -- Just w -> focus w + -- Nothing -> + -- case filter (fuzzyCompletion str) (Map.keys windowTitlesToWinId) of + -- [s] -> mapM_ focus (Map.lookup s windowTitlesToWinId) + -- _ -> return () -- cgit From 0d13796f6cb360ec8c00bf84651d68df5a108a33 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Tue, 2 Nov 2021 00:41:08 -0600 Subject: Big powerpill added to my XMonad and XMobar. --- src/Internal/LayoutDraw.hs | 19 ++++++++++--------- src/Main.hs | 38 ++++++++++++++++++++++++++++++-------- 2 files changed, 40 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/Internal/LayoutDraw.hs b/src/Internal/LayoutDraw.hs index 7dc2087..4bb069a 100644 --- a/src/Internal/LayoutDraw.hs +++ b/src/Internal/LayoutDraw.hs @@ -54,13 +54,13 @@ drawPng l = do -- (0.9, 0.9, 1.0), -- (0.8, 0.8, 1.0), -- (0.7, 0.7, 1.0), - (0.6, 0.6, 0.8), - (0.5, 0.5, 0.8), - (0.4, 0.4, 0.8), - (0.3, 0.3, 0.8), - (0.2, 0.2, 0.8), - (0.1, 0.1, 0.8), - (0.0, 0.0, 0.8) + (0.8, 0.6, 0.6), + (0.8, 0.5, 0.5), + (0.8, 0.4, 0.4), + (0.8, 0.3, 0.3), + (0.8, 0.2, 0.2), + (0.8, 0.1, 0.1), + (0.8, 0.0, 0.0) ] exists <- liftIO $ doesFileExist filepathXpm @@ -71,7 +71,7 @@ drawPng l = do setLineCap LineCapButt setLineJoin LineJoinMiter - forM_ (reverse $ zip (map (second padR) rects) colors) $ + forM_ (reverse $ zip (map (second extraPad) rects) colors) $ \((wind, Rectangle x y w h), (r, g, b)) -> do setSourceRGBA r g b 1 @@ -93,7 +93,8 @@ drawPng l = do return filepathXpm where - padR = id + extraPad (Rectangle x y w h) = + Rectangle (x + 100) (y + 100) (w - 100) (h - 100) -- padR (Rectangle x y w h) = -- Rectangle x y (max 1 $ w - 120) (max 1 $ h - 120) diff --git a/src/Main.hs b/src/Main.hs index 25c930e..7e1cc68 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -10,6 +10,7 @@ import Internal.Layout import XMonad.Hooks.ManageHelpers import XMonad.Layout.IndependentScreens import Text.Printf +import Data.List.Split import XMonad.Hooks.EwmhDesktops import Internal.Keys @@ -29,7 +30,8 @@ main = do , borderWidth = 2 , keys = \config -> mempty , focusedBorderColor = "#ff6c00" - , normalBorderColor = "#ffd9bf" + -- , normalBorderColor = "#ffd9bf" + , normalBorderColor = "#000000" , layoutHook = myLayout , startupHook = do ewmhDesktopsStartup @@ -55,15 +57,17 @@ main = do statusBar "xmobar" xmobarPP { - ppCurrent = xmobarColor "#ffffff" "red" . printf "%s" - , ppVisible = xmobarColor "#8888ff" "" . printf "%s" - , ppHidden = xmobarColor "#888888" "" . printf "%s" - , ppWsSep = " · " + ppCurrent = xmobarColor "#ff8888" "red" . printf "%s" + , ppVisible = xmobarColor "#8888ff" "" . printf "%s" + , ppHidden = xmobarColor "#888888" "" . printf "%s" + , ppWsSep = " " , ppTitle = - xmobarColor "#8888ff" "" . printf "%s" . - (printf "%s" :: String -> String) + xmobarColor "#808080" "" . + printf "%s" . + parseOut . + trunc 50 - , ppSep = xmobarColor "#404040" "" " ──── " + , ppSep = xmobarColor "#404040" "" " │ " , ppLayout = const "" , ppExtras = [showLayout] , ppOrder = \ss -> @@ -72,3 +76,21 @@ main = do } toggleStructsKey config + + where + parseOut :: String -> String + parseOut str = + let colors = ["#ff878f", "#e187ff", "#8f87ff", "#87fff7", "#8bff87", "#ffe987", "#ff8787"] + components = zip (cycle colors) (splitOnAll [" - ", " · ", " "] str) + in concatMap (\(color, str) -> + printf "%s " color str) components + + trunc amt str = + if length str > amt - 4 + then take (amt - 4) str ++ " ..." + else str + + splitOnAll arr str = splitOnAll' arr [str] + splitOnAll' [] str = str + splitOnAll' (a:as) str = splitOnAll' as (concatMap (splitOn a) str) + -- cgit From bc641331a060a8bd4941b1854a08a97b3700fe6c Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Tue, 2 Nov 2021 00:53:16 -0600 Subject: Changed how titles are parsed. --- src/Main.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Main.hs b/src/Main.hs index 7e1cc68..195c151 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -92,5 +92,6 @@ main = do splitOnAll arr str = splitOnAll' arr [str] splitOnAll' [] str = str - splitOnAll' (a:as) str = splitOnAll' as (concatMap (splitOn a) str) + splitOnAll' (a:as) [str] = splitOnAll' as (splitOn a str) + splitOnAll' _ lst = lst -- cgit From 791ea7971b097a8146e993ed5ba490ccf0b2c72c Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Tue, 2 Nov 2021 20:15:32 -0600 Subject: More XMobar sexiness. Revamped the install script to make it easier to handle the install process. --- src/Internal/Keys.hs | 6 +++++- src/Main.hs | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Internal/Keys.hs b/src/Internal/Keys.hs index c97736f..3dff864 100644 --- a/src/Internal/Keys.hs +++ b/src/Internal/Keys.hs @@ -85,7 +85,8 @@ newKeys markContext = , ((modm .|. mod1Mask, xK_s), (void $ spawn "sudo systemctl suspend && xsecurelock")) , ((modm .|. shiftMask, xK_c), kill) , ((modm .|. shiftMask, xK_t), withFocused $ windows . W.sink) - , ((mod4Mask, xK_Escape), (void $ spawn "xterm")) + , ((mod4Mask, xK_BackSpace), (void $ spawn "xterm")) + , ((mod3Mask, xK_BackSpace), (void $ spawn "pkill -SIGUSR1 xmobar")) , ((mod3Mask, xK_t), (void $ spawn (terminal config))) , ((modm, xK_m), (submap $ mapAlpha modm (markCurrentWindow markContext))) , ((modm, xK_w), runXPlus markContext config windowJump) @@ -122,6 +123,9 @@ newKeys markContext = , ((modm, xK_q), spawn "xmonad --recompile && xmonad --restart") , ((modm, xK_z), sendMessage ToggleZoom) + , ((modm, xK_x), spawn "bluetooth-select.sh") + , ((modm .|. shiftMask, xK_x), spawn "bluetoothctl -- disconnect") + , ((modm, xK_Tab), windows W.focusDown) , ((modm .|. shiftMask, xK_Tab), windows W.focusUp) diff --git a/src/Main.hs b/src/Main.hs index 195c151..85d18c7 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -58,7 +58,7 @@ main = do "xmobar" xmobarPP { ppCurrent = xmobarColor "#ff8888" "red" . printf "%s" - , ppVisible = xmobarColor "#8888ff" "" . printf "%s" + , ppVisible = xmobarColor "#8888ff" "" . printf "%s" , ppHidden = xmobarColor "#888888" "" . printf "%s" , ppWsSep = " " , ppTitle = -- cgit From 62bccd284a4ae1c6c6c324112df8c6c14dc26ac9 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Tue, 2 Nov 2021 21:58:50 -0600 Subject: Synchronize with the look on photon --- src/Internal/Layout.hs | 4 +++- src/Main.hs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Internal/Layout.hs b/src/Internal/Layout.hs index c54ffa7..2339cca 100644 --- a/src/Internal/Layout.hs +++ b/src/Internal/Layout.hs @@ -10,6 +10,7 @@ import Data.List import XMonad.Layout.Spiral import XMonad.Layout.ThreeColumns import XMonad.Layout.Grid +import XMonad.Layout.Dishes import XMonad.Layout import XMonad.Layout.LayoutModifier import XMonad @@ -24,7 +25,8 @@ myLayout = Tall 1 (3/100) (1/2) ||| ThreeCol 1 (3/100) (1/2) ||| Full ||| - Grid + Grid ||| + Dishes 2 (1/6) data ResizeZoom = ShrinkZoom | ExpandZoom deriving (Typeable) diff --git a/src/Main.hs b/src/Main.hs index 85d18c7..28d50ad 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -81,7 +81,7 @@ main = do parseOut :: String -> String parseOut str = let colors = ["#ff878f", "#e187ff", "#8f87ff", "#87fff7", "#8bff87", "#ffe987", "#ff8787"] - components = zip (cycle colors) (splitOnAll [" - ", " · ", " "] str) + components = zip (cycle colors) (splitOnAll [" - ", " | ", " · ", " "] str) in concatMap (\(color, str) -> printf "%s " color str) components -- cgit From 4db7274561b8dd6444e6b93c483479423450c6e6 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Tue, 2 Nov 2021 23:20:35 -0600 Subject: Rework keys Finally removed the buggy hjkl navigation in favor of a more traditional key bindings: - h,l move between windows like Tab and S-Tab - j,k adjust the master window size Added ability to swap current window with a marked window using S-'-. --- src/Internal/Keys.hs | 44 ++++++++++++++++++++++++-------------- src/Internal/Marking.hs | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/Internal/Keys.hs b/src/Internal/Keys.hs index 3dff864..0b7b1c3 100644 --- a/src/Internal/Keys.hs +++ b/src/Internal/Keys.hs @@ -42,8 +42,7 @@ applyKeys config@(XConfig {modMask = modm}) = withNewMarkContext $ \markContext -> do ks <- newKeys markContext ms <- newMouse markContext - withWindowNavigation (xK_k, xK_h, xK_j, xK_l) $ - config { keys = ks, mouseBindings = ms } + return $ config { keys = ks, mouseBindings = ms } newMouse :: MarkContext -> IO (XConfig l -> Map (KeyMask, Button) (Window -> X ())) newMouse markContext = @@ -74,28 +73,41 @@ newKeys :: MarkContext -> IO (KeyMap l) newKeys markContext = return $ \config@(XConfig {modMask = modm}) -> Map.fromList - [ ((modm, xK_F12), (void $ spawn "spotify-control next")) - , ((modm, xK_F11), (void $ spawn "spotify-control prev")) - , ((modm, xK_semicolon), scratchpadSpawnActionTerminal "scratchpad") - , ((modm, xK_F10), (void $ spawn "spotify-control play")) - , ((modm, xK_r), runDMenu) - , ((modm, xK_c), runPassMenu) + [ ((modm, xK_F12), (void $ spawn "spotify-control next")) + , ((modm, xK_F11), (void $ spawn "spotify-control prev")) + , ((modm, xK_semicolon), scratchpadSpawnActionTerminal "scratchpad") + , ((modm, xK_F10), (void $ spawn "spotify-control play")) + , ((modm, xK_r), runDMenu) + , ((modm, xK_c), runPassMenu) + , ((modm, xK_h), windows W.focusDown) + , ((modm, xK_l), windows W.focusUp) + , ((modm .|. shiftMask, xK_h), windows W.swapUp) + , ((modm .|. shiftMask, xK_l), windows W.swapDown) + , ((modm , xK_Return), windows W.swapMaster) + , ((modm, xK_j), sendMessage Shrink) + , ((modm, xK_k), sendMessage Expand) , ((modm .|. shiftMask, xK_r), (void $ spawn "gmrun")) - , ((modm .|. mod1Mask, xK_l), (void $ spawn "xsecurelock")) - , ((modm .|. mod1Mask, xK_s), (void $ spawn "sudo systemctl suspend && xsecurelock")) + , ((modm .|. mod1Mask, xK_l), (void $ spawn "xsecurelock")) + , ((modm .|. mod1Mask, xK_s), (void $ spawn "sudo systemctl suspend && xsecurelock")) , ((modm .|. shiftMask, xK_c), kill) , ((modm .|. shiftMask, xK_t), withFocused $ windows . W.sink) - , ((mod4Mask, xK_BackSpace), (void $ spawn "xterm")) - , ((mod3Mask, xK_BackSpace), (void $ spawn "pkill -SIGUSR1 xmobar")) - , ((mod3Mask, xK_t), (void $ spawn (terminal config))) - , ((modm, xK_m), (submap $ mapAlpha modm (markCurrentWindow markContext))) - , ((modm, xK_w), runXPlus markContext config windowJump) - , ((modm, xK_apostrophe), (submap $ + , ((mod4Mask, xK_BackSpace), (void $ spawn "xterm")) + , ((modm, xK_BackSpace), (void $ spawn "pkill -SIGUSR1 xmobar")) + , ((modm, xK_t), (void $ spawn (terminal config))) + , ((modm, xK_m), (submap $ mapAlpha modm (markCurrentWindow markContext))) + , ((modm, xK_w), runXPlus markContext config windowJump) + , ((modm, xK_apostrophe), (submap $ Map.insert (modm, xK_apostrophe) (jumpToLast markContext) (mapAlpha modm (jumpToMark markContext)))) + , ((modm .|. shiftMask, xK_apostrophe), (submap $ + Map.insert + (modm .|. shiftMask, xK_apostrophe) + (swapWithLastMark markContext) + (mapAlpha (modm .|. shiftMask) (swapWithMark markContext)))) + , ((modm, xK_g), (submap $ mapNumbersAndAlpha 0 ( runXPlus markContext config . gotoWorkspace))) diff --git a/src/Internal/Marking.hs b/src/Internal/Marking.hs index e5cf696..606b55e 100644 --- a/src/Internal/Marking.hs +++ b/src/Internal/Marking.hs @@ -2,6 +2,7 @@ module Internal.Marking where import XMonad +import XMonad.StackSet hiding (focus) import Data.IORef import Data.Map (Map) @@ -77,3 +78,58 @@ jumpToMark ctx@(MarkContext ioref) mark = do focus w saveMarkState =<< liftIO (readIORef ioref) + +mapWindows :: (Ord a, Ord b) => (a -> b) -> StackSet i l a s sd -> StackSet i l b s sd +mapWindows fn (StackSet cur vis hid float) = + StackSet + (mapWindowsScreen cur) + (map mapWindowsScreen vis) + (map mapWindowsWorkspace hid) + (Map.mapKeys fn float) + where + mapWindowsScreen (Screen work a b) = Screen (mapWindowsWorkspace work) a b + mapWindowsWorkspace (Workspace t l stack) = + Workspace t l (fmap (mapStack fn) stack) + +-- | What genius decided to hide the instances for the Stack type!!??? +mapStack :: (a -> b) -> Stack a -> Stack b +mapStack fn (Stack focus up down) = Stack (fn focus) (map fn up) (map fn down) + +setFocusedWindow :: a -> StackSet i l a s sd -> StackSet i l a s sd +setFocusedWindow + window + (StackSet (Screen (Workspace t l stack) a b) vis hid float) = + let newStack = + case stack of + Nothing -> Nothing + Just (Stack _ up down) -> Just (Stack window up down) in + (StackSet (Screen (Workspace t l newStack) a b) vis hid float) + +swapWithFocused :: (Ord a) => a -> StackSet i l a s sd -> StackSet i l a s sd +swapWithFocused winToSwap stackSet = + case peek stackSet of + Nothing -> stackSet + Just focused -> do + setFocusedWindow winToSwap $ + mapWindows ( + \w -> if w == winToSwap then focused else w) stackSet + +swapWithLastMark :: MarkContext -> X () +swapWithLastMark ctx@(MarkContext ioref) = do + MarkState {markStateMap = m} <- liftIO $ readIORef ioref + m <- markLast <$> (liftIO $ readIORef ioref) + saveLastMark ctx + + case m of + Nothing -> return () + Just win -> windows $ swapWithFocused win + +swapWithMark :: MarkContext -> Mark -> X () +swapWithMark ctx@(MarkContext ioref) mark = do + MarkState {markStateMap = m} <- liftIO $ readIORef ioref + saveLastMark ctx + + case Map.lookup mark m of + Nothing -> return () + Just winToSwap -> + windows $ swapWithFocused winToSwap -- cgit From 6f76e166bb2572ade759291f308460f78e8af12f Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Tue, 2 Nov 2021 23:49:25 -0600 Subject: Add ability to flip the layout with mod-f. --- src/Internal/Keys.hs | 43 ++++++++++++++++++++++--------------------- src/Internal/Layout.hs | 43 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 58 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/Internal/Keys.hs b/src/Internal/Keys.hs index 0b7b1c3..ab6eab6 100644 --- a/src/Internal/Keys.hs +++ b/src/Internal/Keys.hs @@ -73,29 +73,30 @@ newKeys :: MarkContext -> IO (KeyMap l) newKeys markContext = return $ \config@(XConfig {modMask = modm}) -> Map.fromList - [ ((modm, xK_F12), (void $ spawn "spotify-control next")) - , ((modm, xK_F11), (void $ spawn "spotify-control prev")) - , ((modm, xK_semicolon), scratchpadSpawnActionTerminal "scratchpad") - , ((modm, xK_F10), (void $ spawn "spotify-control play")) - , ((modm, xK_r), runDMenu) - , ((modm, xK_c), runPassMenu) - , ((modm, xK_h), windows W.focusDown) - , ((modm, xK_l), windows W.focusUp) - , ((modm .|. shiftMask, xK_h), windows W.swapUp) - , ((modm .|. shiftMask, xK_l), windows W.swapDown) - , ((modm , xK_Return), windows W.swapMaster) - , ((modm, xK_j), sendMessage Shrink) - , ((modm, xK_k), sendMessage Expand) - , ((modm .|. shiftMask, xK_r), (void $ spawn "gmrun")) - , ((modm .|. mod1Mask, xK_l), (void $ spawn "xsecurelock")) - , ((modm .|. mod1Mask, xK_s), (void $ spawn "sudo systemctl suspend && xsecurelock")) - , ((modm .|. shiftMask, xK_c), kill) - , ((modm .|. shiftMask, xK_t), withFocused $ windows . W.sink) + [ ((modm, xK_F12), (void $ spawn "spotify-control next")) + , ((modm, xK_F11), (void $ spawn "spotify-control prev")) + , ((modm, xK_semicolon), scratchpadSpawnActionTerminal "scratchpad") + , ((modm, xK_F10), (void $ spawn "spotify-control play")) + , ((modm, xK_r), runDMenu) + , ((modm, xK_c), runPassMenu) + , ((modm, xK_h), windows W.focusDown) + , ((modm, xK_l), windows W.focusUp) + , ((modm .|. shiftMask, xK_h), windows W.swapUp) + , ((modm .|. shiftMask, xK_l), windows W.swapDown) + , ((modm , xK_f), sendMessage FlipLayout) + , ((modm , xK_Return), windows W.swapMaster) + , ((modm, xK_j), sendMessage Shrink) + , ((modm, xK_k), sendMessage Expand) + , ((modm .|. shiftMask, xK_r), (void $ spawn "gmrun")) + , ((modm .|. mod1Mask, xK_l), (void $ spawn "xsecurelock")) + , ((modm .|. mod1Mask, xK_s), (void $ spawn "sudo systemctl suspend && xsecurelock")) + , ((modm .|. shiftMask, xK_c), kill) + , ((modm .|. shiftMask, xK_t), withFocused $ windows . W.sink) , ((mod4Mask, xK_BackSpace), (void $ spawn "xterm")) , ((modm, xK_BackSpace), (void $ spawn "pkill -SIGUSR1 xmobar")) - , ((modm, xK_t), (void $ spawn (terminal config))) - , ((modm, xK_m), (submap $ mapAlpha modm (markCurrentWindow markContext))) - , ((modm, xK_w), runXPlus markContext config windowJump) + , ((modm, xK_t), (void $ spawn (terminal config))) + , ((modm, xK_m), (submap $ mapAlpha modm (markCurrentWindow markContext))) + , ((modm, xK_w), runXPlus markContext config windowJump) , ((modm, xK_apostrophe), (submap $ Map.insert (modm, xK_apostrophe) diff --git a/src/Internal/Layout.hs b/src/Internal/Layout.hs index 2339cca..aa3df1a 100644 --- a/src/Internal/Layout.hs +++ b/src/Internal/Layout.hs @@ -1,6 +1,7 @@ {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-} module Internal.Layout where +import Control.Arrow (second) import XMonad.Hooks.ManageDocks import XMonad.Layout.Circle import XMonad.Layout.Accordion @@ -20,26 +21,54 @@ import qualified XMonad.StackSet as W myLayout = ModifiedLayout (Zoomable False 0.05 0.05) $ - spacingRaw True (Border 5 5 5 5) True (Border 5 5 5 5) True $ avoidStruts $ - spiral (6/7) ||| - Tall 1 (3/100) (1/2) ||| - ThreeCol 1 (3/100) (1/2) ||| - Full ||| - Grid ||| - Dishes 2 (1/6) + ModifiedLayout (Flippable False) $ + spacingRaw True (Border 5 5 5 5) True (Border 5 5 5 5) True $ avoidStruts $ + spiral (6/7) ||| + Tall 1 (3/100) (1/2) ||| + ThreeCol 1 (3/100) (1/2) ||| + Full ||| + Grid ||| + Dishes 2 (1/6) data ResizeZoom = ShrinkZoom | ExpandZoom deriving (Typeable) instance Message ResizeZoom where +data Flippable a = Flippable Bool -- True if flipped + deriving (Show, Read) + +data FlipLayout = FlipLayout deriving (Typeable) + data Zoomable a = Zoomable Bool Float Float -- True if zooming in on the focused window. deriving (Show, Read) data ToggleZoom = ToggleZoom deriving (Typeable) +instance Message FlipLayout where + instance Message ToggleZoom where +instance (Eq a) => LayoutModifier Flippable a where + pureModifier (Flippable flip) (Rectangle _ _ sw _) stack returned = + if flip + then (map (second doFlip) returned, Nothing) + else (returned, Nothing) + where + doFlip (Rectangle x y w h) = Rectangle (fromIntegral sw - x - fromIntegral w) y w h + + pureMess (Flippable flip) message = + case fromMessage message of + Just FlipLayout -> Just (Flippable (not flip)) + Nothing -> Nothing + + modifyDescription (Flippable flipped) underlying = + let descr = description underlying in + if flipped + then descr ++ " Flipped" + else descr + + instance (Eq a) => LayoutModifier Zoomable a where redoLayout (Zoomable doit ws hs) (Rectangle x y w h) stack returned = if doit -- cgit From 8f6e5103dc8dc3068637b696762e96c2729e939e Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Wed, 3 Nov 2021 01:13:07 -0600 Subject: Added MosaicAlt Layout. Changed weather icon to use moon icon for 'clear' --- src/Internal/Keys.hs | 4 ++++ src/Internal/Layout.hs | 50 +++++++++++++++++++++++++++++++++++++--------- src/Internal/LayoutDraw.hs | 3 ++- 3 files changed, 47 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/Internal/Keys.hs b/src/Internal/Keys.hs index ab6eab6..cf7846d 100644 --- a/src/Internal/Keys.hs +++ b/src/Internal/Keys.hs @@ -1,6 +1,7 @@ {-# LANGUAGE RankNTypes #-} module Internal.Keys where +import XMonad.Layout.MosaicAlt import Graphics.X11.ExtraTypes.XorgDefault import System.Process import XMonad.Util.Ungrab @@ -84,6 +85,7 @@ newKeys markContext = , ((modm .|. shiftMask, xK_h), windows W.swapUp) , ((modm .|. shiftMask, xK_l), windows W.swapDown) , ((modm , xK_f), sendMessage FlipLayout) + , ((modm .|. shiftMask, xK_f), sendMessage HFlipLayout) , ((modm , xK_Return), windows W.swapMaster) , ((modm, xK_j), sendMessage Shrink) , ((modm, xK_k), sendMessage Expand) @@ -92,6 +94,8 @@ newKeys markContext = , ((modm .|. mod1Mask, xK_s), (void $ spawn "sudo systemctl suspend && xsecurelock")) , ((modm .|. shiftMask, xK_c), kill) , ((modm .|. shiftMask, xK_t), withFocused $ windows . W.sink) + , ((modm, xK_comma), withFocused $ sendMessage . shrinkWindowAlt) + , ((modm, xK_period), withFocused $ sendMessage . expandWindowAlt) , ((mod4Mask, xK_BackSpace), (void $ spawn "xterm")) , ((modm, xK_BackSpace), (void $ spawn "pkill -SIGUSR1 xmobar")) , ((modm, xK_t), (void $ spawn (terminal config))) diff --git a/src/Internal/Layout.hs b/src/Internal/Layout.hs index aa3df1a..853a885 100644 --- a/src/Internal/Layout.hs +++ b/src/Internal/Layout.hs @@ -12,23 +12,27 @@ import XMonad.Layout.Spiral import XMonad.Layout.ThreeColumns import XMonad.Layout.Grid import XMonad.Layout.Dishes +import XMonad.Layout.MosaicAlt import XMonad.Layout import XMonad.Layout.LayoutModifier import XMonad import XMonad.Core +import qualified Data.Map as M import qualified XMonad.StackSet as W myLayout = ModifiedLayout (Zoomable False 0.05 0.05) $ ModifiedLayout (Flippable False) $ - spacingRaw True (Border 5 5 5 5) True (Border 5 5 5 5) True $ avoidStruts $ - spiral (6/7) ||| - Tall 1 (3/100) (1/2) ||| - ThreeCol 1 (3/100) (1/2) ||| - Full ||| - Grid ||| - Dishes 2 (1/6) + ModifiedLayout (HFlippable False) $ + spacingRaw True (Border 5 5 5 5) True (Border 5 5 5 5) True $ avoidStruts $ + spiral (6/7) ||| + Tall 1 (3/100) (1/2) ||| + ThreeCol 1 (3/100) (1/2) ||| + Full ||| + Grid ||| + Dishes 2 (1/6) ||| + (MosaicAlt M.empty :: MosaicAlt Window) data ResizeZoom = ShrinkZoom | ExpandZoom deriving (Typeable) @@ -37,8 +41,13 @@ instance Message ResizeZoom where data Flippable a = Flippable Bool -- True if flipped deriving (Show, Read) +data HFlippable a = HFlippable Bool -- True if flipped + deriving (Show, Read) + data FlipLayout = FlipLayout deriving (Typeable) +data HFlipLayout = HFlipLayout deriving (Typeable) + data Zoomable a = Zoomable Bool Float Float -- True if zooming in on the focused window. deriving (Show, Read) @@ -47,15 +56,18 @@ data ToggleZoom = ToggleZoom instance Message FlipLayout where +instance Message HFlipLayout where + instance Message ToggleZoom where instance (Eq a) => LayoutModifier Flippable a where - pureModifier (Flippable flip) (Rectangle _ _ sw _) stack returned = + pureModifier (Flippable flip) (Rectangle sx _ sw _) stack returned = if flip then (map (second doFlip) returned, Nothing) else (returned, Nothing) where - doFlip (Rectangle x y w h) = Rectangle (fromIntegral sw - x - fromIntegral w) y w h + doFlip (Rectangle x y w h) = + Rectangle ((sx + fromIntegral sw) - x - fromIntegral w + sx) y w h pureMess (Flippable flip) message = case fromMessage message of @@ -67,6 +79,26 @@ instance (Eq a) => LayoutModifier Flippable a where if flipped then descr ++ " Flipped" else descr + +instance (Eq a) => LayoutModifier HFlippable a where + pureModifier (HFlippable flip) (Rectangle _ sy _ sh) stack returned = + if flip + then (map (second doFlip) returned, Nothing) + else (returned, Nothing) + where + doFlip (Rectangle x y w h) = + Rectangle x ((sy + fromIntegral sh) - y - fromIntegral h + sy) w h + + pureMess (HFlippable flip) message = + case fromMessage message of + Just HFlipLayout -> Just (HFlippable (not flip)) + Nothing -> Nothing + + modifyDescription (HFlippable flipped) underlying = + let descr = description underlying in + if flipped + then descr ++ " HFlipped" + else descr instance (Eq a) => LayoutModifier Zoomable a where diff --git a/src/Internal/LayoutDraw.hs b/src/Internal/LayoutDraw.hs index 4bb069a..7c69a08 100644 --- a/src/Internal/LayoutDraw.hs +++ b/src/Internal/LayoutDraw.hs @@ -10,6 +10,7 @@ import Control.Monad import Graphics.Rendering.Cairo import Graphics.Rendering.Cairo.Internal (Render(runRender)) import Graphics.Rendering.Cairo.Types (Cairo(Cairo)) +import Control.Concurrent (threadDelay) import System.FilePath import XMonad @@ -85,7 +86,7 @@ drawPng l = do surfaceWriteToPNG surface filepathPng - (!_) <- readProcessWithExitCode + out <- readProcessWithExitCode "/usr/bin/convert" [filepathPng, filepathXpm] "" -- cgit From e4d9cc1c22ba36516d24902c7f0de52b1009570b Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Wed, 3 Nov 2021 13:17:54 -0600 Subject: Finally, after much wailing and gnashing of teeth, fixed the Xmobar layout icon issue! --- src/Internal/LayoutDraw.hs | 106 +++++++++++++++++++++++---------------------- src/Main.hs | 59 ++++++++++++++----------- 2 files changed, 88 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/Internal/LayoutDraw.hs b/src/Internal/LayoutDraw.hs index 7c69a08..dedac0f 100644 --- a/src/Internal/LayoutDraw.hs +++ b/src/Internal/LayoutDraw.hs @@ -2,6 +2,8 @@ ScopedTypeVariables, BangPatterns #-} module Internal.LayoutDraw where +import System.IO + import System.Process import Text.Printf import Control.Arrow @@ -21,17 +23,17 @@ import System.Directory import Internal.Layout import Internal.Hash -showLayout :: X (Maybe String) +showLayout :: X (Bool, String, Maybe String) showLayout = do winset <- gets windowset let layout = S.layout . S.workspace . S.current $ winset - xpm <- drawPng layout - return $ Just $ printf "" xpm + (cached, xpm) <- drawPng layout + return $ (cached, description layout, Just $ printf "" xpm) iconSize :: (Num a) => (a, a) iconSize = (64, 32) -drawPng :: (LayoutClass layout Window) => layout Window -> X String +drawPng :: (LayoutClass layout Window) => layout Window -> X (Bool, String) drawPng l = do dir <- getXMonadDir let sixWindows = [1..(4 :: Window)] @@ -45,54 +47,54 @@ drawPng l = do let descr = description l let pngCacheDir = dir "icons" "cache" - liftIO $ createDirectoryIfMissing True pngCacheDir - let testf = dir "text.txt" - let filepathPng = pngCacheDir (quickHash descr ++ ".png") - let filepathXpm = pngCacheDir (quickHash descr ++ ".xpm") - - let colors = [ - -- (1.0, 1.0, 1.0), - -- (0.9, 0.9, 1.0), - -- (0.8, 0.8, 1.0), - -- (0.7, 0.7, 1.0), - (0.8, 0.6, 0.6), - (0.8, 0.5, 0.5), - (0.8, 0.4, 0.4), - (0.8, 0.3, 0.3), - (0.8, 0.2, 0.2), - (0.8, 0.1, 0.1), - (0.8, 0.0, 0.0) - ] - - exists <- liftIO $ doesFileExist filepathXpm - when (not exists) $ - liftIO $ do - withImageSurface FormatARGB32 64 32 $ \surface -> do - renderWith surface $ do - setLineCap LineCapButt - setLineJoin LineJoinMiter - - forM_ (reverse $ zip (map (second extraPad) rects) colors) $ - \((wind, Rectangle x y w h), (r, g, b)) -> do - setSourceRGBA r g b 1 - - rectangle - (fromIntegral $ floor (fromIntegral x / 30.0)) - (fromIntegral $ floor (fromIntegral y / 30.0)) - (fromIntegral $ floor (fromIntegral w / 30.0)) - (fromIntegral $ floor (fromIntegral h / 30.0)) - - fill - - surfaceWriteToPNG surface filepathPng - - out <- readProcessWithExitCode - "/usr/bin/convert" - [filepathPng, filepathXpm] - "" - return () - - return filepathXpm + liftIO $ do + createDirectoryIfMissing True pngCacheDir + let testf = dir "text.txt" + let filepathPng = pngCacheDir (quickHash descr ++ ".png") + let filepathXpm = pngCacheDir (quickHash descr ++ ".xpm") + + let colors = [ + -- (1.0, 1.0, 1.0), + -- (0.9, 0.9, 1.0), + -- (0.8, 0.8, 1.0), + -- (0.7, 0.7, 1.0), + (0.8, 0.6, 0.6), + (0.8, 0.5, 0.5), + (0.8, 0.4, 0.4), + (0.8, 0.3, 0.3), + (0.8, 0.2, 0.2), + (0.8, 0.1, 0.1), + (0.8, 0.0, 0.0) + ] + + exists <- doesFileExist filepathXpm + when (not exists) $ do + withImageSurface FormatARGB32 64 32 $ \surface -> do + renderWith surface $ do + setLineCap LineCapButt + setLineJoin LineJoinMiter + + forM_ (reverse $ zip (map (second extraPad) rects) colors) $ + \((wind, Rectangle x y w h), (r, g, b)) -> do + setSourceRGBA r g b 1 + + rectangle + (fromIntegral $ floor (fromIntegral x / 30.0)) + (fromIntegral $ floor (fromIntegral y / 30.0)) + (fromIntegral $ floor (fromIntegral w / 30.0)) + (fromIntegral $ floor (fromIntegral h / 30.0)) + + fill + + surfaceWriteToPNG surface filepathPng + + _ <- handle (\(e :: SomeException) -> return ()) $ void $ readProcessWithExitCode + "/usr/bin/convert" + [filepathPng, filepathXpm] + "" + return () + + return (exists, filepathXpm) where extraPad (Rectangle x y w h) = Rectangle (x + 100) (y + 100) (w - 100) (h - 100) diff --git a/src/Main.hs b/src/Main.hs index 28d50ad..47a00e2 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -1,5 +1,7 @@ import XMonad +import Control.Exception import XMonad.Hooks.DynamicLog +import Control.Concurrent import XMonad.Layout.Spacing import XMonad.Actions.WindowNavigation import XMonad.Util.CustomKeys @@ -12,10 +14,15 @@ import XMonad.Layout.IndependentScreens import Text.Printf import Data.List.Split import XMonad.Hooks.EwmhDesktops +import XMonad.Hooks.ManageDocks +import XMonad.Util.Run (spawnPipe) +import Control.Monad (when) +import System.IO import Internal.Keys import Internal.LayoutDraw import Data.List (partition, isPrefixOf) +import Data.Maybe main = do @@ -23,8 +30,10 @@ main = do homeDir <- getHomeDirectory let fp = homeDir ".xmonad" "startup" + xmproc <- spawnPipe "xmobar" + config <- - applyKeys $ def + applyKeys $ docks $ def { terminal = "alacritty" , modMask = mod3Mask , borderWidth = 2 @@ -49,33 +58,33 @@ main = do , handleEventHook = fullscreenEventHook , focusFollowsMouse = False , clickJustFocuses = False - } + , logHook = do + (_, _, layout) <- showLayout - let toggleStructsKey XConfig {XMonad.modMask = modMask} = (modMask, xK_b) + dynamicLogWithPP $ xmobarPP { + ppCurrent = xmobarColor "#ff8888" "red" . printf "%s" + , ppVisible = xmobarColor "#8888ff" "" . printf "%s" + , ppHidden = xmobarColor "#888888" "" . printf "%s" + , ppWsSep = " " + , ppTitle = + xmobarColor "#808080" "" . + printf "%s" . + parseOut . + trunc 50 + + , ppSep = xmobarColor "#404040" "" " │ " + , ppLayout = const (fromMaybe "" layout) + , ppExtras = [] + , ppOutput = hPutStrLn xmproc + , ppOrder = \ss -> + let (icons, etc) = partition ("%s" - , ppVisible = xmobarColor "#8888ff" "" . printf "%s" - , ppHidden = xmobarColor "#888888" "" . printf "%s" - , ppWsSep = " " - , ppTitle = - xmobarColor "#808080" "" . - printf "%s" . - parseOut . - trunc 50 + -- let toggleStructsKey XConfig {XMonad.modMask = modMask} = (modMask, xK_b) - , ppSep = xmobarColor "#404040" "" " │ " - , ppLayout = const "" - , ppExtras = [showLayout] - , ppOrder = \ss -> - let (icons, etc) = partition (" String -- cgit From f890f6d10158af006dda0be806813d4779cd1e89 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Wed, 3 Nov 2021 16:46:42 -0600 Subject: Killed Dependency on Cairo. Vastly improved layout experience. --- src/Internal/Layout.hs | 51 +++++++++++- src/Internal/LayoutDraw.hs | 193 ++++++++++++++++++++++++--------------------- 2 files changed, 150 insertions(+), 94 deletions(-) (limited to 'src') diff --git a/src/Internal/Layout.hs b/src/Internal/Layout.hs index 853a885..eb33a5e 100644 --- a/src/Internal/Layout.hs +++ b/src/Internal/Layout.hs @@ -13,6 +13,7 @@ import XMonad.Layout.ThreeColumns import XMonad.Layout.Grid import XMonad.Layout.Dishes import XMonad.Layout.MosaicAlt +import qualified XMonad.Layout.Dwindle as D import XMonad.Layout import XMonad.Layout.LayoutModifier import XMonad @@ -27,12 +28,56 @@ myLayout = ModifiedLayout (HFlippable False) $ spacingRaw True (Border 5 5 5 5) True (Border 5 5 5 5) True $ avoidStruts $ spiral (6/7) ||| - Tall 1 (3/100) (1/2) ||| - ThreeCol 1 (3/100) (1/2) ||| + ModifyDescription TallDescriptionModifier (Tall 1 (3/100) (1/2)) ||| + ModifyDescription ThreeColDescMod (ThreeCol 1 (3/100) (1/2)) ||| Full ||| Grid ||| Dishes 2 (1/6) ||| - (MosaicAlt M.empty :: MosaicAlt Window) + (MosaicAlt M.empty :: MosaicAlt Window) ||| + (D.Dwindle D.R D.CW 1.5 1.1) + +data ModifyDescription m l a = ModifyDescription m (l a) + deriving (Show, Read) + +data TallDescriptionModifier = TallDescriptionModifier + deriving (Show, Read) + +data ThreeColDescMod = ThreeColDescMod + deriving (Show, Read) + +class DescriptionModifier m l where + newDescription :: m -> l a -> String -> String + +instance (Show m, DescriptionModifier m l, LayoutClass l a) => LayoutClass (ModifyDescription m l) a where + runLayout (W.Workspace t (ModifyDescription m l) a) rect = do + (rects, maybeNewLayout) <- runLayout (W.Workspace t l a) rect + return (rects, fmap (ModifyDescription m) maybeNewLayout) + + doLayout (ModifyDescription m l) a s = do + (rects, maybeNewLayout) <- doLayout l a s + return (rects, fmap (ModifyDescription m) maybeNewLayout) + + pureLayout (ModifyDescription m l) a s = pureLayout l a s + + emptyLayout (ModifyDescription m l) a = do + (rects, maybeNewLayout) <- emptyLayout l a + return (rects, fmap (ModifyDescription m) maybeNewLayout) + + handleMessage (ModifyDescription m l) a = do + maybeNewLayout <- handleMessage l a + return (ModifyDescription m <$> maybeNewLayout) + + pureMessage (ModifyDescription m l) a = + let maybeNewLayout = pureMessage l a in + ModifyDescription m <$> maybeNewLayout + + description (ModifyDescription m l) = newDescription m l (description l) + +instance DescriptionModifier TallDescriptionModifier Tall where + newDescription _ (Tall mast _ _) _ = "Tall(" ++ show mast ++ ")" + +instance DescriptionModifier ThreeColDescMod ThreeCol where + newDescription _ (ThreeCol mast _ _) _ = "ThreeCol(" ++ show mast ++ ")" data ResizeZoom = ShrinkZoom | ExpandZoom deriving (Typeable) diff --git a/src/Internal/LayoutDraw.hs b/src/Internal/LayoutDraw.hs index dedac0f..7f960f2 100644 --- a/src/Internal/LayoutDraw.hs +++ b/src/Internal/LayoutDraw.hs @@ -4,20 +4,20 @@ module Internal.LayoutDraw where import System.IO +import Control.Monad.Writer +import XMonad.Layout.Spacing import System.Process import Text.Printf import Control.Arrow import Control.Exception import Control.Monad -import Graphics.Rendering.Cairo -import Graphics.Rendering.Cairo.Internal (Render(runRender)) -import Graphics.Rendering.Cairo.Types (Cairo(Cairo)) import Control.Concurrent (threadDelay) import System.FilePath import XMonad import XMonad.StackSet as S import Data.Maybe +import Data.Foldable import System.Directory import Internal.Layout @@ -27,93 +27,104 @@ showLayout :: X (Bool, String, Maybe String) showLayout = do winset <- gets windowset let layout = S.layout . S.workspace . S.current $ winset - (cached, xpm) <- drawPng layout + + layout' <- handleMessage layout ( + SomeMessage $ ModifyWindowBorder ( + const (Border 0 0 0 0))) + + let layout'' = layout' + + (cached, xpm) <- + case layout'' of + Just l -> drawXpmIO l + Nothing -> drawXpmIO layout return $ (cached, description layout, Just $ printf "" xpm) -iconSize :: (Num a) => (a, a) -iconSize = (64, 32) - -drawPng :: (LayoutClass layout Window) => layout Window -> X (Bool, String) -drawPng l = do - dir <- getXMonadDir - let sixWindows = [1..(4 :: Window)] - let stack = differentiate sixWindows - (rects, _) <- - runLayout - (Workspace "0" l stack) - (Rectangle 0 0 (fst iconSize * 30) (snd iconSize * 30)) - return () - - let descr = description l - let pngCacheDir = dir "icons" "cache" - - liftIO $ do - createDirectoryIfMissing True pngCacheDir - let testf = dir "text.txt" - let filepathPng = pngCacheDir (quickHash descr ++ ".png") - let filepathXpm = pngCacheDir (quickHash descr ++ ".xpm") - - let colors = [ - -- (1.0, 1.0, 1.0), - -- (0.9, 0.9, 1.0), - -- (0.8, 0.8, 1.0), - -- (0.7, 0.7, 1.0), - (0.8, 0.6, 0.6), - (0.8, 0.5, 0.5), - (0.8, 0.4, 0.4), - (0.8, 0.3, 0.3), - (0.8, 0.2, 0.2), - (0.8, 0.1, 0.1), - (0.8, 0.0, 0.0) - ] - - exists <- doesFileExist filepathXpm - when (not exists) $ do - withImageSurface FormatARGB32 64 32 $ \surface -> do - renderWith surface $ do - setLineCap LineCapButt - setLineJoin LineJoinMiter - - forM_ (reverse $ zip (map (second extraPad) rects) colors) $ - \((wind, Rectangle x y w h), (r, g, b)) -> do - setSourceRGBA r g b 1 - - rectangle - (fromIntegral $ floor (fromIntegral x / 30.0)) - (fromIntegral $ floor (fromIntegral y / 30.0)) - (fromIntegral $ floor (fromIntegral w / 30.0)) - (fromIntegral $ floor (fromIntegral h / 30.0)) - - fill - - surfaceWriteToPNG surface filepathPng - - _ <- handle (\(e :: SomeException) -> return ()) $ void $ readProcessWithExitCode - "/usr/bin/convert" - [filepathPng, filepathXpm] - "" - return () - - return (exists, filepathXpm) - where - extraPad (Rectangle x y w h) = - Rectangle (x + 100) (y + 100) (w - 100) (h - 100) - -- padR (Rectangle x y w h) = - -- Rectangle x y (max 1 $ w - 120) (max 1 $ h - 120) - -newtype InterceptLayout l a = - InterceptLayout { - unIntercept :: (l a) - } deriving (Show, Read) - -instance (LayoutClass l Window) => LayoutClass (InterceptLayout l) Window where - runLayout (Workspace t l s) rect = do - (rects, mr) <- runLayout (Workspace t (unIntercept l) s) rect - return (rects, fmap InterceptLayout mr) - - handleMessage this mesg = do - ret <- handleMessage (unIntercept this) mesg - -- mapM_ drawThing ret - return (InterceptLayout <$> ret) - - description = ("Intercepted "++) . description . unIntercept +pointInRect :: (Dimension, Dimension) -> Rectangle -> Bool +pointInRect (x, y) (Rectangle x' y' w h) = + x <= (fi x' + fi w) && x >= fi x' && y <= (fi y' + fi h) && y >= fi y' + where + fi :: (Integral a, Num b) => a -> b + fi = fromIntegral + +sf :: (Integral a) => a +sf = 1024 + +drawXpmIO :: (LayoutClass layout Window) => layout Window -> X (Bool, String) +drawXpmIO l = do + dir <- getXMonadDir + + let shrinkAmt = 4 + + let (w, h) = (56 + shrinkAmt, 28 + shrinkAmt) + let descr = description l + let iconCacheDir = dir "icons" "cache" + let iconPath = iconCacheDir (quickHash descr ++ ".xpm") + + let colors = [ + "#cc9a9a", + "#cc9999", + "#cc8080", + "#cc6666", + "#cc4c4c", + "#cc3232", + "#cc1818" + ] + + (rects', _) <- + runLayout + (Workspace "0" l (differentiate [1 .. 6])) + (Rectangle 0 0 (w * sf) (h * sf)) + + let rects = flip map rects' $ \(_, (Rectangle x y w h)) -> + Rectangle (x `div` sf) (y `div` sf) (w `div` sf) (h `div` sf) + + liftIO $ do + exists <- doesFileExist iconPath + createDirectoryIfMissing True iconCacheDir + + when (not exists) $ do + let xpmText = drawXpm (w, h) (zip (cycle colors) rects) 4 + writeFile iconPath xpmText + + return (exists, iconPath) + +drawXpm :: (Dimension, Dimension) -> [(String, Rectangle)] -> Dimension -> String +drawXpm (w, h) rects' shrinkAmt = execWriter $ do + tell "/* XPM */\n" + tell "static char *out[] = {\n" + forM_ rects' $ \(_, rect) -> do + tell $ "/* " ++ show rect ++ " */\n" + tell $ "/* --------------------------- */\n" + forM_ rects $ \(_, rect) -> do + tell $ "/* " ++ show rect ++ " */\n" + + tell $ printf "\"%d %d %d 1 \",\n" (w - shrinkAmt) (h - shrinkAmt) (length rects + 1) + + let zipRects = (zip ['A' .. 'Z'] rects) + + forM_ zipRects $ \(char, (color, _)) -> do + tell $ printf "\"%c c %s\",\n" char color + tell "\"% c None\"a,\n" + + forM_ [0 .. h - 1 - shrinkAmt] $ \y -> do + tell "\"" + forM_ [0 .. w - 1 - shrinkAmt] $ \x -> + (case find (matches x y) zipRects of + Nothing -> tell "%" + Just (chr, _) -> tell [chr]) + tell "\"" + when (y /= h - 1 - shrinkAmt) (tell ",") + tell "\n" + tell "};" + + where + matches x y (_, (_, r)) = pointInRect (x, y) r + rects = map (second (shrink shrinkAmt)) rects' + guard a b = if a <= shrinkAmt then 1 else b + shrink amt (Rectangle x y w h) = + Rectangle + x + y + (guard w $ w - fromIntegral amt) + (guard h $ h - fromIntegral amt) -- cgit From 59f501a195ab437954c748b2feaedbe60b3d4cd5 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Wed, 3 Nov 2021 17:18:57 -0600 Subject: Add ability to truncate xmobar output. This is done by removing all visible characters after a certain point. Right now that's set to 70, which was found just via trial-and-error. This will break if something has '>' or '<' and this will not be able to handle xmobar's 'raw' tag, but it's good enough. --- src/Internal/Keys.hs | 2 ++ src/Main.hs | 33 +++++++++++++++++---------------- 2 files changed, 19 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/Internal/Keys.hs b/src/Internal/Keys.hs index cf7846d..75c70a3 100644 --- a/src/Internal/Keys.hs +++ b/src/Internal/Keys.hs @@ -101,6 +101,8 @@ newKeys markContext = , ((modm, xK_t), (void $ spawn (terminal config))) , ((modm, xK_m), (submap $ mapAlpha modm (markCurrentWindow markContext))) , ((modm, xK_w), runXPlus markContext config windowJump) + , ((modm, xK_space), sendMessage NextLayout) + , ((modm .|. shiftMask, xK_space), sendMessage FirstLayout) , ((modm, xK_apostrophe), (submap $ Map.insert (modm, xK_apostrophe) diff --git a/src/Main.hs b/src/Main.hs index 47a00e2..689411c 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -67,15 +67,13 @@ main = do , ppHidden = xmobarColor "#888888" "" . printf "%s" , ppWsSep = " " , ppTitle = - xmobarColor "#808080" "" . - printf "%s" . - parseOut . - trunc 50 + xmobarColor "#a0a0a0" "" . + printf "%s" , ppSep = xmobarColor "#404040" "" " │ " , ppLayout = const (fromMaybe "" layout) , ppExtras = [] - , ppOutput = hPutStrLn xmproc + , ppOutput = hPutStrLn xmproc . reverse . trunc 80 , ppOrder = \ss -> let (icons, etc) = partition (" String - parseOut str = - let colors = ["#ff878f", "#e187ff", "#8f87ff", "#87fff7", "#8bff87", "#ffe987", "#ff8787"] - components = zip (cycle colors) (splitOnAll [" - ", " | ", " · ", " "] str) - in concatMap (\(color, str) -> - printf "%s " color str) components - - trunc amt str = - if length str > amt - 4 - then take (amt - 4) str ++ " ..." - else str + trunc amt str = trunc' False amt str [] + trunc' _ _ [] acc = acc + trunc' ignore amt (a:as) acc = + case a of + '<' -> trunc' True amt as (a : acc) + '>' -> trunc' False amt as (a : acc) + _ -> + if ignore + then trunc' True amt as (a : acc) + else + case amt of + 0 -> trunc' False 0 as acc + 4 -> trunc' False 0 as ("... " ++ acc) + _ -> trunc' False (amt - 1) as (a : acc) splitOnAll arr str = splitOnAll' arr [str] splitOnAll' [] str = str -- cgit From 63b6a57db25652853b574239dc1b8f1f5f614a9e Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Wed, 3 Nov 2021 17:23:42 -0600 Subject: Display stdin ellipsis only if it makes the string shorter. i.e. would rather show 'My Title' rather than 'My Titl ...' --- src/Main.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Main.hs b/src/Main.hs index 689411c..020c0f8 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -97,7 +97,7 @@ main = do else case amt of 0 -> trunc' False 0 as acc - 4 -> trunc' False 0 as ("... " ++ acc) + 4 | length as > 3 -> trunc' False 0 as ("... " ++ acc) _ -> trunc' False (amt - 1) as (a : acc) splitOnAll arr str = splitOnAll' arr [str] -- cgit From 3464c1dbb093b8a5729c40cc51f4448fd3e43337 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Wed, 3 Nov 2021 17:34:26 -0600 Subject: Change the strut behavior. It wasn't working as expected for flips. This is because the avoidStructs layout modifier was too low in the layout stack. --- src/Internal/Keys.hs | 2 ++ src/Internal/Layout.hs | 2 +- src/Main.hs | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Internal/Keys.hs b/src/Internal/Keys.hs index 75c70a3..09d0cc8 100644 --- a/src/Internal/Keys.hs +++ b/src/Internal/Keys.hs @@ -1,6 +1,7 @@ {-# LANGUAGE RankNTypes #-} module Internal.Keys where +import XMonad.Hooks.ManageDocks import XMonad.Layout.MosaicAlt import Graphics.X11.ExtraTypes.XorgDefault import System.Process @@ -159,6 +160,7 @@ newKeys markContext = , ((modm .|. mod1Mask, xK_a), runXPlus markContext config (withScreen W.greedyView 0)) , ((modm .|. mod1Mask, xK_o), runXPlus markContext config (withScreen W.greedyView 1)) , ((modm .|. mod1Mask, xK_e), runXPlus markContext config (withScreen W.greedyView 2)) + , ((modm, xK_b), sendMessage ToggleStruts) -- Buttons programmed on my mouse. , ((shiftMask, xK_F1), click >> (withFocused $ windows . W.sink)) diff --git a/src/Internal/Layout.hs b/src/Internal/Layout.hs index eb33a5e..2b66f06 100644 --- a/src/Internal/Layout.hs +++ b/src/Internal/Layout.hs @@ -26,7 +26,7 @@ myLayout = ModifiedLayout (Zoomable False 0.05 0.05) $ ModifiedLayout (Flippable False) $ ModifiedLayout (HFlippable False) $ - spacingRaw True (Border 5 5 5 5) True (Border 5 5 5 5) True $ avoidStruts $ + spacingRaw True (Border 5 5 5 5) True (Border 5 5 5 5) True $ spiral (6/7) ||| ModifyDescription TallDescriptionModifier (Tall 1 (3/100) (1/2)) ||| ModifyDescription ThreeColDescMod (ThreeCol 1 (3/100) (1/2)) ||| diff --git a/src/Main.hs b/src/Main.hs index 020c0f8..6129839 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -41,7 +41,7 @@ main = do , focusedBorderColor = "#ff6c00" -- , normalBorderColor = "#ffd9bf" , normalBorderColor = "#000000" - , layoutHook = myLayout + , layoutHook = avoidStruts myLayout , startupHook = do ewmhDesktopsStartup spawn fp -- cgit From 1705eeae8e3c14aa188dcd073e8875aab40e888c Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Thu, 4 Nov 2021 02:17:24 -0600 Subject: Fixed huuuuge bug related to dynamicLogWithPP. dynamicLogWithPP does not support Unicode properly!! It was encoding each "Char" (32 bits in Haskell, mind you!) to a utf-8 byte instead of a codepoint. The result was a butchared faux-utf8 encoded string. This was causing xmobar to crash with unicode + my truncating code. I have now moved away from dynamicLogWithPP and am writing my own log string manually. It's better this way anyway; less hacky; more fine-grained control. --- src/Internal/Layout.hs | 25 ++++++----- src/Main.hs | 118 ++++++++++++++++++++++++++++++------------------- 2 files changed, 86 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/Internal/Layout.hs b/src/Internal/Layout.hs index 2b66f06..06ac7d6 100644 --- a/src/Internal/Layout.hs +++ b/src/Internal/Layout.hs @@ -23,18 +23,19 @@ import qualified Data.Map as M import qualified XMonad.StackSet as W myLayout = - ModifiedLayout (Zoomable False 0.05 0.05) $ - ModifiedLayout (Flippable False) $ - ModifiedLayout (HFlippable False) $ - spacingRaw True (Border 5 5 5 5) True (Border 5 5 5 5) True $ - spiral (6/7) ||| - ModifyDescription TallDescriptionModifier (Tall 1 (3/100) (1/2)) ||| - ModifyDescription ThreeColDescMod (ThreeCol 1 (3/100) (1/2)) ||| - Full ||| - Grid ||| - Dishes 2 (1/6) ||| - (MosaicAlt M.empty :: MosaicAlt Window) ||| - (D.Dwindle D.R D.CW 1.5 1.1) + avoidStruts $ + ModifiedLayout (Zoomable False 0.05 0.05) $ + ModifiedLayout (Flippable False) $ + ModifiedLayout (HFlippable False) $ + spacingRaw True (Border 5 5 5 5) True (Border 5 5 5 5) True $ + spiral (6/7) ||| + ModifyDescription TallDescriptionModifier (Tall 1 (3/100) (1/2)) ||| + ModifyDescription ThreeColDescMod (ThreeCol 1 (3/100) (1/2)) ||| + Full ||| + Grid ||| + Dishes 2 (1/6) ||| + (MosaicAlt M.empty :: MosaicAlt Window) ||| + (D.Dwindle D.R D.CW 1.5 1.1) data ModifyDescription m l a = ModifyDescription m (l a) deriving (Show, Read) diff --git a/src/Main.hs b/src/Main.hs index 6129839..9785b52 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -1,28 +1,44 @@ import XMonad -import Control.Exception -import XMonad.Hooks.DynamicLog + import Control.Concurrent -import XMonad.Layout.Spacing -import XMonad.Actions.WindowNavigation -import XMonad.Util.CustomKeys +import Control.Exception +import Control.Monad +import Control.Monad (when) +import Control.Monad.Writer +import Data.Ord +import Data.List (partition, isPrefixOf, sortBy) +import Data.List.Split +import Data.Maybe +import Internal.Keys +import Internal.Layout +import Internal.LayoutDraw import System.Directory import System.FilePath +import System.IO import System.Process -import Internal.Layout -import XMonad.Hooks.ManageHelpers -import XMonad.Layout.IndependentScreens import Text.Printf -import Data.List.Split +import XMonad.Actions.WindowNavigation +import XMonad.Hooks.DynamicLog import XMonad.Hooks.EwmhDesktops import XMonad.Hooks.ManageDocks +import XMonad.Hooks.ManageHelpers +import XMonad.Layout.IndependentScreens +import XMonad.Layout.Spacing +import XMonad.Util.CustomKeys +import XMonad.Util.NamedWindows import XMonad.Util.Run (spawnPipe) -import Control.Monad (when) -import System.IO -import Internal.Keys -import Internal.LayoutDraw -import Data.List (partition, isPrefixOf) -import Data.Maybe +import qualified XMonad.StackSet as S + +data WorkspaceState = Current | Hidden | Visible + +getWorkspaces :: (Ord i) => S.StackSet i l a sid sd -> [(WorkspaceState, i)] +getWorkspaces (S.StackSet (S.Screen cur _ _) vis hi _) = + sortBy (comparing snd) $ + mapMaybe (\(a, S.Workspace t _ s) -> fmap (const (a, t)) s) $ + map (\w -> (Hidden, w)) hi ++ + map (\(S.Screen w _ _) -> (Visible, w)) vis ++ + [(Current, cur)] main = do @@ -31,9 +47,15 @@ main = do let fp = homeDir ".xmonad" "startup" xmproc <- spawnPipe "xmobar" + hSetEncoding xmproc utf8 + + logFile <- openFile "/tmp/xmonad.log" WriteMode + + hPutStrLn logFile "·······························" + hFlush logFile config <- - applyKeys $ docks $ def + applyKeys $ def { terminal = "alacritty" , modMask = mod3Mask , borderWidth = 2 @@ -41,10 +63,10 @@ main = do , focusedBorderColor = "#ff6c00" -- , normalBorderColor = "#ffd9bf" , normalBorderColor = "#000000" - , layoutHook = avoidStruts myLayout + , layoutHook = myLayout , startupHook = do ewmhDesktopsStartup - spawn fp + spawn fp , manageHook = composeAll [ isFullscreen --> doFullFloat , className =? "Tilda" --> doFloat @@ -61,44 +83,50 @@ main = do , logHook = do (_, _, layout) <- showLayout - dynamicLogWithPP $ xmobarPP { - ppCurrent = xmobarColor "#ff8888" "red" . printf "%s" - , ppVisible = xmobarColor "#8888ff" "" . printf "%s" - , ppHidden = xmobarColor "#888888" "" . printf "%s" - , ppWsSep = " " - , ppTitle = - xmobarColor "#a0a0a0" "" .