New to xmonad/xmobar/haskell, trying to get the name of the current workspace to show up in xmobar. So far I have this xmonad.hs:

module Main where
  import XMonad
  import XMonad.Hooks.SetWMName
  import XMonad.Hooks.DynamicLog
  import XMonad.Actions.WorkspaceNames
  import XMonad.Util.EZConfig(additionalKeys)
  import XMonad.Prompt
  import XMonad.Util.EZConfig

  main = xmonad =<< xmobar myConfig

  myConfig = defaultConfig { startupHook = setWMName "LG3D" , logHook = myLogHook } `additionalKeys` [ ((mod4Mask, xK_r      ), renameWorkspace defaultXPConfig) ]

  myLogHook = workspaceNamesPP xmobarPP >>= dynamicLogString >>= xmonadPropLog

This seems to allow me to change the name of a workspace (at least a prompt with "Workspace name:" appears, and takes my input).

However, xmobar doesn't show the name.


You are mixing two different ways to send information to xmobar.

Here :

main = xmonad =<< xmobar myConfig

You are using the xmobar convenience function. You can click on the source link on the documentation to see how it is defined. It uses the statusBar function to launch xmobar with the default xmobarPP. The statusBar function uses spawnPipe to launch the status bar application, and modifies the PP to output to that pipe.

This is the bar you are seeing, with the default pretty printer and logger that only prints the workspaces tags. The XMonad.Actions.WorkspaceNames module you are using associates names with workspaces tags. It provides the workspaceNamesPP function that combines with a PP to retrieve the names.

And here :

myLogHook = workspaceNamesPP xmobarPP >>= dynamicLogString >>= xmonadPropLog

You are using the workspaceNamesPP function with xmobarPP, you pass the result to dynamicLogString that returns the status as a string, and you pass that string to xmonadPropLog that writes it as a _XMONAD_LOG property on the root window. This is a different way to communicate the information to xmobar, which can be configured to read that property. In that case, you don't have to launch xmobar from xmonad.

So you should decide which way you want to use.

You can for example keep launching xmobar from XMonad using spawnPipe, and have myLogHook write the status to a pipe that you pass to it :

import XMonad.Util.Run -- spawnPipe and associated functions

main = xmonad . myConfig =<< spawnPipe "xmobar"

myConfig pipe = defaultConfig { startupHook = setWMName "LG3D" , 
                                logHook = myLogHook pipe} 
                 [((mod4Mask, xK_r), renameWorkspace defaultXPConfig)]

myLogHook pipe = workspaceNamesPP xmobarPP {ppOutput = hPutStrLn pipe}
                   >>= dynamicLogWithPP

The statusBar function also modifies the manageHook and layoutHook to add the manageDocks and avoidStruts from the XMonad.Hooks.ManageDocks module to them. You should use this module so that the bar and windows don't step on each other. The manageDocks makes XMonad ignore the windows of type dock or desktop. The avoidStruts layout modifier changes the layouts to reserve space for the bars, according to their _NET_WM_STRUT_PARTIAL property.

manageHook layoutHook and handleEventHook are part of XConfig, so to add the function provided by the XMonad.Hooks.ManageDocks module :

 myConfig pipe = defaultConfig 
        startupHook = setWMName "LG3D" , 
        logHook = myLogHook pipe,
        manageHook = manageDocks <+> manageHook defaultConfig,
        layoutHook = avoidStruts $ layoutHook defaultConfig,
        handleEventHook = docksEventHook <+> handleEventHook defaultConfig
       } `additionalKeys` [((mod4Mask, xK_r), renameWorkspace defaultXPConfig) ]

The xmobar function you were using also binds the mod + B key shortcut to sendMessage ToggleStruts to toggle the bar gaps, so if you want that keybinding you should add it too.

Also :

import XMonad.Util.EZConfig(additionalKeys)
import XMonad.Util.EZConfig

You are importing additionalKeys from the XMonad.Util.EZConfig module, and then you are importing all of the XMonad.Util.EZConfig module.

  • Thanks! Nearly there. The only weird thing now is that the xmobar hides part of the screen (e.g. it hides the menu bar of gnome terminals) which was not happening before. – mitchus Jul 22 '15 at 14:49
  • Yes, that's because statusBar also added the manageDocks and avoidStruts functions from the XMonad.Hooks.ManageDocks module for you. Edited. – Leiaz Jul 22 '15 at 17:10
  • "You should use [XMonad.Hooks.ManageDocks] so that the bar and windows don't step on each other." -- trying to, but not sure how to add it to your example. – mitchus Jul 24 '15 at 8:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.