p
This commit is contained in:
Leon Kowarschick 2020-05-18 12:08:22 +02:00
parent d7176d7125
commit 0eb7b94742
4 changed files with 81 additions and 63 deletions

View file

@ -10,15 +10,15 @@ import Control.Exception ( catch
, SomeException , SomeException
) )
import Control.Monad ( filterM ) import Control.Monad ( filterM )
import Data.List ( isSuffixOf import Data.List ( isPrefixOf
, isPrefixOf , isSuffixOf
) )
import System.Exit (exitSuccess) import System.Exit (exitSuccess)
import qualified Rofi import qualified Rofi
import qualified DescribedSubmap
import Data.Function ((&)) import Data.Function ((&))
import qualified Data.Map as M
import qualified Data.Monoid import qualified Data.Monoid
import Data.Foldable ( for_ ) import Data.Foldable ( for_ )
import qualified System.IO as SysIO import qualified System.IO as SysIO
@ -27,7 +27,6 @@ import XMonad.Layout.HintedGrid
import XMonad hiding ((|||)) import XMonad hiding ((|||))
import XMonad.Actions.CopyWindow import XMonad.Actions.CopyWindow
import XMonad.Actions.Submap
import XMonad.Config.Desktop import XMonad.Config.Desktop
import XMonad.Hooks.DynamicLog import XMonad.Hooks.DynamicLog
import XMonad.Hooks.ManageDocks import XMonad.Hooks.ManageDocks
@ -72,6 +71,7 @@ import XMonad.Util.WorkspaceCompare ( getSortByXineramaPhysicalRule
) )
import XMonad.Layout.WindowNavigation ( windowNavigation ) import XMonad.Layout.WindowNavigation ( windowNavigation )
{-# ANN module "HLint: ignore Redundant $" #-} {-# ANN module "HLint: ignore Redundant $" #-}
{-# ANN module "HLint: ignore Redundant bracket" #-} {-# ANN module "HLint: ignore Redundant bracket" #-}
{-# ANN module "HLint: ignore Move brackets to avoid $" #-} {-# ANN module "HLint: ignore Move brackets to avoid $" #-}
@ -92,17 +92,15 @@ useSharedWorkspaces = False
scriptFile :: String -> String scriptFile :: String -> String
scriptFile script = "/home/leon/scripts/" ++ script scriptFile script = "/home/leon/scripts/" ++ script
scratchpads :: [NamedScratchpad] scratchpads :: [NamedScratchpad]
scratchpads = scratchpads =
[ NS "terminal" launchTerminal (className =? "scratchpad_term") (customFloating $ W.RationalRect 0.66 0.7 0.34 0.3) [ NS "terminal" "alacritty --class scratchpad_term" (className =? "scratchpad_term") defaultFloating
, NS "spotify" "spotify" (appName =? "spotify") defaultFloating , NS "spotify" "spotify" (appName =? "spotify") defaultFloating
, NS "discord" "discord" (appName =? "discord") defaultFloating , NS "discord" "discord" (appName =? "discord") defaultFloating
, NS "whatsapp" launchWhatsapp (("WhatsApp" `isSuffixOf`) <$> title) defaultFloating , NS "whatsapp" "whatsapp-nativefier" (("WhatsApp" `isSuffixOf`) <$> title) defaultFloating
, NS "slack" "slack" (("Slack | " `isPrefixOf`) <$> 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"
@ -128,7 +126,6 @@ aqua = "#8ec07c"
-- }}} -- }}}
-- Layout ---------------------------------------- {{{ -- Layout ---------------------------------------- {{{
--
myTabTheme = def myTabTheme = def
{ activeColor = "#504945" { activeColor = "#504945"
@ -239,7 +236,8 @@ myKeys =
windows W.focusMaster) 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-b", launchWithBackgroundInstance (className =? "qutebrowser") "bwrap --bind / / --dev-bind /dev /dev --tmpfs /tmp --tmpfs /run qutebrowser")
, ("M-S-<Return>", launchWithBackgroundInstance (className =? "Alacritty") "alacritty") , ("M-S-<Return>", launchWithBackgroundInstance (className =? "Alacritty") "alacritty")
@ -270,7 +268,7 @@ myKeys =
, ("M-n", scratchpadSubmap) , ("M-n", scratchpadSubmap)
, ("M-e", Rofi.promptRunCommand def specialCommands) , ("M-e", Rofi.promptRunCommand def specialCommands)
, ("M-o", Rofi.promptRunCommand def withSelectionCommands) , ("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 ] ++ generatedMappings
where where
generatedMappings :: [(String, X ())] 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 :: X ()
toggleTabbedLayout = do toggleTabbedLayout = do
sendMessage $ ToggleLayouts.Toggle "Tabbed" sendMessage $ ToggleLayouts.Toggle "Tabbed"
@ -312,18 +323,12 @@ myKeys =
windows W.focusDown) windows W.focusDown)
(return ()) (return ())
toggleFullscreen :: X ()
toggleFullscreen = do
sendMessage $ MTog.Toggle MTog.FULL
sendMessage ToggleStruts
-- | launch a program by starting an instance in a hidden workspace, -- | 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. -- 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! -- For this to work, the window needs to have the `_NET_WM_PID` set and unique!
launchWithBackgroundInstance :: (Query Bool) -> String -> X () launchWithBackgroundInstance :: (Query Bool) -> String -> X ()
launchWithBackgroundInstance windowQuery commandToRun = withWindowSet $ \winSet -> do 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) |> filterM (runQuery windowQuery)
case quteWins of case quteWins of
[] -> do spawnHere commandToRun [] -> do spawnHere commandToRun
@ -332,18 +337,6 @@ myKeys =
spawnOn "NSP" commandToRun spawnOn "NSP" commandToRun
(winId:_) -> windows $ W.shiftWin (W.currentTag winSet) winId (winId:_) -> windows $ W.shiftWin (W.currentTag winSet) winId
scratchpadSubmap :: X ()
scratchpadSubmap = describedSubmap "Scratchpads"
[ ((myModMask, xK_n), "<M-n> terminal", namedScratchpadAction scratchpads "terminal")
, ((myModMask, xK_w), "<M-w> whatsapp", namedScratchpadAction scratchpads "whatsapp")
, ((myModMask, xK_s), "<M-s> slack", namedScratchpadAction scratchpads "slack")
, ((myModMask, xK_m), "<M-m> spotify", namedScratchpadAction scratchpads "spotify")
, ((myModMask, xK_d), "<M-m> discord", namedScratchpadAction scratchpads "discord")
]
withSelectionCommands :: [(String, X ())] withSelectionCommands :: [(String, X ())]
withSelectionCommands = withSelectionCommands =
[ ("Google", XSel.transformPromptSelection ("https://google.com/search?q=" ++) "qutebrowser") [ ("Google", XSel.transformPromptSelection ("https://google.com/search?q=" ++) "qutebrowser")
@ -357,22 +350,16 @@ myKeys =
[ ("screenshot", spawn $ scriptFile "screenshot.sh") [ ("screenshot", spawn $ scriptFile "screenshot.sh")
, ("screenshot to file", spawn $ scriptFile "screenshot.sh --tofile") , ("screenshot to file", spawn $ scriptFile "screenshot.sh --tofile")
, ("screenshot full to file", spawn $ scriptFile "screenshot.sh --tofile --fullscreen") , ("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) , ("toggleOptimal", sendMessage ToggleGaps >> toggleWindowSpacingEnabled)
, ("toggleSpacing", toggleWindowSpacingEnabled) , ("toggleSpacing", toggleWindowSpacingEnabled)
, ("toggleGaps", sendMessage ToggleGaps) , ("toggleGaps", sendMessage ToggleGaps)
, ("Copy to all workspaces", windows copyToAll) , ("Copy to all workspaces", windows copyToAll)
, ("Kill all other copies", killAllOtherCopies) , ("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 -------------------------------{{{ -- ManageHook -------------------------------{{{
@ -484,11 +471,10 @@ infixl 1 |>
dropEndWhile :: (a -> Bool) -> [a] -> [a] dropEndWhile :: (a -> Bool) -> [a] -> [a]
dropEndWhile _ [] = [] dropEndWhile _ [] = []
dropEndWhile test [x] = if test x then [] else [x]
dropEndWhile test xs = if test $ last xs then dropEndWhile test (init xs) else xs dropEndWhile test xs = if test $ last xs then dropEndWhile test (init xs) else xs
catchAndNotifyAny :: IO () -> IO () 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] getVisibleWorkspacesTagsOnMonitor :: ScreenId -> X [VirtualWorkspace]
@ -500,6 +486,9 @@ getVisibleWorkspacesTagsOnMonitor monitor = do
|> map unmarshallW |> 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 :: String -> X a -> X a -> X a
ifLayoutIs layoutAName = ifLayoutName (== layoutAName) ifLayoutIs layoutAName = ifLayoutName (== layoutAName)
@ -512,21 +501,4 @@ ifLayoutName check onLayoutA onLayoutB = do
-- Get the name of the active layout. -- Get the name of the active layout.
getActiveLayoutDescription :: X String getActiveLayoutDescription :: X String
getActiveLayoutDescription = (description . W.layout . W.workspace . W.current) <$> gets windowset 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"
-- }}} -- }}}

View file

@ -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"

View file

@ -9,6 +9,7 @@ executable my-xmonad
other-modules: other-modules:
Config Config
Rofi Rofi
DescribedSubmap
default-language: Haskell2010 default-language: Haskell2010
ghc-options: -Wall -threaded -fno-warn-missing-signatures ghc-options: -Wall -threaded -fno-warn-missing-signatures