all repos — ryudo @ 2281498cebb1606c6a481ea010681c341010e0ed

the floatiling window manager that flows; fork of rio from plan9port

README: update; client, config, fns, key, manage: fix focus bugs, tweak center snap, and wrangle out of bounds windows
Iris Lightshard nilix@nilfm.cc
PGP Signature
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEkFh6dA+k/6CXFXU4O3+8IhROY5gFAmA4iOUACgkQO3+8IhRO
Y5jRuA//dB8Hcczgr0tfMphRxWFhv+thAzIdj4oBgvWJKi6oMIX+4RpyDkMCqRku
sNp5sPPZdCRy2GktWFgZ7gP4SAE60HDwheuh6sxhpZBZEoe8P3mnqbC2tBkRj/tz
C0KxXeHgadwIBAyW8RLRxtlUxXQYVOuL+iw50Ogt2fFrDPF1yH2mWXoT8PzpQooo
P2ddfKXRJj0f130k4ke0EPDaS3mKD1O/U1L+3Ul7Mdrc99mPcZCyGg2EJLRdL6XI
YpOf/qcoXGP0rd//NiWd+x+Hn2dF88U7JwkjxhKNp6pYtlvGDKb5TX/YcmEPpgXH
7zHxMhOZYjEUqCL4NJ33WVKsVR604rK7bo6GtO2WWruS66PaZssiPRv3KO+6s3Q6
CSoBl+/v9WpRXNdY22MA3JFdsxnmVwsW0S4ATrHZHbUv5/x3p7rnnwgPAub65GDV
Aj5j3tPgB0fNgeWQM3L4g/TsPZ8mXuE3ljHgY3+rZAFVTtAZaIoVbA10+1ukatoo
+k0wrvR0mzYQvtoZs9x3nw3IrFVPareRMCbf0mvgIOt4A8I/3TVBqddjQsAam3JS
rF5k0CQcF/D02O10uzBnLNqR/OoevbsqQIkLuBZf3RaxEor7P6D1c3HUdyqsRM3f
gPLseZCt9JRC0fv5ue5CoAZ4txX3t+TzywsdihBOdvvE+W3HonY=
=s65h
-----END PGP SIGNATURE-----
commit

2281498cebb1606c6a481ea010681c341010e0ed

parent

9a9bba58186da366aa5eaccfb65408fdcb274c51

6 files changed, 79 insertions(+), 21 deletions(-)

jump to
M README.mdREADME.md

@@ -6,9 +6,9 @@ ### About

`ryudo` is a fork of Russ Cox's Rio, itself a fork of David Hogan's 9wm. The primary additions I've made are: -- `urxvt` is detected as a proper terminal program for sweeping out new windows +- `urxvt`, `konsole`, and `Alacritty` are detected as proper terminal programs for sweeping out new windows - `urxvt` is the default terminal emulator (still tries `9term` and then `xterm` if no dice) -- Customizable colors, borders, fonts, and keybinds in `config.h` +- Customizable colors, borders, fonts, gaps, and keybinds in `config.h` - Default keybindings: + New Terminal: Super+Slash + Destroy: Super+D

@@ -31,8 +31,9 @@ + Virtual Desk++: Super+Right

+ Virtual Desk--: Super+Left - Other new features customizable by `config.h`: + Show/hide 'Stick' Button3 menuitem - + `AUTOSTICK` list of windows to spawn sticky by default + + `AUTOSTICK` list of windows to spawn sticky by default and not focus (pseudo-panel/dock windows) + Optionally notify with `notify-send` which desktop is switched to (I use it with `dunst`) + + Gaps for pseudo-tiling The name "Ryudo" is a nod to "Rio" and a Japanese word for "flow." Using Ryudo should feel very natural -- you can do things with keyboard or

@@ -41,15 +42,16 @@ using the popup menu, or using the keyboard, which will spawn a terminal

window centered taking up 9/25 of the screen (3/5 width, 3/5 height). ### Dependencies, Building, Installation -Being forked from Rio, Ryudo requires **plan9port**, **Xlib**, and **Xt**. -Make it with **mk ryudo** and then copy the resulting executable **ryudo** to +Being forked from Rio, Ryudo requires `plan9port`, `Xlib`, and `Xt`. +If you enable notifications, it of course requires `notify-send`. +Make it with `mk ryudo` and then copy the resulting executable `ryudo` to somewhere in your **PATH** -If you try to install it with **mk install** it will probably install -to **$PLAN9/bin/** under the name **rio**. This is less than ideal but I'm -not a master of mk, so my protocol is to use a mk target **ryudo** which -builds the program as **o.rio**, then calls **ryudomagic.sh** to rename -the program. +If you try to install it with `mk install` it will probably install +to `$PLAN9/bin/` under the name `rio`. This is less than ideal but I'm +not a master of mk, so my protocol is to use a mk target `ryudo` which +builds the program as `o.rio`, then calls `ryudomagic.sh` to rename +the program. A proper mkfile is planned before version 1.0. If you have trouble building, you might need to edit the **mkfile** at line 2 to point to the proper location of your plan9port's **mkwsysrules.sh**.

@@ -57,8 +59,8 @@

### Bugs and Caveats Of the bugs and caveats not already mentioned in Rio's readme: - Rendering of windows with RGBA surfaces is bound to RGB space (xshove and transset can be leveraged to get transparent terminals if you want it) -- Since maximization doesn't use the EWM Hint for maximization, programs like Firefox will remember their window size as the maximized size and probably start offset so they aren't completely onscreen. There is probably a rule we can put in newwindow() to mitigate this, but it's not super important. -- Sticky windows may show their borders with the active color regardless of their state. +- Since maximization doesn't use the EWM Hint for maximization, programs like Firefox will remember their window size as the maximized size and probably start offset so they aren't completely onscreen. Smarter window placement to fix this is on the short list. +- Multimonitor setups are treated like one giant monitor. This is on the short list also. - Probably more! ### Legacy
M client.cclient.c

@@ -302,7 +302,7 @@ static char *autostick[] = AUTOSTICK;

char **a = autostick; while(*a){ - if(strstr(c->class, *a)) { + if(c && c->class && strstr(c->class, *a)) { return 1; } ++a;
M config.hconfig.h

@@ -15,6 +15,15 @@ #define MENUBGCOL 0x000000

#define SMENUFGCOL 0x000000 #define SMENUBGCOL 0x1F9B92 +/* This sets the size ratio for windows spawned via keyboard or + * center-snapped + */ +#define CENTERNUM 2 +#define CENTERDEN 3 + +/* Centered windows should maximize vertically? */ +#define CENTERVMAX + /* Show 'Stick' menuitem? */ //#define SHOWSTICK
M fns.hfns.h

@@ -67,6 +67,7 @@ void keyrelease();

void keysetup(); void quickreshape(Client *c, int x, int y, int dx, int dy); void stickystack(int); +void centercurrent(XWindowAttributes ra); /* menu.c */ void button();
M key.ckey.c

@@ -166,8 +166,9 @@ else if (e->keycode == pcode && (e->state&SHORTCUTMOD) == (MODBITS))

quickreshape(current, ra.width/2 + 0.5*GAPSZ, GAPSZ, ra.width/2 - 1.5*GAPSZ, ra.height/2 - 1.5*GAPSZ); /* center snap */ - else if (e->keycode == ccode && (e->state&SHORTCUTMOD) == (MODBITS)) - quickreshape(current, ra.width/6, GAPSZ, 2*ra.width/3, ra.height - 2*GAPSZ); + else if (e->keycode == ccode && (e->state&SHORTCUTMOD) == (MODBITS)){ + centercurrent(ra); +} #ifdef DEVEL /* manage autostuck windows */

@@ -236,6 +237,24 @@ c->dx = dx-2*BORDER;

c->dy = dy-2*BORDER; XMoveResizeWindow(dpy, c->window, BORDER, BORDER, c->dx, c->dy); sendconfig(c); +} + +void +centercurrent(XWindowAttributes ra) +{ + static int centeroffsetnum = CENTERNUM%2 == 0 ? + CENTERDEN - CENTERNUM : + (CENTERDEN - CENTERNUM)/2; + + static int centeroffsetden = CENTERNUM%2 == 0 ? + CENTERDEN*2 : + CENTERDEN; + + #ifdef CENTERVMAX + quickreshape(current, centeroffsetnum*ra.width/centeroffsetden, GAPSZ, CENTERNUM*ra.width/CENTERDEN, ra.height - 2*GAPSZ); + #else + quickreshape(current, centeroffsetnum*ra.width/centerofsetden, centeroffsetnum*ra.height/centeroffsetden, CENTERNUM*ra.width/CENTERDEN, CENTERNUM*ra.height/CENTERDEN); + #endif } static void
M manage.cmanage.c

@@ -30,6 +30,11 @@ long msize;

XClassHint class; XWMHints *hints; XSetWindowAttributes attrs; + + + static XWindowAttributes ra; + XGetWindowAttributes(dpy, DefaultRootWindow(dpy), &ra); + trace("manage", c, 0); XSelectInput(dpy, c->window, ColormapChangeMask | EnterWindowMask | PropertyChangeMask | FocusChangeMask | KeyPressMask);

@@ -180,14 +185,11 @@ XMapWindow(dpy, c->window);

XMapWindow(dpy, c->parent); XUnmapWindow(dpy, c->screen->sweepwin); #ifdef AUTOSTICK - if(c->class && !isautostick(c)) - active(c); -#else - if(c->class) - active(c); + if(!isautostick(c)) #endif - else if(c->trans != None && current && current->window == c->trans) active(c); + /*else if(c->trans != None && current && current->window == c->trans) + active(c);*/ else setactive(c, 0); setstate(c, NormalState);

@@ -195,6 +197,31 @@ }

if(current && (current != c)) cmapfocus(current); c->init = 1; + + /* If the window is out of bounds of the screen, try to wrangle it */ + + /* If it's bigger than the screen, try to set it maximized */ + if (c->dx >= ra.width || c->dy >= ra.width){ + if (c->dx >= ra.width) + quickreshape(c, -BORDER, c->y - BORDER, ra.width + 2*BORDER, c->dy + 2*BORDER); + if (c->dy >= ra.height) + quickreshape(c, c->x - BORDER, -BORDER, c->dx + 2*BORDER, ra.height + 2*BORDER); + + /* and if it's got an edge out of bounds, nudge it into bounds */ + } else { + if (c->x < BORDER){ + quickreshape(c, 0, c->y - BORDER, c->dx + 2*BORDER, c->dy + 2*BORDER); + } + if (c->y < BORDER){ + quickreshape(c, c->x - BORDER, 0, c->dx + 2*BORDER, c->dy + 2*BORDER); + } + if (c->x + c->dx + BORDER > ra.width){ + quickreshape(c, ra.width - (c->dx + 2*BORDER), c->y - BORDER, c->dx + 2*BORDER, c->dy + 2*BORDER); + } + if (c->y + c->dy + BORDER > ra.height){ + quickreshape(c, c->x - BORDER, ra.height - (c->dy + 2*BORDER), c->dx + 2*BORDER, c->dy + 2*BORDER); + } + } /* * If we swept the window, let's send a resize event to the