multi monitors and how it should all work (long babble)

at work i use two screens for my day to day workflow. i find it’s much more efficient for doing work, like coding. i’ll often have at least one terminal open, a full screen text editor, and usually a number of references, such as the dbus specification open in a web browser.

i recently just realized that one of the reasons multiple monitors are so useful to me, isn’t because of the increased screen real estate (although that certaintly is an important factor) but because of how the window manager deals with the windows. for example, when i click maximize, the chosen window expands to fill that monitors capacity, and not the entire set of monitors. it would be nice for this type of behaviour to be configurable somewhere for people with ultra large screens, who want to manage their windows better. the closest i’ve found is: winwrangler which i’ve started using at home where i only have one screen. it works sort of along those lines, however i still want more. multiple “workspaces” are essential. no matter how many screens i have, i’ll always need a few workspaces to be able to flip between email and coding– there is no sense in mixing it all together.

the cheeses (“the cheddar”, aka the suggestions i want to make in this babble):

  • as i change workspaces both/(all) screens change along with me. adding multiple monitors, essentially extends the size of the workspace. let us call this “mode 1“.
  • an alternate behaviour could be to allow “x” independent workspaces on monitor 1, and “y” independent workspaces on monitor 2, and so on… i read somewhere that someone accomplished this with two different x sessions somehow; the problem was that you couldn’t drag windows from one to the other. if someone was able to solve that problem and that type of usability was possible, then we could call this “mode 2
  • even more exciting would be to have a workspace on each monitor sharing a common set of workspaces. for example workspace “c” could be displayed on monitor 1, and workspace “e” could be displayed on monitor 2. you could switch each independently, and in the special case that both monitors were displaying the same workspace, then you would be getting an almost “clone”. the one exception to this being a true clone is that when using multiple monitors, you usually have a static per-monitor panel layout which doesn’t change as you switch workspaces. that functionality is good. all this would be called “mode 3
  • for completeness sake, a *true* clone of one screen to another is a possibility, and should be called “mode 0“.

the complicated point to this discussion is doing what any good mathematician, computer scientist, or ropes-technician (because of the knot tying) would do, and that is to extend the idea of our our modes to the more general case where we can mix and match them for N screens. (to take it a step further would be to let any physical screen be split into M virtual screens, and then use those to solve the above problem!)

think of combining two screens in mode 1, which together are in mode 2 with a second screen, which all together could be in mode 3 with an auxiliary monitor. you’ve got a big mess, and maybe it would be nice to dump this whole setup to your clone output in mode 0 to the projector. now i’m pretty sure that nobody would want that particular setup, but there should be some sensible way to choose what setup you do want, and to configure it appropriately.

i’ve heard that xmonad can apparently do something like mode 3. it makes me want to switch to using that. mode 1 is currently what i’m using. mode 2 could probably be emulated in a window manager which supports mode 3, by confining monitor 1 to only allow even numbered workspaces, and monitor 2 to only allow odd numbered workspaces (mod N if you have N monitors), and mode 0 already exists and is nice for presentations.

i think there are two important things to get right:

1) have a way to create “virtual screens” – it would be nice to be able to benefit from multiple screen logic, without physically buying 8 screens. also this would be indispensible for testing.
2) have a beautifully designed tool for managing the configuration, which obviously uses a well thought out configuration file format.

i would love to hear your thoughts, and if anyone knows of projects with great goals like these, please let me know.

ps: compiz has a “multi output mode” but i’m not sure exactly what it does and if it helps with any of this.

tech support for a keyboard

so my boss was recently kind enough to purchase a new keyboard and mouse combo to attempt to relieve the elbow-and-down pain that i endure due to constant programming and mouse moving. thanks.

i received my “logitech cordless desktop wave pro” today, and 15 seconds later i’m up and running in linux. the keyboard and mouse seem to be really nice, however i won’t dwell on their merits here, i’m sure you can read about that elsewhere on the internets. what i would like to point out is that for some stupid reason, the keyboard only sports a battery indicator light. that’s right, NO NUM LOCK, CAPS LOCKS OR SCROLL LOCK LIGHTS. (woops, sorry didn’t realize caps was on.)

apparently, the bundled software will notify you via on screen display when you push the caps locks key, however who is silly enough to install that ? (linux users defintely aren’t, especially since it’s windows -only-) the confused engineer who thought this was a good idea should probably get the boot. i suppose it’s one of the reasons they can boast long keyboard battery life, but i’d rather have my keyboard led’s back.

i suppose it would be easy to hack up a little osd notifier that tells me when the caps locks key gets pressed, but it won’t fundamentally change the fact that i don’t want to see an indicator on my screen, i want it on the keyboard.

ps: the reason this is titled “tech support for a keyboard” was because i had to call their surprisingly unhelpful keyboard support department to figure out that there wasn’t a hidden indicator light. never thought i would need to call in for something like that.

vanilla: my favourite flavour of gnome

after a recent upgrade to ubuntu 9.04, it seems that i’ve been pushed into using some “unfeatures” that i didn’t ask for. well apparently they won’t be unfeatures forever, but for me, notify-osd and indicator-applet aren’t quite ready for my consumption. i realize that ubuntu is trying to improve the desktop experience, but i’m going to need to wait for some more polish first.

so how do i get rid of these horrible things ? i really liked the look of the notification-daemon, and i wanted it back. turns out i can do:

sudo aptitude install gnome-stracciatella-session

and when i log into x there is a “gnome (without ubuntu specific components)” option that i can choose. it seems to work and i’m running it now. hope this tip is helpful to you. thanks to martin pitt for making it easier for us to choose.

why linux is powerful or: how to erase half your system and then fix it

after a brief bout of stupidity i quickly realized that my makefile had gone awry and was quickly eating through my filesystem.

after ^C killing it, it seems i only took out most of /lib/* and /usr/sbin/* — who needs those anyways… apparently almost everyone.

what happened next. well it turns out i was lucky and had a few shells and a webbrowser open– attempts to launch new programs will fail, but existing programs are already loaded in memory so i was able to work.

since almost everything was broken, i first had to get dpkg and apt/apt-utils going again. after much anguish, i manually installed the missing library files and binaries from http://packages.ubuntu.com/ and i was on my way with apt.

if you’re manually installing files from .deb’s use:
dpkg -x <package_file.deb> outputfolder/

which will let you get in and use mv and cp to put back the missing .so files.
once some basic tools were working, you can try and fix up your tool chain doing things like:
sudo apt-get --reinstall install <package_name>

it’s good to do this to apt-utils, dpkg, and whatever other utilities are throwing library errors. the packages themselves need various utilities installed, and as you get a missing abc.so file, find out what package it needs with:
dpkg -S <filename>

my apt seems to be back, but many utilities still aren’t. finding out what should go in /lib was a little harder but i was able to get a list of packages like this:

(find out what *should* be installed)
dpkg --get-selections > installed-software

(list which files come from these packages, sort and uniq it)
dpkg -L `cat installed-software` | sort | uniq > uniq-software

(find what we deleted)
cat uniq-software | grep ^/lib/ > missing-software

(which packages does this come from, sort and uniq it. (might get too long argument list))
dpkg -S `cat missing-software` > package-list

(find the package name by itself, get rid of the colons, sort, uniq)
cat package-list | awk '{print $1}' | sed -e 's/://' | sed -e 's/,//' | sort | uniq > reinstall-me

(do the reinstall)
sudo apt-get --reinstall install `cat reinstall-me`

at the moment this is running, and i luckily had a cd lying around to help speed up the process. use:
apt-cdrom add

(with the cd in the drive) to add it to your /etc/apt/sources.list

turns out this eventually failed with some obscure errors… it ultimately might be a more concise list if you know what got killed, but i think the sheer number of packages i messed up and that needed to get updated somehow confused apt with some cyclical cycles, and i had to go about it slightly more manually and generally.

first of all, when every i had an annoying library error, i ran this script:
#!/bin/bash
in=`echo $1 | sed -e 's/://'`
fix=`dpkg -S $in | awk '{print $1}' | sed -e 's/://'`
sudo apt-get -y --reinstall install $fix

which would reinstall the missing library. since i ended up doing this rather repetitively, it helped a lot.

secondly, i was forced to run something like this:
for i in `cat get-selections`; do
sudo apt-get -y --reinstall install $i;
done

which reinstalls each package. slowly after pruning the list for problem packages, and deleting the successful ones, my system came back. at one point you won’t have to run them individually, and you can run:
sudo apt-get --reinstall install `cat get-selections`

and be done! i finished with a:
do-release-upgrade

and now things are looking great. luckily no important user files were squished, and hopefully this is a good reference for you. i hopefully won’t have to reference it again for all the dpkg commands i’ll forget.

the python subprocess module

i’m sure that i won’t be able to tell you anything revolutionary which can’t be found out by reading the manual, but i thought i would clarify it, and by showing you a specific example which i needed.

subprocess.Popen accepts a bunch or args, one of which is the shell argument, which is False by default. If you specify shell=True then the first argument of popen should be a string which is what gets parsed by the shell and then eventually run. (nothing revolutionary)

the magic happens if you use shell=False (the default), in which case the first argument then accepts an array of arguments to pass. this array exactly transforms to become the sys.argv of the subprocess that you’ve opened with popen. magic!

this means you could pass an argument like: “hello how are you” and it will get received as one element in sys.argv, versus being split up into 4 arguments: “hello”, “how”, “are”, “you”. it’s still possible to try to do some shell quoting magic, and achieve the same result, but it’s much harder that way.


>>> _ = subprocess.Popen(['python', '-c', 'print "dude, this is sweet"'])
>>> dude, this is sweet

vs.


>>> _ = subprocess.Popen("python -c 'print "dude, this isnt so sweet"'", shell=True)
>>> dude, this isnt so sweet

and i’m not 100% sure how i would even add an ascii apostrophe for the isn’t.

the second thing i should mention is that you have to remember that each argument actually needs to be split up; for example:


>>> _ = subprocess.Popen(['ls', '-F', '--human-readable', '-G'])
[ ls output ]

yes it’s true that you can combine flags into one argument, but that’s magic happening inside the program.

all this wouldn’t be powerful if we couldn’t pipe programs together. here is a simple example:


>>> p1 = subprocess.Popen(['dmesg'], stdout=subprocess.PIPE)
>>> p2 = subprocess.Popen(['grep', '-i', 'sda'], stdin=p1.stdout)
[ dmesg output that matches sda ]

i think it’s pretty self explanatory. now let’s say we wanted to add one more stage to the pipeline, but have it be something that usually gets executed with os.system:


p1 = subprocess.Popen(['dmesg'], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['grep', '-i', 'sda'], stdin=p1.stdout)
p3 = subprocess.Popen(['less'], stdin=p2.stdout)
sts = os.waitpid(p3.pid, 0)
print 'all done'

this above example should all be pasted into a file and run; the call to waitpid is important, because it stops the interpreter from continuing on before less has finished executing.

hope this took the learning curve and guessing out of using the new subprocess module, (even though it actually has existed for a while…)