Thornton 2 dot Com

Patching x11-wm/wmx on FreeBSD

I like wmx, but my mouse wheel makes using the middle mouse button to access the program menu a pain, so I ended up creating my own patch and installing wmx from ports instead of pkg. Based on what I found in Web searches, I think I'm doing this the right way, but I haven't talked to any FreeBSD porters to make sure. I just wanted something customized for my own PCs.

When I wrote this page, I was using FreeBSD 12.0-RELEASE-p8.

The pages that most influenced me are:

I used vim when editing originally, but I'm going to use ed(1) here to show editing. See the ed(1) manpage and other tutorials if you're not familiar with it. I don't use much here.

Making changes

First, I got a root shell, changed into the wmx port directory, and extracted the wmx source:

$ su -
root@tinkerbell:~ # cd /usr/ports/x11-wm/wmx/
root@tinkerbell:/usr/ports/x11-wm/wmx # make extract
===>   wmx-8 depends on file: /usr/local/sbin/pkg - found
=> wmx-8.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
=> Attempting to fetch
wmx-8.tar.gz                                           137 kB  222 kBps 00s
===> Fetching all distfiles required by wmx-8 for building
===>  Extracting for wmx-8
=> SHA256 Checksum OK for wmx-8.tar.gz.
root@tinkerbell:/usr/ports/x11-wm/wmx # 

Once extracted, I changed into the wmx work directory. The mouse button settings are in Config.h, a reasonably well-documented file, so that's the file I edited. However, in order to make a patch, I had to preserve the original file first. To do that, I made a copy of Config.h called Config.h.orig:

root@tinkerbell:/usr/ports/x11-wm/wmx # cd work/wmx-8/
root@tinkerbell:/usr/ports/x11-wm/wmx/work/wmx-8 # cp -i Config.h Config.h.orig
root@tinkerbell:/usr/ports/x11-wm/wmx/work/wmx-8 # 

Next, I read the Config.h file and found the line numbers the settings were on:

less -N Config.h

The less command is useful for reading and understanding the file, of course, but with the -N switch, it also gives the line number of every line.

In my copy of wmx, the settings are on lines 263 and 264, at the end of what the author called Section II:

    255 // Mouse Configuration
    256 // Use this section to remap your mouse button actions.
    257 //   Button1 = LMB, Button2 = MMB, Button3 = RMB
    258 //   Button4 = WheelUp, Button5 = WheelDown
    259 // To prevent one or more of these from being supported
    260 // at all, define it to CONFIG_NO_BUTTON.
    261 #define CONFIG_NO_BUTTON 999
    262 #define CONFIG_CLIENTMENU_BUTTON  Button1
    263 #define CONFIG_COMMANDMENU_BUTTON Button2
    264 #define CONFIG_CIRCULATE_BUTTON   Button3 // switch window, when over fr
    264 ame
    265 #define CONFIG_PREVCHANNEL_BUTTON Button5 // flip channel, when over fra
    265 me
    266 #define CONFIG_NEXTCHANNEL_BUTTON Button4 // flip channel, when over fra
    266 me
    269 // ==============================
    270 // Section III. Colours and fonts
    271 // ==============================

Now all I had to do was edit lines 263 and 264, swapping Button2 and Button3:

root@tinkerbell:/usr/ports/x11-wm/wmx/work/wmx-8 # ed Config.h
#define CONFIG_CIRCULATE_BUTTON   Button2 // switch window, when over frame
root@tinkerbell:/usr/ports/x11-wm/wmx/work/wmx-8 # 

(See subexpressions and backreferences in the ed(1) manpage and online tutorials if you want to know why the "s/" command magic I used works and saves typing.)

Making the patch

Now with the original and edited files, I took a diff of them. The ports system has a "makepatch" target that automatically makes diffs of the source tree and saves the resulting patches in the port's patch directory.

root@tinkerbell:/usr/ports/x11-wm/wmx/work/wmx-8 # cd ../..
root@tinkerbell:/usr/ports/x11-wm/wmx # make makepatch
Generated patch-Config.h
root@tinkerbell:/usr/ports/x11-wm/wmx # 

Saving the patch

Finally, before building and installing wmx, I made a shell archive of the patched wmx so that I can reinstall the patch if a ports tree upgrade deletes the patch:

root@tinkerbell:/usr/ports/x11-wm/wmx # make clean
===>  Cleaning for wmx-8
root@tinkerbell:/usr/ports/x11-wm/wmx # cd ..
root@tinkerbell:/usr/ports/x11-wm # shar `find wmx/files/ -print` \ 
? > ~/wmx-8-personal-freebsd-patch.shar
root@tinkerbell:/usr/ports/x11-wm # 

Ordinarily when building a patch to submit to a port maintainer, you want to make a shell archive of the clean and whole port, but all I want is an archive of the patch, not the whole port. If you were making a port change to submit to the port's maintainer, the find command would be find wmx/ -print instead, and the output name would not be the one I used.

Restoring the patch if it gets removed

Now, if anything happens to the wmx port in the ports tree and my patch gets deleted, all I'd have to do to restore my patch and reinstall wmx is:

root@tinkerbell:~ # cd /usr/ports/x11-wm/
root@tinkerbell:/usr/ports/x11-wm # sh ~/wmx-8-personal-freebsd-patch.shar 
c - wmx/files/
x - wmx/files/patch-Config.h
root@tinkerbell:/usr/ports/x11-wm # cd wmx
root@tinkerbell:/usr/ports/x11-wm/wmx # make clean build deinstall install clean

^v^v^v^v [a whole bunch of output snipped] ^v^v^v^v

root@tinkerbell:/usr/ports/x11-wm/wmx # 

The only thing I'll have to watch out for is if an upgraded version lands in the ports tree. If I'm still using wmx when that happens, I can't count on the author keeping Config.h unchanged between versions, so I'll have to make a new patch for that new version.

As infrequently as wmx is upgraded (only 8 version upgrades over 22 years, a testament to its simple design, if you ask me), that shouldn't happen anytime soon.