Anti-WIMP JWM Mods
10 Dec 2007 – 0800 US/Central
This page is a log of modifications I’m making to JWM to see how well it can work in a less icon-centric point-and-click environment. I know this is counter the new paradigm in DSL 4, but it’s for a specific use.
I don’t like using my touchpad mouse on my laptop, so I mostly use ratpoison on it. It has some limitations, especially when it comes to applications with multiple windows that I don’t want on separate screens (such as GIMP, but it also applies to anything that opens a popup window — which is just about every GUI app) or in full screens.
I try to take advantage of keybindings in whatever window manager I’m using. Some window managers are better at this than others. And, sadly, some window managers that are ideal for complete keyboard use come with default bindings that clobber bindings in applications. Ion would be one of my favorite window managers if it didn’t bind its commands to function keys by default (I have mixed opinions, too, about the use of Lua for ion scripting). Many console applications use function keys so that requires rebinding something — the window manager or applications — just to have everything get along.
I’ve been fiddling more with DSL 4.0/4.1. The new default window manager is JWM. JWM doesn’t have a big footprint but it’s very easy to customize it. I wanted to see how well I could make it work for a mouse-less (or near mouse-less) environment.
I’m using ratpoison as my base line for comparison. Both ratpoison and jwm are light on system resources, with jwm using a trivial amount more RAM (ratpoison shows on top as 1% of my 122 MB available RAM versus 1.3% for jwm).
The first step was binding as many common functions to keystrokes as possible. There are three default keybindings that spare the keystrokes required for several functions in ratpoison. In ratpoison, many default keybindings are set parallel to similar bindings in GNU screen; the difference is screen uses ctrl-a to precede commands while ratpoison uses ctrl-t (those sequences can be rebound in the respective rc files). In jwm, I have access to the root menu with alt-F1, access to window manipulation commands (maximize, minimize, shade, close, kill, etc.) in alt-F2, and can switch between windows with the traditional alt-tab. Ratpoison doesn’t have a menu (there are menu programs that can be added to it), and the other tasks require several ctrl-t command sequences.
The next task is taking advantage of whatever tools jwm has to provide a more automated window placement. In ratpoison, you get a new full screen view of whatever application you open; it’s sans window decorations, so it really is full screen. Since my laptop screen is fairly small, I like having as little decoration as possible. I also don’t want to have to do alt-F2-maximize every time I open something (including aterm). So I modified my jwmrc so various applications open maximized and without window decorations or borders using the GROUP tag and setting up applications to open how I want them to open.
Here’s the result: my tray stays on top and shows the task bar, pager (I’ve changed the active color to a more neutral tone of blue since things are now maximized by default), etc., while the applications are started without title bars or borders. I set my tray to 20 pixels, so I’m losing an area of 20×800 compared to ratpoison. I could factor out the tray altogether, but I don’t object to trading that space for task bar and pager — though I’ve gone ahead and removed the menu button since I can access it via alt-F1.
The maximized applications open in similar style as anti-WIMP window managers without any need to maximize or move them around — just toggle between them with alt-tab or between virtual desktops with alt-n (where n is the number of the desktop). I also don’t have to type a keystroke to make applications “float” as some window managers would require — if they’re not in the group that opens maximized and without borders or title bars, they open as they normally would. You can see the outline of the little GIMP box on the second desktop.
And here’s another shot editing a document.
Manipulation of windows is easy. Want to unmaximize a terminal so it “floats”? Just alt-F2 unmaximize. Want to move a window from one desktop to another? Just alt-F2 for the window menu and then select “move to” and choose your desktop. Don’t want multiple desktops? That’s in the configuration file. Don’t want alt-F2? Change it to what you want or bind commands separately.
I’m still tweaking things, but so far I think it’s very possible to configure jwm to work in a completely mouse-free environment. I’ll post more later.
10 Dec 2007 – 1049 US/Central
I have a few minutes between meetings to post more shots of the task bar without the menu button and some shots of Opera to show that jwm can be configured without any window decorations. The far left corner icon is the desktop toggle, which only works with a mouse. I left that for convenience but it isn’t necessary. I set a binding for the run application in DSL, which is keyboard friendly. This shot shows it launched and “floating.”
I opened Opera, which is set in my GROUP that opens maximized and without any window decorations.
I’m not limited to keeping it that size or in that position. I can alt-F2 to control the window.
Select resize, then adjust the size to whatever I want.
Then I can move it the same way.
And then I can re-maximize it and it goes back to where I started. Other applications needn’t be set to open full screen. GIMP opens with multiple small windows (depending how many you had open when you previously shut down). I keep it on a separate desktop so it doesn’t clutter screenshots or get in the way when using alt-tab between things on a desktop.
Many other apps also work well without a mouse using this kind of approach. I included xzgv in my maximized and no window decorations group. It works very well with keyboard.
Here’s the GROUP tag I used for full screen. This is set up below the last closing menu tag in .jwmrc (I factored out the default DSL menu and INCLUDE it, giving me a little more flexibility).
I’m still fiddling with other apps and settings. I’m going to try to set all my GUI apps to open on desktop 2, 3, or 4. I’m also going to bind a separate “speed” menu of my most commonly used apps so I don’t have to navigate through the default.
More later if I get time.
12 Dec 2007 – 0645 US/Central
I’ve added two more root menus. One of them is the aforementioned “speed menu” with my most commonly used and needed tasks. I know the M in WIMP is for menu, but these are bound by keystroke not pointing device and navigable by arrow keys as well as the standard vi bindings per default keybindings in jwmrc. They’re also inaccessible to pointing and clicking because I removed the default menu button altogether — see some of the above screenshots (the Opera ones are most recent, and here’s a full size screenshot that’s more recent than those; across the top: desktop hide button, six pagers, task list, clock, and rox filer window showing icon scaling for perspective).
The next root menu is an initial attempt to get back to the DSL 4 paradigm of data-centric computing. I have some work to do. For now, it’s a static list of documents I work with on a regular basis with standard commands to open in the manner they should. I also included my playlists, my local html content, some image directories, etc. My plan is to make it more dynamic in the manner of a “recent documents” folder/menu so that the most recently saved file appears at the top and all files open per MIME association (text in gvim, images in either GIMP or xzgv, audio in mpg321, etc.). I have a few ideas how to do this without running a script in cron every minute to recurse my directories for most recent files and thereby crippling my CPU. I should have some time to work on this later in the week and this weekend. (Maybe something like this could be used with an INCLUDE tag in the main menu for a “recent documents” section, adding further utility to DSL 4.)
Let me summarize what I’ve done so far.
- Factored out the main DSL menu and INCLUDE it in the default root menu.
- Increased the number of keybindings.
- Added two more root menus: one for frequently used commands and applications and another for frequently worked on documents (and playlists, etc.). The goal is to make the latter dynamic rather than static to fit in with the DSL 4 way.
- Removed menu buttons. Reduced size of tray. Reduced menu size. Added pagers.
- Configured specific apps to open without additional title decorations or borders and to maximum size. This automates window management to some extent like other window managers.
There have been a few shortcomings compared to other window managers. I don’t like how jwm’s root binding clobbers everything. By default, it’s alt-_. So accessing commands on GUI apps via alt-f (which is nearly universal) doesn’t work. I thought changing it to shift-alt-_ would help, but that clobbered the shift key (while in vim, no less — no : without shift, no way to save or exit). Changing it to ctrl-alt is no good, either, (especially with F1, which I suppose I could change) because ctrl clobbers everything.
More later, after I figure out what to do about my dynamic content menu.
14 Dec 2007 – 0730 US/Central
Now I have my dynamic content menu. I wasn’t even going to get to it until later this afternoon or this weekend. I was taking care of a few things for work and wanted to play a new playlist I’d made. I went to open my content menu and remembered I hadn’t edited it to include any new content so I’d either have to start it manually or add it to the list.
While thinking it over, I switched jwm themes. A dim little light went on. I copied Robert’s code for the theme switcher over to /opt/bin/rhapsodyM3Uplayer.lua:
home = os.getenv(“HOME”)
if #arg == 1 then
playlist = arg
playlist = fltk.fl_file_chooser(“select playlist”, “Types\
if playlist == nil then
os.execute(“mpg321 -@ “..playlist..” & exit”)
I checked to see that it was executable, added a link to it in my formerly-static content menu, and gave it a shot.
In the above screenshot, you can see the file manager box with the root menu I set up for content opened back up. So now I can set up variations according to file type and, as long as I keep my data organized and nested (which I usually do), I can set up menu entries based on MIME-types as I did for playlists and select according to data file on the fly.
Here’s a close up. The mpg321 playlists
are were static — the menu (separate from the jwmrc and INCLUDED in it) would have to be edited for each new playlist. I included entries for mocp and a killall, but both are going to the other personal root menu (which has my most frequent commands and applications). EDIT: I changed the verb tense above because all the static data entries have now been removed from that root menu and will be in another root menu that opens that specific data.
I just did a few more this morning and moved all my playlists to a single directory and changed the above script to reflect the new directory (I wanted those separated from the directories for each ripped CD). I have the menu now set up for podcasts, Open Office formats, HTML, images, Wiki (vim potwiki), and jwm configuration files.
You can see in the above shot of my personal keybindings that I now have three root menus (alt-f1 is the default for jwm’s menu; I changed that to root:3 from root:123). The default (accessed via alt-F1) is the standard DSL menu. I have another “speed” menu of my favorite apps and frequent commands (accessed via alt-F12). The third is a data-oriented menu (accessed via alt-F11) that shows the content I have and opens according to the data:application relationship I’ve set up in each Lua script. It can be changed in a manner similar to how dfm sets up associations, though it’s not nearly as centralized (I am using my hostname — rhapsody — as a prefix on each of those scripts so they stay together).
If I make any changes, it may be in my keybindings. Some of them are redundant to what’s already available elsewhere (such as the window management bindings I set up with ctl-alt which are all available in alt-F2). There’s also less of a need to open apps now that I can associate the data and have a separate menu for that.
I haven’t decided yet if I want to do any more than this — such as a “recent documents” menu. I don’t see the need because this puts my mouseless reconfiguration on par with the changes in DSL 4 that make it more data-centric. This also doesn’t require more overhead from cron scripts, maintaining databases of file changes, etc. It’s simple, fast, no more overhead than is already required to run the system, and others have done 98-99% of the work (thanks Robert) to make my 1-2% pretty damn easy. Maybe that’s the best part.
29 Dec 2007 – 0700 US/Central
I switched my xinitrc back to the one I use for ratpoison because I was fed up with not being able to get JWM to behave the way I wanted it.
I played around with my keybindings last night and narrowed the issue of why the alt/meta key is useless outside of JWM. I thought it was due to the root menus being bound to alt commands, but instead it was the nextstacked command. As soon as I figured that out, I was able to regain use of alt commands for all my apps — I’m very happy.
I’m using the next command instead of nextstacked to toggle through windows on any given desktop. The only difference is next is completely sequential while nextstacked toggles between the current and previous windows (unless the user continues using it repeatedly and then it either goes forward or backward sequentially). This is much more acceptable even though it means the only way to toggle between two particular windows is to only have two windows on that desktop.
This is pretty cool because now I don’t have to completely disable JWM’s keybindings and try to use a separate utility to manage them. I’m not sure I would’ve been able to get any of my menus to open with a separate app. I also didn’t like the idea of running yet another process in the background to duplicate what should already be available in JWM.
With that nagging issue resolved, I heartily approve of JWM as a mouseless window manager. Just make sure to change the default alt-tab binding from nextstacked to next, or consider making other changes like reassigning unused keys to those jwm can use as masks, etc.