diff --git a/CHANGES.md b/CHANGES.md index 941cb6b3..20d9c1eb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -46,6 +46,11 @@ visible workspaces combined with the workspace name, for example in a status bar. This module provides utility functions to do just that. + * `XMonad.Hooks.ShowWName` + + Flashes the name of the current workspace when switching to it. + Like `XMonad.Layout.ShowWName`, but as a logHook. + ### Bug Fixes and Minor Changes * `XMonad.Prompt.OrgMode` diff --git a/XMonad/Hooks/ShowWName.hs b/XMonad/Hooks/ShowWName.hs new file mode 100644 index 00000000..1fc25776 --- /dev/null +++ b/XMonad/Hooks/ShowWName.hs @@ -0,0 +1,84 @@ +{-# LANGUAGE InstanceSigs #-} +----------------------------------------------------------------------------- +-- | +-- Module : XMonad.Hooks.ShowWName +-- Description : Like 'XMonad.Layout.ShowWName', but as a logHook +-- Copyright : (c) 2022 Solid +-- License : BSD3-style (see LICENSE) +-- +-- Maintainer : soliditsallgood@mailbox.org +-- +-- Flash the names of workspaces name when switching to them. This is a +-- reimplementation of 'XMonad.Layout.ShowWName' as a logHook. +----------------------------------------------------------------------------- + +module XMonad.Hooks.ShowWName ( + -- * Usage + -- $usage + showWNameLogHook, + SWNConfig(..), + flashName, +) where + +import qualified XMonad.StackSet as W +import qualified XMonad.Util.ExtensibleState as XS + +import XMonad +import XMonad.Layout.ShowWName (SWNConfig (..)) +import XMonad.Prelude +import XMonad.Util.XUtils (WindowConfig (..), showSimpleWindow) + +import Control.Concurrent (threadDelay) + +{- $usage + +You can use this module with the following in your +@~\/.xmonad\/xmonad.hs@: + +> import XMonad.Hooks.ShowWName +> +> main :: IO () +> main = xmonad $ def +> { logHook = showWNameLogHook def +> } + +Whenever a workspace gains focus, the above logHook will flash its name. +You can customise the duration of the flash, as well as colours by +customising the 'SWNConfig' argument that 'showWNameLogHook' takes. + +Alternatively, you can also bind 'flashName' to a key and manually +invoke it when you want to know which workspace you are on. +-} + +-- | LogHook for flashing the name of a workspace upon entering it. +showWNameLogHook :: SWNConfig -> X () +showWNameLogHook cfg = do + LastShown s <- XS.get + foc <- withWindowSet (pure . W.currentTag) + unless (s == foc) $ do + flashName cfg + XS.put (LastShown foc) + +-- | Flash the name of the currently focused workspace. +flashName :: SWNConfig -> X () +flashName cfg = do + n <- withWindowSet (pure . W.currentTag) + showSimpleWindow cfg' [n] >>= \w -> void . xfork $ do + dpy <- openDisplay "" + threadDelay (fromEnum $ swn_fade cfg * 1000000) -- 1_000_000 needs GHC 8.6.x and up + void $ destroyWindow dpy w + closeDisplay dpy + where + cfg' :: WindowConfig + cfg' = def{ winFont = swn_font cfg, winBg = swn_bgcolor cfg, winFg = swn_color cfg } + +-- | Last shown workspace. +newtype LastShown = LastShown WorkspaceId + deriving (Show, Read) + +instance ExtensionClass LastShown where + initialValue :: LastShown + initialValue = LastShown "" + + extensionType :: LastShown -> StateExtension + extensionType = PersistentExtension diff --git a/xmonad-contrib.cabal b/xmonad-contrib.cabal index a80f5c2c..0b2052af 100644 --- a/xmonad-contrib.cabal +++ b/xmonad-contrib.cabal @@ -198,6 +198,7 @@ library XMonad.Hooks.Script XMonad.Hooks.ServerMode XMonad.Hooks.SetWMName + XMonad.Hooks.ShowWName XMonad.Hooks.StatusBar XMonad.Hooks.StatusBar.PP XMonad.Hooks.StatusBar.WorkspaceScreen