Xterm

From ArchWiki
Revision as of 09:01, 26 May 2010 by MSchmarck (Talk | contribs) (Making it work: → Scripts should be Shell /bin/sh scripts)

Jump to: navigation, search


Introduction

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>
</action>

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:

#!/bin/sh
${*}
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:

#!/bin/sh
transset-df -i `set | grep WINDOWID | awk 'BEGIN { FS = "=" } ; { print $2 }'` $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.

Explanation

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

/bin/bash

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.

Links

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