obda.net

Microsoft’s Natural Ergonomic Keyboard 4000 and its Zoom Slider

Add a comment

Articles tagged with gentoo may not totally apply to your preferred flavor of Linux.

If you are using Microsoft’s excellent Natural Ergonomic Keyboard 4000—at least one product that Microsoft got right—under Linux, chances are that the zoom slider in the middle of the keyboard does not work out of the box. The problem is that the zoom slider uses keycodes greater than 255, which the evdev driver cannot handle.

Fortunately, you can use udev to remap the keys. The default keyboard mappings are contained in /lib/udev/hwdb.d/60-keyboard.hwdb, where you will also find detailed documentation comments on the file format in the header, including:

# To update this file, create a new file
#   /etc/udev/hwdb.d/70-keyboard.hwdb
# and add your rules there. To load the new rules execute (as root):
#   udevadm hwdb --update
#   udevadm trigger /dev/input/eventXX
# where /dev/input/eventXX is the keyboard in question. If in
# doubt, simply use /dev/input/event* to reload all input rules.

You might even already find a section for the Natural Ergonomic Keyboard 4000 in this file. If that is the case, copy its definition and use it as a starting point for the new /etc/udev/hwdb.d/70-keyboard.hwdb. If you want the zoom slider keys to be mapped as “Page Up” and “Page Down” keys, use the following:

keyboard:usb:v045Ep00DB*
 KEYBOARD_KEY_c022d=pageup
 KEYBOARD_KEY_c022e=pagedown

Of course, you can map it to anything you like. For example, to emulate a mouse wheel scroll, you could define your custom mapping as:

keyboard:usb:v045Ep00DB*
 KEYBOARD_KEY_c022d=scrollup
 KEYBOARD_KEY_c022e=scrolldown

This should result in Xorg receiving the zoom slider keys as XF86ScrollUp and XF86ScrollDown. Finally, make things work with xdotool1 by binding those keys within your window manager to run xdotool click 4 (scroll up) and xdotool click 5 (scroll down).


  1. Gentoo package x11-misc/xdotool 

.gitignore per branch

Add a comment

Git does not support to ignore files based on the current branch. Patterns listed in any .gitignore file as well as in .git/info/exclude are always applied. A workaround is possible by creating per-branch ignore/exclude files, and automatically symlinking the correct one using Git’s post-checkout hook:

This hook is invoked when a git checkout is run after having updated the worktree. The hook is given three parameters: the ref of the previous HEAD, the ref of the new HEAD (which may or may not have changed), and a flag indicating whether the checkout was a branch checkout (changing branches, flag=1) or a file checkout (retrieving a file from the index, flag=0). This hook cannot affect the outcome of git checkout.

For example, the following script looks if there is a file named exclude.<branchname> in the .git/info directory, and uses this as link target for .git/info/exclude. If there is no branch-specific exclude file, it will symlink exclude.__default__ instead.

#!/bin/sh

old_ref=$1
new_ref=$2
branch_switched=$3

if [[ $branch_switched != '1' ]]
then
    exit 0
fi

current_branch=$(git rev-parse --abbrev-ref HEAD)
hook_dir=$(dirname $0)
info_dir=$(realpath "$hook_dir/../info")

exclude_target='__default__'
if [[ -f "$info_dir/exclude.$current_branch" ]]
then
    exclude_target=$current_branch
fi
cd $info_dir
rm exclude
ln -s exclude.$exclude_target exclude

Modify this script as needed, save it as .git/hooks/post-checkout, and make it executable—et voilà.

Ignore join/part/quit messages in WeeChat

Add a comment

cheat-sheet articles are about code snippets that I need every once in a while, and which I constantly forget about.

From the WeeChat FAQ:

With smart filter (keep join/part/quit from users who spoke recently):

/set irc.look.smart_filter on
/filter add irc_smart * irc_smart_filter *

With a global filter (hide all join/part/quit):

/filter add joinquit * irc_join,irc_part,irc_quit *

Ignoring the messages only in specific channels can be achieved by providing the full channel names (in a comma-separated list) after the filter name:

/filter add myfilter irc.freenode.#mychannel irc_smart_filter *

Use /filter disable myfilter or /filter del myfilter to disable or delete the filter.