From ArchWiki
Revision as of 15:42, 10 April 2011 by Ledti (talk | contribs) (Added a Tips section.)
Jump to: navigation, search

Automatic transparency

The simple approach

I happened across this page and found the method described to be horribly overcomplicated. I've left it here since I'm not really sure what to do with it, but here's what I did:

install transset-df and xcompmgr:

pacman -S transset-df xcompmgr

Add the following line to your ~/.bashrc :

[ -n "$WINDOWID" ] && transset-df -i $WINDOWID >/dev/null

now, each time you launch a shell in an xterm, if xcompmgr is running, it will become transparent. xterm sets the WINDOWID environment variable to its own window id, so we can use this to find the window we want to make transparent. the test in front of the transset-df command keeps it from executing if that variable is not defined. note that your terminal will not be transparent if you launch a program other than the shell this way. to me this isn't a big deal, since I essentially never do that. It's probably possible to work around this if you want the functionality.

The old way

This is the way I found described here, it seems overcomplicated to me.

Pacman -S transset-df xcompmgr. Add "xcompmgr &" to .xinitrc, or use another compositing manager. Then add this to openbox's rc.xml(inside chosen keybind/mousebind of course):

<action name="execute">
<execute>sh -c 'xterm &amp; sleep .8s &amp;&amp; transset-df -a'</execute>

Try this command in terminal

xterm & sleep .8s && transset-df -a

Using openbox, it is as yet impossible to automatically apply transparency to a window as it opens. This is a way of automatically applying tranparency to an opening xterm using transset-df. It uses a trick of running a script as you start the xterm which then runs another script which calls transset-df. The reason that it is so complicated, is that to run transet-df on the new xterm window as it opens, we need the XWINDOWID value for the window.

The three steps which happen to run transset-df on an opening xterm are:

  • Start xterm
  • Run a script which executes a command, then starts a bash shell
    • (This step is necessary because when you open an xterm with 'xterm -e' the command is executed and then the xterm closes. This is not what we want.)
  • Run a script which finds the XWINDOWID of the current xterm and passes it to transset-df to set the transparency

Making it work

Make a script in (for instance) /usr/local/bin called pre-exec. Make sure you have execute permission for everyone. The script is:

exec /bin/bash

Make a script in (for instance) /usr/local/bin called fader. Make sure you have execute permission for everyone. The script is:

transset-df -i "$WINDOWID" $1 >/dev/null 2>&1

When you want an xterm to open with a transparency level of 70%, call:

xterm -geom 80x50 -T xterm -e /usr/local/bin/pre-exec /usr/local/bin/fader 0.7 &

I have put this line in my .config/openbox/menu.xml file so I always get a transparent xterm.


How this doesn't work

There is some discussion on how to get the correct process id for a launched program. When a shell (in this case gnu bash) is running, it's process id (PID) is found by:

echo $$

The last process put into the background (like xterm&) is found by:

echo $!

So, you think - why all this trouble to get the PID of an xterm? Surely you can simply get the PID by doing:

xterm & ; echo $!

And if you do this at the command line, then this works. You get the PID of the xterm and you can then find the XWINDOWID of the xterm to pass to transset-df. All is well. But who is running xterm when you start it from a menu? The answer is not obvious. If you try to use the $! that is valid in the menu scope, you turn the previous xterm transparent, not the one you just started.

How this works

The pre-exec script does two things:

  • run the commands passed to it in the xterm's bash shell
  • start a new bash shell

The magic comes from


which just passes everything on the command line of the script (pre-exec) to the shell which is started because you used the -e directive. If this was all that happened, then the xterm would immediately exit. But we start a new interactive shell


which takes control so there is still an interactive prompt alive in the xterm.

That is quite clever, because it leaves a gap between when the xterm is started with an active shell and when the interactive shell is started up. In that gap, you can run anything you want that needs the same environment as the later interactive shell, but which needs doing before the interactive shell starts. (NB this is a lot like putting something in a .profile or .bashrc file, which will be executed before the interactive prompt when you start a bash shell.)

When the xterm starts its bash shell to execute the pre-exec script, the automatic environment initialization sets variables like XWINDOWID. The fader script looks up the XWINDOWID and passes it to transset-df along with the command line argument for the transparency. This command finishes, the new bash shell is started and the shell started by -e exits, leaving you at a bash prompt.


Tried to find the source links for my working on this and they have gone away. Thanks and qudos to all those whose work I've leeched to get this working!

Problems with this approach

Your new transparent xterm is called pre-exec. This can be changed - someone let us all know how :) [edit] Use '-T xterm' on the command line to keep the window called 'xterm'.

See Also


Xterm menu

Xterm has a hidden menu that can be viewed by holding the Control key and pressing the first mouse button (left click) on the XTerm window.

Enable bell urgency

Add the following line to your .Xdefaults or .Xresources file:

xterm*bellIsUrgent: true

Remove black border

Xterm has a black border in some cases, you can disable this by adding the following line to your .Xdefaults or .Xresources file.

xterm*borderWidth: 0

My ALT key doesn't work correctly

You can fix this on a per term basis by enabling the Meta Sends Escape option in the Xterm menu, or for all Xterm terminals by adding the following line to your .Xdefaults or .Xresources file.

xterm*metaSendsEscape: true