Merge pull request #564 from slotThe/nspHide

X.U.NamedScratchpad: Add logHook to auto-hide named scratchpads on focus loss
This commit is contained in:
slotThe 2021-06-29 14:15:29 +02:00 committed by GitHub
commit 1351f9a931
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 11 deletions

View File

@ -387,6 +387,9 @@
- Exported the `scratchpadWorkspaceTag`. - Exported the `scratchpadWorkspaceTag`.
- Added a new logHook `nsHideOnFocusLoss` for hiding scratchpads
when they lose focus.
* `XMonad.Prompt.Window` * `XMonad.Prompt.Window`
- Added `allApplications` function which maps application executable - Added `allApplications` function which maps application executable

View File

@ -41,7 +41,9 @@ module XMonad.Hooks.RefocusLast (
RecentWins(..), RecentWins(..),
RecentsMap(..), RecentsMap(..),
RefocusLastLayoutHook(..), RefocusLastLayoutHook(..),
RefocusLastToggle(..) RefocusLastToggle(..),
-- * Library functions
withRecentsIn,
) where ) where
import XMonad import XMonad
@ -262,7 +264,7 @@ updateRecentsOn tag = withWindowSet $ \ws ->
-- }}} -- }}}
-- --< Private Utilities >-- {{{ -- --< Utilities >-- {{{
-- | Focuses the first window in the list it can find on the current workspace. -- | Focuses the first window in the list it can find on the current workspace.
tryFocus :: [Window] -> WindowSet -> WindowSet tryFocus :: [Window] -> WindowSet -> WindowSet

View File

@ -27,15 +27,17 @@ module XMonad.Util.NamedScratchpad (
allNamedScratchpadAction, allNamedScratchpadAction,
namedScratchpadManageHook, namedScratchpadManageHook,
namedScratchpadFilterOutWorkspace, namedScratchpadFilterOutWorkspace,
namedScratchpadFilterOutWorkspacePP namedScratchpadFilterOutWorkspacePP,
nsHideOnFocusLoss,
) where ) where
import XMonad import XMonad
import XMonad.Prelude (filterM, find, unless)
import XMonad.Hooks.ManageHelpers (doRectFloat)
import XMonad.Actions.DynamicWorkspaces (addHiddenWorkspace) import XMonad.Actions.DynamicWorkspaces (addHiddenWorkspace)
import XMonad.Hooks.DynamicLog (PP, ppSort)
import XMonad.Actions.SpawnOn (spawnHere) import XMonad.Actions.SpawnOn (spawnHere)
import XMonad.Hooks.DynamicLog (PP, ppSort)
import XMonad.Hooks.ManageHelpers (doRectFloat)
import XMonad.Hooks.RefocusLast (withRecentsIn)
import XMonad.Prelude (filterM, find, unless, when)
import qualified Data.List.NonEmpty as NE import qualified Data.List.NonEmpty as NE
@ -93,6 +95,11 @@ import qualified XMonad.StackSet as W
-- 'XMonad.Util.WorkspaceCompare.filterOutWs'. See the documentation of these -- 'XMonad.Util.WorkspaceCompare.filterOutWs'. See the documentation of these
-- functions for examples. -- functions for examples.
-- --
-- Further, there is also a @logHook@ that you can use to hide
-- scratchpads when they lose focus; this is functionality akin to what
-- some dropdown terminals provide. See the documentation of
-- 'nsHideOnFocusLoss' for an example how to set this up.
--
-- | Single named scratchpad configuration -- | Single named scratchpad configuration
data NamedScratchpad = NS { name :: String -- ^ Scratchpad name data NamedScratchpad = NS { name :: String -- ^ Scratchpad name
@ -152,6 +159,31 @@ allNamedScratchpadAction :: NamedScratchpads
-> X () -> X ()
allNamedScratchpadAction = someNamedScratchpadAction mapM_ runApplication allNamedScratchpadAction = someNamedScratchpadAction mapM_ runApplication
-- | A @logHook@ to hide scratchpads when they lose focus. This can be
-- useful for e.g. dropdown terminals. Note that this also requires you
-- to use the 'XMonad.Hooks.RefocusLast.refocusLastLogHook'.
--
-- ==== __Example__
--
-- > import XMonad.Hooks.RefocusLast (refocusLastLogHook)
-- > import XMonad.Util.NamedScratchpad
-- >
-- > main = xmonad $ def
-- > { logHook = refocusLastLogHook
-- > >> nsHideOnFocusLoss myScratchpads
-- > -- enable hiding for all of @myScratchpads@
-- > }
nsHideOnFocusLoss :: NamedScratchpads -> X ()
nsHideOnFocusLoss scratches = withWindowSet $ \winSet -> do
let cur = W.currentTag winSet
withRecentsIn cur () $ \lastFocus _ ->
when (lastFocus `elem` W.index winSet && cur /= scratchpadWorkspaceTag) $
whenX (isNS lastFocus) $
shiftToNSP (W.workspaces winSet) ($ lastFocus)
where
isNS :: Window -> X Bool
isNS w = or <$> traverse ((`runQuery` w) . query) scratches
-- | execute some action on a named scratchpad -- | execute some action on a named scratchpad
someNamedScratchpadAction :: ((Window -> X ()) -> NE.NonEmpty Window -> X ()) someNamedScratchpadAction :: ((Window -> X ()) -> NE.NonEmpty Window -> X ())
-> (NamedScratchpad -> X ()) -> (NamedScratchpad -> X ())
@ -173,11 +205,7 @@ someNamedScratchpadAction f runApp scratchpadConfig scratchpadName =
Just wins -> f (windows . W.shiftWin (W.currentTag winSet)) wins Just wins -> f (windows . W.shiftWin (W.currentTag winSet)) wins
-- matching window running on current workspace -> window should be shifted to scratchpad workspace -- matching window running on current workspace -> window should be shifted to scratchpad workspace
Just wins -> do Just wins -> shiftToNSP (W.workspaces winSet) (`f` wins)
unless (any (\wsp -> scratchpadWorkspaceTag == W.tag wsp) (W.workspaces winSet))
(addHiddenWorkspace scratchpadWorkspaceTag)
f (windows . W.shiftWin scratchpadWorkspaceTag) wins
Nothing -> return () Nothing -> return ()
-- | Tag of the scratchpad workspace -- | Tag of the scratchpad workspace
@ -189,6 +217,14 @@ namedScratchpadManageHook :: NamedScratchpads -- ^ Named scratchpads configurati
-> ManageHook -> ManageHook
namedScratchpadManageHook = composeAll . fmap (\c -> query c --> hook c) namedScratchpadManageHook = composeAll . fmap (\c -> query c --> hook c)
-- | Shift some windows to the scratchpad workspace according to the
-- given function. The workspace is created if necessary.
shiftToNSP :: [WindowSpace] -> ((Window -> X ()) -> X ()) -> X ()
shiftToNSP ws f = do
unless (any ((scratchpadWorkspaceTag ==) . W.tag) ws) $
addHiddenWorkspace scratchpadWorkspaceTag
f (windows . W.shiftWin scratchpadWorkspaceTag)
-- | Transforms a workspace list containing the NSP workspace into one that -- | Transforms a workspace list containing the NSP workspace into one that
-- doesn't contain it. Intended for use with logHooks. -- doesn't contain it. Intended for use with logHooks.
namedScratchpadFilterOutWorkspace :: [WindowSpace] -> [WindowSpace] namedScratchpadFilterOutWorkspace :: [WindowSpace] -> [WindowSpace]