Fluxbox
From Gentoo Linux Wiki
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,
[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:
... 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:
... 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]
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:
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:
Once that has finished, you can run it with the following command:
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:
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:
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:
Then, to make sure that fbsetbg knows that feh is what you plan on using, run:
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:
This command will set a JPEG image as a fullscreen background:
This command will set a random image as a fullscreen background:
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.
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.
... # 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:
[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.
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:
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:
Now create a file in your home directory called ~/.ideskrc and add the following content:
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:
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:
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.
[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.
[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
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')
|
