diff --git a/README.md b/README.md index c7fa617..d5a061b 100755 --- a/README.md +++ b/README.md @@ -52,17 +52,11 @@ window centered (its exact geometry is configurable via `config.h`). ### Dependencies, Building, Installation 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. A proper mkfile is planned before version 1.0. +Build with `build.sh` (calls `mk` and does some other magic), and install with `install.sh` (will install to a local folder if run as a normal user, or to your `$PLAN9/bin/` if run as root). -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**. +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`. ### Bugs and Caveats Of the bugs and caveats not already mentioned in Rio's readme: diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..74ceeaf --- /dev/null +++ b/build.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +mk clean +mk o.rio + +mv o.rio ryudo diff --git a/client.c b/client.c index ae94c87..b7e8d55 100644 --- a/client.c +++ b/client.c @@ -300,6 +300,14 @@ void shuffle(int up) { XMapRaised(dpy, c->parent); top(c); active(c); + if (zoom) { + quickreshape( + c, + -BORDER, + -BORDER, + ra.width + 2 * BORDER, + ra.height + 2 * BORDER); + } } else { c = clients; for (l = &clients; *l; l = &(*l)->next) @@ -328,3 +336,8 @@ int isautostick(Client* c) { return 0; } #endif + +void ensureactive() { + if (!current) + shuffle(0); +} diff --git a/config.h b/config.h index 749ecd3..da3f6da 100644 --- a/config.h +++ b/config.h @@ -1,100 +1,44 @@ -#define SHOLDCOL 0xC8C8C8 -#define HOLDCOL 0x444444 +/*********************** + * RYUDO CONFIGURATION * + **********************/ + +/*************** + * LOOK & FEEL * [All of these are required options] + **************/ + +/* Border colors */ #define SBORDERCOL 0x17736C #define BORDERCOL 0x000000 + +/* Window sweep border color */ #define GHOSTCOL 0x797979 + +/* Hold mode border colors -- if you don't use 9term you don't need to + * care what these are + */ +#define SHOLDCOL 0xC8C8C8 +#define HOLDCOL 0x444444 + +/* Border width in pixels */ #define BORDER 4 -/* Should be even */ +/* Gap size, in pixels, for pseudo-tiling. Should be even */ #define GAPSZ 4 +/* Menu border width and color */ #define MENUBORDER 0 #define MBORDERCOL 0x000000 + +/* Normal menu colors */ #define MENUFGCOL 0x797979 #define MENUBGCOL 0x000000 + +/* Selected menu colors */ #define SMENUFGCOL 0x000000 #define SMENUBGCOL 0x1F9B92 -/* This sets the size ratio for windows spawned via keyboard or - * center-snapped; CENTERNUM should be >= 2, so use 2/4 instead of 1/2 - */ -#define CENTERNUM 2 -#define CENTERDEN 3 - -/* Centered windows should maximize vertically by default? - * This is the behavior of new windows spawned with the launch shortcut - * and of centered windows with SHORTCUTMOD + SNAPCENTER_KEY -- - * use SHORTCUTMOD + SHIFT + SNAPCENTER_KEY to get the other behavior. - */ -#define CENTERVMAX - -/* Show 'Stick' menuitem? */ -//#define SHOWSTICK - -/* Notify on virtual desktop switch? */ -#define VIRTNOTIFY - -/* The summary and message to pass to the notifcation daeomon */ -#define VIRTHEADER "virtual" -#define VIRTMSG "[%s]" - -/* Modifier key and associated modifier bits; - * Shift = (1<<0) - * Lock = (1<<1) - * Control = (1<<2) - * Mod1 = (1<<3) - * Mod2 = (1<<4) - * Mod3 = (1<<5) - * Mod4 = (1<<6) - * Mod5 = (1<<7) - */ -#define SHORTCUTMOD Mod4Mask -#define MODBITS (1 << 6) - -/* Shortcut keys */ - -#define MAX_KEY XK_m -#define ICON_KEY XK_i -#define UNHIDE_KEY XK_u -#define MOVE_KEY XK_v -#define RESIZE_KEY XK_r -#define DESTROY_KEY XK_d -#define STICK_KEY XK_s - -#define STICKYTOFRONT_KEY XK_t -#define STICKYTOBACK_KEY XK_b - -#define SNAPLEFT_KEY XK_h -#define SNAPRIGHT_KEY XK_l -#define SNAPTOP_KEY XK_k -#define SNAPBOTTOM_KEY XK_j - -#define SNAPTOPLEFT_KEY XK_q -#define SNAPBOTTOMLEFT_KEY XK_w -#define SNAPBOTTOMRIGHT_KEY XK_o -#define SNAPTOPRIGHT_KEY XK_p - -#define SNAPCENTER_KEY XK_c - -#define NEXTVIRT_KEY XK_Right -#define PREVVIRT_KEY XK_Left - -#define LAUNCH_KEY XK_slash - // clang-format off -/* List of window classes to spawn as sticky; - * Class values for currently open windows are conveniently shown in the last - * column of the 'xshove' command given with no arguments. - * Remember the backslash at the end of non-terminating lines! - */ - -#define AUTOSTICK {\ - "XOsview", \ - "XClock", \ - 0 \ -} - /* List of fonts to try, in order, for rendering the menus. * Remember the backslash at the end of non-terminating lines! */ @@ -110,8 +54,9 @@ 0 \ } -/* Names for the virtual desktops. You can define all 12, or only - * as many as you use. +/* Names for the virtual desktops. Even if you don't use all of them, + * it's safer to keep dummy or null values for all of them in case you + * start the program with a different number of virtuals by happenstance. * Remember the backslash at the end of non-terminating lines! */ @@ -132,3 +77,123 @@ } // clang-format on + +/************ + * BEHAVIOR * [Everything in this section is optional unless otherwise noted] + ***********/ + +/* This sets the size ratio for windows spawned via keyboard or + * center-snapped; CENTERNUM should be >= 2, so use 2/4 instead of 1/2 + */ +#define CENTERNUM 2 // required unless you also comment/omit SNAPCENTER_KEY +#define CENTERDEN 3 // required unless you also comment/omit SNAPCENTER_KEY + +/* Centered windows should maximize vertically by default? + * This is the behavior of new windows spawned with the launch shortcut + * and of centered windows with SHORTCUTMOD + SNAPCENTER_KEY -- + * use SHORTCUTMOD + SHIFT + SNAPCENTER_KEY to get the other behavior. + */ +#define CENTERVMAX + +/* Show 'Maximize' menuitem? */ +// #define SHOWMAX + +/* Show 'Stick' menuitem? */ +// #define SHOWSTICK + +/* Notify on virtual desktop switch? */ +#define VIRTNOTIFY + +/* The summary and message to pass to the notifcation daeomon */ +#define VIRTHEADER "virtual" +#define VIRTMSG "[%s]" + +// clang-format off + +/* List of window classes to spawn as sticky; + * Class values for currently open windows are conveniently shown in the last + * column of the 'xshove' command given with no arguments. + * Can be partial strings. + * Remember the backslash at the end of non-terminating lines! + */ + +#define AUTOSTICK {\ + "XOsview", \ + "XClock", \ + 0 \ +} + +/* List of terminal window classes -- include your favorite terminal here, + * and remove those you don't use. Can be partial strings. + * This array is required. Remember the backslash at the end of non- + * terminating lines! + */ + +#define TERMINALS {\ + "term", \ + "Term", \ + "xvt", \ + "Alacritty", \ + "onsole", \ + 0 \ +} + +/* List of window classes to REQUIRE window sweeping when spawning; + * Can be partial strings. + * Remember the backslash at the end of non-terminating lines! + */ + +#define ALWAYSDRAW {\ + 0 \ +} + +// clang-format on + +/*************** + * KEYBINDINGS * [Any shortcut key can be omitted] + **************/ + +/* Modifier key and associated modifier bits; + * Shift = (1<<0) + * Lock = (1<<1) + * Control = (1<<2) + * Mod1 = (1<<3) + * Mod2 = (1<<4) + * Mod3 = (1<<5) + * Mod4 = (1<<6) + * Mod5 = (1<<7) + */ + +#define SHORTCUTMOD Mod4Mask +#define MODBITS (1 << 6) + +/* Shortcut keys */ + +#define MAX_KEY XK_m +#define ICON_KEY XK_i +#define UNHIDE_KEY XK_u +#define MOVE_KEY XK_v +#define RESIZE_KEY XK_r +#define DESTROY_KEY XK_d +#define STICK_KEY XK_s + +#define SNAPLEFT_KEY XK_h +#define SNAPRIGHT_KEY XK_l +#define SNAPTOP_KEY XK_k +#define SNAPBOTTOM_KEY XK_j + +#define SNAPTOPLEFT_KEY XK_q +#define SNAPBOTTOMLEFT_KEY XK_w +#define SNAPBOTTOMRIGHT_KEY XK_o +#define SNAPTOPRIGHT_KEY XK_p + +#define SNAPCENTER_KEY XK_c + +#define NEXTVIRT_KEY XK_Right +#define PREVVIRT_KEY XK_Left + +#define LAUNCH_KEY XK_slash + +// ignore these for now -- this is a feature in development +#define STICKYTOFRONT_KEY XK_t +#define STICKYTOBACK_KEY XK_b diff --git a/cursor.c b/cursor.c index 75ff861..69d0c0f 100644 --- a/cursor.c +++ b/cursor.c @@ -141,8 +141,7 @@ static char grey_bits[] = {0x01, 0x04}; static XColor bl, wh; -Cursor getcursor(Cursordata* c, ScreenInfo* s) -{ +Cursor getcursor(Cursordata* c, ScreenInfo* s) { Pixmap f, m; f = XCreatePixmapFromBitmapData( @@ -166,8 +165,7 @@ Cursor getcursor(Cursordata* c, ScreenInfo* s) return XCreatePixmapCursor(dpy, f, m, &bl, &wh, c->hot[0], c->hot[1]); } -void initcurs(ScreenInfo* s) -{ +void initcurs(ScreenInfo* s) { XColor dummy; XAllocNamedColor(dpy, DefaultColormap(dpy, s->num), "black", &bl, &dummy); diff --git a/dat.h b/dat.h index cd41513..f97bf8c 100644 --- a/dat.h +++ b/dat.h @@ -6,7 +6,9 @@ #define CORNER _corner #define INSET _inset #define MAXHIDDEN 128 -#ifdef SHOWSTICK +#if defined (SHOWMAX) && defined (SHOWSTICK) +#define B3FIXED 7 +#elif defined (SHOWMAX) || defined (SHOWSTICK) #define B3FIXED 6 #else #define B3FIXED 5 diff --git a/event.c b/event.c index 1c4f214..44b928e 100644 --- a/event.c +++ b/event.c @@ -159,6 +159,8 @@ void configurereq(XConfigureRequestEvent* e) { XConfigureWindow(dpy, c->parent, e->value_mask, &wc); if (e->value_mask & CWStackMode) { + if (c->virt > 0 && c->virt != virt) + switch_to(c->virt); top(c); active(c); } @@ -292,23 +294,21 @@ void newwindow(XCreateWindowEvent* e) { void destroy(Window w) { int i; Client* c; -// int v; + // int v; curtime = CurrentTime; c = getclient(w, 0); if (c == 0) return; -// v = c->virt; + // v = c->virt; if (numvirtuals > 1) for (i = 0; i < numvirtuals; i++) if (currents[i] == c) currents[i] = 0; rmclient(c); - //if (v == virt) { - // shuffle(0); - //} + ensureactive(); /* flush any errors generated by the window's sudden demise */ ignore_badwindow = 1; diff --git a/fns.h b/fns.h index 89f8769..ab65645 100644 --- a/fns.h +++ b/fns.h @@ -60,6 +60,8 @@ void setstate(); void setlabel(); void getproto(); void gettrans(); +int shouldalwaysdraw(Client* c); +int isterminalwindow(Client* c); /* key.c */ void keypress(); @@ -97,6 +99,7 @@ void dump_revert(); void dump_clients(); void shuffle(int); int isautostick(Client* c); +void ensureactive(); /* grab.c */ int menuhit(); diff --git a/grab.c b/grab.c index ad16a9d..136ab5f 100644 --- a/grab.c +++ b/grab.c @@ -555,6 +555,9 @@ void misleep(int msec) { select(0, 0, 0, 0, &t); } +/* Not grabbing the server during sweep ops might make Xorg unstable. + -drkste */ + int sweepdrag( Client* c, int but, XButtonEvent* e0, BorderOrient bl, int (*recalc)(Client*, int, int, BorderOrient, int)) { @@ -578,7 +581,7 @@ int sweepdrag( getmouse(&cx, &cy, c->screen); else getmouse(&c->x, &c->y, c->screen); - XGrabServer(dpy); + // XGrabServer(dpy); if (bl != BorderUnknown) { notmoved = recalc(c, cx, cy, bl, notmoved); } @@ -590,10 +593,10 @@ int sweepdrag( if (rx != cx || ry != cy || ++idle > 300) { drawbound(c, 0); if (rx == cx && ry == cy) { - XUngrabServer(dpy); + // XUngrabServer(dpy); XFlush(dpy); - misleep(500); - XGrabServer(dpy); + // misleep(500); + // XGrabServer(dpy); idle = 0; } if (e0 || bl != BorderUnknown) @@ -614,7 +617,7 @@ int sweepdrag( case ButtonRelease: drawbound(c, 0); ungrab(e); - XUngrabServer(dpy); + // XUngrabServer(dpy); if (e->button != but && c->init) goto bad; if (c->dx < 0) { diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..82ac188 --- /dev/null +++ b/install.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +if [ -z "$PLAN9" ]; then + echo "PLAN9 not set;" + echo "Please set it to the location of your plan9port installation." + exit 1 +fi + +if [ $(whoami) != "root" ]; then + mkdir -p ~/bin/9 + cp ryudo ~/bin/9/ryudo + echo "ryudo has been installed to '${HOME}/bin/9/';" + echo "You may want to add it to your PATH." + echo "The manual pages were not installed." +else + cp ryudo $PLAN9/bin/ryudo + cp ryudo.1 $PLAN9/man/man1/ryudo.1 + echo "ryudo has been installed to '${PLAN9}/bin/';" + echo "The manual pages have been installed to '${PLAN9}/man/'" +fi diff --git a/key.c b/key.c index 6b9ae27..90b69bf 100644 --- a/key.c +++ b/key.c @@ -30,25 +30,66 @@ static void alttab(int shift); void keysetup(void) { int i; int tabcode = XKeysymToKeycode(dpy, XK_Tab); +#ifdef DESTROY_KEY int dcode = XKeysymToKeycode(dpy, DESTROY_KEY); +#endif +#ifdef ICON_KEY int icode = XKeysymToKeycode(dpy, ICON_KEY); +#endif +#ifdef UNHIDE_KEY int ucode = XKeysymToKeycode(dpy, UNHIDE_KEY); +#endif +#ifdef MAX_KEY int mcode = XKeysymToKeycode(dpy, MAX_KEY); +#endif +#ifdef MOVE_KEY int vcode = XKeysymToKeycode(dpy, MOVE_KEY); +#endif +#ifdef RESIZE_KEY int rcode = XKeysymToKeycode(dpy, RESIZE_KEY); +#endif +#ifdef STICK_KEY int scode = XKeysymToKeycode(dpy, STICK_KEY); +#endif +#ifdef SNAPLEFT_KEY int hcode = XKeysymToKeycode(dpy, SNAPLEFT_KEY); +#endif +#ifdef SNAPRIGHT_KEY int lcode = XKeysymToKeycode(dpy, SNAPRIGHT_KEY); +#endif +#ifdef SNAPBOTTOM_KEY int jcode = XKeysymToKeycode(dpy, SNAPBOTTOM_KEY); +#endif +#ifdef SNAPTOP_KEY int kcode = XKeysymToKeycode(dpy, SNAPTOP_KEY); +#endif +#ifdef SNAPTOPLEFT_KEY int qcode = XKeysymToKeycode(dpy, SNAPTOPLEFT_KEY); +#endif +#ifdef SNAPBOTTOMLEFT_KEY int wcode = XKeysymToKeycode(dpy, SNAPBOTTOMLEFT_KEY); +#endif +#ifdef SNAPBOTTOMRIGHT_KEY int ocode = XKeysymToKeycode(dpy, SNAPBOTTOMRIGHT_KEY); +#endif +#ifdef SNAPTOPRIGHT_KEY int pcode = XKeysymToKeycode(dpy, SNAPTOPRIGHT_KEY); +#endif +#ifdef SNAPCENTER_KEY int ccode = XKeysymToKeycode(dpy, SNAPCENTER_KEY); +#endif +#ifdef LAUNCH_KEY int slcode = XKeysymToKeycode(dpy, LAUNCH_KEY); +#endif +#ifdef ZOOM_KEY + int zcode = XKeysymToKeycode(dpy, ZOOM_KEY); +#endif +#ifdef NEXTVIRT_KEY int rightcode = XKeysymToKeycode(dpy, NEXTVIRT_KEY); +#endif +#ifdef PREVVIRT_KEY int leftcode = XKeysymToKeycode(dpy, PREVVIRT_KEY); +#endif #ifdef DEVEL int tcode = XKeysymToKeycode(dpy, STICKYTOFRONT_KEY); int bcode = XKeysymToKeycode(dpy, STICKYTOBACK_KEY); @@ -63,6 +104,7 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#ifdef DESTROY_KEY XGrabKey( dpy, dcode, @@ -71,6 +113,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef ICON_KEY XGrabKey( dpy, icode, @@ -79,6 +123,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef UNHIDE_KEY XGrabKey( dpy, ucode, @@ -87,6 +133,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef RESIZE_KEY XGrabKey( dpy, rcode, @@ -95,6 +143,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef MOVE_KEY XGrabKey( dpy, vcode, @@ -103,6 +153,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef MAX_KEY XGrabKey( dpy, mcode, @@ -111,6 +163,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef STICK_KEY XGrabKey( dpy, scode, @@ -119,6 +173,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef SNAPLEFT_KEY XGrabKey( dpy, hcode, @@ -127,6 +183,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef SNAPRIGHT_KEY XGrabKey( dpy, lcode, @@ -135,6 +193,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef SNAPBOTTOM_KEY XGrabKey( dpy, jcode, @@ -143,6 +203,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef SNAPTOP_KEY XGrabKey( dpy, kcode, @@ -151,6 +213,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef SNAPTOPLEFT_KEY XGrabKey( dpy, qcode, @@ -159,6 +223,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef SNAPBOTTOMLEFT_KEY XGrabKey( dpy, wcode, @@ -167,6 +233,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef SNAPBOTTOMRIGHT_KEY XGrabKey( dpy, ocode, @@ -175,6 +243,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef SNAPTOPRIGHT_KEY XGrabKey( dpy, pcode, @@ -183,6 +253,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef SNAPCENTER_KEY XGrabKey( dpy, ccode, @@ -199,6 +271,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef PREVVIRT_KEY XGrabKey( dpy, leftcode, @@ -207,6 +281,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef NEXTVIRT_KEY XGrabKey( dpy, rightcode, @@ -215,6 +291,8 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef LAUNCH_KEY XGrabKey( dpy, slcode, @@ -223,6 +301,17 @@ void keysetup(void) { 0, GrabModeSync, GrabModeAsync); +#endif +#ifdef ZOOM_KEY + XGrabKey( + dpy, + zcode, + SHORTCUTMOD, + screens[i].root, + 0, + GrabModeSync, + GrabModeAsync); +#endif XGrabKey( dpy, tabcode, @@ -263,25 +352,66 @@ void keypress(XKeyEvent* e) { * process key press here */ int tabcode = XKeysymToKeycode(dpy, XK_Tab); +#ifdef DESTROY_KEY int dcode = XKeysymToKeycode(dpy, DESTROY_KEY); +#endif +#ifdef ICON_KEY int icode = XKeysymToKeycode(dpy, ICON_KEY); +#endif +#ifdef UNHIDE_KEY int ucode = XKeysymToKeycode(dpy, UNHIDE_KEY); +#endif +#ifdef MAX_KEY int mcode = XKeysymToKeycode(dpy, MAX_KEY); +#endif +#ifdef MOVE_KEY int vcode = XKeysymToKeycode(dpy, MOVE_KEY); +#endif +#ifdef STICK_KEY int scode = XKeysymToKeycode(dpy, STICK_KEY); +#endif +#ifdef RESIZE_KEY int rcode = XKeysymToKeycode(dpy, RESIZE_KEY); +#endif +#ifdef LAUNCH_KEY int slcode = XKeysymToKeycode(dpy, LAUNCH_KEY); +#endif +#ifdef ZOOM_KEY + int zcode = XKeysymToKeycode(dpy, ZOOM_KEY); +#endif +#ifdef SNAPLEFT_KEY int hcode = XKeysymToKeycode(dpy, SNAPLEFT_KEY); +#endif +#ifdef SNAPRIGHT_KEY int lcode = XKeysymToKeycode(dpy, SNAPRIGHT_KEY); +#endif +#ifdef SNAPBOTTOM_KEY int jcode = XKeysymToKeycode(dpy, SNAPBOTTOM_KEY); +#endif +#ifdef SNAPTOP_KEY int kcode = XKeysymToKeycode(dpy, SNAPTOP_KEY); +#endif +#ifdef SNAPTOPLEFT_KEY int qcode = XKeysymToKeycode(dpy, SNAPTOPLEFT_KEY); +#endif +#ifdef SNAPBOTTOMLEFT_KEY int wcode = XKeysymToKeycode(dpy, SNAPBOTTOMLEFT_KEY); +#endif +#ifdef SNAPBOTTOMRIGHT_KEY int ocode = XKeysymToKeycode(dpy, SNAPBOTTOMRIGHT_KEY); +#endif +#ifdef SNAPTOPRIGHT_KEY int pcode = XKeysymToKeycode(dpy, SNAPTOPRIGHT_KEY); +#endif +#ifdef SNAPCENTER_KEY int ccode = XKeysymToKeycode(dpy, SNAPCENTER_KEY); +#endif +#ifdef NEXTVIRT_KEY int rightcode = XKeysymToKeycode(dpy, NEXTVIRT_KEY); +#endif +#ifdef PREVVIRT_KEY int leftcode = XKeysymToKeycode(dpy, PREVVIRT_KEY); +#endif #ifdef DEVEL int tcode = XKeysymToKeycode(dpy, STICKYTOFRONT_KEY); int bcode = XKeysymToKeycode(dpy, STICKYTOBACK_KEY); @@ -293,16 +423,27 @@ void keypress(XKeyEvent* e) { /* basic wm functionality */ if (e->keycode == tabcode && (e->state & Mod1Mask) == (1 << 3)) alttab(e->state & ShiftMask); +#ifdef DESTROY_KEY else if (e->keycode == dcode && (e->state & SHORTCUTMOD) == (MODBITS)) delete (current, 0); +#endif +#ifdef ICON_KEY else if (e->keycode == icode && (e->state & SHORTCUTMOD) == (MODBITS)) hide(current); +#endif +#ifdef UNHIDE_KEY else if (e->keycode == ucode && (e->state & SHORTCUTMOD) == (MODBITS)) unhide(0, 1); +#endif +#ifdef MOVE_KEY else if (e->keycode == vcode && (e->state & SHORTCUTMOD) == (MODBITS)) move(current, Button3); +#endif +#ifdef RESIZE_KEY else if (e->keycode == rcode && (e->state & SHORTCUTMOD) == (MODBITS)) reshape(current, Button3, sweep, 0); +#endif +#ifdef MAX_KEY else if (e->keycode == mcode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, @@ -310,10 +451,29 @@ void keypress(XKeyEvent* e) { -BORDER, ra.width + 2 * BORDER, ra.height + 2 * BORDER); +#endif +#ifdef STICK_KEY else if (e->keycode == scode && (e->state & SHORTCUTMOD) == (MODBITS)) stick(current); + else if (e->keycode == zcode && (e->state & SHORTCUTMOD) == (MODBITS)) + zoom = !zoom; +#endif +#ifdef ZOOM_KEY + else if (e->keycode == zcode && (e->state & SHORTCUTMOD) == (MODBITS)) { + zoom = !zoom; + if (zoom) { + quickreshape( + current, + -BORDER, + -BORDER, + ra.width + 2 * BORDER, + ra.height + 2 * BORDER); + } + } +#endif /* half snap */ +#ifdef SNAPLEFT_KEY else if (e->keycode == hcode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, @@ -321,6 +481,8 @@ void keypress(XKeyEvent* e) { GAPSZ, ra.width / 2 - 1.5 * GAPSZ, ra.height - 2 * GAPSZ); +#endif +#ifdef SNAPRIGHT_KEY else if (e->keycode == lcode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, @@ -328,6 +490,8 @@ void keypress(XKeyEvent* e) { GAPSZ, ra.width / 2 - 1.5 * GAPSZ, ra.height - 2 * GAPSZ); +#endif +#ifdef SNAPBOTTOM_KEY else if (e->keycode == jcode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, @@ -335,6 +499,8 @@ void keypress(XKeyEvent* e) { ra.height / 2 + 0.5 * GAPSZ, ra.width - 2 * GAPSZ, ra.height / 2 - 1.5 * GAPSZ); +#endif +#ifdef SNAPTOP_KEY else if (e->keycode == kcode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, @@ -342,8 +508,10 @@ void keypress(XKeyEvent* e) { GAPSZ, ra.width - 2 * GAPSZ, ra.height / 2 - 1.5 * GAPSZ); +#endif - /* quarter snap */ + /* quarter snap */ +#ifdef SNAPTOPLEFT_KEY else if (e->keycode == qcode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, @@ -351,6 +519,8 @@ void keypress(XKeyEvent* e) { GAPSZ, ra.width / 2 - 1.5 * GAPSZ, ra.height / 2 - 1.5 * GAPSZ); +#endif +#ifdef SNAPBOTTOMLEFT_KEY else if (e->keycode == wcode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, @@ -358,6 +528,8 @@ void keypress(XKeyEvent* e) { ra.height / 2 + 0.5 * GAPSZ, ra.width / 2 - 1.5 * GAPSZ, ra.height / 2 - 1.5 * GAPSZ); +#endif +#ifdef SNAPBOTTOMRIGHT_KEY else if (e->keycode == ocode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, @@ -365,6 +537,8 @@ void keypress(XKeyEvent* e) { ra.height / 2 + 0.5 * GAPSZ, ra.width / 2 - 1.5 * GAPSZ, ra.height / 2 - 1.5 * GAPSZ); +#endif +#ifdef SNAPTOPRIGHT_KEY else if (e->keycode == pcode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, @@ -372,8 +546,10 @@ void keypress(XKeyEvent* e) { GAPSZ, ra.width / 2 - 1.5 * GAPSZ, ra.height / 2 - 1.5 * GAPSZ); +#endif - /* center snap */ + /* center snap */ +#ifdef SNAPCENTER_KEY else if (e->keycode == ccode && (e->state & SHORTCUTMOD) == (MODBITS)) { if ((e->state & ShiftMask) == (1 << 0)) { #ifdef CENTERVMAX @@ -389,6 +565,7 @@ void keypress(XKeyEvent* e) { #endif } } +#endif #ifdef DEVEL /* manage autostuck windows */ @@ -398,8 +575,9 @@ void keypress(XKeyEvent* e) { stickystack(0); #endif - /* launch */ - if (e->keycode == slcode && (e->state & SHORTCUTMOD) == (MODBITS)) { + /* launch */ +#ifdef LAUNCH_KEY + else if (e->keycode == slcode && (e->state & SHORTCUTMOD) == (MODBITS)) { kbLaunch = 1; if (fork() == 0) { close(ConnectionNumber(dpy)); @@ -419,21 +597,28 @@ void keypress(XKeyEvent* e) { perror("ryudo: exec urxvt/9term/xterm failed"); } } +#endif /* switch virts */ - if (e->keycode == rightcode && (e->state & SHORTCUTMOD) == (MODBITS)) +#ifdef NEXTVIRT_KEY + else if (e->keycode == rightcode && (e->state & SHORTCUTMOD) == (MODBITS)) { if (numvirtuals > 1) if (virt < numvirtuals - 1) switch_to(virt + 1); else switch_to(0); + } +#endif - if (e->keycode == leftcode && (e->state & SHORTCUTMOD) == (MODBITS)) +#ifdef PREVVIRT_KEY + else if (e->keycode == leftcode && (e->state & SHORTCUTMOD) == (MODBITS)) { if (numvirtuals > 1) if (virt > 0) switch_to(virt - 1); else switch_to(numvirtuals - 1); + } +#endif XAllowEvents(dpy, SyncKeyboard, e->time); } diff --git a/manage.c b/manage.c index d710adb..550d18f 100644 --- a/manage.c +++ b/manage.c @@ -44,14 +44,15 @@ int manage(Client* c, int mapped) { if (XGetClassHint(dpy, c->window, &class) != 0) { /* ``Success'' */ c->instance = class.res_name; c->class = class.res_class; +#ifdef ALWAYSDRAW + c->is9term = shouldalwaysdraw(c); +#else c->is9term = 0; +#endif if (isNew) { - c->is9term = strstr(c->class, "term") || strstr(c->class, "Term") || - strstr(c->class, "urxvt") || strstr(c->class, "URxvt") || - strstr(c->class, "onsole") || strstr(c->class, "Alacritty"); + c->is9term = isterminalwindow(c); isNew = 0; } - printf("%s: is9term = %d", c->class, c->is9term); } else { c->instance = 0; c->class = 0; @@ -545,3 +546,31 @@ void getproto(Client* c) { XFree((char*)p); } + +#ifdef ALWAYSDRAW +int shouldalwaysdraw(Client* c) { + static char* alwaysdraw[] = ALWAYSDRAW; + char** a = alwaysdraw; + + while (*a) { + if (c && c->class && strstr(c->class, *a)) { + return 1; + } + ++a; + } + return 0; +} +#endif + +int isterminalwindow(Client* c) { + static char* termnames[] = TERMINALS; + char** t = termnames; + + while (*t) { + if (c && c->class && strstr(c->class, *t)) { + return 1; + } + ++t; + } + return 0; +} diff --git a/menu.c b/menu.c index c496941..530c477 100644 --- a/menu.c +++ b/menu.c @@ -35,24 +35,38 @@ char* b3items[B3FIXED + MAXHIDDEN + 1] = { "New", "Reshape", "Move", - "Delete", - "Hide", +#if defined(SHOWMAX) && defined(SHOWSTICK) + "Maximize", + "Stick", +#else +#ifdef SHOWMAX + "Maximize", +#endif #ifdef SHOWSTICK "Stick", #endif +#endif + "Delete", + "Hide", 0}; enum { New, Reshape, Move, - Delete, -#ifdef SHOWSTICK - Hide, - Stick +#if defined(SHOWMAX) && defined(SHOWSTICK) + Maximize, + Stick, #else - Hide +#ifdef SHOWMAX + Maximize, #endif +#ifdef SHOWSTICK + Stick, +#endif +#endif + Delete, + Hide }; Menu b3menu = {b3items}; @@ -65,6 +79,9 @@ void button(XButtonEvent* e) { Window dw; ScreenInfo* s; + static XWindowAttributes ra; + XGetWindowAttributes(dpy, DefaultRootWindow(dpy), &ra); + curtime = e->time; s = getscreen(e->root); if (s == 0) @@ -165,11 +182,28 @@ void button(XButtonEvent* e) { case Delete: shift = 0; c = selectwin(1, &shift, s); - delete(c, shift); + delete (c, shift); break; case Hide: hide(selectwin(1, 0, s)); break; +#ifdef SHOWMAX + case Maximize: + c = selectwin(1, 0, s); +#ifdef AUTOSTICK + if (isautostick(c)) + break; +#endif + quickreshape( + c, + -BORDER, + -BORDER, + ra.width + 2 * BORDER, + ra.height + 2 * BORDER); + active(c); + top(c); + break; +#endif #ifdef SHOWSTICK case Stick: stick(selectwin(1, 0, s)); @@ -260,18 +294,15 @@ void move(Client* c, int but) { } void delete (Client* c, int shift) { - int v; + // int v; if (c == 0) return; - v = c->virt; - if ((c->proto & Pdelete) && !shift) { + // v = c->virt; + if ((c->proto & Pdelete) && !shift) sendcmessage(c->window, wm_protocols, wm_delete, 0, 0); - if (v == virt) { - shuffle(0); - } - } else XKillClient(dpy, c->window); /* let event clean up */ + ensureactive(); } void hide(Client* c) { @@ -300,6 +331,7 @@ void hide(Client* c) { } numhidden++; b3items[B3FIXED + numhidden] = 0; + ensureactive(); } void unhide(int n, int map) { @@ -435,7 +467,9 @@ void switch_to(int n) { switch_to_c(n, clients); current = currents[virt]; + ensureactive(); top(current); +#ifdef VIRTNOTIFY if (fork() == 0) { close(ConnectionNumber(dpy)); if (dpy != '\0') @@ -443,7 +477,6 @@ void switch_to(int n) { signal(SIGINT, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGHUP, SIG_DFL); -#ifdef VIRTNOTIFY sprintf(virtmsg, VIRTMSG, b2items[virt]); execlp( "notify-send", @@ -453,8 +486,8 @@ void switch_to(int n) { VIRTHEADER, virtmsg, (char*)0); -#endif } +#endif } void initb2menu(int n) { b2items[n] = 0; } diff --git a/mkfile b/mkfile index c4b22d2..052c9a3 100755 --- a/mkfile +++ b/mkfile @@ -1,5 +1,5 @@ <$PLAN9/src/mkhdr -<|sh /usr/lib/plan9/src/cmd/devdraw/mkwsysrules.sh # for X11 +<|sh $PLAN9/src/cmd/devdraw/mkwsysrules.sh # for X11 RIOFILES=\ client.$O\ diff --git a/ryudomagic.sh b/ryudomagic.sh deleted file mode 100755 index 079ca9c..0000000 --- a/ryudomagic.sh +++ /dev/null @@ -1 +0,0 @@ -mv $O.rio ryudo