This release has been a long time coming! The biggest change here is moving away from the compiled dwm-style config to a standalone config file. Initially I planned to use TOML as so many Rust projects do, but I wanted to preserve the dynamic aspects of the dwm config, like setting tags with left shift (1 << 3
) and marking all tags with bitwise negation (~0
) 1. Initially I wrote my own config language called fig but decided this would be too painful to support and switched to Lua. I'm not actually that familiar with Lua, but it was easy to embed with mlua and the syntax is straightforward enough. Lua is currently only used as a deserialization format for loading the config at startup, but it's obviously a full scripting language and could lead to opportunities for more runtime dynamism in the future.
The other major change is the inclusion of several dwm patches that I like in my own config. All of these (except the pertag patch), can easily be disabled by removing the relevant bindings from your config. Both of these changes are discussed more fully down below.
Finally, intermixed with these user-facing changes, are many internal improvements. There's still a ton of C-style unsafe code, but the amount has dropped a bit. There's also a new test (not a test suite, a single new test) that ensures the program at least builds, runs, and can handle receiving a single event. My attempts to extend this into a true test suite didn't go very well, but hopefully this can be improved in the future.
Thanks everyone for the support here and on YouTube! I've been using rwm as my daily driver for the past ~4 months now, and I think these changes make it a much nicer window manager to use. If you give it a try and run into any issues, please feel free to open an issue!
What's Changed
New config format
As mentioned above, rwm now has a config file read from $XDG_CONFIG_HOME/rwm/config.lua
or $HOME/.config/rwm/config.lua
. This file is evaluated in a context populated initially by the src/config.lua
file from the repository and by adding useful X11 symbols from src/config/env.rs
. rwm deserializes the rwm
table after loading all of this configuration to get its Config
struct, so the main job of your config.lua
file is to update fields of this table. For a simple example, you could patch a couple of basic options:
rwm.resize_hints = true
rwm.fonts = {"monospace:size=12"}
Or you can write functions and loops to accomplish what you need:
-- Look for key collisions and replace any conflicts instead of appending. If
-- you actually want multiple behaviors on the same key, just call
-- `table.insert` directly
function locate_key (o)
for i, k in ipairs(rwm.keys) do
if k.keysym == o.keysym and k.mod_ == o.mod_ then
return i
end
end
return false
end
for _, key in ipairs(keys) do
idx = locate_key(key)
if idx then
rwm.keys[idx] = key
else
table.insert(rwm.keys, key)
end
end
(These examples are duplicated from the README. This one in particular may be useful for adding custom key bindings)
ghostty came out while I was working on these changes, and their philosophy of having the default config work out of the box inspired me to take this approach. If you don't even have a config.lua
file, rwm will still launch normally and use the default values, which are mostly drawn from dwm. Then you can iteratively patch your config.lua
file and restart rwm without having to recompile. That workflow was the goal of these changes.
dwm patches
rwm is opinionated. I want to use it as my daily driver without having to apply or maintain a set of separate patches. As a result, I applied the patches that I used in my build of dwm:
- systray for a system tray
- swallow for window swallowing
- pertag for per-tag layouts and other settings
- scratchpad for a persistent but hidable scratch terminal
- stacker (partial) for moving windows up and down the stack
Again, all of these can be "disabled" by simply not binding their functions or functionality in your config file, with the exception of pertag
. I didn't really realize that about pertag
until I was preparing for the release, but after trying pertag
, I really didn't like going back to the default non-per-tag behavior. If you try it and don't like it, open an issue, and I'll try to gate it behind a config option too.
macOS support
Thanks to the report in #20, there is now a low level of support for macOS. I haven't tried this myself, but based on the comments there, rwm can be built on Mac and run inside of XQuartz.
Other changes
- Bump libc from 0.2.155 to 0.2.158 by @dependabot in #17
- Bump libc from 0.2.158 to 0.2.169 by @dependabot in #43
- Update dependencies by @ntBre in #46
Full Changelog: 1.0.1...2.0.0
-
This is a slightly touchy example because Lua doesn't have true integers. This means that you can't actually write
~0
in the new config file, unless you mean-1
. To get all the bits set in au32
in Rust, you need to usemath.floor(2^32 - 1)
in Lua, or theall_tags
variable included in the base environment for this purpose. ↩