From bb8a508ef46e5d4789f82dea644636b91bdca50f Mon Sep 17 00:00:00 2001 From: Luis Lavaire Date: Fri, 27 Dec 2024 01:36:56 -0600 Subject: [PATCH] Major refactor. --- README.md | 43 ++++++++++++++++++++++++------------------- build.sh | 1 - mwm-custom.c | 30 ++++++++++++++++++++++++++++++ mwm.c | 39 +++++++++++++-------------------------- 4 files changed, 67 insertions(+), 46 deletions(-) create mode 100644 mwm-custom.c diff --git a/README.md b/README.md index f2c3d8a..51436c4 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,42 @@ # mwm -For the true minimalist: +The window manager for the true minimalist: -- ~40 LOC. -- No default keybindings (just edit the source). -- No title bars, no status bars, no buttons, no borders, no menus, etc. -- No eye-candy. +- 20 LOC. +- No modes. +- No "eye-candy". - No mouse control. - No virtual desktops. - 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. - Includes just what is strictly needed. -- Not standards-compliant. -- All windows are full-screen, just one is visible at any given time. -- No modes. + +This is the smallest, actually usable window manager I know about. Even +TinyWM is twice as large. However, it doesn't let you launch programs, or +switch between windows. `mwm` does. ## Why? -Most software today is crappy. Do you really need all that? I found out -through experience that, generally, you don't. Do you really need to have -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. +Most software today is crappy. Do you really need all the bells and whistles? +Generally, you don't. You need to get the job done. -We are in dire need of software that is hackable, fun, small, malleable, -and that you can wrap your head around, because: is it truly free software -if, due to its complexity, you cannot modify it? ;) +We are in dire need of software that is hackable, fun, small, malleable, and +that you can wrap your head around, because: is it truly free software if, due +to its complexity, you cannot modify it? ;) ## How? -Two macros are available for assigning keybindings: `grab` and `K`. -Read the source for an example on how to use them (my own setup). +Two macros are available for assigning keybindings: `grab` and `map`. Read +`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. diff --git a/build.sh b/build.sh index ddae530..c103169 100755 --- a/build.sh +++ b/build.sh @@ -1,4 +1,3 @@ #! /bin/sh - rm -f mwm; ${CC:-tcc} -lX11 mwm.c -o mwm diff --git a/mwm-custom.c b/mwm-custom.c new file mode 100644 index 0000000..e2b4b8f --- /dev/null +++ b/mwm-custom.c @@ -0,0 +1,30 @@ +#include +#include + +#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"))) + } +} diff --git a/mwm.c b/mwm.c index 1644f31..9869ff7 100644 --- a/mwm.c +++ b/mwm.c @@ -2,35 +2,22 @@ #include #define stk(s) XKeysymToKeycode(d, XStringToKeysym(s)) -#define K(k, x) if (e.xkey.keycode == stk(k)) { x; } -#define E(_, x) if (e.type == _) { x; } -#define grab(...) const char *l[] = { __VA_ARGS__ }; \ - for (size_t i = 0; i < sizeof(l) / sizeof(*l); ++i) \ - XGrabKey (d, stk(l[i]), Mod4Mask, r, 1, 1, 1); +#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 () { +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"); + XSelectInput(d, r, SubstructureRedirectMask); + grab("n", "q", "e"); while (!XNextEvent (d, &e)) { - E (KeyPress, - K("n", XCirculateSubwindowsUp(d, r); XSetInputFocus(d, e.xkey.window, 2, 0)) - K("q", XKillClient(d, e.xkey.subwindow)) - K("w", system("chromium --enable-features=WebContentsForceDark &")) - K("t", system("xterm &")) - K("l", system("rotK")) - 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)) + on(ConfigureRequest, XMoveResizeWindow(d, e.xconfigure.window, 0, 0, e.xconfigure.width, e.xconfigure.height)); + 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("e", system("dmenu_run &"))); } }