haskellxmonadxmobar

Xmonad toggle fullscreen / xmobar


Given my limited (zero) knowledge with Haskell the xmonad.hs can be challenging.

I am looking for how to modify my config file to allow for "true" fullscreen using for example VLC watching videos.

My current xmonad.hs:

    import XMonad
    import XMonad.Hooks.DynamicLog
    import XMonad.Hooks.ManageDocks
    import XMonad.Util.Run(spawnPipe)
    import XMonad.Util.EZConfig(additionalKeys)
    import Graphics.X11.ExtraTypes.XF86
    import System.IO

main = do
    xmproc <- spawnPipe "xmobar /home/user/.xmobarrc"
    xmonad $ defaultConfig
        { terminal = "urxvt",
          manageHook = manageDocks <+> manageHook defaultConfig
        , layoutHook = avoidStruts  $  layoutHook defaultConfig
        , logHook = dynamicLogWithPP xmobarPP
                        { ppOutput = hPutStrLn xmproc
                        , ppTitle = xmobarColor "green" "" . shorten 50
                        }
        } `additionalKeys`
                [ ((0 , xF86XK_AudioLowerVolume), spawn "amixer set Master on && amixer set Headphone on && amixer set Master 2-"),
                  ((0 , xF86XK_AudioRaiseVolume), spawn "amixer set Master on && amixer set Headphone on && amixer set Master 2+"),
                  ((0 , xF86XK_AudioMute), spawn "amixer set Master toggle && amixer set Headphone toggle")
                ]

Currently my xmobar is visible when watching videos as well I have a red border on the window which displays the video.

How can I modify this config to allow for example to have a Mod-b to toggle between fullscreen mode and normal?


Solution

  • While I'm not at all sure about this, I think that your problem arises when you try to fullscreen a tiled window. The line in your config that says

    manageHook = manageDocks <+> ...
    

    tells xmonad that you don't want your tiled windows to overlap xmobar. So xmonad tries to obey this even for fullscreened windows when they are tiled. So there are three parts to the solution:

    1. You can float your windows before fullscreening them. This is usually accomplished by holding down the modkey and left clicking on the window once. When you have floated the window, it can cover all other windows, including xmobar. So if you then try to fullscreen the window, it should cover the entire screen.

    2. You can tell xmonad to float VLC by default. This is built-in behaviour for mplayer, but apparently not for VLC. You do this by changing your config to say

      manageHook = manageDocks <+> (className =? "Vlc" --> doFloat) <+> manageHook defaultConfig
      

      The "manage hook" is the thing that decides how windows are supposed to appear. The <+> thing combines options for the manage hook. The bit that says

      (className =? "Vlc" --> doFloat)
      

      just means that "if the window is a VLC window, make it floating by default."

    3. A third, very viable, option is to download the xmonad-contrib package, which contains the XMonad.Hooks.ManageHelpers module. This module contains a lot of clever helper functions for customsing how xmonad is supposed to handle your windows. For example, with it, you can add a rule that says

      (isFullscreen --> doFullFloat)
      

      which means "if the window is trying to be fullscreen, automatically float it and make it cover the entire screen" – this is just the effect you want. You add this to your manage hook in just the same way as the class name thing:

      manageHook = manageDocks <+> (isFullscreen --> doFullFloat) <+> manageHook defaultConfig
      

      and then VLC should behave properly when you fullscreen it regardless of whether you have it floated or not!


    As a small tip: When you start getting a lot of different options in your manage hooks and you get tired of combining them with <+>, you can alternatively write the thing as

    manageHook = composeAll [
        manageDocks,
        isFullscreen --> doFullFloat,
        className =? "Vlc" --> doFloat,
        manageHook defaultConfig
      ]
    

    This composeAll will automatically combine every item in the list with the <+> operator.

    Please ask if there is some bit of configuring that you are unsure what it means. I bet a lot of people here are glad to try to translate the Haskell code to a human language. I know how frustrating it is to have to just wildly copy and paste configuration without really knowing how it works. (And it's just recently that I started to learn how xmonad configuration works, and it's a beauty.)


    Edit: About your window borders on full screened windows. There is a module XMonad.Layout.NoBorders that provides the neat function smartBorders, which modifies your layout hook so that it doesn't draw borders on windows that seem fullscreened. You can change your layout hook to use this function as well by changing the line in your config to

    layoutHook = smartBorders . avoidStruts $ layoutHook defaultConfig
    

    The . thing combines several functions into one, in this case it will combine smartBorders with avoidStruts to give you the benefits of both. Then it will pass the default layout hook into both of them, to create your modified, better layout hook.

    I can unfortunately not test how well this works, since I am running XMonad without borders.