diff --git a/files/.xmonad/.stack-work/stack.sqlite3 b/files/.xmonad/.stack-work/stack.sqlite3 index 59f7f75..2fb3308 100644 Binary files a/files/.xmonad/.stack-work/stack.sqlite3 and b/files/.xmonad/.stack-work/stack.sqlite3 differ diff --git a/files/.xmonad/lib/Config.hs b/files/.xmonad/lib/Config.hs index bf0f526..5a4c350 100644 --- a/files/.xmonad/lib/Config.hs +++ b/files/.xmonad/lib/Config.hs @@ -10,15 +10,15 @@ import Control.Exception ( catch , SomeException ) import Control.Monad ( filterM ) -import Data.List ( isSuffixOf - , isPrefixOf +import Data.List ( isPrefixOf + , isSuffixOf ) import System.Exit (exitSuccess) import qualified Rofi +import qualified DescribedSubmap import Data.Function ((&)) -import qualified Data.Map as M import qualified Data.Monoid import Data.Foldable ( for_ ) import qualified System.IO as SysIO @@ -27,7 +27,6 @@ import XMonad.Layout.HintedGrid import XMonad hiding ((|||)) import XMonad.Actions.CopyWindow -import XMonad.Actions.Submap import XMonad.Config.Desktop import XMonad.Hooks.DynamicLog import XMonad.Hooks.ManageDocks @@ -72,6 +71,7 @@ import XMonad.Util.WorkspaceCompare ( getSortByXineramaPhysicalRule ) import XMonad.Layout.WindowNavigation ( windowNavigation ) + {-# ANN module "HLint: ignore Redundant $" #-} {-# ANN module "HLint: ignore Redundant bracket" #-} {-# ANN module "HLint: ignore Move brackets to avoid $" #-} @@ -92,18 +92,16 @@ useSharedWorkspaces = False scriptFile :: String -> String scriptFile script = "/home/leon/scripts/" ++ script + scratchpads :: [NamedScratchpad] scratchpads = - [ NS "terminal" launchTerminal (className =? "scratchpad_term") (customFloating $ W.RationalRect 0.66 0.7 0.34 0.3) - , NS "spotify" "spotify" (appName =? "spotify") defaultFloating - , NS "discord" "discord" (appName =? "discord") defaultFloating - , NS "whatsapp" launchWhatsapp (("WhatsApp" `isSuffixOf`) <$> title) defaultFloating - , NS "slack" "slack" (("Slack | " `isPrefixOf`) <$> title) defaultFloating + [ NS "terminal" "alacritty --class scratchpad_term" (className =? "scratchpad_term") defaultFloating + , NS "spotify" "spotify" (appName =? "spotify") defaultFloating + , NS "discord" "discord" (appName =? "discord") defaultFloating + , NS "whatsapp" "whatsapp-nativefier" (("WhatsApp" `isSuffixOf`) <$> title) defaultFloating + , NS "slack" "slack" (("Slack | " `isPrefixOf`) <$> title) defaultFloating ] - where - launchTerminal = myTerminal ++ " --class scratchpad_term" - launchWhatsapp = "whatsapp-nativefier" - --launchWhatsapp = "gtk-launch chrome-hnpfjngllnobngcgfapefoaidbinmjnm-Default.desktop" +--launchWhatsapp = "gtk-launch chrome-hnpfjngllnobngcgfapefoaidbinmjnm-Default.desktop" -- Colors ------ {{{ @@ -128,7 +126,6 @@ aqua = "#8ec07c" -- }}} -- Layout ---------------------------------------- {{{ --- myTabTheme = def { activeColor = "#504945" @@ -239,7 +236,8 @@ myKeys = windows W.focusMaster) - , ("M-f", toggleFullscreen) + , ("M-f", do sendMessage $ MTog.Toggle MTog.FULL + sendMessage ToggleStruts) , ("M-b", launchWithBackgroundInstance (className =? "qutebrowser") "bwrap --bind / / --dev-bind /dev /dev --tmpfs /tmp --tmpfs /run qutebrowser") , ("M-S-", launchWithBackgroundInstance (className =? "Alacritty") "alacritty") @@ -270,7 +268,7 @@ myKeys = , ("M-n", scratchpadSubmap) , ("M-e", Rofi.promptRunCommand def specialCommands) , ("M-o", Rofi.promptRunCommand def withSelectionCommands) - , ("M-S-C-g", spawn "killall -INT -g giph" >> spawn "notify-send gif 'saved gif in ~/Bilder/gifs'") -- stop gif recording + , ("M-S-C-g", spawn "killall -INT -g giph" >> notify "gif" "saved gif in ~/Bilder/gifs") -- stop gif recording ] ++ generatedMappings where generatedMappings :: [(String, X ())] @@ -300,7 +298,20 @@ myKeys = ] - -- | toggle tabbed Tall layout, merging all non-master windows into a single tab group when initializing the tabbed layout. + + scratchpadSubmap :: X () + scratchpadSubmap = DescribedSubmap.describedSubmap "Scratchpads" + [ ("M-n", "terminal", namedScratchpadAction scratchpads "terminal") + , ("M-w", "whatsapp", namedScratchpadAction scratchpads "whatsapp") + , ("M-s", "slack", namedScratchpadAction scratchpads "slack") + , ("M-m", "spotify", namedScratchpadAction scratchpads "spotify") + , ("M-d", "discord", namedScratchpadAction scratchpads "discord") + ] + + + + -- | toggle tabbed Tall layout, merging all non-master windows + -- into a single tab group when initializing the tabbed layout. toggleTabbedLayout :: X () toggleTabbedLayout = do sendMessage $ ToggleLayouts.Toggle "Tabbed" @@ -312,18 +323,12 @@ myKeys = windows W.focusDown) (return ()) - - toggleFullscreen :: X () - toggleFullscreen = do - sendMessage $ MTog.Toggle MTog.FULL - sendMessage ToggleStruts - -- | launch a program by starting an instance in a hidden workspace, -- and just raising an already running instance. This allows for super quick "startup" time. -- For this to work, the window needs to have the `_NET_WM_PID` set and unique! launchWithBackgroundInstance :: (Query Bool) -> String -> X () launchWithBackgroundInstance windowQuery commandToRun = withWindowSet $ \winSet -> do - quteWins <- (W.allWindows winSet) |> filter (\win -> Just True == (("NSP" ==) <$> (W.findTag win winSet))) + quteWins <- (W.allWindows winSet) |> filter (\win -> Just "NSP" == W.findTag win winSet) |> filterM (runQuery windowQuery) case quteWins of [] -> do spawnHere commandToRun @@ -332,18 +337,6 @@ myKeys = spawnOn "NSP" commandToRun (winId:_) -> windows $ W.shiftWin (W.currentTag winSet) winId - - - - scratchpadSubmap :: X () - scratchpadSubmap = describedSubmap "Scratchpads" - [ ((myModMask, xK_n), " terminal", namedScratchpadAction scratchpads "terminal") - , ((myModMask, xK_w), " whatsapp", namedScratchpadAction scratchpads "whatsapp") - , ((myModMask, xK_s), " slack", namedScratchpadAction scratchpads "slack") - , ((myModMask, xK_m), " spotify", namedScratchpadAction scratchpads "spotify") - , ((myModMask, xK_d), " discord", namedScratchpadAction scratchpads "discord") - ] - withSelectionCommands :: [(String, X ())] withSelectionCommands = [ ("Google", XSel.transformPromptSelection ("https://google.com/search?q=" ++) "qutebrowser") @@ -357,22 +350,16 @@ myKeys = [ ("screenshot", spawn $ scriptFile "screenshot.sh") , ("screenshot to file", spawn $ scriptFile "screenshot.sh --tofile") , ("screenshot full to file", spawn $ scriptFile "screenshot.sh --tofile --fullscreen") - , ("screengif to file", spawn (scriptFile "screengif.sh") >> spawn "notify-send gif 'stop gif-recording with M-S-C-g'") + , ("screengif to file", spawn (scriptFile "screengif.sh") >> notify "gif" "stop gif-recording with M-S-C-g") , ("toggleOptimal", sendMessage ToggleGaps >> toggleWindowSpacingEnabled) , ("toggleSpacing", toggleWindowSpacingEnabled) , ("toggleGaps", sendMessage ToggleGaps) , ("Copy to all workspaces", windows copyToAll) , ("Kill all other copies", killAllOtherCopies) - , ("toggle polybar", safeSpawn "polybar-msg" ["cmd", "toggle"]) + , ("toggle polybar", sendMessage ToggleStruts >> safeSpawn "polybar-msg" ["cmd", "toggle"]) ] - describedSubmap :: String -> [((KeyMask, KeySym), String, X ())] -> X () - describedSubmap submapTitle mappings = promptDzenWhileRunning submapTitle descriptions mySubmap - where - mySubmap = submap $ M.fromList $ map (\(k, _, f) -> (k, f)) mappings - descriptions = map (\(_,x,_) -> x) mappings - -- }}} -- ManageHook -------------------------------{{{ @@ -484,11 +471,10 @@ infixl 1 |> dropEndWhile :: (a -> Bool) -> [a] -> [a] dropEndWhile _ [] = [] -dropEndWhile test [x] = if test x then [] else [x] dropEndWhile test xs = if test $ last xs then dropEndWhile test (init xs) else xs catchAndNotifyAny :: IO () -> IO () -catchAndNotifyAny ioAction = catch ioAction (\(e :: SomeException) -> safeSpawn "notify-send" ["Xmonad exception", show e]) +catchAndNotifyAny ioAction = catch ioAction (\(e :: SomeException) -> notify "Xmonad exception" (show e)) getVisibleWorkspacesTagsOnMonitor :: ScreenId -> X [VirtualWorkspace] @@ -500,6 +486,9 @@ getVisibleWorkspacesTagsOnMonitor monitor = do |> map unmarshallW +notify :: MonadIO m => String -> String -> m () +notify notificationTitle notificationMsg = safeSpawn "notify-send" [notificationTitle, notificationMsg] + ifLayoutIs :: String -> X a -> X a -> X a ifLayoutIs layoutAName = ifLayoutName (== layoutAName) @@ -512,21 +501,4 @@ ifLayoutName check onLayoutA onLayoutB = do -- Get the name of the active layout. getActiveLayoutDescription :: X String getActiveLayoutDescription = (description . W.layout . W.workspace . W.current) <$> gets windowset - - - - - -promptDzenWhileRunning :: String -> [String] -> X () -> X () -promptDzenWhileRunning promptTitle options action = do - handle <- spawnPipe $ "sleep 1 && dzen2 -e onstart=uncollapse -l " ++ lineCount ++ " -fn '" ++ font ++ "'" - io $ SysIO.hPutStrLn handle (promptTitle ++ unlines options) - _ <- action - io $ SysIO.hClose handle - where - lineCount = show $ length options - font = "-*-iosevka-medium-r-s*--16-87-*-*-*-*-iso10???-1" - - - -- }}} diff --git a/files/.xmonad/lib/DescribedSubmap.hs b/files/.xmonad/lib/DescribedSubmap.hs new file mode 100644 index 0000000..4c37a69 --- /dev/null +++ b/files/.xmonad/lib/DescribedSubmap.hs @@ -0,0 +1,45 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# OPTIONS_GHC -fno-warn-missing-signatures -fno-warn-unused-binds #-} + +module DescribedSubmap + ( describedSubmap + ) +where + +import XMonad.Util.Run ( spawnPipe ) +import XMonad.Util.EZConfig ( mkKeymap ) +import XMonad +import XMonad.Actions.Submap ( submap ) +import qualified System.IO as SysIO + + + +describedSubmap :: String -> [(String, String, X ())] -> X () +describedSubmap submapTitle mappings = do + conf <- asks config + let generatedSubmap = + submap $ mkKeymap conf $ map (\(k, _, a) -> (k, a)) mappings + promptDzenWhileRunning submapTitle descriptions generatedSubmap + where descriptions = map (\(k, desc, _) -> "<" ++ k ++ "> " ++ desc) mappings + + +-- | run a dzen prompt with the given title and lines for as long as the given `X` action is running +promptDzenWhileRunning :: String -> [String] -> X a -> X a +promptDzenWhileRunning promptTitle options action = do + handle <- + spawnPipe + $ "sleep 1 && dzen2 -e onstart=uncollapse -l " + ++ lineCount + ++ " -fn '" + ++ font + ++ "'" + io $ SysIO.hPutStrLn handle (unlines $ promptTitle : options) + result <- action + io $ SysIO.hClose handle + return result + where + lineCount = show $ length options + font = "-*-iosevka-medium-r-s*--16-87-*-*-*-*-iso10???-1" + + + diff --git a/files/.xmonad/my-xmonad.cabal b/files/.xmonad/my-xmonad.cabal index 798c1ee..9ea7f31 100644 --- a/files/.xmonad/my-xmonad.cabal +++ b/files/.xmonad/my-xmonad.cabal @@ -9,6 +9,7 @@ executable my-xmonad other-modules: Config Rofi + DescribedSubmap default-language: Haskell2010 ghc-options: -Wall -threaded -fno-warn-missing-signatures