My patches to CTWM

This page contains a couple of patches for CTWM that I (Bjorn Knutsson) have created and that, as of CTWM 3.6, have not yet been rolled into the main distribution of CTWM. (See also the CTWM home page.)

Binding keys in the workspace manager

The first patch adds a new context, workspace to CTWM to allow you to bind actions to keys within the workspace manager in the same way that keys can be bound in the icon manager. This is the description I posted when I first posted the patch:

I found it very annoying that ctwm treats the workspace window as a "normal"
window. I'd like to be able to bind keys tat will only work when the pointer is
in the workspace manager window, just as you can bind keys to functions when
the pointer is in the icon manager window. This was a quick'n'dirty hack, so
perhaps someone more familiar with the inner workings of ctwm could take a look
at it. The key bindings below illustrates my point:

"F1" = : iconmgr : !"xeyes &"

Vanilla ctwm can bind F1 to pop up xeyes, if pressed in the icon manager, but
to get the same effect for the workspace manager, one would have to bind F1 in
all application windows. My patch allow you to bind keys in the workspace
window context, e.g.:

"F1" = : workspace : !"xeyes &"

will pop up xeyes if F1 is pressed in the workspace manager, but not anywhere
else.

A more useful example, and one I use personally, is the following snippet that allows me to use the cursor keys to move around between workspaces when the workspace manager window is active:

"Up" =          : workspace : f.upworkspace
"Down" = : workspace : f.downworkspace
"Right" = : workspace : f.rightworkspace
"Left" = : workspace : f.leftworkspace

Allowing windows to be moved off < #MoveOffResistance pixels despite DontMoveOff being defined

The second patch changes the behavior of DontMoveOff/MoveOffResistance to allow moving a window off screen less than #MoveOffResistance pixels without resorting to f.forcemove. The original behavior of CTWM is to block movement until the window has moved #MoveOffResistance pixels, and then "snap" to the position the window would have been in had DontMoveOff not been defined. This patch changes this behavior to first block movement, and then start moving the window off-screen one pixel at a time. This is the description I posted when I first posted the patch:

I did however change the behavior of DontMoveOff/MoveOffResistance.
Currently the behavior of CTWM if you have set DontMoveOff and set a
MoveOffResistance is to prevent the window from being moved off until
you have moved the window #MoveOffResistance pixels outside the
screen, at which time the window snaps to the position it "should" be
in had DontMoveOff not been defined. What this means is that if you
have set a MoveOffResistance to 25, no part of the window can be moved
off the screen less than 25 pixels.

I find that often when I want to move a window partially off-screen, I
only want to move it a little bit off the screen, but to accomplish
this I often end up using force move.

My patch below changes the behavior of DontMoveOff/MoveOffResistance
so that when you attempt to move a window off screen, it will not move
at all until it's been moved #MoveOffResistance pixels (as before),
but at this time it will no longer "snap", but instead it will start
moving off screen. This means that you still have the old behavior of
DontMoveOff, but now with the ability to move a window off screen less
that #MoveOffResistance pixels.

If I find the time over the holidays I'll try to implement similar
functionality for MovePack.

(I noticed some code in workmgr.c that also seemed to make use of the
MoveOffResistance, but I didn't change that. I assume that this code
is for moving windows from within the workspacemanager. I didn't touch
this code.)

Fixing the bug in f.warpring

The strange first line of the description of my previous patch refers to my attempt at hunting down this bug. The bug manifests itself when your use f.warpring "next" and f.warpring "prev" to warp between windows. This will sometimes work fine, but often I found that I would loop through a subset of the available windows. The cause turned out to be the icon manager. When warping to the icon manager window, if the icon under the cursor was iconified, everything would work just fine. If, on the other hand, it was on screen, the loop would occur. This behavior should be the expected if NoIconManagerFocus wasn't set - it should focus on the currently active window in the icon manager, but I had set this option, so it shouldn't focus on this window. In fact, it didn't, but part of the code you'd expect to run when this happened - the change in position in the warp ring - still happened. Here follows the description of the patch I posted with the original posting of the patch:

I think I've finally fixed the f.warpring problem. I did not want to
get into the hairy code in HandleEnterNotify(), but I did realize that
the reason the problem came up in the first place was that the code in
iconmgr.c was set up to generate events when the icons in the icon
manager were entered/exited. If we don't have IconManagerFocus enabled,
there is no reason to generate the events that eventually (!) cause
the problem. My patch will thus disable the creation of these events
when IconManagerFocus is disabled.

This seems to fix the problem, but I invite comments and corrections.

Random placement not honoring DontMoveOff

This patch fixes something that's been bothering me with RandomPlacement, specifically that it will place windows partially outside of the screen. While this might be acceptable if you haven't specified DontMoveOff, it seems illogical that CTWM should place windows outside of the screen when I, as the user, cannot unless I really try. The below text is the original text from the patch:
I've often been annoyed that randomly placed windows will be placed
off-screen. I've specified DontMoveOff, so I think I've made my
preference clear on this point.

The below patch will keep the old behavior if you have not specified
DontMoveOff, or if the currently active random placement would put the
window entirely in the current screen. If, on the other hand, the
current random placement would place the window (partially) outside of
the current screen, and DontMoveOff is specified, the placement will
be re-calculated to put the window inside the screen, or if it's too
big, aligned with the top of the screen.

Diffs agains CTWM 3.6

Here are links to all the patches:

To apply the patches:
  1. Download the patch (make sure it's downloaded as plain text)
  2. cd to your CTWM source directory
  3. Run:
    patch -l -p3 < path_to_downloaded_patch_file
    to patch source
  4. Run:
    make install
    to compile and install patched version of CTWM

Back to Björn Knutsson's home page