README: update; client, config, fns, key, manage: fix focus bugs, tweak center snap, and wrangle out of bounds windows

This commit is contained in:
Iris Lightshard 2021-02-26 00:36:37 -05:00
parent 9a9bba5818
commit 2281498ceb
Signed by: Iris Lightshard
GPG key ID: 3B7FBC22144E6398
6 changed files with 79 additions and 21 deletions

View file

@ -6,9 +6,9 @@
`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 @@ The primary additions I've made are:
+ 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 @@ to point to the proper location of your plan9port's **mkwsysrules.sh**.
### 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

View file

@ -302,7 +302,7 @@ isautostick(Client *c)
char **a = autostick;
while(*a){
if(strstr(c->class, *a)) {
if(c && c->class && strstr(c->class, *a)) {
return 1;
}
++a;

View file

@ -15,6 +15,15 @@
#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

1
fns.h
View file

@ -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();

23
key.c
View file

@ -166,8 +166,9 @@ keypress(XKeyEvent *e)
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 */
@ -238,6 +239,24 @@ quickreshape(Client *c, int x, int y, int dx, int 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
alttab(int shift)
{

View file

@ -30,6 +30,11 @@ manage(Client *c, int mapped)
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 @@ manage(Client *c, int mapped)
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);
@ -196,6 +198,31 @@ manage(Client *c, int mapped)
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
* guy who just got resized. It's not clear whether the apps