Quake like terminal with Fvwm

Friday, September 7th, 2007

 

Contents

 

Why

Well we already have many quake like terminals already:

But what if you don’t like loading the whole KDE libraries to get
this? Or, what if all those programs lacks some features you really
like, like a transparent background to your root window with a nice
tint color?

Today we’ll turn a general purpose terminal, like the Terminal
program for the Xfce project, or rxvt-unicode, to a quake like
terminal, with Fvwm.

I think I don’t need to give too much introduction to Fvwm: If you
are reading this, there is a good chance that you are already using
it :)

 

What do we want

First of all we’ll need to find out what do we want from a Quake like
terminal. Here’s the list:

In this article we’ll use the Terminal program as an example. And
we’ll set its title to ” quick_terminal”.

Ready? Let’s rock!

 

Accessible with a single key stroke

To make the quick terminal Accessible via a single key stroke, we’ll
need two things:

  1. If the terminal is not running, start one
  2. If the terminal is already running, make it at the right place and focus on it

Here’s the code:

DestroyFunc raise_or_fire_quick_terminal
AddToFunc raise_or_fire_quick_terminal
+ I None ("quick_terminal", CurrentDesk) Exec exec Terminal -T quick_terminal
+ I All ("quick_terminal", CurrentDesk) Iconify Off
+ I All ("quick_terminal", CurrentDesk) Resize 800p 600p
+ I All ("quick_terminal", CurrentDesk) Move 112p 85p
+ I All ("quick_terminal", CurrentDesk) Raise
+ I All ("quick_terminal", CurrentDesk) Focus
+ I Break

DestroyFunc hide_quick_terminal
AddToFunc hide_quick_terminal
+ I All ("quick_terminal") Iconify On
+ I Next Raise
+ I Break

DestroyFunc show_or_hide_quick_terminal
AddToFunc show_or_hide_quick_terminal
+ I ThisWindow ("quick_terminal") hide_quick_terminal
+ I ThisWindow (!"quick_terminal") raise_or_fire_quick_terminal
+ I NoWindow raise_or_fire_quick_terminal

We’ll explain this line by line.

The first two line is how we define functions: AddToFunc says to add
the following command to a function, with the function name following
it. If the function does not exists, then create one. The
DestroyFunc is a safe keeper: It removes any, if there is any,
functions with the same name. There’s no overload kind of thing in
Fvwm configure file. You may wonder why not just a “DefineFunc”. The
answer is that Fvwm configuration is really flexible: You can add
instructions to one function in different places.

Then we come to the line:

+ I None ("quick_terminal", CurrentDesk) Exec exec Terminal -T quick_terminal

There’s a lot to talk about if you are new to Fvwm configuration
files:

The + I at the beginning says the command in this line will be
invoked Immediately. This is what we need most of the time.

The None (”"quick_terminal”, CurrentDesk) follows is a condition
statement in Fvwm. It means “Run the following command when there’s
no window has the title “quick_terminal” in the current desk”. None
is the verb here, “when there is no… do…”. And the stuff between
the brackets are the conditions. We are going to make our terminal across
all the virtual desktops of Fvwm, so we add CurrentDest here, to be
more efficient: Fvwm won’t need to search all the desktops for this
title name now.

Then Exec exec Terminal -T quick_terminal. Exec is a general
command in the Unix world, and it means what you are thinking :) . We
use double Exec to make sure the following command returns
immediately. This is recommended in the Fvwm manual. And finally, the
command we want to run: Terminal -T quick_terminal. This starts a
Terminal instance with the title set to quick_terminal. You can
replace this with whatever terminal program you like, for example,
urxvt -T quake_terminal.

The following several lines are easy to understand:

+ I All ("quick_terminal", CurrentDesk) Iconify Off
+ I All ("quick_terminal", CurrentDesk) Resize 800p 600p
+ I All ("quick_terminal", CurrentDesk) Move 112p 85p
+ I All ("quick_terminal", CurrentDesk) Raise
+ I All ("quick_terminal", CurrentDesk) Focus
+ I Break

First we release our quick_terminal from Iconify status. So the window
is not minimized anymore. Then we Resize it and Move it to a location
we like. I’m assuming you are using a 1024×768 screen and this will
bring the terminal in the middle of your screen, with 800×600
pixels. The Raise command makes the terminal window appears on top
of all the other windows, and the Focus command will put the
keyboard focus to this window, so what we types next, will be
transferred to our quick_terminal. The final Break command is,
well, a break, like in any other programming languages. We’ll talk
more about this later.

The following hide_quick_terminal command is rather simple: We
first set the Iconify status of our quick_terminal on, so it
disappears and lost the keyboard focus. Then we use Next Raise to
set the keyboard focus to the window we are working on before calling
our quick terminal. Next here is another conditional command in
Fvwm. We don’t use any conditions (stuffs between brackets) here so
it just selects the next window in the stack.

The last function, show_or_hide_quick_terminal, calls the two
functions above in different conditions: ThisWindow is another
conditional command. It tests if the current windows matches the
conditions following. So the first two line of this function says: If
I’m working on a window named “quick_terminal”, call
hide_quick_terminal, else call raise_or_fire_quick_terminal. The
final NoWindow conditional command matches when we are not on any
window. This is useful when, for example, you just started Fvwm and
haven’t got any program running.

OK. We’ve got all these set. The final step would be, make our primary
function, show_or_hide_quick_terminal, be invoked with a simple
key stroke. We’ll use the F1 key, as an example:

Key F1 A N show_or_hide_quick_terminal

Here Key starts a key binding. F1 is the key we want. The
following A and N needs some explanation: A defines the context
of this key binding. That is, where this key binding is available? on
an application window? a root window? or the side bar (border) of a
window? We use A here so it’s available in all conditions. Then the
modifier N. If you want Ctrl-F1, Alt-F1, or Shift-F1 instead
of just F1, you can put C, A, or S here, accordingly. This
time we think the quick terminal is so useful that we just want an
F1, so we put a N here, which means “no modifier”".

And here’s why we add a Break statement at the end of the first two
functions: show_or_hide_quick_terminal is the function get
called. If we don’t add a break some where, all the three statements
in it will be called one by one. Say if we are on the quick_terminal
window. The first condition matches, and hide_quick_terminal get
called. And now we are at another window, and the second condition
matches, so raise_or_fire_quick_terminal get called too, and our
window re-appears. That’s definitely not what we want.

 

Available on all virtual desktops

This is easy with Fvwm:

Style "quick_terminal"           Sticky

Style is the Fvwm command controlling how a window
behaves. Following by the window name (title) and the
behavior. Sticky is the style this time. It means the window will
be available on all virtual desktops.

 

No Title, No border

Here is the code:

Style "quick_terminal" !Title, !Handles, !Borders
Style "quick_terminal" BorderWidth 0, HandleWidth 0

The first line makes the quick_terminal window has no title bar, no
handles, and no borders, as you can guess from the name. Handles is
the tiny triangle on the lower-right corner that you can drag to
resize the window. As we want a fixed width and height of this quick
window, and to make sure there’s no borders anyway, we turn this off
for our terminal.

The second line is a safe keeper, again. In case you have some
settings that turns on Handles and/or Borders for all the windows,
this will make the width zero.

 

Transparent background

This is really not a window manager’s work. Well, at least until
Compiz and Beryl comes out.

All I have to say is to choose a terminal emulator program that have
good transparent background support. There are a lot: Terminal,
rxvt-unicode, aterm, eterm, etc. I may talk about how to set your
background window to be compatible with these programs in a later
article.

 

Not shown on task-bar, task switch, or Alt-Tab

Fvwm uses the FvwmTaskBar module for the MS windows like “task
bar”. If you don’t like it and don’t use it, fine, nothing will appear
on the task bar, cause there is no task bar :)

If you are using task bar, here’s how to hide our terminal from it:

Style "quick_terminal"           WindowListSkip
*FvwmTaskBar UseSkipList

The first line add style WindowListSkip to our terminal. This
prevent the window from appearing in the menu that the WindowList
command created. This is the menu that most people bind to Alt-Tab.

And the second line, is a Fvwm option line for FvwmTaskBar. This
tells FvwmTaskBar not to show the window with a WindowListSkip style,
on the task bar.

With these two lines, our always available terminal won’t pollute our
window switching window and task bar.

 

And finally, nice animation

Hmmm, want to look cool? Let’s add some animation here :) We’ll make a
pull-down animation cause this is what all the other quake like
terminals have. And you’ll find out soon that Fvwm can do much more.

The Fvwm module that handles animation is FvwmAnimatie. To start it,
add the following line to your Fvwm configuration file:

Module FvwmAnimate

With this started, there is a good chance that you can find an
“animation” item on your “settings” menu. If not, go to your Fvwm
Console and issue the command:

Popup MenuFvwmAnimate

then the menu popups up, where you can choose the animation effects, line width,
delay times, etc. Because we haven’t turn animation on for our little
command when we make our terminal Accessible with a single key
stroke
, you can’t see the effect right now. Just make sure the
effect is Frame here.

Now we need to add two:

+ I SendToModule FvwmAnimate animate

statements to those two functions. This means “send an animate
command to the FvwmAnimate module”. And it takes 8 parameters: x1,
y1, w1, h1, x2, y2, w2, h2. The first four defines a rectangle where
the animation starts, and the last four defines a rectangle where the
animation ends.

For us, we need to add:

+ I SendToModule FvwmAnimate animate 112 300 800 0 112 300 800 600

before:

+ I All ("quick_terminal", CurrentDesk) Iconify Off

in function raise_or_fire_quick_terminal and:

+ I SendToModule FvwmAnimate animate 112 300 800 600 112 300 800 0

before:

+ I All ("quick_terminal") Iconify On

in function hide_quick_terminal.

Now we are all set. Restart your Fvwm and press F1. Do you see the
magic? Use your imagination here, for example, you can make a
rectangle rolls out from the upper left corner when you want the
terminal. And this, is left for you as an exercise :)

Tags: , , , , , , ,

Comments 7

  1. boyu wrote:

    [quote]Here’s the code:……[/quote]

    some code is outside the quota?

    Posted 04 Oct 2007 at 3:26 pm
  2. dryice wrote:

    boyu: Do you mean the “no title, no boarder” section? Frankly this is not exactly what I use in my config, (I turn title and boarder off for all the windows), but I think it should be good. Why are you thinking something is missing?

    Posted 17 Oct 2007 at 8:30 am
  3. Thomas Adam wrote:

    Interesting, save for the fact that:

    * You’re using “quotes” where they’re not needed.

    * You mean to use “Next” in place of “All”, seeing as you only ever start one instance of this thing.

    * You don’t need the “+ I break” statements at the end of the function; they’re useless in your context.

    * Your raise_or_fire_quake_terminal needs more thought, since with:

    + I None ("quick_terminal", CurrentDesk) Exec exec Terminal -T quick_terminal
    + I All ("quick_terminal", CurrentDesk) Iconify Off

    You’re placing assumptions about the speed, and order in which a function executes, It’s unlikely in this case, but a function is not always executed
    in the order you have your commands listed in (http://edulinux.homeunix.org/~n6tadam/fvwm/for_fhobia.txt). Also, you have numerous operands on the same window… hmm. How about this:

    DestroyFunc raise_or_fire_quick_terminal
    AddToFunc raise_or_fire_quick_terminal
    + I Any (quick_terminal, CurrentDesk) Break
    + I Exec exec Terminal -T quick_terminal
    + I Wait quick_terminal
    + I Next (quick_terminal) PositionIt

    DestroyFunc PositionIt
    AddToFunc   PositionIt
    + I ResizeMove 800p 600p 112p 85p
    + I Raise
    + I Focus

    There’s also no need to ignore the window context with “NoWindow” in this case. So you can remove that as well.

    Posted 22 Oct 2007 at 8:40 am
  4. dryice wrote:

    Hi Thomas,

    Thanks for the detailed comment! I added the “code” tag in your
    comment so it looks nicer. And I think I’ll join #fvwm someday :)

    - the “quotes”. Yes, you are right, they are not needed. It was
    something from Rest to HTML and then to WordPress. And I was too
    lazy to remove them :)

    - Yes. There supposed to be only one instance of quick_terminal,
    because it’s quick terminal :)

    - I still think the “break” is needed. I have some explanation in the
    blog. I saw you use “break” too. Moving it to the beginning of the
    function.

    - Thanks! The “wait” command is exactly what I need!

    - I still think the “NoWindow” is needed. It matches when the root
    window have the focus.

    Posted 24 Oct 2007 at 11:44 am
  5. Thomas Adam wrote:

    “- I still think the “break” is needed. I have some explanation in the blog. I saw you use “break” too. Moving it to the beginning of the
    function.”

    Yes, in the *middle* or *start* of a function, but not at the *end* as you have it. The way FVWM parses its functions is such that as soon as it reaches the end, it stops anyway. Adding a “+ I Break” right at the end of the function is meaningless — it was _going_ to end before you explicitly told it to.

    “- I still think the “NoWindow” is needed. It matches when the rootwindow have the focus.”

    It’s needed here because you’ve ballsed up your function by smacking a “+ i Next focus” command in there. Really, it’s not needed here, even with your supposed root-window excuse.

    Posted 24 Oct 2007 at 1:58 pm
  6. Voronin wrote:

    Douh! Send on email clear code plz!

    Posted 29 Jan 2010 at 5:58 am
  7. sipingal wrote:

    It’s recommended to append below line
    + I wait quick_terminal

    to:
    + I None (”quick_terminal”, CurrentDesk) Exec exec Terminal -T quick_terminal

    The terminal has not been fully started, but the resize command has already executed. So the first time the windows may not resized.

    Posted 04 Sep 2012 at 11:55 am

Post a Comment

You could use <code type="name"> to get your code colorized

Your email is never published nor shared. Required fields are marked *

Close
E-mail It