XMonad.Hooks.DynamicLog

xmonad-contrib-0.18.1: Community-maintained extensions for xmonad

Copyright | (c) Don Stewart <dons@cse.unsw.edu.au>
License | BSD3-style (see LICENSE)
Maintainer | Don Stewart <dons@cse.unsw.edu.au>
Stability | unstable
Portability | unportable
Safe Haskell | None
Language | Haskell2010

XMonad.Hooks.DynamicLog

Contents

- Usage
- Drop-in loggers
- Build your own formatter
- Example formatters
- Formatting utilities
- Internal formatting functions

Description

Note: This module is a compatibility wrapper for the following:

- XMonad.Hooks.StatusBar
- XMonad.Hooks.StatusBar.PP

DynamicLog API is frozen and users are encouraged to migrate to these modern replacements.

Original description and documentation follows:

xmonad calls the logHook with every internal state update, which is useful for (among other things) outputting status information to an external status bar program such as xmobar or dzen. DynamicLog provides several drop-in logHooks for this purpose, as well as flexible tools for specifying your own formatting.

Synopsis

- xmobarProp :: forall (l :: Type -> Type). LayoutClass l Window => XConfig l -> XConfig (ModifiedLayout AvoidStruts l)
- xmobar :: forall (l :: Type -> Type). LayoutClass l Window => XConfig l -> IO (XConfig (ModifiedLayout AvoidStruts l))
- statusBar :: forall (l :: Type -> Type). LayoutClass l Window => String -> PP -> (XConfig Layout -> (KeyMask, KeySym)) -> XConfig l -> IO (XConfig (ModifiedLayout AvoidStruts l))
- dzen :: forall (l :: Type -> Type). LayoutClass l Window => XConfig l -> IO (XConfig (ModifiedLayout AvoidStruts l))
- dzenWithFlags :: forall (l :: Type -> Type). LayoutClass l Window => String -> XConfig l -> IO (XConfig (ModifiedLayout AvoidStruts l))
- dynamicLog :: X ()
- dynamicLogXinerama :: X ()
- xmonadPropLog :: String -> X ()
- xmonadPropLog' :: String -> String -> X ()
- xmonadDefProp :: String
- dynamicLogWithPP :: PP -> X ()
- dynamicLogString :: PP -> X String
- data PP = PP {
  - ppCurrent :: WorkspaceId -> String
  - ppVisible :: WorkspaceId -> String
  - ppHidden :: WorkspaceId -> String
  - ppHiddenNoWindows :: WorkspaceId -> String
  - ppVisibleNoWindows :: Maybe (WorkspaceId -> String)
  - ppUrgent :: WorkspaceId -> String
  - ppRename :: String -> WindowSpace -> String
  - ppSep :: String
  - ppWsSep :: String
  - ppTitle :: String -> String
  - ppTitleSanitize :: String -> String
  - ppLayout :: String -> String
  - ppOrder :: [String] -> [String]
  - ppSort :: X ([WindowSpace] -> [WindowSpace])
  - ppExtras :: [X (Maybe String)]
  - ppOutput :: String -> IO ()
  - ppPrinters :: WSPP
  }
- def :: Default a => a
- dzenPP :: PP
- xmobarPP :: PP
- sjanssenPP :: PP
- byorgeyPP :: PP
- wrap :: String -> String -> String -> String
- pad :: String -> String
- trim :: String -> String
- shorten :: Int -> String -> String
- shorten' :: String -> Int -> String -> String
- shortenLeft :: Int -> String -> String
- shortenLeft' :: String -> Int -> String -> String
- xmobarColor :: String -> String -> String -> String
- xmobarAction :: String -> String -> String -> String
- xmobarBorder :: String -> String -> Int -> String -> String
- xmobarRaw :: String -> String
- xmobarStrip :: String -> String
- xmobarStripTags :: [String] -> String -> String
- dzenColor :: String -> String -> String -> String
- dzenEscape :: String -> String
- dzenStrip :: String -> String
- filterOutWsPP :: [WorkspaceId] -> PP -> PP
- pprWindowSet :: WorkspaceSort -> [Window] -> PP -> WindowSet -> String
- pprWindowSetXinerama :: WindowSet -> String

# Usage

You can use this module with the following in your `xmonad.hs`:

    import XMonad
    import XMonad.Hooks.DynamicLog

If you just want a quick-and-dirty status bar with zero effort, try the `xmobar` or `dzen` functions:

    main = xmonad =<< xmobar myConfig

    myConfig = def { ... }

There is also `statusBar` if you'd like to use another status bar, or would like to use different formatting options. The `xmobar`, `dzen`, and `statusBar` functions are preferred over the other options listed below, as they take care of all the necessary plumbing -- no shell scripting required!

Alternatively, you can choose among several default status bar formats (`dynamicLog` or `dynamicLogXinerama`) by simply setting your logHook to the appropriate function, for instance:

    main = xmonad $ def {
       ...
       logHook = dynamicLog
       ...
     }

For more flexibility, you can also use `dynamicLogWithPP` and supply your own pretty-printing format (by either defining one from scratch, or customizing one of the provided examples). For example:

       -- use sjanssen's pretty-printer format, but with the sections
       -- in reverse
       logHook = dynamicLogWithPP $ sjanssenPP { ppOrder = reverse }

Note that setting the `logHook` only sets up xmonad's output; you are responsible for starting your own status bar program (e.g. dzen or xmobar) and making sure xmonad's output is piped into it appropriately, either by putting it in your `.xsession` or similar file, or by using `spawnPipe` in your `main` function, for example:

    import XMonad.Util.Run   -- for spawnPipe and hPutStrLn

    main = do
        h <- spawnPipe "xmobar -options -foo -bar"
        xmonad $ def {
          ...
          logHook = dynamicLogWithPP $ def { ppOutput = hPutStrLn h }

If you use `spawnPipe`, be sure to redefine the `ppOutput` field of your pretty-printer as in the example above; by default the status will be printed to stdout rather than the pipe you create.

Even if you don't use a statusbar, you can still use `dynamicLogString` to show on-screen notifications in response to some events. For example, to show the current layout when it changes, you could make a keybinding to cycle the layout and display the current status:

       , ((mod1Mask, xK_a     ), sendMessage NextLayout >> (dynamicLogString myPP >>= xmessage))

# Drop-in loggers

xmobarProp #

Arguments

:: forall (l :: Type -> Type). LayoutClass l Window |
=> XConfig l | The base config
-> XConfig (ModifiedLayout AvoidStruts l) |

Run xmonad with a property-based xmobar status bar set to some nice defaults.

    main = xmonad $ xmobarProp myConfig

    myConfig = def { ... }

The intent is that the above config file should provide a nice status bar with minimal effort. Note that you still need to configure xmobar to use the `XMonadLog` plugin instead of the default `StdinReader`, see above.

If you wish to customize the status bar format at all, use the modernized interface provided by the XMonad.Hooks.StatusBar and XMonad.Hooks.StatusBar.PP modules instead.

The binding uses the XMonad.Hooks.ManageDocks module to automatically handle screen placement for xmobar, and enables 'mod-b' for toggling the menu bar.

xmobar #

Arguments

:: forall (l :: Type -> Type). LayoutClass l Window |
=> XConfig l | The base config
-> IO (XConfig (ModifiedLayout AvoidStruts l)) |

This function works like `xmobarProp`, but uses pipes instead of property-based logging.

statusBar #

Arguments

:: forall (l :: Type -> Type). LayoutClass l Window |
=> String | The command line to launch the status bar
-> PP | The pretty printing options
-> (XConfig Layout -> (KeyMask, KeySym)) | The desired key binding to toggle bar visibility
-> XConfig l | The base config
-> IO (XConfig (ModifiedLayout AvoidStruts l)) |

Like `statusBarProp`, but uses pipes instead of property-based logging. Only use this function if your status bar does not support reading from a property of the root window.

dzen #

Arguments

:: forall (l :: Type -> Type). LayoutClass l Window |
=> XConfig l | The base config
-> IO (XConfig (ModifiedLayout AvoidStruts l)) |

Run xmonad with a dzen status bar set to some nice defaults.

    main = xmonad =<< dzen myConfig

    myConfig = def { ... }

This works pretty much the same as the `xmobar` function.

dzenWithFlags #

Arguments

:: forall (l :: Type -> Type). LayoutClass l Window |
=> String | Flags to give to `dzen`
-> XConfig l | The base config
-> IO (XConfig (ModifiedLayout AvoidStruts l)) |

Run xmonad with a dzen status bar with specified dzen command line arguments.

    main = xmonad =<< dzenWithFlags flags myConfig

    myConfig = def { ... }

    flags = "-e onstart lower -w 800 -h 24 -ta l -fg #a8a3f7 -bg #3f3c6d"

This function works much in the same way as the `dzen` function, only that it can also be used to customize the arguments passed to dzen2, e.g changing the default width and height of dzen2.

You should use this function only when the default `dzen` function does not serve your purpose.

dynamicLog :: X () #

An example log hook, which prints status information to stdout in the default format:

    1 2 [3] 4 7 : full : title

That is, the currently populated workspaces, the current workspace layout, and the title of the focused window.

To customize the output format, see `dynamicLogWithPP`.

dynamicLogXinerama :: X () #

Workspace logger with a format designed for Xinerama:

    [1 9 3] 2 7

where 1, 9, and 3 are the workspaces on screens 1, 2 and 3, respectively, and 2 and 7 are non-visible, non-empty workspaces.

At the present time, the current layout and window title are not shown. The xinerama workspace format shown above can be (mostly) replicated using `dynamicLogWithPP` by setting `ppSort` to getSortByXineramaRule from XMonad.Util.WorkspaceCompare. For example,

    def { ppCurrent = dzenColor "red" "#efebe7"
        , ppVisible = wrap "[" "]"
        , ppSort    = getSortByXineramaRule
        }

xmonadPropLog :: String -> X () #

Write a string to the `_XMONAD_LOG` property on the root window.

xmonadPropLog' #

Arguments

:: String | Property name
-> String | Message to be written to the property
-> X () |

Write a string to a property on the root window. This property is of type `UTF8_STRING`.

xmonadDefProp :: String #

The default property xmonad writes to. (`_XMONAD_LOG`).

# Build your own formatter

dynamicLogWithPP :: PP -> X () #

Format the current status using the supplied pretty-printing format, and write it to stdout.

dynamicLogString :: PP -> X String #

The same as `dynamicLogWithPP`, except it simply returns the status as a formatted string without actually printing it to stdout, to allow for further processing, or use in some application other than a status bar.

data PP #

The `PP` type allows the user to customize the formatting of status information.

Constructors

PP |
Fields ppCurrent :: WorkspaceId -> String how to print the tag of the currently focused workspace ppVisible :: WorkspaceId -> String how to print tags of visible but not focused workspaces (xinerama only) ppHidden :: WorkspaceId -> String how to print tags of hidden workspaces which contain windows ppHiddenNoWindows :: WorkspaceId -> String how to print tags of empty hidden workspaces ppVisibleNoWindows :: Maybe (WorkspaceId -> String) how to print tags of empty visible workspaces ppUrgent :: WorkspaceId -> String format to be applied to tags of urgent workspaces. ppRename :: String -> WindowSpace -> String rename/augment the workspace tag (note that `WindowSpace -> …` acts as a Reader monad) ppSep :: String separator to use between different log sections (window name, layout, workspaces) ppWsSep :: String separator to use between workspace tags ppTitle :: String -> String window title format for the focused window. To display the titles of all windows—even unfocused ones—check `logTitles`. ppTitleSanitize :: String -> String escape / sanitizes input to `ppTitle` ppLayout :: String -> String layout name format ppOrder :: [String] -> [String] how to order the different log sections. By default, this function receives a list with three formatted strings, representing the workspaces, the layout, and the current window titles, respectively. If you have specified any extra loggers in `ppExtras`, their output will also be appended to the list. To get them in the reverse order, you can just use `ppOrder = reverse`. If you don't want to display the current layout, you could use something like `ppOrder = \(ws:_:t:_) -> [ws,t]`, and so on. ppSort :: X ([WindowSpace] -> [WindowSpace]) how to sort the workspaces. See XMonad.Util.WorkspaceCompare for some useful sorts. ppExtras :: [X (Maybe String)] loggers for generating extra information such as time and date, system load, battery status, and so on. See XMonad.Util.Loggers for examples, or create your own! ppOutput :: String -> IO () applied to the entire formatted string in order to output it. Can be used to specify an alternative output method (e.g. write to a pipe instead of stdout), and/or to perform some last-minute formatting. Note that this is only used by `dynamicLogWithPP`; it won't work with `dynamicLogString` or XMonad.Hooks.StatusBar. ppPrinters :: WSPP extend workspace types with custom predicates. Check $predicates for more details.

#### Instances

Instances details

Default PP # | The default pretty printing options:
    1 2 [3] 4 7 : full : title
That is, the currently populated workspaces, the current workspace layout, and the title of the focused window.
Instance details Defined in XMonad.Hooks.StatusBar.PP Methods def :: PP #

def :: Default a => a #

The default value for this type.

# Example formatters

dzenPP :: PP #

Settings to emulate dwm's statusbar, dzen only.

xmobarPP :: PP #

Some nice xmobar defaults.

sjanssenPP :: PP #

The options that sjanssen likes to use with xmobar, as an example. Note the use of `xmobarColor` and the record update on `def`.

byorgeyPP :: PP #

The options that byorgey likes to use with dzen, as another example.

# Formatting utilities

wrap #

Arguments

:: String | left delimiter
-> String | right delimiter
-> String | output string
-> String |

Wrap a string in delimiters, unless it is empty.

pad :: String -> String #

Pad a string with a leading and trailing space.

trim :: String -> String #

Trim leading and trailing whitespace from a string.

shorten :: Int -> String -> String #

Limit a string to a certain length, adding "..." if truncated.

shorten' :: String -> Int -> String -> String #

Limit a string to a certain length, adding `end` if truncated.

shortenLeft :: Int -> String -> String #

Like `shorten`, but truncate from the left instead of right.

shortenLeft' :: String -> Int -> String -> String #

Like `shorten'`, but truncate from the left instead of right.

xmobarColor #

Arguments

:: String | foreground color: a color name, or #rrggbb format
-> String | background color
-> String | output string
-> String |

Use xmobar escape codes to output a string with given foreground and background colors.

xmobarAction #

Arguments

:: String | Command. Use of backticks (`) will cause a parse error.
-> String | Buttons 1-5, such as "145". Other characters will cause a parse error.
-> String | Displayed/wrapped text.
-> String |

Encapsulate text with an action. The text will be displayed, and the action executed when the displayed text is clicked. Illegal input is not filtered, allowing xmobar to display any parse errors. Uses xmobar's new syntax wherein the command is surrounded by backticks.

xmobarBorder #

Arguments

:: String | Border type. Possible values: VBoth, HBoth, Full, Top, Bottom, Left or Right
-> String | color: a color name, or #rrggbb format
-> Int | width in pixels
-> String | output string
-> String |

Use xmobar box to add a border to an arbitrary string.

xmobarRaw :: String -> String #

Encapsulate arbitrary text for display only, i.e. untrusted content if wrapped (perhaps from window titles) will be displayed only, with all tags ignored. Introduced in xmobar 0.21; see their documentation. Be careful not to shorten the result.

xmobarStrip :: String -> String #

Strip xmobar markup, specifically the <fc>, <icon> and <action> tags and the matching tags like </fc>.

xmobarStripTags #

Arguments

:: [String] | tags
-> String |
-> String | with all <tag>...</tag> removed

dzenColor #

Arguments

:: String | foreground color: a color name, or #rrggbb format
-> String | background color
-> String | output string
-> String |

Use dzen escape codes to output a string with given foreground and background colors.

dzenEscape :: String -> String #

Escape any dzen metacharacters.

dzenStrip :: String -> String #

Strip dzen formatting or commands.

filterOutWsPP :: [WorkspaceId] -> PP -> PP #

Transforms a pretty-printer into one not displaying the given workspaces.

For example, filtering out the `NSP` workspace before giving the `PP` to `dynamicLogWithPP`:

    logHook = dynamicLogWithPP . filterOutWsPP [scratchpadWorkspaceTag] $ def

Here is another example, when using XMonad.Layout.IndependentScreens. If you have handles `hLeft` and `hRight` for bars on the left and right screens, respectively, and `pp` is a pretty-printer function that takes a handle, you could write

    logHook = let log screen handle = dynamicLogWithPP . filterOutWsPP [scratchpadWorkspaceTag] . marshallPP screen . pp $ handle
              in log 0 hLeft >> log 1 hRight

# Internal formatting functions

pprWindowSet :: WorkspaceSort -> [Window] -> PP -> WindowSet -> String #

Format the workspace information, given a workspace sorting function, a list of urgent windows, a pretty-printer format, and the current WindowSet.

pprWindowSetXinerama :: WindowSet -> String #