speedwm is a window manager forked from dwm or dynamic window manager. It manages the user's open windows and tiles them according to a set layout (dynamic).
Just like dwm, speedwm also tries to be minimal but also has functionality and aesthetics as a goal. Tiling window managers (unlike floating window managers that you may be used to) tile windows based on a set layout making them easy to get productive on. They also encourage the user to use their keyboard instead of the mouse so that the user doesn't have to move his hands much but there are also mouse binds and more can be added by the user if desired.
- If a display manager is used, make sure it supports .desktop entries.
- NOTE: `ly` is known to have issues with dwm and speedwm.
If you see a bar or at least a cursor, your X server is likely working.
If you do **not** see a cursor or a bar, and no keys seem to do anything, your X server is most likely not configured properly.
If you get sent back to the TTY, your X server is most likely not configured properly. In this case, see your distro's wiki page on how to set up X11.
Note that speedwm is not and will **never** be compatible with Wayland. I have no interest in ever supporting or developing for it. Please don't create any issues regarding Wayland support.
If you're having any issues on operating systems with the BSD kernel, or something like NixOS, please file a bug report here on Codeberg, or by emailing me.
- Very minimal C compiler that speedwm uses to greatly speed up compile times. If you do not want this dependency, edit host.mk and set CC to 'cc' (or what C99 compiler you prefer).
- As of speedwm 1.9, speedwm now expects spmenu (fork of dmenu) to be on the system instead of dmenu. While you can revert this change I cannot provide support due to missing arguments.
To configure speedwm, you may /usr/share/speedwm/example.Xresources to either ~/.speedwmrc or ~/.config/speedwm/speedwmrc. Alternatively, you can also copy the values to your .Xresources file.
.speedwmrc or speedwm/speedwmrc will be loaded when speedwm restarts. If you want to load a .Xresources file you'll need to add that to autostart.sh.
Colors do not reload automatically though, you must reload them manually. Use a signal for this (See list of signals above) or simply 'libspeedwm --perform core_wm_reload'. This won't restart speedwm, but it will reload colors.
To use .Xresources, make sure 'xrdb' is installed. If a .xinitrc is used, add 'xrdb /path/to/.Xresources/file' before 'speedwm'. If a .Xresources file is not used, add it to ~/.config/speedwm/autostart.sh instead.
If you don't want to define the options manually, there is an example .Xresources file containing speedwm default settings in docs/example.Xresources. You can copy this somewhere or you can simply '<docs/example.Xresources>> ~/.Xresources' to append the speedwm options to your .Xresources file.
The magic of .Xresources is that it is a universal configuration file. While you *can* use the col.value values, you can also use traditional colors 0 through 15 as well. These colors take priority over regular speedwm colors. This is so that speedwm is compatible with Pywal and more general/mainstream .Xresources configurations.
Below is a list of all .Xresources values you can define.
To use signals, you can use libspeedwm. Previously, speedwm-utils (part of speedwm-extras) would be used but that now depends on libspeedwm anyway. Using libspeedwm directly is the easiest option.
If you do not have speedwm-extras or libspeedwm, you can use the speedwm binary itself. The syntax is speedwm -s "#cmd:<signum>"
This option is not as solid though as signums can and will likely be moved around breaking your scripts. Therefore I highly recommend you use libspeedwm when writing scripts.
- This allows you to color the status bar text at any time.
- statuscmd markup
- This allows the status bar to have clickable modules.
as well as regular plain text and colored emojis or glyphs. To override this status, you can use the 'speedwm -s "status text"' command. If you prefer, you can also use `xsetroot -name` which does the same thing.
Bundled with speedwm is a fork of dwmblocks. dwmblocks is a dwm status bar that handles this all for you through a block system. This fork has been integrated into the Makefile and is (by default) installed when speedwm is compiled. The status bar can be configured in the status.c and status.h.
By default the status bar runs modules that are also bundled with speedwm (see modules/ directory). To configure these modules, you can edit ~/.config/speedwm/statusrc which should be created when a module runs.
The bundled status bar is autostarted by speedwm if it is installed. If you want to use your own status bar, comment out 'USESTATUS' in toggle.mk and remove /usr/bin/status if speedwm has been installed previously. Then simply start the status bar through autostart.h, ~/.config/speedwm/autostart.sh, .xinitrc or some other means of running a program.
If you wish to add autostart entries without recompiling, consider using $HOME/.config/speedwm/autostart.sh. This is a path added to autostart.h and you can fill it with anything you want.
As of 1.8, speedwm has a module system. It is based on the `barmodules` patch for dwm and allows extensive control over the way the speedwm bar functions. This control has its own header, `bar.h`.
`bar.h` contains a somewhat detailed list of all possible options here, but more importantly it contains a `barrules` array which allows extensive control over where each bar module is placed and how it functions. In theory, this means you could put 22 instances of the same, boring tags on one bar, although why would one do that?
Each module can be aligned to any part of the bar (See 'Alignment' for possible values). If, let's say multiple modules both align to the right next to the center split (middle), the first module takes priority.
Below is a list of all modules bundled with speedwm. The source code for these modules are all in `bar/` and declared in `bar/items.c` and `bar/items.h`.
- title: Title, shows all windows, including hidden windows.
- title_basic: Basic title, shows focused window.
### Monitor
The monitor value allows you to specify which monitor the module should be placed on. In addition to this, you can also choose to only draw the module on the focused monitor.
-1: Show the module on all monitors.
0: Show on the main monitor (monitor 0).
1: Show on monitor #1 (This can be any monitor you want).
### Bar
This value allows you to specify which bar the module is placed on. speedwm supports two (0 and 1) bars. 0 is the main bar, which is by default placed at the top. 1 is the second bar which is only visible if modules actively use it. If the main bar is placed on the top, the second bar is placed on the bottom and vice versa.
0: Place the module on the main bar
1: Place the module on the extra bar
### Alignment
This value allows you to specify an alignment for the module in question. As previously mentioned, the first module takes priority if multiple modules have the same alignment.
The 'center split' refers to the middle of the bar, and that's where any free space/remainder of the screen ends up for other modules to use if desired.
- bar_align_left: Force the module to be placed on the left side of the bar if possible.
- bar_align_right: Force the module to be placed on the right side of the bar if possible.
- bar_align_center: Force the module to be placed in the center of the bar if possible.
- bar_align_left_left: Force the module to be placed on the left side of the bar next to the center split.
- bar_align_left_right: Force the module to be placed on the right side of the bar next to the center split.
- bar_align_left_center: Force the module to be placed on the center in the middle of the remaining space left of the center split on the left..
- bar_align_right_left: Force the module to be placed on the left side of the bar next to the center split.
- bar_align_right_right: Force the module to be placed on the right side of the bar next to the center split.
- bar_align_right_center: Force the module to be placed on the center in the middle of the remaining space left of the center split on the right.
- bar_align_none: No specific alignment. This will give the module the remaining space.
### Width
'Width' refers to the function to call which returns the width of a module. The syntax below applies to all default modules.
Syntax: width_<module>
Example: width_tags_pwl
### Draw
'Draw' refers to the function to call which draws the module on the bar. The syntax below applies to all default modules.
Syntax: draw_<module>
Example: draw_tags_pwl
### Click
'Click' refers to the function to call which checks if you clicked on said module. The syntax below applies to all default modules.
With all that said, you should now be able to add a module. In case you weren't able to follow along, here is an example of how you can add powerline tags on the focused monitor.
Remember that you can have put any module wherever you want. Nothing is stopping you from having your tags on the right. This is what makes bar rules so powerful.
Like the bar array mentioned previously, there is a `Key keys` array in `keybinds.h` which contains all keybinds speedwm will recognize. While this isn't the only way to add keybinds in speedwm, it does not require any additional software to be installed.
In keybinds.h, MODIFIER1 and MODIFIER2 are also defined. MODIFIER1 is defined in order to make modifying keybinds easier. MODIFIER1 is by default defined as SUPER or Mod4Mask. For instance, if you want to use MODIFIER1 as your modifier, `MODIFIER1` would be the right value here.
Do note that you can may use multiple modifiers. Do this by adding two or more modifiers separated by a pipe (MODIFIER1|SHIFT)
### Chain key
This value *is* mandatory, but it does not have to be used. speedwm has supported chained keybinds since 0.4. Chained keybinds allow more keybinds as like the name implies, the user has to press multiple keys to activate it. You can think of it as in Vim where there's different modes.
The first key that needs to be pressed to activate a chain needs to be the key specified here. In order to see a list of possible keys, see `/usr/include/X11/keysymdef.h`. If, let's say we want to use simply the letter `a` as the key to start a chain, the value here would be `XK_a`.
The next value, similar to the Chain key also needs to be a keysym. If the key is a chained key, this is the second key that needs to be pressed. If it isn't a chained key, this is the key that needs to be pressed while the Modifier is pressed.
In order to see a list of possible keys, see `/usr/include/X11/keysymdef.h`. Note that this path may differ depending on your operating system.
There are a lot more keys technically defined, see `/usr/include/X11/XF86keysym.h` for a list of media keys.
Many functions expect an argument to be passed to them. However this value does require any function argument to be specified because it simply passes the next value to the function and calls it.
There is no list of functions, but `speedwm.c` has a lot of declared functions which you may use in keybinds provided the function expects `const Arg *arg`.
Passing a float (such as mfact) through would mean I should override `.f`, passing an integer (such as barposition) through would mean I should override `.i`. There's also `.v` for `void` and `.ui` for tags. This is not used unless you want to mess with tag keybinds.
When you don't care about the value given to the function, you may simply enter a `0`.
### Example keybind
With all that said, you probably get the idea of how it works. But you still don't know how to put all this knowledge together.
1.`{ KeyPress,`
2.`MODIFIER1|SHIFT,`
3.`-1,`
4.`XK_w,`
5.`spawn,`
6.`cmd( "firefox" ) },`
Combined into one line: `{ KeyPress, MODIFIER1|SHIFT, -1, XK_w, spawn, cmd( "firefox" ) },`
### Example chained keybind
1.`{ KeyPress,`
2.`MODIFIER1|SHIFT,`
3.`XK_a,`
4.`XK_w,`
5.`togglebar,`
6.`{0} },`
Combined into one line: `{ KeyPress, MODIFIER1|SHIFT, XK_a, XK_w, togglebar, {0} },`
This should give you a brief idea of how keybinds work in speedwm. Most of this carries over to `dwm` as well, although it does not have some of this stuff.
I far from wrote this entire project myself. Below are people who made this project what it is through submitting patches to suckless or otherwise contributing code in some way in alphabetical order.