Tuesday, June 14, 2011

A man page for xkeyboard-config

Command-line configuration of XKB keyboard maps usually involves setxkbmap:

setxkbmap -layout "foo" -variant "bar" -options "gobble:dygook"

The problem is though that you need to know your layout, your variant, and your options. And they're not always straightforward. What command would you use for a US querty and German Dvorak layout where the Meta key is on the left Windows key and Ctrl is mapped to the Caps Lock key? If you knew the answer [1] without looking it up first you're scaring me. Stay away from children please.

A few days ago Carl Worth asked a few XKB-configuration questions on IRC and amongst other things this led to yet another complaint about the lack of a man page. Which I answered with the usual "feel free to write one". Except that a few hours later I suddenly had the epiphany: we already have all this data - GNOME uses it just fine for its own keyboard configuration panel. A little later some XSL had been beaten into submission enough for me to proudly say that we now have a man page that lists every single option that you can pipe into setxkbmap. xkeyboard-config(7) for president!

This will be available in the next version, scheduled for September 27. Until then, see the git commit here. Fedora users: xkeyboard-config-2.3-2.fc16 and xkeyboard-config-2.3-2.fc15.


[1] setxkbmap -layout "us,de" -variant ",dvorak" \
-option "altwin:left_meta_win,ctrl:nocaps"
Obvious now, isn't it?

Wednesday, June 8, 2011

Using environment git trees

Despite the confusing title, this is not tree-hugger territory ;)

I have two main machines and several test boxes. More often than not, I end up installing a new machine and get new home directory. This is annoying, because I've gotten quite used to my zsh setup, my vim customisations and all the other little tweaks my systems have accumulated over the years.

Somewhen around last year, this really started pissing me off so I set up a git tree for all those configurations, but I have now split that git tree into two trees: one called environment and one called shellenv.

Here's the current list of files in shellenv:

:: whot@barra:~/shellenv (master)> git ls-files
.gitconfig
.screenrc
.ssh/authorized_keys2
.tigrc
.zsh/10-exports
.zsh/20-aliases
.zsh/30-chpwd
.zsh/30-compctl
.zsh/30-keybindings
.zsh/40-xinput-compctl
.zsh/90-prompt
.zsh/func.tmp
.zsh/func/_fedpkg
.zshrc
setup.sh


The list of files in environment includes my mutt setup, my $HOME/scripts directory with all scripts to automate various stuff, my irssi setups, etc. Both repositories have a setup.sh:


#!/bin/bash

pwd=$PWD
filename=`basename $0`
excludes=". .. .git $filename"

for file in `ls -a`; do
skip=0
for exclude in $excludes; do
if test $file = $exclude; then
skip=1
break
fi
done

if test $skip -eq 1; then
continue
fi

if ! test -e "$HOME/$file"; then
echo ln -s "$pwd/$file" "$HOME/$file"
ln -s "$pwd/$file" "$HOME/$file"
elif test -d "$file"; then
echo "$file already exists"
else
echo "$file already exists"
fi
done


All this does is to symlink the target file with the current file (provided if the target does not exist). The script used in my environment tree is a tad more complicated since it takes hostnames into account to populate the various /etc directories as well but you get the gist.

The result of all that? I can install a new test machine, run git clone and ./setup.sh and the machine has my shell environment. I get a new actual machine (or I update any of my local configuration) and I can run git clone or git pull and all my main boxes have the identical setup. Do try this at home.


Note: I know there are a few bugs in the symlink scripts. I always run them the same way though, they work for me and it's not really worth my time right now to try to make them perfect

Friday, June 3, 2011

Linking kernel and X devices

XI2 has made it possible to access any device the X server knows about and get events from those devices. Alas, one piece was missing: short of parsing the Xorg.log file it was so far impossible to link the system devices with kernel device. You had to guess that /dev/input/event3 was your "AT Translated Set 2 keyboard" with the X device ID of 6.

Why would one need this? Some properties of a device are not exported in X. These included for example anything in sysfs.

I've now pushed patches to evdev, synaptics and the wacom driver to export the device node as a simple string property. From this device node, a client can navigate to the matching sysfs dir, get other events out of the kernel or do whatever they like to do.

The property name is "Device Node" and it is a standard char* that contains the device path. The path is set by the driver, so even if you use e.g. auto-dev on synaptics, the value will be filled in correctly. On the downside, if the driver doesn't support it, the property will not be available on a device. If you write clients that require this information, ensure that you can cope with a missing property and remember that several X devices may share the same device node (e.g. wacom).

These patches do not require a new server, though we have added a #define XI_PROP_DEVICE_NODE to the server to make it easier for others to use this property without misspelling it.

Another property that was pushed in the same series was the "Device Product ID" property (#define XI_PROP_PRODUCT_ID once the new server is out). This property contains two unsigned 32-bit values: vendor ID and product ID. Having this information available makes it simpler for X clients to apply configuration based on specific devices. This can come in handy if you e.g. need different acceleration for a set of mice or you simply want to remap buttons on a specific device.
Again, the two values are set by the driver and all the above rules apply.

I may end up writing those patches for mouse and keyboard too but feel free to help me out with it.

The obligatory not-quite-a screenshot:

:: whot@barra:~> xinput list-props "SynPS/2 Synaptics TouchPad"
Device 'SynPS/2 Synaptics TouchPad':
[...]
Device Product ID (252): 2, 7
Device Node (253): "/dev/input/event4"



Update June 7 2011: As Peter pointed out in the comments, the device node is always local to the host the server runs on. It is up to the client to figure out if it runs on the same host.

Thursday, May 26, 2011

Fedora 15 and offlineimap users beware

This is just a word of warning: if you have upgraded to F15 and you use offlineimap, observe very carefully what it does and ensure you have a backup of your email.

This post has updates. See at the end of the post

I noticed yesterday that I couldn't search for some email that I knew existed. On closer inspection I found a huge chunk of my archive inbox to be missing. Several months worth of emails, they stopped in March and then continued with the emails from yesterday that I had copied in from my Inbox.

The same happened to my fedora-devel and xorg-devel folders, possibly others. Re-running offlineimap to sync these pulled down hundreds of emails, so I let it run overnight. This morning I discovered that sometimes offlineimap simply states something like "Deleted 1018 messages" and they're gone again. This is cumulative, it seems to delete only newer ones (I was at September 2010, but after one more run I'm now back to July 2010 being the newest messages in in my xorg-devel folder).

The good news is that the emails are still on the server. Also, so far only mailboxes with huge numbers of emails (>10000) seem to be affected, smaller mailboxes appear to work fine.

I have not filed a bug yet because I don't know what the actual issue is. Could be offlineimap, could be something else. But in the meantime, beware.
Update May 30: Filed as Bug 708898

Update May 30
I downgraded to offlineimap 6.2.0 which is in F14 (offlineimap-6.2.0-2.fc14.noarch) and managed to eventually resync my mailboxes. Then I went back to F15's offlineimap-6.3.3-1.fc15.noarch. Of course it didn't trigger on my test mailbox, but it did then do the same thing again on my xorg-devel inbox.


Syncing lists-xorg: IMAP -> Maildir
Deleting 8181 messages (33540, 335
[...]
in Maildir[lists-xorg]


F15's offlineimap-6.2.0-3.fc15.noarch does not show this behaviour and seems to resync the locally deleted emails. Of course that'll take a while, but I'll try to get logs this time (my first couple of tries to get logs from offlineimap crashed it).

Monday, April 18, 2011

GNOME 3.0 middle mouse button emulation

This is essentially a GNOME 3.0-specific update to New evdev middle mouse button emulation defaults. In recent evdev versions, middle mouse button emulation is disabled by default and can be enabled with Option "Emulate3Buttons" "on" in the xorg.conf file or an xorg.conf.d snippet.

GNOME 3.0 has a gsettings key to also trigger this behaviour on a per-user basis (see bug 633863). The default value is off (false). Settings applied from the desktop environment overwrite xorg.conf(.d) settings, so to get middle button emulation in GNOME simply toggle the gsettings key and don't worry about xorg.conf(.d). The command to toggle the key is:


$> gsettings set org.gnome.settings-daemon.peripherals.mouse \
middle-button-enabled true


Since this gsettings are persistent, setting the key once is sufficient. It will be applied after login, for each device and as new devices are hot-plugged.

Tuesday, March 22, 2011

Custom input device configuration in GNOME

Thanks largely to Bastien, Gnome Bug 635486 just got committed, in time for GNOME3.

It adds is the ability for custom configuration of input devices from within GNOME, especially for settings that are not handled by the GNOME UI tools. It's principle is quite simple. A new gsettings key hotplug-command in the org.gnome.settings-daemon.peripherals.input-devices schema points to an executable. This executable is called at gnome-settings-daemon startup, whenever a device has been added and whenever a device has been removed. Something like this:


$HOME/executable -t added -i 12 My device name


So the device with the ID 12 and the name "My device name" just got added. Other types are "removed" and "present" for those device that are already present when g-s-d starts up. It's quite simple to configure any device to your liking now. Have a look at the input-device-example.sh script shipped with gnome-settings-daemon. I'll give you two examples of what you could add to the script and the rest should be easy enough to figure out:


# Map stylus button 1 to button 8
if [ "$device" = "Wacom Intuos4 6x9 stylus" ]; then
xsetwacom set "$device" Button 1 8
fi

# map tapping to LMR instead of default LRM
if [ "$device" = "SynPS/2 Synaptics TouchPad" ]; then
xinput set-prop $id "Synaptics Tap Action" 0 0 0 0 1 2 3
fi

Friday, March 4, 2011

How to DOS a developer

So you think your favourite FOSS project is moving too fast? Easy, just DOS the developers. Here's a few tips on how to achieve this:

On IRC



  • If you have a problem, just state that you have a problem. Let the developer ask for what exactly it is. Then answer every question with the minimum amount of information possible and let the developer keep asking.

  • Wait 5 minutes before answering but keep asking why the developer doesn't answer immediately. That way you can maximise the context switching costs of the developer, ensuring he or she can't get anything else done while waiting for you.

  • If the developer asks for version numbers, be vague. Things like "whatever was in $DISTRO three days ago" is best because unless the developer is also the distro maintainer, you've answered the question without providing any information.

  • Don't stay on IRC. Just go offline whenever your computer goes to sleep and re-ask the question every time you reconnect. This way you ensure that those not monitoring the channel will try to answer the questions whenever you're currently offline. Never send email to the list, because others could answer it in their own time.



Via email



  • Send bug reports to the developers directly. That way you force them to reply with at least "please file a bug in $BUGZILLA". That takes 2 min of their time, not counting context switches. Make sure you reply with more than one "thank you" email so they need to deal with more email.

  • Randomly remove the CC from mailing lists during discussions. That way you make sure the developer has to answer twice if they didn't notice the CC was missing.

  • When taking discussions back onto the list, misquote (or purposely misinterpret) the results of the private discussion. Force the developer to justify themselves in public.

  • Be verbose. As verbose you can be. If you can say something in one sentence or three paragraphs (with three overlapping or identical examples), choose the latter. Searching for signal in lots of noise is a favourite pasttime of many developers.

  • If you change the subject of a discussion, leave the email subject as-is. This way you ensure that the email cannot easily be found later. Wait for a few weeks, then refer to this discussion, but not in the same thread.

  • Pastebin everything instead of including it in emails. Links to websites, backtraces, log files, patches, etc. Make sure the pastebin has a short expiry date.

  • If you must include something as attachment, make sure it's at least in a zipfile so no-one can look at it without a few mouse-clicks first.



Via code



  • When commenting on patches, reply with vague statements on how the patch doesn't work. This way, the patch is made to look bad and the developer now has to spend time making sure your vague statements weren't just unfounded.

  • When testing code, make sure you don't explain how a bug happend. Just say "after a while it crashed", that's enough information for anyone to figure out what's going wrong.

  • Read The Daily WTF and gain inspiration for your next open source project. If you ever get other people helping you, you maximise their pain.

  • Don't document anything. Just use arbitrary hardcoded values, with no explanation.

  • Never, ever, explain why you're doing something. Code is not meant to be self-explanatory.

  • Don't follow anything I said in on commit messages

  • Do everything as complicated as possible but don't explain why. Obfuscating that you're flipping the sign of a variable three to four times is a good example, anyone reading the code is sure to spend hours on it

  • Use numbers as both bools and numbers. C is great for that, you can return 2 and then use it as Boolean and as actual numeric value lateron. Hide any such usage as well as you can.

  • When sending patches, mix code changes with arbitrary whitespace changes. Fun minutes can be spend looking at two identical lines trying to find the difference that's missing.

  • When sending updated versions of a patch, don't tell anyone what has changed. That way, you force your reviewers to review the whole patch, every time you change a single character.

  • When sending patches, make sure that it only fixes the problem on your specific setup. That way you also can tell the developers off for not merging an important bugfix that clearly works when you tested it. And you force them to reply to you.



Those are just the immediate things that come to my mind. If the project is already low on manpower, any of these will have a high impact. If it has enough developers, you may need to use several of them at once to tie up the most resources. Of course all this requires developers that still think that communicating with users is worthwile and that other people generally tell the truth. If they have given up on humanity, they may just ignore you and keep improving the project. In that case, you can at least badmouth everyone on tech "news" sites forums and comments.

Oh, in case you're wondering why I don't get anything done lately, see above. I realise that probably none of it is intentional, though the net effect is the same.