a .xinitrc to switch window managers on the fly
by jr_bob_dobbs from LinuxQuestions.org on (#6EK3Q)
First of all, I was just going to post this in the programming section of Linux Questions, since that is the obvious place for it. I'm obviously confused, because there isn't one, or I can't find it today. :p Because it involves running window managers in xorg, I guess this Deskstop section is the correct place? If this is in the wrong place, sorry. :o
Background
When I boot up any Linux distro on my computer, I log on in text mode and then, depending on what I am doing, when I am good & ready, I'll type startx to start xorg. If I want to switch to a different window manager, I exit back to the console, copy the corresponding file to be the new .xinitrc and then start the gui again.
I've always wanted to switch between window managers in such a way that I don't have to do that copying. Also I'd like for any running GUI programs to still run, interrupted by the switch. Imagine you're in blackbox and you've got gimp, xterm, a file manager and a browser running. You'd select a menu option and ... boink, you're in dwm. All the programs are still there, though their windows have been abruptly resized. You work for a bit, then, you hit some key combination and ... plink plink, you're in windowmaker, and the programs are still running.
This must be possible because in some distros I've seen blackbox with menu choices to switch to other window managers. The thing is, things like dock apps and tray things get kind of funny: multiple copies run, or get terminated and not restarted, that sort of thing. It only partially works.
The three main things to solve seem to be as follows.
One: a way, independent of window manager, to pick and switch to another window manager, while keeping everything running.
Two: a way to stop certain programs (dock apps, tool-tray things, etc.) that need to be stopped when exiting a specific window manager.
Three: a way to start certain programs whenever starting a specific window manager.
I eventually worked out a way to do this, based on an assumption: despite not having a "#!/bin/sh" as the first line, .xinitrc is actually a shell script. Turns out that assumption is correct. Now I can switch managers on the fly, with only having find and resize program windows.
Based on looping code from the sample .xinit code included in the treewm (window manager) package, my .xinitrc, when one exits a window manager, brings up a dialog box to select a window manager or to exit out of xorg entirely.
There is a subroutine for cleanup (killall on various known tool-tray and dockapp programs) after exiting any window manager, plus an entry subroutine for each window manager.
xmessage (It comes with xorg so it seems a reasonably portable choice) is used to bring up the file manager selection menu.
I've been using this for several weeks now, on two distros.
The Actual Question
There is just one strange bug: when one first runs startx, the xmessage dialog appears, but there is no cursor (pointer). After a delay, and some mouse-waving on my part, it appears. I've no idea why. Because of this, I've set a time out of 60 seconds, after which, if no button is pressed, it will exit out of xorg, back to the console. I hoping someone here can figure it out whatever I am overlooking.
Thank you.
My .xinit follows (note: yes I know I have a lot of per-wm hard-coding):
Code:#!/bin/bash
b4_wm_choice()
{
killall bbkeys > /dev/null 2>&1
killall bbkeys > /dev/null 2>&1
killall pnmixer > /dev/null 2>&1
killall pnmixer > /dev/null 2>&1
killall autocutsel > /dev/null 2>&1
killall autocutsel > /dev/null 2>&1
killall wmacpi > /dev/null 2>&1
killall wmacpi > /dev/null 2>&1
killall wmmoonclock > /dev/null 2>&1
killall wmmoonclock > /dev/null 2>&1
killall nm-applet > /dev/null 2>&1
killall nm-applet > /dev/null 2>&1
killall stalonetray > /dev/null 2>&1
killall stalonetray > /dev/null 2>&1
xrdb $HOME/.Xresources
xmodmap $HOME/.Xmodmap
}
after_all()
{
killall pulseaudio
killall gmplayer
killall gmplayer
killall worker
}
do_blackbox()
{
autocutsel 2>/dev/null > /dev/null &
bbkeys > /dev/null &
xrdb $HOME/.Xresources
xmodmap $HOME/.Xmodmap
(stalonetray --dockapp-mode simple -bg "#7f7f7f" -t false -p true \
--geometry 2x2 --kludges force_icons_size) &
( sleep 1 ; pnmixer ) &
( sleep 2 ; wmmoonclock -lat 39.173869 -lon 78.176356 ) &
( sleep 3 ; wmacpi -a 5 ) &
( sleep 4 ; xsetroot -xcf /usr/share/icons/Adwaita/cursors/left_ptr 36 ) &
( sleep 5 ; nm-applet ) &
blackbox
}
do_dwm()
{
autocutsel 2>/dev/null > /dev/null &
xrdb $HOME/.Xresources
xmodmap $HOME/.Xmodmap
( sleep 3 ; pnmixer ) &
( sleep 4 ; xsetroot -xcf /usr/share/icons/Adwaita/cursors/left_ptr 36 ) &
( sleep 5 ; nm-applet ) &
while true
do
LALDATE=`date +"%l:%M %P"`
SBTRY=`acpi -b`
xsetroot -name "[$SBTRY] [$LALDATE]"
sleep 19
done &
dwm
}
do_fvwm()
{
autocutsel 2>/dev/null > /dev/null &
xrdb $HOME/.Xresources
xmodmap $HOME/.Xmodmap
( sleep 2 ; pnmixer ) &
( sleep 5 ; xsetroot -xcf /usr/share/icons/Adwaita/cursors/left_ptr 36 ) &
( sleep 6 ; nm-applet ) &
fvwm
}
do_treewm()
{
~/.fehbg
xrdb $HOME/.Xresources
xmodmap $HOME/.Xmodmap
LANG=C treewm
}
gamma_fix 2>/dev/null > /dev/null
.fehbg
while true
do
b4_wm_choice
# pick Exit or a window manager
BLOORP=`xmessage 'Which Window Manager?' \
-buttons Blackbox,Dwm,Fvwm,Treewm,Exit -nearmouse -print -timeout 60`
case "$BLOORP" in
"Blackbox" )
do_blackbox
;;
"Dwm" )
do_dwm
;;
"Fvwm" )
do_fvwm
;;
"Treewm" )
do_treewm
;;
* )
# exit now
after_all
exec true
;;
esac
done
# Actual end of this file.
Background
When I boot up any Linux distro on my computer, I log on in text mode and then, depending on what I am doing, when I am good & ready, I'll type startx to start xorg. If I want to switch to a different window manager, I exit back to the console, copy the corresponding file to be the new .xinitrc and then start the gui again.
I've always wanted to switch between window managers in such a way that I don't have to do that copying. Also I'd like for any running GUI programs to still run, interrupted by the switch. Imagine you're in blackbox and you've got gimp, xterm, a file manager and a browser running. You'd select a menu option and ... boink, you're in dwm. All the programs are still there, though their windows have been abruptly resized. You work for a bit, then, you hit some key combination and ... plink plink, you're in windowmaker, and the programs are still running.
This must be possible because in some distros I've seen blackbox with menu choices to switch to other window managers. The thing is, things like dock apps and tray things get kind of funny: multiple copies run, or get terminated and not restarted, that sort of thing. It only partially works.
The three main things to solve seem to be as follows.
One: a way, independent of window manager, to pick and switch to another window manager, while keeping everything running.
Two: a way to stop certain programs (dock apps, tool-tray things, etc.) that need to be stopped when exiting a specific window manager.
Three: a way to start certain programs whenever starting a specific window manager.
I eventually worked out a way to do this, based on an assumption: despite not having a "#!/bin/sh" as the first line, .xinitrc is actually a shell script. Turns out that assumption is correct. Now I can switch managers on the fly, with only having find and resize program windows.
Based on looping code from the sample .xinit code included in the treewm (window manager) package, my .xinitrc, when one exits a window manager, brings up a dialog box to select a window manager or to exit out of xorg entirely.
There is a subroutine for cleanup (killall on various known tool-tray and dockapp programs) after exiting any window manager, plus an entry subroutine for each window manager.
xmessage (It comes with xorg so it seems a reasonably portable choice) is used to bring up the file manager selection menu.
I've been using this for several weeks now, on two distros.
The Actual Question
There is just one strange bug: when one first runs startx, the xmessage dialog appears, but there is no cursor (pointer). After a delay, and some mouse-waving on my part, it appears. I've no idea why. Because of this, I've set a time out of 60 seconds, after which, if no button is pressed, it will exit out of xorg, back to the console. I hoping someone here can figure it out whatever I am overlooking.
Thank you.
My .xinit follows (note: yes I know I have a lot of per-wm hard-coding):
Code:#!/bin/bash
b4_wm_choice()
{
killall bbkeys > /dev/null 2>&1
killall bbkeys > /dev/null 2>&1
killall pnmixer > /dev/null 2>&1
killall pnmixer > /dev/null 2>&1
killall autocutsel > /dev/null 2>&1
killall autocutsel > /dev/null 2>&1
killall wmacpi > /dev/null 2>&1
killall wmacpi > /dev/null 2>&1
killall wmmoonclock > /dev/null 2>&1
killall wmmoonclock > /dev/null 2>&1
killall nm-applet > /dev/null 2>&1
killall nm-applet > /dev/null 2>&1
killall stalonetray > /dev/null 2>&1
killall stalonetray > /dev/null 2>&1
xrdb $HOME/.Xresources
xmodmap $HOME/.Xmodmap
}
after_all()
{
killall pulseaudio
killall gmplayer
killall gmplayer
killall worker
}
do_blackbox()
{
autocutsel 2>/dev/null > /dev/null &
bbkeys > /dev/null &
xrdb $HOME/.Xresources
xmodmap $HOME/.Xmodmap
(stalonetray --dockapp-mode simple -bg "#7f7f7f" -t false -p true \
--geometry 2x2 --kludges force_icons_size) &
( sleep 1 ; pnmixer ) &
( sleep 2 ; wmmoonclock -lat 39.173869 -lon 78.176356 ) &
( sleep 3 ; wmacpi -a 5 ) &
( sleep 4 ; xsetroot -xcf /usr/share/icons/Adwaita/cursors/left_ptr 36 ) &
( sleep 5 ; nm-applet ) &
blackbox
}
do_dwm()
{
autocutsel 2>/dev/null > /dev/null &
xrdb $HOME/.Xresources
xmodmap $HOME/.Xmodmap
( sleep 3 ; pnmixer ) &
( sleep 4 ; xsetroot -xcf /usr/share/icons/Adwaita/cursors/left_ptr 36 ) &
( sleep 5 ; nm-applet ) &
while true
do
LALDATE=`date +"%l:%M %P"`
SBTRY=`acpi -b`
xsetroot -name "[$SBTRY] [$LALDATE]"
sleep 19
done &
dwm
}
do_fvwm()
{
autocutsel 2>/dev/null > /dev/null &
xrdb $HOME/.Xresources
xmodmap $HOME/.Xmodmap
( sleep 2 ; pnmixer ) &
( sleep 5 ; xsetroot -xcf /usr/share/icons/Adwaita/cursors/left_ptr 36 ) &
( sleep 6 ; nm-applet ) &
fvwm
}
do_treewm()
{
~/.fehbg
xrdb $HOME/.Xresources
xmodmap $HOME/.Xmodmap
LANG=C treewm
}
gamma_fix 2>/dev/null > /dev/null
.fehbg
while true
do
b4_wm_choice
# pick Exit or a window manager
BLOORP=`xmessage 'Which Window Manager?' \
-buttons Blackbox,Dwm,Fvwm,Treewm,Exit -nearmouse -print -timeout 60`
case "$BLOORP" in
"Blackbox" )
do_blackbox
;;
"Dwm" )
do_dwm
;;
"Fvwm" )
do_fvwm
;;
"Treewm" )
do_treewm
;;
* )
# exit now
after_all
exec true
;;
esac
done
# Actual end of this file.