Bug.n patches by pitkali

May 7th, 2009 Shell hook patch was completely rewritten as a new line of patches related to general window information handling. Also, added killclient patch.

Introduction

Bug.n is a great Autohotkey script that brings functionality of the DWM window manager to Windows operating system. This includes automatic Window placement and resizing, and support for multiple virtual workspaces. The project webpage can be located at:

http://freenet-homepage.de/bug.n/

However, I did encounter certain annoyances. Hence I have prepared a set of patches that removes my personal itches. Below you can find in-depth description of each of the issues and solutions I have prepared.

All my patches are available both as a textual file to be applied with command patch -p0 in distribution directory, and as a Bazaar 1.14 repository. In particular I imported Bug.n 3.5.1 into repository http://pitkali.info/bugn/upstream. Each patch has a branch derived from this one (level 1 patches) or from branch of another patch (level 2 patches.) Patch files were generated using appropriate bzr diff command.

Disclaimer Even though I do have some experience in development, never before have I seen or even heard of Autohotkey. I’ve been learning its language during modyfing Bug.n code. Hence my patches probably could use some tweaking by people more experienced in Autohotkey development.

Do take also note that I have not used nor seen the original DWM window manager. Under my Linux I am planning to use awesome 3 (compiled, installed and learned lua, time to learn API for configuration file…)

Move mouse patch

The Problem

I am very fond of focus follows mouse idea. Which is why I used Powertoys to enable it under my Windows XP system (here it is called X-mouse.) However, this means that what to my mouse has influence on window focus, and thus — window arrangement. Even though it did work pretty well by default, it sometimes failed to do what I consider best. Hence I created a patch to explicitly manage my mouse.

Solution

I have prepared a patch that does the following (configurable through BUGN_arrangeMouse variable, enabled by default):

Patch: patch1-move-mouse.patch
Bzr: bzr branch http://pitkali.info/bugn/patch1-move-mouse

Save/Restore master window

The Problem

I happen to use tags a lot. This also means switching between them quite often. I found it counter-intuitive and counter-productive that each time I switch between tags, different window is placed in master area (or is the topmost window in monocle layout, for that matter.)

Solution

Note that this is level 2 patch that is technically dependent on the previous one. This pertains to the last of the above-mentioned points only so it is easy to manually remove this dependency.

Patch: patch2-save-master.patch
Bzr (includes dependency): bzr branch http://pitkali.info/bugn/patch2-save-master

Window detection upon BUGN scan

The Problem

Each new window that is not excluded from BUGN should be supplied to BUGN_manage function. It remembers its properties and restores them upon quiting bug.n (or reload.) However, new windows are managed like that only if they are detected by a shell hook, so only if:

However, it is possible to have windows that are being arranged by BUGN and were not processed by BUGN_manage function. For example:

  1. Open unregistered version of Total Commander.
  2. Click the correct button to make it work.
  3. Switch to other tag and back.
  4. The Total Commander is now arranged because switching back caused BUGN_arrange, which detected its window as non-excluded. But it is not known — the call to BUGN_manage is missing here.

Solution

The patch is quite simple. BUGN_scan function that collects available windows for arrangement may check each non-excluded window for being listed in BUGN_wins_id array. If window is not there, it should be supplied to BUGN_manage call.

Patch: patch1-scan-detection-fix.patch
Bzr: bzr branch http://pitkali.info/bugn/patch1-scan-detection-fix

Dialog detection upon BUGN manage

The Problem

  1. Open a dialog box that should be floating by default. For example, in main Opera window, click Tools, Preferences.
  2. Force rearrangement of windows. For example switch to a different tag and back.
  3. Expected: dialog box remains floating.
    Actual: dialog box is arranged as any other window.

Solution

It seems to be sufficient to check for WS_POPUP (0x80000000) style of window upon its detection. Then its ID can be added to BUGN_wins_floating array. If previous patch was applied (fix for window detection upon BUGN scan operation), it is sufficient to modify BUGN_manage function, so that it checks new windows for this style item. This seems to work pretty well for various boxes and even Kaspersky Internet Security’s non-resizable windows.

Note: The dialog box was floating before forced rearrangement, because Windows did not send shell event for it.

Note: This patch does not, technically, depend on previous one, as in: they touch different parts of code. Logically, it works best with the previous patch applied.

Patch: patch1-dialog-detection.patch
Bzr: bzr branch http://pitkali.info/bugn/patch1-dialog-detection

Regular expression support in BUGN exclusion rules

The Problem

It all started with Opera widgets. It seems that they (or, at least, the Post It widget) work best when excluded from Bug.n. Unfortunately enough, all Opera windows have class OpWindow and may be distinguished only by title: browser windows have titles ending with string ’ - Opera’.

So you could create an exclusion rule just for those widgets that you use. Not very elegant. And not working very well, because Opera windows are detected before they have the right title set. So I decided the following regex would solve my problem:

OpWindow,,.+(?<! - Opera);

This uses negative look-behind feature that translates exactly to OpWindows with titles NOT ending with string ’ - Opera’.

Solution

Originally bug.n uses three string searches within exclusion string to determine, if a window should excluded from BUGN module. This is fast. Regular expressions on the other hand may be slow, if used the wrong way. Admittedly, my first attempt to implement this was quite lousy and caused deterioration in performance that was noticeable even on my quite speedy laptop.

This patch is my third, and most successful attempt. For each window, it checks length of class name and title, and performs a single RegExMatch call.

This is done by taking an exclusion string and converting it into a regular expression with alternatives. Additionally, each alternative has ^ at its beginning and ends with $.

Note that this would allow to replace most of default rules with a single expression:

AutoHotkeyGUI,,sb+

I decided to leave them be, for the time being. It will be easier to merge in changes from next bug.n releases, should this patch be rejected.

Note: I have isolated the rule processing code in a single function in file BUGN.ahk. The file config.ahk only calls this function with different exclusion string. This will make it easier to modify rule processing code in the future. If the user needs super-flexibility, they can still just do something else instead of calling this function.

Patch: patch1-bugn.excl-regexp.patch
Bzr: bzr branch http://pitkali.info/bugn/patch1-bugn.excl-regexp

PS: I think it could be interesting to enable using regular expressions in other exclusions and BREW rule matching. Though I am currently out of spare time until I finish my Master’s Thesis…

Killclient

The Problem

Under certain circumnstances it may happen that after using a hotkey to kill a client (invoking BUGN_killclient function) the client is killed (window is closed) but windows stay arranged as if that window was still present.

Solution

This happens if BUGN_arrange is called too early after WinClose command. The solution is to add WinWaitClose waiting for window to be closed. I also use a timeout of 1 second.

Patch: patch1-killclient.patch
Bzr: bzr branch http://pitkali.info/bugn/patch1-killclient

Window information handling patches

It all started with a previously described shell hook fix that enabled detection of new windows not only on wParam = 1 or 2, but also for values of 4 and 6. I was initially confused whether it’s useful at all, but then I realised that at my office awfully many windows appear with only wParam of 4 (activation) and without 1.

Hence I started using this patch, discovered a number of vaguely related issues and rewritten the patch as a series of different patches. They fix the following issues:

The base patch is scan detection fix described above: patch1-scan-detection-fix.patch. The remaining patches are, in order of application:

Note: Each patch file was generated against a lower level patch, so to get all the changes in the series you need to apply all of them. But each bazaar repository contains all of the series up to and including current level patch. Hence to get bazaar repository with all of the series, it is sufficient to branch only the last repository.

Final notes

Most of these patches are prepared against base version (Bug.n 3.5.1). They are, however, quite compatible. I managed to merge them all into all.patch with only a few simple to remove text conflicts. Feel free to examine http://pitkali.info/bugn/all-patches repository containing all these patches. Additionally, http://pitkali.info/bugn/myconfig repository contains all patches and some of my personal tweaks (including custom hotkeys.)

Contact

Feel free to .