Xmonad toggle fullscreen / xmobar

21.6k views Asked by At

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?

5

There are 5 answers

2
kqr On BEST ANSWER

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.

0
AudioBubble On

You don't have to float your windows to make fullscreen work though.

Using fullscreen layout modifiers, you can have nice fullscreen capabilities, that for example allow switching to other windows (but still shows xmobar).

I wrote a small layout modifier on top of Layout.Fullscreen that uses SetStruts (from Hooks.ManageDocks) to hide/show the bar when windows go fullscreen :

{-# LANGUAGE DeriveDataTypeable, MultiParamTypeClasses, FlexibleInstances, TypeSynonymInstances #-}
import XMonad
import qualified XMonad.Layout.Fullscreen as FS
import XMonad.Hooks.ManageDocks (SetStruts(..))
import XMonad.Layout.LayoutModifier (LayoutModifier(..), ModifiedLayout(..))
import Data.List (delete, nub)

fullscreenToggleStruts = ModifiedLayout $ FullscreenToggleStruts []
data FullscreenToggleStruts a = FullscreenToggleStruts [a]
     deriving (Read, Show)
instance LayoutModifier FullscreenToggleStruts Window where
    handleMess ff@(FullscreenToggleStruts fulls) m = case fromMessage m of
        Just (FS.AddFullscreen win) -> setStruts $ nub $ win:fulls
        Just (FS.RemoveFullscreen win) -> setStruts $ delete win fulls
        Just FS.FullscreenChanged -> return $ Just ff
        _ -> return Nothing
        where setStruts f = do
                let m = if null f
                        then SetStruts [minBound .. maxBound] []
                        else SetStruts [] [minBound .. maxBound]
                sendMessage m
                return $ Just $ FullscreenToggleStruts f

Use it like this for example:

layoutHook = fullscreenToggleStruts $ FS.fullscreenFocus $ avoidStruts $ layoutHook'

It even works well with multiple monitors !

See my github for my xmonad+xmobar config

3
Tarmil On

This is what I have in my config (reformatted a bit to look more like yours):

main = do
    config <- statusBar "xmobar" myPP toggleXMobarKey myConfig
    xmonad config

myPP = xmobarPP { -- your PP customizations...
                  ppOutput = hPutStrLn xmproc
                , ppTitle = xmobarColor "green" "" . shorten 50
                }

toggleXMobarKey XConfig { XMonad.modMask = modMask } = (modMask, xK_b)

myConfig = defaultConfig { -- put your config here...
                           -- not including your logHook
                         }
0
sabauma On

I think I got this from one of the default configurations I found somewhere. Mine watches for full screen windows and then sets the to full screen using a management hook.

myManageHook = composeAll
    [ className =? "Firefox"        --> doShift (head myWorkspaces)
    , className =? "banshee"        --> doShift (last myWorkspaces)
    , resource  =? "desktop_window" --> doIgnore
    , isFullscreen                  --> doFullFloat ] -- this one

Then it just adds that to the list of hooks.

allHooks = [manageDocks, myManageHook, manageHook defaultConfig, manageSpawn]

Finally, compose the all the hooks together

defaults xmproc = defaultConfig
   { -- Simple Stuff
     terminal           = myTerminal
   , focusFollowsMouse  = myFocusFollowsMouse
   , borderWidth        = myBorderWidth
   , modMask            = myModMask
     -- numlockMask        = myNumlockMask,
   , workspaces         = myWorkspaces
   , normalBorderColor  = myNormalBorderColor
   , focusedBorderColor = myFocusedBorderColor

     -- key bindings
   , keys               = myKeys
   , mouseBindings      = myMouseBindings
     -- hooks, layouts
   , layoutHook         = myLayout
   , manageHook         = foldr1 (<+>) allHooks -- Right here
   , logHook            = myLogHook xmproc
   , startupHook        = myStartupHook
   }

This is not the most minimal example of how to do it, but I just copied and pasted it from my config.

2
Gauthier On

Try setting lowerOnStart = True in you .xmobarrc, have avoidStruts (you have it already), and a keyboard shortcut to toggle struts, for example:

((mod4Mask .|. shiftMask, xK_f), sendMessage ToggleStruts)