Merge pull request #351 from elkowar/master

Make XMonad.Util.NamedScratchpad more flexible
This commit is contained in:
Brent Yorgey 2020-06-18 07:06:21 -05:00 committed by GitHub
commit 5c8ff36bcb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 21 deletions

View File

@ -52,6 +52,14 @@
### Bug Fixes and Minor Changes ### Bug Fixes and Minor Changes
* `XMonad.Util.NamedScratchpad`
Added two new exported functions to the module:
- `customRunNamedScratchpadAction`
(provides the option to customize the `X ()` action the scratchpad is launched by)
- `spawnHereNamedScratchpadAction`
(uses `XMonad.Actions.SpawnOn.spawnHere` to initially start the scratchpad on the workspace it was launched on)
* `XMonad.Util.Run` * `XMonad.Util.Run`
Added two new functions to the module: Added two new functions to the module:

View File

@ -22,6 +22,8 @@ module XMonad.Util.NamedScratchpad (
customFloating, customFloating,
NamedScratchpads, NamedScratchpads,
namedScratchpadAction, namedScratchpadAction,
spawnHereNamedScratchpadAction,
customRunNamedScratchpadAction,
allNamedScratchpadAction, allNamedScratchpadAction,
namedScratchpadManageHook, namedScratchpadManageHook,
namedScratchpadFilterOutWorkspace, namedScratchpadFilterOutWorkspace,
@ -32,8 +34,11 @@ import XMonad
import XMonad.Hooks.ManageHelpers (doRectFloat) import XMonad.Hooks.ManageHelpers (doRectFloat)
import XMonad.Actions.DynamicWorkspaces (addHiddenWorkspace) import XMonad.Actions.DynamicWorkspaces (addHiddenWorkspace)
import XMonad.Hooks.DynamicLog (PP, ppSort) import XMonad.Hooks.DynamicLog (PP, ppSort)
import XMonad.Actions.SpawnOn (spawnHere)
import Control.Monad (filterM) import qualified Data.List.NonEmpty as NE
import Control.Monad (filterM, unless)
import Data.Maybe (listToMaybe) import Data.Maybe (listToMaybe)
import qualified XMonad.StackSet as W import qualified XMonad.StackSet as W
@ -109,43 +114,67 @@ type NamedScratchpads = [NamedScratchpad]
-- | Finds named scratchpad configuration by name -- | Finds named scratchpad configuration by name
findByName :: NamedScratchpads -> String -> Maybe NamedScratchpad findByName :: NamedScratchpads -> String -> Maybe NamedScratchpad
findByName c s = listToMaybe $ filter ((s==) . name) c findByName c s = listToMaybe $ filter ((s ==) . name) c
-- | Runs application which should appear in specified scratchpad -- | Runs application which should appear in specified scratchpad
runApplication :: NamedScratchpad -> X () runApplication :: NamedScratchpad -> X ()
runApplication = spawn . cmd runApplication = spawn . cmd
-- | Runs application which should appear in a specified scratchpad on the workspace it was launched on
runApplicationHere :: NamedScratchpad -> X ()
runApplicationHere = spawnHere . cmd
-- | Action to pop up specified named scratchpad -- | Action to pop up specified named scratchpad
namedScratchpadAction :: NamedScratchpads -- ^ Named scratchpads configuration namedScratchpadAction :: NamedScratchpads -- ^ Named scratchpads configuration
-> String -- ^ Scratchpad name -> String -- ^ Scratchpad name
-> X () -> X ()
namedScratchpadAction = someNamedScratchpadAction (\f ws -> f $ head ws) namedScratchpadAction = customRunNamedScratchpadAction runApplication
-- | Action to pop up specified named scratchpad, initially starting it on the current workspace.
spawnHereNamedScratchpadAction :: NamedScratchpads -- ^ Named scratchpads configuration
-> String -- ^ Scratchpad name
-> X ()
spawnHereNamedScratchpadAction = customRunNamedScratchpadAction runApplicationHere
-- | Action to pop up specified named scratchpad, given a custom way to initially start the application.
customRunNamedScratchpadAction :: (NamedScratchpad -> X ()) -- ^ Function initially running the application, given the configured @scratchpad@ cmd
-> NamedScratchpads -- ^ Named scratchpads configuration
-> String -- ^ Scratchpad name
-> X ()
customRunNamedScratchpadAction = someNamedScratchpadAction (\f ws -> f $ NE.head ws)
allNamedScratchpadAction :: NamedScratchpads allNamedScratchpadAction :: NamedScratchpads
-> String -> String
-> X () -> X ()
allNamedScratchpadAction = someNamedScratchpadAction mapM_ allNamedScratchpadAction = someNamedScratchpadAction mapM_ runApplication
someNamedScratchpadAction :: ((Window -> X ()) -> [Window] -> X ()) -- | execute some action on a named scratchpad
someNamedScratchpadAction :: ((Window -> X ()) -> NE.NonEmpty Window -> X ())
-> (NamedScratchpad -> X ())
-> NamedScratchpads -> NamedScratchpads
-> String -> String
-> X () -> X ()
someNamedScratchpadAction f confs n someNamedScratchpadAction f runApp scratchpadConfig scratchpadName =
| Just conf <- findByName confs n = withWindowSet $ \s -> do case findByName scratchpadConfig scratchpadName of
filterCurrent <- filterM (runQuery (query conf)) Just conf -> withWindowSet $ \winSet -> do
((maybe [] W.integrate . W.stack . W.workspace . W.current) s) let focusedWspWindows = maybe [] W.integrate (W.stack . W.workspace . W.current $ winSet)
filterAll <- filterM (runQuery (query conf)) (W.allWindows s) allWindows = W.allWindows winSet
case filterCurrent of matchingOnCurrent <- filterM (runQuery (query conf)) focusedWspWindows
[] -> matchingOnAll <- filterM (runQuery (query conf)) allWindows
case filterAll of
[] -> runApplication conf case NE.nonEmpty matchingOnCurrent of
_ -> f (windows . W.shiftWin (W.currentTag s)) filterAll -- no matching window on the current workspace -> scratchpad not running or in background
_ -> do Nothing -> case NE.nonEmpty matchingOnAll of
if null (filter ((== scratchpadWorkspaceTag) . W.tag) (W.workspaces s)) Nothing -> runApp conf
then addHiddenWorkspace scratchpadWorkspaceTag Just wins -> f (windows . W.shiftWin (W.currentTag winSet)) wins
else return ()
f (windows . W.shiftWin scratchpadWorkspaceTag) filterAll -- matching window running on current workspace -> window should be shifted to scratchpad workspace
| otherwise = return () Just wins -> do
unless (any (\wsp -> scratchpadWorkspaceTag == W.tag wsp) (W.workspaces winSet))
(addHiddenWorkspace scratchpadWorkspaceTag)
f (windows . W.shiftWin scratchpadWorkspaceTag) wins
Nothing -> return ()
-- tag of the scratchpad workspace -- tag of the scratchpad workspace