xmonad-contrib- Community-maintained extensions for xmonad
Copyright(c) 2020 Leon Kowarschick
LicenseBSD3-style (see LICENSE)
MaintainerLeon Kowarschick. <thereal.elkowar@gmail.com>
Safe HaskellSafe-Inferred



This module is a collection of random fixes, workarounds and other functions that rely on somewhat hacky implementations which may have unwanted side effects and/or are small enough to not warrant a separate module.

Import this module as qualified like so:

import qualified XMonad.Util.Hacks as Hacks

and then use the functions you want as described in their respective documentation.


Windowed fullscreen

Windowed fullscreen describes the behaviour in which XMonad, by default, does not automatically put windows that request being fullscreened into actual fullscreen, but keeps them constrained to their normal window dimensions, still rendering them in fullscreen.

With chromium based applications like Chrome, Discord and others this can cause issues, where the window does not correctly see the size of the window when displaying the fullscreen content, thus cutting off the window content.

This function works around that issue by forcing the window to recalculate their dimensions after initiating fullscreen, thus making chrome-based applications behave properly when in windowed fullscreen.

The following gif shows the behaviour of chrome (left) without this fix compared to firefox, which already behaves as expected by default:

Using this function, chrome will now behave as expected as well:

Usage: add to handleEventHook as follows:

handleEventHook = handleEventHook def <> Hacks.windowedFullscreenFixEventHook

windowedFullscreenFixEventHook :: Event -> X All Source #

Fixes fullscreen behaviour of chromium based apps by quickly applying and undoing a resize. This causes chromium to recalculate the fullscreen window dimensions to match the actual "windowed fullscreen" dimensions.

Java Hack

Some java Applications might not work with xmonad. A common workaround would be to set the environment variable _JAVA_AWT_WM_NONREPARENTING to 1. The function javaHack does exactly that. Example usage:

main = xmonad $ Hacks.javaHack (def {...})

javaHack :: XConfig l -> XConfig l Source #

Fixes Java applications that don't work well with xmonad, by setting _JAVA_AWT_WM_NONREPARENTING=1

Stacking trays (trayer) above panels (xmobar)

Placing trayer on top of xmobar is somewhat tricky:

  • they both should be lowered to the bottom of the stacking order to avoid overlapping fullscreen windows
  • the tray needs to be stacked on top of the panel regardless of which happens to start first

trayerAboveXmobarEventHook (and the more generic trayAbovePanelEventHook) is an event hook that ensures the latter: whenever the tray lowers itself to the bottom of the stack, it checks whether there are any panels above it and lowers these again.

To ensure the former, that is having both trayer and xmobar lower themselves, which is a necessary prerequisite for this event hook to trigger:

  • set lowerOnStart = True and overrideRedirect = True in ~/.xmobarrc
  • pass -l to trayer


handleEventHook = … <> Hacks.trayerAboveXmobarEventHook

trayerAboveXmobarEventHook :: Event -> X All Source #

Like trayAbovePanelEventHook, but specialised for trayer/xmobar.

trayAbovePanelEventHook Source #


:: Query Bool


-> Query Bool


-> Event -> X All

event hook

Whenever a tray window lowers itself to the bottom of the stack, look for any panels above it and lower these.

Inform xmobar when trays (e.g. trayer) change width

Communicating tray (e.g., trayer) resize events to xmobar so that padding space may be reserved on xmobar for the tray.

Basic Usage with trayer:

First, add the padding hook to your handleEventHook as follows:

main = xmonad $ def
{ ...
, handleEventHook = handleEventHook def
                 <> Hacks.trayerPaddingXmobarEventHook

Then, assuming the tray is placed on the right, update your xmobarrc as follows:

Config { ...
       , commands = [ ...
                    , Run XPropertyLog "_XMONAD_TRAYPAD", ... ]
       , template = " ... %_XMONAD_TRAYPAD%"

As an example of what happens in this basic usage, consider the case where trayer updates to a width of 53 pixels. The following property will appear on the root window:

_XMONAD_TRAYPAD(UTF8_STRING) = "<hspace=53/>"

trayerPaddingXmobarEventHook Source #


:: Event 
-> X All

event hook

A simple trayer/xmobar-specific event hook that watches for trayer window resize changes and updates the _XMONAD_TRAYPAD property with xmobar markup that leaves a gap for the trayer.

trayPaddingXmobarEventHook Source #


:: Query Bool

query to identify the tray window

-> String

xmonadPropLog' property to use

-> Event 
-> X All

resulting event hook

A generic version of trayerPaddingXmobarEventHook that allows the user to specify how to identify a tray window and the property to use with xmonadPropLog'. This is useful for other trays like stalonetray and also when space for more than one tray-like window needs to be reserved.

trayPaddingEventHook Source #


:: Query Bool

query to identify the tray window

-> (Int -> X ())

action to perform when tray width changes

-> Event 
-> X All

resulting event hook

A fully generic tray resize hook that invokes a callback whenever a tray-like window changes width.