I'd like every window to be transparent, I'm using xmonad and X11. I am not very familiar with any of Haskell, xmonad or X11.
How can I configure xmonad for that? I don't even know how to even get started.
To do that, you need an event hook that sets the opacity property on creation of new windows. This is what I'm using (requires xprop
to be on the path):
import XMonad
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
import Data.Monoid
import Data.Word
setTransparentHook :: Event -> X All
setTransparentHook ConfigureEvent{ev_event_type = createNotify, ev_window = id} = do
setOpacity id opacity
return (All True) where
opacityFloat = 0.9
opacity = floor $ fromIntegral (maxBound :: Word32) * opacityFloat
setOpacity id op = spawn $ "xprop -id " ++ show id ++ " -f _NET_WM_WINDOW_OPACITY 32c -set _NET_WM_WINDOW_OPACITY " ++ show op
setTransparentHook _ = return (All True)
main = xmonad $ def
{ handleEventHook = setTransparentHook <+> handleEventHook def }
Give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime.
In the spirit of this quote I'm describing my process of coming up with this. Note that I have very limited experience with all of Haskell, xmonad and X11.
The initial mindset was that I needed a script that sets the opacity on all windows (which turned out not to be exactly what I needed). I know that composite managers on linux do this kind of stuff (visual effects), so I check out the man page of compton (which I'm using) via man compton
.
Searching for "opacity", I see the --opacity-rule
flag, which mentions that compton-trans
is recommended for this instead, so I look at its source. Trying out the script in the command line to discover that I need the window ID to set its opacity, so I look up how to do that.
A solution was to use xwininfo
. You can list all the windows using xwininfo -tree -root
. I thought I needed to parse the output of that and was already looking up awk
tutorials.
Then I get the idea: "Wait, what if I just set the opacity on window creation? Xmonad is a window manager, it should definitely have the window ID!". So I look through xmonad's config options where I find the handleEventHook
property. By clicking on the types Event
and All
I find out which imports I need (Graphics.X11.Xlib.Extras
and Data.Monoid
).
Creating a skeleton for my event hook by coping the default:
import XMonad
import Graphics.X11.Xlib.Extras
import Data.Monoid
myEventHook :: Event -> X All
myEventHook _ = return (All True)
Now some Haskell knowledge is needed, I want to do something when Event
is a window creation event. Looking through the Event
docs and a bit of probing, I found out I need the ConfigureEvent
where ev_event_type
is createNotify
while ev_window
is the created window ID. To use createNotify
I also import Graphics.X11.Xlib
:
import XMonad
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
import Data.Monoid
myEventHook :: Event -> X All
myEventHook ConfigureEvent{ ev_event_type = createNotify, ev_window = id } = do
return (All True)
myEventHook _ = return (All True)
Now what do we actually want to do? We want to spawn a shell process with the compton-trans
command. There is the simple function spawn
used throughout xmonad:
myEventHook :: Event -> X All
myEventHook ConfigureEvent{ ev_event_type = createNotify, ev_window = id } = do
spawn $ "compton-trans -w " ++ show id ++ " 50"
return (All True)
myEventHook _ = return (All True)
It worked! That's great but I noticed it being a bit slow and it still has the compton dependency which isn't really needed. So I look at the compton-trans
source again, and see the last line that actually does the work which just uses xprop
! Now this is great because I don't need all the stuff of compton-trans
which does some checks and is optimized for user convenience. Using some number conversion I came up with the final version as shown above. It may even be faster to use the direct path to the executable.
I sometimes also used the ghci ~/.xmonad/xmonad.hs
to check some types and man xprop
/man whatever
to check the documentation.
I hope this helps fellow xmonads to getting started! If someone has some improvements, please let me know.