Fluxbox

From Gentoo Linux Wiki

Jump to: navigation, search

Window managers TOC

Back to X.Org

Gentoo.png
Gentoo has an official article on:


Fluxbox is a window manager for X, based on Blackbox. It is extremely fast and customizable through configuration files. Although when you first emerge it may appear too simplistic, this article will show you how to reconfigure Fluxbox and add extra eye candy and functionality.

Contents

[edit] Installation

Before you emerge Fluxbox, you'll want to be sure you know which USE flags you would like to have enabled or disabled.

[edit] USE Flags

Existing USE flags for Fluxbox are.

  • gnome Support Gnome Window Manager Hints.
  • imlib Use media-libs/imlib2 for image loading and rendering.
  • kde KDE Dockapp support, allows KDE applications to work with the Fluxbox systemtray.
  • nls Native Language Support is required for any language other than English.
  • truetype FreeType font rendering.
  • xinerama Support for multi-headed X, for those who have two or more monitors.

[edit] Emerge

When you set what USE-flags you want, emerge fluxbox,

emerge -av fluxbox

[edit] Configuration

[edit] Xsession

If you are using a log-in manager such as GDM, you should be able to select Fluxbox from the appropriate menu. If you want to use the default XDM that comes with X.Org, edit /etc/rc.conf and change the line that reads XSESSION="Xsession" to XSESSION="fluxbox".

If you don't plan on using a graphical login manager then you can configure the global /etc/X11/xinit/xinitrc or the per-user ~/.xinitrc file to run it via startx. See Xsession for further instruction.

[edit] Basic Usage

Starting up other applications when you log in to Fluxbox is handled by the ~/.fluxbox/startup file, which will be covered later in this article.

When you first start Fluxbox, you should see a blank background and a little toolbar at the bottom. The interface is fairly intuitive. Right-clicking on the background pops up the Fluxbox menu. The toolbar works as expected, showing the icons of every open window. The screen is divided into four workspaces by default, in a similar way to KDE. This means that applications that are open in one workspace won't show up on the other ones. You can also move applications through workspaces by selecting Send To... in their right-click menus, or by dragging the window to the edge of the screen.

Now that you have a working Fluxbox installation, you will first want to customize the functionality to your needs and work habits. Let's check the files in the ~/.fluxbox directory.

  • init: Main configuration file.
  • menu: File that changes the items in your root menu.
  • keys: Lets you change keybindings and create new ones.
  • apps: Stores information about every application that you want Fluxbox to remember, such as default position, size and decoration.
  • lastwallpaper: Created by fbsetbg, more on that later, this file stores the information about the last wallpaper you used so that you don't have to specify its location again.

[edit] Unicode Support

If you have your system configured to use Unicode, you might want Fluxbox to use Unicode, too. Fluxbox comes with some styles most of which are selecting fonts that are not fully suitable for Unicode. To fix this you will have to edit the style in /usr/share/fluxbox/styles/$YourStyle, where $YourStyle is the style you wish to fix, and add:

File: /usr/share/fluxbox/styles/$YourStyle
...
window.font:                         -*-*-*-*-*-*-*-*-*-*-*-*-*-u
...

Another solution is to set the locale in ~/.xinitrc. For example, let's say you use English most of the time -- afterall, you are reading this article in English, so.... -- you will want to write this in your ~/.xinitrc:

File: ~/.xinitrc
...
export LANG="en_EN.UTF-8"
export LC_ALL="en_EN.UTF-8"
...

All window titles will then be in Unicode UTF-8 format and your locale will be English. Obviously, you will want to set this to your appropriate country or native tongue. UTF-8 shows to the system which encoding you'll be using by default so you want Unicode you will get Unicode. You may want to add same two lines to ~/.bash_profile. If you have not configured it yet, go to Gentoo Handbook and Gentoo Localization Guide to read about locales.

[edit] Generating Menus

[edit] fluxbox-generate_menu

To keep your menu up to date after merging or unmerging applications, use the menu generator that comes with Fluxbox, simply run it like so:

fluxbox-generate_menu -ds -is

It will search for the applications installed and create a new ~/.fluxbox/menu file. As some applications are still missing in this script you may add them editing /usr/bin/fluxbox-generate_menu (as root).

Also it will install a ~/.fluxbox/menuconfig which you can customize to your liking, for example, to add GNOME or KDE support or to change the default browser or terminal. To enable easy customizing of the menu, fluxbox-generate_menu looks in ~/.fluxbox/usermenu for settings that will appear in a user submenu. The location can be changed by running fluxbox-generate_menu with the "-u <path>" option.

[edit] Menu Maker

Menu Maker is a program meant to integrate the menus of different window managers, in such a way to keep it consistant between them. Since it isn't part of Fluxbox, you must emerge it to run it:

emerge -va menumaker

Once that has finished, you can run it with the following command:

mmaker -v fluxbox

Note that it adds a lot of items to your menu.

[edit] Denu

Denu (x11-misc/denu) is a GUI menu editor for many window managers, including Fluxbox, complete with icons. To install, run:

emerge -av denu

See Denu at Sourceforge.

[edit] Autostart

Edit ~/.fluxbox/startup and add the names of each application that you want to start with Fluxbox on their own lines. If it is an application that runs continuously, be sure to put an ampersand (&) at the end of the command. This is the case for most commands, and it won't hurt anything if you include the ampersand for a command/program that doesn't run continuously. For example:

File: ~/.fluxbox/startup
unclutter -idle 2 &
wmnd &
wmsmixer -w &
idesk &
urxvtd &

[edit] The Desktop

[edit] Setting the Wallpaper

Fbsetbg comes standard with Fluxbox and is a clever wrapper script to set the background using any installed application which supports it, such as xsri, feh, eterm and xv. Not all of these applications support Pseudo-Transparency. feh is a popular choice as it is small, fast and supports transparency. So to start, install feh:

emerge -av feh

Then, to make sure that fbsetbg knows that feh is what you plan on using, run:

fbsetbg -i

It should say, "feh is a nice wallpapersetter. You won't have any problems." If this is the case, then you can go on to set the background. If it says you are using some other application, then run this command to set feh as your setter:

fbsetbg -u feh

This command will set a JPEG image as a fullscreen background:

fbsetbg -f /path/to/image.jpeg

This command will set a random image as a fullscreen background:

fbsetbg -r /path/to/images/directory/

This command will set the background to whichever image you last used. If the last time your ran fbsetbg was with the random option, it will select a random image from the same directory as the image last used.

fbsetbg -l

You can make this happen every time you start Fluxbox by adding the command to the ~/.fluxbox/startup file. You can also use the simplified command fbsetbg -l to load the last wallpaper loaded by fbsetbg, to avoid changing the init file each time you change your wallpaper.

File: .fluxbox/startup
...
# You can set your favourite wallpaper here if you don't want
# to do it from your style.

# Set the defined image to be a fullscreen, stretched, wallpaper
fbsetbg -f /path/to/image/wallpaper.png

# Set the wallpaper to that of the last used
# Will be random if the last time you ran fbsetbg was with the random switch
fbsetbg -l

# Set a solid color as your wallpaper
fbsetroot -solid black

# Set a random image as your wallpaper
fbsetbg -R /path/to/images/directory/
....

[edit] Set the Wallpaper Through the Menu

Another neat thing you can do with feh is to use it with Fluxbox's wallpaper menu option. This option gives you a wallpaper list off your Fluxbox menu, and is implemented as such:

File: ~/.fluxbox/menu
[submenu] (Wallpaper)
    [wallpapers] (/path/to/wallpaper) {feh --bg-scale}
[end]

You can use whhichever commandline option(s) you wish with feh.

[edit] Setting Wallpaper Using Overlay File

In addition to the style file, the overlay file, whose location is specified by session.screen0.styleOverlay (default: ~/.fluxbox/overlay) can be used to set style resources that override all styles. For more information about which parts of Fluxbox can be controlled by the overlay file, see man fluxstyle.

Every style must specify the background option. If you don't want your style to change the user's background, then use background: none.

The options centered, aspect, tiled, and fullscreen require the background.pixmap resource to contain a valid file name. The random option requires background.pixmap to contain a valid directory name. For these options, Fluxbox will call fbsetbg to set the background.

The options gradient, solid, and mod all require background.color to be set. Additionally, gradient and mod both require background.colorTo. Furthermore, mod requires background.modX and background.modY to be set as well. These options will be passed to fbsetroot to set the background.

File: ~/.fluxbox/overlay
background: centered|aspect|tiled|fullscreen|random|solid|gradient <texture>|mod|none
background.pixmap: <file or directory>
background.color: <color>
background.colorTo: <color>
background.modX: <integer>
background.modY: <integer>

In a simple way, you can write in your overlay file something like this:

File: ~/.fluxbox/overlay
background: random
background.pixmap: /path/to/backgrounds/directory

So, Fluxbox will chose a random wallpaper from /path/to/backgrounds/directory for you on startup.

[edit] Icons Using Idesk

Idesk is a nice program for creating clickable, themeable icons on the desktop. You can use PNG or SVG images as icons and several premade icon packs are available.

To start, we should install idesk:

emerge -av idesk

Now create a file in your home directory called ~/.ideskrc and add the following content:

File: ~/.ideskrc
table Config
FontName: verdana
FontSize: 12
FontColor: #ffffff
Locked: false
Transparency: 100
Shadow: true
ShadowColor: #000000
ShadowX: 1
ShadowY: 2
Bold: false
ClickDelay: 300
IconSnap: true
SnapWidth: 55
SnapHeight: 100
SnapOrigin: BottomLeft
SnapShadow: true
SnapShadowTrans: 200
CaptionOnHover: false
end

table Actions
Lock: control right doubleClk
Reload: middle doubleClk
Drag: left hold
EndDrag: left singleClk
Execute[0]: left doubleClk
Execute[1]: right doubleClk
end

Now create a directory called ~/.idesktop/ also in your home directory. This is where you will be storing the icons you want to use along with info on what the icons do. Make one file for each icon you want, for example, for the HOME icon, we would create a home.lnk:

File: home.lnk
table Icon
Caption: Home
Command: rox
Icon: /home/ikaro/.idesktop/home.png # the image to be used as an desktop icon
end

Do the same for the other icons you want.

Start idesk like this:

nohup idesk > /dev/null &

Make sure that you only run idesk once, and dont have multiple instances running at the same time. After you have your icons finished and where you want them in the desktop, change Locked from false to true in ~/.ideskrc. Add idesk to your ~/.fluxbox/startup or other startup script to run it automatically when you start X.

[edit] Toolkit Themes

For instructions on GTK+ and Qt theme control, see Toolkit Beautification.

[edit] Transparency

Fluxbox supports two kinds of transparency: pseudo-transparency, transparency for fakes; and true transparency, transparency for reals. See the examples to the right to compare the difference between the two.

Screen shot example of pseudo-transparency.

[edit] Pseudo-Transparency

As you can see from the example to the right, pseudo-transparency does not apply the alpha value to the entire window but only the title bars, and that the menu blends a copy of the wallpaper into the background of the menu. It does not actually blend in any objects that are behind the menu.

The good news, however, is that there is nothing that needs to be emerged in order to have pseudo-transparency. Also, any text within an object will not be made translucent or transparent, so text will remain opaque.

To set the default alpha values (translucency/transparency) -- so that when a new window is opened, it has the alpha values you want already applied -- you will need to set it via the Fluxbox menu. Right-click on the desktop to get the menu and go to Fluxbox menu -> Configure -> Transparency. You'll see on the first line Force Pseudo-Transparency. Check the box next to it to enable the transparency and adjust the values of Focused Window Alpha, Unfocused Window Alpha, and Menu Alpha by using either the wheel of your mouse or by left- and/or right-clicking. This will set the default alpha values for all windows and the menu itself. To adjust the alpha value of the toolbar, you will need to right-click on that to bring up its menu.

Screen shot example of true transparency.

[edit] True Transparency

From the the other example to the right you can see that the transparency effects do apply to the entire window, and that the menu does blend in any objects that are behind it. By default there are drop shadows as well.

True transparency requires xcompmgr to be emerged. Also, any text within an object will have the transparency effects applied to it, so text will not remain opaque. See the article Transparency for a tutorial on xcompmgr, but you may ignore the portions regarding transset because Fluxbox handles transparency natively, which is set in the same way as pseudo-transparency with one difference: leave Force Pseudo-Transparency unchecked.

[edit] Scripts

Warning: USE AT YOUR OWN RISK!

All scripts offered here, are offered as is. There is no warranty expressed or implied.

Fix me: Someone who knows Bash and Python should read these over and see if they're any good. Or if they can be improved, improve them please. Once done, remove this notice.

[edit] Portage Menu Generation

This script will allow you to emerge packages straight from your menu. This script may be slow to respond to your actions.

Code: gen-portage-menu.sh
#!/bin/sh

# from http://dev.gentoo.org/~solar/portage_misc/gen-portage-menu.sh.txt
# modified by joe@neoturbine.net to add -a option and sudo

OUTFILE=~/.fluxbox/portage_menu

source /etc/make.conf
source /sbin/functions.sh

if [ -e ${OUTFILE}.lock ]; then
        ewarn "Refusing to load another session for $$"
        exit 0
fi
touch ${OUTFILE}.lock
echo $$ > ${OUTFILE}.lock

[ -e "$PORTDIR" ] || PORTDIR=/usr/portage
cd ${PORTDIR}

TOTAL=0

echo \[begin\] \(Portage @TOTAL@\) > $OUTFILE
echo \[submenu\] \(Portage @TOTAL@\) >> $OUTFILE
find ${PORTDIR} -name '*[a-z]-[a-z]*' -type d -maxdepth 1 | while read line; do
        # [ -f /usr/bin/beep ] && beep -n 1 -r 1
        pushd $line > /dev/null
        count=$(find . -type d -maxdepth 1 | cut -c 3- | grep -v ^CVS$ | grep -v ^$ |wc -l | awk '{print $1}')
        category=$(basename $line)
        # [ -w /dev/speech ] && echo $category > /dev/speech &
        echo -ne '\t' >> $OUTFILE
        echo \[submenu\] \(${category}\) \{$count packages\} >> $OUTFILE

        find . -type d -maxdepth 1 | cut -c 3- | grep -v ^CVS$ | grep -v ^$ | while read dname ; do
                echo -ne '\t\t' >> $OUTFILE
                #/usr/lib/portage/bin/portageq has_version / $category/$dname
                ret=$?
                #if [ "$ret" == 0 ] ; then
                #       vname=$(basename $(/usr/lib/portage/bin/portageq best_version / $category/$dname))
                #else
                        vname=$dname
                #fi
                echo \[exec\] \($vname\) \{ xterm -rv -e \"sudo emerge -va $category/$dname \; bash --login\" \} >> $OUTFILE
                let ++TOTAL
        done
        echo -ne '\t' >> $OUTFILE
        echo \[end\] >> $OUTFILE
        popd $line > /dev/null

done
echo \[end\] >> $OUTFILE
echo \[end\] >> $OUTFILE
sed -e "s:@TOTAL@:${TOTAL}:g" < $OUTFILE > $OUTFILE~ && cp $OUTFILE~ $OUTFILE

[ -f /usr/bin/beep ] && beep -n 1 -r 5

rm ${OUTFILE}.lock

You can use this by adding [include] (~/.fluxbox/portage_menu) to ~/.fluxbox/menu if you make your own, or add it to ~/.fluxbox/usermenu if you use fluxbox-generate_menu


[edit] Show Processes

This script will include processes in your menu. This only useful if you're running Fluxbox as root, so the only menu this should be attached to is root's.

Code: fbprocmenu

#!/usr/bin/env python

#------------------------ process info script for Fluxbox menu ------------------

import sys, os
from os.path import isdir, isfile, join
from time import sleep
def getprocesses():
    """Sort out process ids from /proc"""
    proccontent = os.listdir("/proc")
    dirsonly = [d for d in proccontent if isdir(join("/proc", d))]
    proclist = [elem for elem in dirsonly if elem[0] in ['1', '2', '3', '4', '5', '6', '7', '8', '9']]
    proclist.sort()
    return proclist

def getprocinfo(procid):
    """Get info about an individual process."""
    procinfo = {}
    procpath = "/proc/%s/status" % procid
    statfile = open(procpath, 'r')
    procinfo["pid"] = procid
    for line in statfile:
        if "Name" in line:
            procinfo["Name"] = line.split(":")[1].strip()
        elif "State" in line:
            procinfo["State"] = line.split(":")[1].split(" ")[0].strip()
        else:
            break
    return procinfo

def makeprocdictlist(proclist):
    """Construct list of procinfo dictionaries"""
    #procdictlist = [getprocinfo(pid) for pid in proclist]
    procdictlist = map(getprocinfo, proclist) 
    return procdictlist

while True:
    procs = getprocesses()
    info = makeprocdictlist(procs)
    os.remove("/usr/share/commonbox/fbprocmenu.txt")
    try:
        outfile = open('/usr/share/commonbox/fbprocmenu.txt', 'w+')
        outfile.write('[begin]  (procinfo) {}\n')
        for elem in info:
            line = "[submenu]  ("+elem["Name"]+" "+elem["pid"]+" "+elem["State"]+") {}\n    [exec] (kill) {kill -9 "+elem["pid"]+"}\n   [exec]"\
                +" (restart) {kill -18 "+elem["pid"]+"}\n    [exec] (terminate) {kill -15 "+elem["pid"]+"}\n[end]\n"
            outfile.write(line)
        outfile.close()
        sleep(5)
    except IOError:
        print "Cannot create fbprocmenu file."

You can use this by adding [include] (/usr/share/commonbox/fbprocmenu.txt) to /root/.fluxbox/menu if you make your own, or add it to /root/.fluxbox/usermenu if you use fluxbox-generate_menu.

[edit] Gnome Menu Generation

This script will convert what gnome thinks the menu should be into Fluxbox syntax. It uses the output of gnome-menu-spec-test and some find/slocate commands to best guess the icons then prints the results to stdout. One can then redirect the output to a file of his or her choice and include it inside the main menu file.

Code: fluxbox-generate_gnome-menu.pl
#!/usr/bin/perl -w 
# fluxbox-generate_gnome_menu.pl
# 2008-06-17
#
# This script uses the output of gnome-menu-spec-test to make a similar menu
# for Fluxbox.  
#
# The format of that ouput is: "category/ app.desktop /path/to/app.desktop"
#
# Each *.desktop file includes many entries including, but not limited to,
# Categories, Name, Exec, Icon
#
# We'll loop through each item, read its .desktop, and create a hash of the
# appopriate data: submenu, name, exec, pixmap.
#
# The trouble for is resolving the Icon to an actual filename.  In most cases
# there are many files that could satisfy it or it is difficult to find the
# location of the icon at all.  In theory there's an xdg or gtk mechanism to
# discover the appropriate icon, but since I don't know it at the moment I'll
# either equery or slocate it.

use strict;

# declare some subs - see below for descriptions.
sub findIconPath($$$);

# A hash to store our new menu data in.
my %data;

# start looping through what gnome thinks the menu should look like
# NOTE: this does not include items from the System menu.
my @output = `gnome-menu-spec-test`;
foreach my $item (@output) {
	$item =~ /^(.+)\/\s+.+\.desktop\s+(\/.+\.desktop)$/;
	my $submenu = $1;
	my $file = $2;

	# open the .desktop file and put it in an array
	my $rc = open(FILE, '<', $file);
	if (!$rc) {
		print STDERR "Couldn't read from $file.\n";
		next;
	}
	my @file = <FILE>;
	
	# loop through the .desktop file's content and find the import fields
	my ($name, $exec, $icon);
	foreach my $line (@file) {
		if ($line =~ /^Name\s*=\s*(.*)/) {
			$name = $1;
		}
		elsif ($line =~ /^Exec\s*=\s*(.*)/) {
			$exec = $1;
		}
		elsif ($line =~ /^Icon\s*=\s*(.*)/) {
			$icon = $1;
		}
	}
	$data{$submenu}{$name}{'exec'} = $exec;
	$data{$submenu}{$name}{'icon'} = findIconPath($name, $exec, $icon);
	close(FILE);
}


# Now that we have a hash representing our new menu, loop through it and print
# it in Fluxbox syntax.
foreach my $submenu (sort(keys(%data))) {
	print "\t[submenu] ($submenu)\n";
	foreach my $name (sort(keys(%{$data{$submenu}}))) {
		my $temp = $name;
		$temp =~ s/(?!\\)(\))/\\$1/g;
		my $exec = $data{$submenu}{$name}{'exec'};
		my $icon = $data{$submenu}{$name}{'icon'};
		print "\t\t[exec] ($temp) {$exec} <$icon>\n";
	}
	print "\t[end]\n";
}

exit 0;

################################## END MAIN ###################################

# findIconPath($name, $exec, $icon)
# attempts to find an icon for the given application using equery and/or slocate.
# eventually this should use some xdg or gnome mechanism
# @param $name The name of the application.
# @param $exec The executable name.
# @param $icon The icon name (probably the same as name).
sub findIconPath($$$) {
	my ($name, $exec, $icon) = @_;
	
	# if the icon given is an actual path, just return it
	if ($icon =~ /^\// && -f $icon) {
		return $icon;
	}

	# TODO: lots of smart things to find an icon

	# check the default icon paths
	my $temp = "find /usr/{local,}/{kde/*/,}share/icons/{gnome,gentoo,hicolor} /usr/share/pixmaps -name '*$icon*' 2>/dev/null | egrep '\.(png|xpm|ico)\$' | tail -n1";
	#print $temp, "\n";
	$temp = `$temp`;
	if ($temp) {
		return trim($temp);
	}


	# TODO: do an equery search

	
	# use an slocate search
	$temp = "locate '$icon' 2>/dev/null | egrep '^/usr/(local/)?(kde/.*/)?share/(icons|pixmaps).*\.(xpm|png|ico)\$' | tail -n1";
	#print $temp, "\n";
	$temp = `$temp`;
	if ($temp) {
		return trim($temp);
	}

	return "";
}

sub trim {
	my ($str) = @_;
	$str =~ s/^\s*//;
	$str =~ s/\s*$//;
	return $str;
}

[edit] Active edges

Also known as Hot corners, active corners, or similar. In fluxbox, you don't have the possibility of binding actions to special mouse positions on the screen. For example you might want to switch Desktops, if your mouse hits the side of your screen (like in e17). However, there is a small python script, that you can use and modify depending on your needs. This script does not principally depend on fluxbox, you can use it in other Window managers as well. You can add this script to your .fluxbox/startup, so that the script is run in background and autostarts with fluxbox.

Code: active_edges.py
#! /usr/bin/env python

# script uses python-xlib, on gentoo simply emerge -va python-xlib
# needs session.screen0.allowRemoteActions set to true in your .fluxbox/init

from Xlib import display
from Xlib.ext.xtest import fake_input
from Xlib import X
import time
import os
	
check_intervall = 0.2
left_trigger = 0
right_trigger = display.Display().screen().width_in_pixels-1

disp = display.Display()
root=display.Display().screen().root
	
def mousemove(x, y):
	fake_input(disp, X.MotionNotify, x=x, y=y)
	disp.sync()
	
def mousepos():
	data = root.query_pointer()._data
	return data["root_x"], data["root_y"]

while True:
	time.sleep(check_intervall)
	pos = mousepos()
	if pos[0] == left_trigger:
		mousemove(right_trigger-1, pos[1])	
		os.system('fluxbox-remote PrevWorkspace')
	elif pos[0] == right_trigger:
		mousemove(left_trigger+1, pos[1])
		os.system('fluxbox-remote NextWorkspace')
Personal tools
In other languages