sowm

An itsy bitsy floating window manager (220~ sloc!).
git clone git://mfeller.io/sowm.git
Log | Files | Refs | README | LICENSE

commit 8ee3294adf653dbe0332ea825bcd344d3511d84c
parent 124ec675796a7879517b9268259ee4a96c7f60be
Author: Dylan Araps <dylan.araps@gmail.com>
Date:   Wed, 18 Dec 2019 11:30:21 +0000

Merge branch 'master' of github.com:dylanaraps/sowm

Diffstat:
MREADME.md | 2++
Apatches/sowm-handlebar.patch | 173+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatches/sowm-rect-to-move.patch | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatches/sowm-wheelresize.patch | 43+++++++++++++++++++++++++++++++++++++++++++
Msowm.c | 8++++++++
5 files changed, 343 insertions(+), 0 deletions(-)

diff --git a/README.md b/README.md @@ -65,6 +65,8 @@ An itsy bitsy floating window manager (*220~ sloc / 24kb compiled!*). 2) Run `make` to build `sowm`. 3) Copy it to your path or run `make install`. - `DESTDIR` and `PREFIX` are supported. +4) (Optional) Apply patch with `git apply patches/patch-name` + - In case of applying multiple patches, it has to be done **manually**. ## Thanks diff --git a/patches/sowm-handlebar.patch b/patches/sowm-handlebar.patch @@ -0,0 +1,173 @@ +diff --git a/config.def.h b/config.def.h +index aaaf38d..bcf49d8 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -3,6 +3,9 @@ + + #define MOD Mod4Mask + ++const int handle_bar_thickness = 20; ++const char *handlebar_colour = "#ffffff"; ++ + const char* menu[] = {"dmenu_run", 0}; + const char* term[] = {"st", 0}; + const char* scrot[] = {"scr", 0}; +diff --git a/sowm.c b/sowm.c +index bc14c4e..42bd732 100644 +--- a/sowm.c ++++ b/sowm.c +@@ -54,6 +54,9 @@ static unsigned int ww, wh; + static Display *d; + static XButtonEvent mouse; + ++static Window hb = 0; ++static XColor hbc; ++ + static void (*events[LASTEvent])(XEvent *e) = { + [ButtonPress] = button_press, + [ButtonRelease] = button_release, +@@ -75,8 +78,36 @@ static void (*events[LASTEvent])(XEvent *e) = { + XGetGeometry(d, W, &(Window){0}, gx, gy, gw, gh, \ + &(unsigned int){0}, &(unsigned int){0}) + ++void configure_hb_for_window(Window w) { ++ XWindowAttributes wa; ++ XGetWindowAttributes(d, w, &wa); ++ if (!hb) { ++ int s = DefaultScreen(d); ++ hb = XCreateSimpleWindow(d, RootWindow(d, s), ++ wa.x, wa.y - handle_bar_thickness, ++ wa.width + 2*wa.border_width, handle_bar_thickness, ++ 0, ++ hbc.pixel, hbc.pixel); ++ XMapWindow(d, hb); ++ XGrabButton(d, AnyButton, AnyModifier, hb, True, ++ ButtonPressMask|ButtonReleaseMask|PointerMotionMask, ++ GrabModeAsync, GrabModeAsync, 0, 0); ++ } else ++ XMoveResizeWindow(d, hb, wa.x, wa.y - handle_bar_thickness, ++ wa.width, handle_bar_thickness); ++ XRaiseWindow(d, hb); ++} ++ ++void destroy_hb(void) { ++ if (!hb) return; ++ XUnmapWindow(d, hb); ++ XDestroyWindow(d, hb); ++ hb = 0; ++} ++ + void win_focus(client *c) { + cur = c; ++ configure_hb_for_window(c->w); + XSetInputFocus(d, cur->w, RevertToParent, CurrentTime); + } + +@@ -93,7 +124,22 @@ void notify_enter(XEvent *e) { + } + + void notify_motion(XEvent *e) { +- if (!mouse.subwindow || cur->f) return; ++ if (e->xmotion.window == hb) { ++ while(XCheckTypedEvent(d, MotionNotify, e)); ++ ++ int xd = e->xbutton.x_root - mouse.x_root; ++ int yd = e->xbutton.y_root - mouse.y_root; ++ ++ XMoveResizeWindow(d, cur->w, ++ wx + (mouse.button == 1 ? xd : 0), ++ wy + (mouse.button == 1 ? yd : 0), ++ ww + (mouse.button == 3 ? xd : 0), ++ wh + (mouse.button == 3 ? yd : 0)); ++ ++ configure_hb_for_window(cur->w); ++ } ++ ++ if (!mouse.subwindow || mouse.subwindow == hb || cur->f) return; + + while(XCheckTypedEvent(d, MotionNotify, e)); + +@@ -105,6 +151,8 @@ void notify_motion(XEvent *e) { + wy + (mouse.button == 1 ? yd : 0), + ww + (mouse.button == 3 ? xd : 0), + wh + (mouse.button == 3 ? yd : 0)); ++ ++ if (mouse.subwindow == cur->w) configure_hb_for_window(cur->w); + } + + void key_press(XEvent *e) { +@@ -116,6 +164,13 @@ void key_press(XEvent *e) { + } + + void button_press(XEvent *e) { ++ if (e->xbutton.window == hb) { ++ mouse = e->xbutton; ++ win_size(cur->w, &wx, &wy, &ww, &wh); ++ XRaiseWindow(d, cur->w); ++ return; ++ } ++ + if (!e->xbutton.subwindow) return; + + win_size(e->xbutton.subwindow, &wx, &wy, &ww, &wh); +@@ -154,6 +209,8 @@ void win_del(Window w) { + + for win if (c->w == w) x = c; + ++ if (x == cur) destroy_hb(); ++ + if (!list || !x) return; + if (x->prev == x) list = 0; + if (list == x) list = x->next; +@@ -174,6 +231,8 @@ void win_center() { + win_size(cur->w, &(int){0}, &(int){0}, &ww, &wh); + + XMoveWindow(d, cur->w, (sw - ww) / 2, (sh - wh) / 2); ++ ++ configure_hb_for_window(cur->w); + } + + void win_fs() { +@@ -182,9 +241,11 @@ void win_fs() { + if ((cur->f = cur->f ? 0 : 1)) { + win_size(cur->w, &cur->wx, &cur->wy, &cur->ww, &cur->wh); + XMoveResizeWindow(d, cur->w, 0, 0, sw, sh); +- +- } else ++ destroy_hb(); ++ } else { + XMoveResizeWindow(d, cur->w, cur->wx, cur->wy, cur->ww, cur->wh); ++ configure_hb_for_window(cur->w); ++ } + } + + void win_to_ws(const Arg arg) { +@@ -201,6 +262,8 @@ void win_to_ws(const Arg arg) { + XUnmapWindow(d, cur->w); + ws_save(tmp); + ++ destroy_hb(); ++ + if (list) win_focus(list); + } + +@@ -227,6 +290,8 @@ void ws_go(const Arg arg) { + + ws_sel(arg.i); + ++ destroy_hb(); ++ + if (list) win_focus(list); else cur = 0; + } + +@@ -290,6 +355,10 @@ int main(void) { + ButtonPressMask|ButtonReleaseMask|PointerMotionMask, + GrabModeAsync, GrabModeAsync, 0, 0); + ++ Colormap cm = DefaultColormap(d, s); ++ XParseColor(d, cm, handlebar_colour, &hbc); ++ XAllocColor(d, cm, &hbc); ++ + while (1 && !XNextEvent(d, &ev)) + if (events[ev.type]) events[ev.type](&ev); + } diff --git a/patches/sowm-rect-to-move.patch b/patches/sowm-rect-to-move.patch @@ -0,0 +1,117 @@ +diff --git a/sowm.c b/sowm.c +index bc14c4e..4ae3a8f 100644 +--- a/sowm.c ++++ b/sowm.c +@@ -65,6 +65,9 @@ static void (*events[LASTEvent])(XEvent *e) = { + [MotionNotify] = notify_motion + }; + ++ ++Window WaitingWindow; ++ + #include "config.h" + + #define win (client *t=0, *c=list; c && t!=list->prev; t=c, c=c->next) +@@ -75,6 +78,23 @@ static void (*events[LASTEvent])(XEvent *e) = { + XGetGeometry(d, W, &(Window){0}, gx, gy, gw, gh, \ + &(unsigned int){0}, &(unsigned int){0}) + ++#define ABS(N) (((N)<0)?-(N):(N)) ++ ++void draw_outline(int x1, int y1, int x2, int y2) { ++ XClearWindow(d, RootWindow(d, DefaultScreen(d))); ++ ++ GC gc = XCreateGC(d, RootWindow(d, DefaultScreen(d)), 0, NULL); ++ if(!gc)return; ++ ++ XSetForeground(d, gc, WhitePixel(d, DefaultScreen(d))); ++ XDrawLine(d, RootWindow(d, DefaultScreen(d)), gc, x1, y1, x1, y2); ++ XDrawLine(d, RootWindow(d, DefaultScreen(d)), gc, x1, y1, x2, y1); ++ XDrawLine(d, RootWindow(d, DefaultScreen(d)), gc, x1, y2, x2, y2); ++ XDrawLine(d, RootWindow(d, DefaultScreen(d)), gc, x2, y1, x2, y2); ++ XFreeGC(d, gc); ++ XFlush(d); ++} ++ + void win_focus(client *c) { + cur = c; + XSetInputFocus(d, cur->w, RevertToParent, CurrentTime); +@@ -93,7 +113,10 @@ void notify_enter(XEvent *e) { + } + + void notify_motion(XEvent *e) { +- if (!mouse.subwindow || cur->f) return; ++ if (!mouse.subwindow || cur->f) { ++ draw_outline(mouse.x_root, mouse.y_root, e->xbutton.x_root, e->xbutton.y_root); ++ return; ++ } + + while(XCheckTypedEvent(d, MotionNotify, e)); + +@@ -116,15 +139,43 @@ void key_press(XEvent *e) { + } + + void button_press(XEvent *e) { +- if (!e->xbutton.subwindow) return; ++ mouse = e->xbutton; + ++ if (!e->xbutton.subwindow) return; + win_size(e->xbutton.subwindow, &wx, &wy, &ww, &wh); + XRaiseWindow(d, e->xbutton.subwindow); +- mouse = e->xbutton; + } + +-void button_release() { +- mouse.subwindow = 0; ++void button_release(XEvent *e) { ++ XClearWindow(d, RootWindow(d, DefaultScreen(d))); ++ ++ if(WaitingWindow){ ++ XSelectInput(d, WaitingWindow, StructureNotifyMask|EnterWindowMask); ++ win_size(WaitingWindow, &wx, &wy, &ww, &wh); ++ win_add(WaitingWindow); ++ cur = list->prev; ++ ++ XMoveResizeWindow(d, cur->w, ++ e->xbutton.x_root > mouse.x_root ? mouse.x_root : e->xbutton.x_root, ++ e->xbutton.y_root > mouse.y_root ? mouse.y_root : e->xbutton.y_root, ++ ABS(mouse.x_root - e->xbutton.x_root), ++ ABS(mouse.y_root - e->xbutton.y_root)); ++ ++ XMapWindow(d, WaitingWindow); ++ win_focus(list->prev); ++ ++ WaitingWindow = 0; ++ ++ } else if(!mouse.subwindow && cur) { ++ ++ XMoveResizeWindow(d, cur->w, ++ e->xbutton.x_root > mouse.x_root ? mouse.x_root : e->xbutton.x_root, ++ e->xbutton.y_root > mouse.y_root ? mouse.y_root : e->xbutton.y_root, ++ ABS(mouse.x_root - e->xbutton.x_root), ++ ABS(mouse.y_root - e->xbutton.y_root)); ++ ++ mouse.subwindow = 0; ++ } + } + + void win_add(Window w) { +@@ -244,17 +295,7 @@ void configure_request(XEvent *e) { + } + + void map_request(XEvent *e) { +- Window w = e->xmaprequest.window; +- +- XSelectInput(d, w, StructureNotifyMask|EnterWindowMask); +- win_size(w, &wx, &wy, &ww, &wh); +- win_add(w); +- cur = list->prev; +- +- if (wx + wy == 0) win_center(); +- +- XMapWindow(d, w); +- win_focus(list->prev); ++ WaitingWindow = e->xmaprequest.window; + } + + void run(const Arg arg) { diff --git a/patches/sowm-wheelresize.patch b/patches/sowm-wheelresize.patch @@ -0,0 +1,43 @@ +diff --git a/config.def.h b/config.def.h +index aaaf38d..5a95d71 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -2,6 +2,7 @@ + #define CONFIG_H + + #define MOD Mod4Mask ++#define WheelResizeStep 5 + + const char* menu[] = {"dmenu_run", 0}; + const char* term[] = {"st", 0}; +diff --git a/sowm.c b/sowm.c +index bc14c4e..3b95c28 100644 +--- a/sowm.c ++++ b/sowm.c +@@ -120,6 +120,17 @@ void button_press(XEvent *e) { + + win_size(e->xbutton.subwindow, &wx, &wy, &ww, &wh); + XRaiseWindow(d, e->xbutton.subwindow); ++ ++ int sd = 0; ++ if(e->xbutton.button == Button4) sd = WheelResizeStep; ++ else if(e->xbutton.button == Button5) sd = -WheelResizeStep; ++ ++ XMoveResizeWindow(d, e->xbutton.subwindow, ++ wx - sd, ++ wy - sd, ++ ww + sd*2, ++ wh + sd*2); ++ + mouse = e->xbutton; + } + +@@ -285,7 +296,7 @@ int main(void) { + XGrabKey(d, XKeysymToKeycode(d, keys[i].keysym), keys[i].mod, + root, True, GrabModeAsync, GrabModeAsync); + +- for (int i=1; i<4; i+=2) ++ for (int i=1; i<6; i++) + XGrabButton(d, i, MOD, root, True, + ButtonPressMask|ButtonReleaseMask|PointerMotionMask, + GrabModeAsync, GrabModeAsync, 0, 0); diff --git a/sowm.c b/sowm.c @@ -42,6 +42,7 @@ static void win_center(); static void win_del(Window w); static void win_fs(); static void win_kill(); +static void win_prev(); static void win_next(); static void win_to_ws(const Arg arg); static void ws_go(const Arg arg); @@ -209,6 +210,13 @@ void win_to_ws(const Arg arg) { if (list) win_focus(list); } +void win_prev() { + if (!cur) return; + + XRaiseWindow(d, cur->prev->w); + win_focus(cur->prev); +} + void win_next() { if (!cur) return;