Major refactor.

This commit is contained in:
Luis Lavaire 2024-12-27 01:36:56 -06:00
parent bf0d3de94b
commit bb8a508ef4
4 changed files with 67 additions and 46 deletions

View file

@ -1,37 +1,42 @@
# mwm # mwm
For the true minimalist: The window manager for the true minimalist:
- ~40 LOC. - 20 LOC.
- No default keybindings (just edit the source). - No modes.
- No title bars, no status bars, no buttons, no borders, no menus, etc. - No "eye-candy".
- No eye-candy.
- No mouse control. - No mouse control.
- No virtual desktops. - No virtual desktops.
- No configuration files. - No configuration files.
- Not standards-compliant.
- No title bars, no status bars, no buttons, no borders, no menus, etc.
- All windows are full-screen, just one is visible at any given time.
- Absolutely adaptable to your needs. - Absolutely adaptable to your needs.
- Includes just what is strictly needed. - Includes just what is strictly needed.
- Not standards-compliant.
- All windows are full-screen, just one is visible at any given time. This is the smallest, actually usable window manager I know about. Even
- No modes. TinyWM is twice as large. However, it doesn't let you launch programs, or
switch between windows. `mwm` does.
## Why? ## Why?
Most software today is crappy. Do you really need all that? I found out Most software today is crappy. Do you really need all the bells and whistles?
through experience that, generally, you don't. Do you really need to have Generally, you don't. You need to get the job done.
a dozen windows opened simultaneously? When you do, you will need a way to
organize that mess. Virtual desktops, window tags, etc. are ways to cope
with the symptoms of a underlying issue.
We are in dire need of software that is hackable, fun, small, malleable, We are in dire need of software that is hackable, fun, small, malleable, and
and that you can wrap your head around, because: is it truly free software that you can wrap your head around, because: is it truly free software if, due
if, due to its complexity, you cannot modify it? ;) to its complexity, you cannot modify it? ;)
## How? ## How?
Two macros are available for assigning keybindings: `grab` and `K`. Two macros are available for assigning keybindings: `grab` and `map`. Read
Read the source for an example on how to use them (my own setup). `mwm-custom.c` for an example on how to use them (my own setup).
Run `./build.sh`. Pass `CC=` to use a different C compiler (I use tcc). You first need to `grab` the keys you want to be able to bind. Then you `map`
them to actions.
## Building.
Run `./build.sh`. Pass `CC=...` to use a different C compiler (I use `tcc`).
Dead simple. Dead simple.

View file

@ -1,4 +1,3 @@
#! /bin/sh #! /bin/sh
rm -f mwm; ${CC:-tcc} -lX11 mwm.c -o mwm rm -f mwm; ${CC:-tcc} -lX11 mwm.c -o mwm

30
mwm-custom.c Normal file
View file

@ -0,0 +1,30 @@
#include <X11/Xlib.h>
#include <stdlib.h>
#define stk(s) XKeysymToKeycode(d, XStringToKeysym(s))
#define on(_, x) if (e.type == _) { x; }
#define map(k, x) if (e.xkey.keycode == stk(k)) { x; }
#define grab(...) const char *l[] = { __VA_ARGS__, 0 }; \
for (int i = 0; l[i]; i++) XGrabKey(d, stk(l[i]), Mod4Mask, r, 1, 1, 1);
int main() {
Display *d = XOpenDisplay(0); Window r = DefaultRootWindow(d); XEvent e;
XSelectInput(d, r, SubstructureRedirectMask);
grab("n", "q", "w", "t", "l", "u", "i", "o", "p");
while (!XNextEvent (d, &e)) {
on(ConfigureRequest, XMoveResizeWindow(d, e.xconfigure.window, 0, 0, e.xconfigure.width, e.xconfigure.height);
XMoveResizeWindow(d, e.xconfigure.window, 0, 0, 1920, 1080)) // Needed due to a bug in XTerm.
on(MapRequest, XMapWindow(d, e.xmaprequest.window);
XSetInputFocus(d, e.xmaprequest.window, 2, 0))
on(KeyPress, map("n", XCirculateSubwindowsUp(d, r); XSetInputFocus(d, e.xkey.window, 2, 0))
map("q", XKillClient(d, e.xkey.subwindow))
map("w", system("chromium &"))
map("t", system("xterm &"))
map("l", system("rotK"))
map("u", system("vol 5%-"))
map("i", system("vol 5%+"))
map("o", system("bri -100"))
map("p", system("bri +100")))
}
}

39
mwm.c
View file

@ -2,35 +2,22 @@
#include <stdlib.h> #include <stdlib.h>
#define stk(s) XKeysymToKeycode(d, XStringToKeysym(s)) #define stk(s) XKeysymToKeycode(d, XStringToKeysym(s))
#define K(k, x) if (e.xkey.keycode == stk(k)) { x; } #define on(_, x) if (e.type == _) { x; }
#define E(_, x) if (e.type == _) { x; } #define map(k, x) if (e.xkey.keycode == stk(k)) { x; }
#define grab(...) const char *l[] = { __VA_ARGS__ }; \ #define grab(...) const char *l[] = { __VA_ARGS__, 0 }; \
for (size_t i = 0; i < sizeof(l) / sizeof(*l); ++i) \ for (int i = 0; l[i]; i++) XGrabKey(d, stk(l[i]), Mod4Mask, r, 1, 1, 1);
XGrabKey (d, stk(l[i]), Mod4Mask, r, 1, 1, 1);
int main () { int main() {
Display *d = XOpenDisplay(0); Window r = DefaultRootWindow(d); XEvent e; Display *d = XOpenDisplay(0); Window r = DefaultRootWindow(d); XEvent e;
XSelectInput (d, r, SubstructureRedirectMask); XSelectInput(d, r, SubstructureRedirectMask);
grab("n", "q", "e");
grab ("n", "q", "w", "t", "l", "u", "i", "o", "p");
while (!XNextEvent (d, &e)) { while (!XNextEvent (d, &e)) {
E (KeyPress, on(ConfigureRequest, XMoveResizeWindow(d, e.xconfigure.window, 0, 0, e.xconfigure.width, e.xconfigure.height));
K("n", XCirculateSubwindowsUp(d, r); XSetInputFocus(d, e.xkey.window, 2, 0)) on(MapRequest, XMapWindow(d, e.xmaprequest.window);
K("q", XKillClient(d, e.xkey.subwindow)) XSetInputFocus(d, e.xmaprequest.window, 2, 0));
K("w", system("chromium --enable-features=WebContentsForceDark &")) on(KeyPress, map("n", XCirculateSubwindowsUp(d, r); XSetInputFocus(d, e.xkey.window, 2, 0))
K("t", system("xterm &")) map("q", XKillClient(d, e.xkey.subwindow))
K("l", system("rotK")) map("e", system("dmenu_run &")));
K("u", system("vol 5%-"))
K("i", system("vol 5%+"))
K("o", system("bri -100"))
K("p", system("bri +100")))
E (MapRequest, XMapWindow(d, e.xmaprequest.window);
XSetInputFocus(d, e.xmaprequest.window, 2, 0))
E (ConfigureRequest,
XMoveResizeWindow (d, e.xconfigure.window, 0, 0, e.xconfigure.width, e.xconfigure.height);
XMoveResizeWindow (d, e.xconfigure.window, 0, 0, 1920, 1080))
} }
} }