2019-12-02 18:23:00 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2019 Derek Stevens, 2005 Russ Cox, 1994-1996 David Hogan
|
|
|
|
* see README for license details
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <X11/X.h>
|
|
|
|
#include <X11/Xos.h>
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Xutil.h>
|
|
|
|
#include <X11/Xatom.h>
|
|
|
|
#include <X11/keysym.h>
|
|
|
|
#include <X11/extensions/shape.h>
|
|
|
|
#include "config.h"
|
|
|
|
#include "dat.h"
|
|
|
|
#include "fns.h"
|
|
|
|
#include "patchlevel.h"
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
GrabAltTab,
|
|
|
|
GrabAltAny
|
|
|
|
};
|
|
|
|
|
|
|
|
/*static int tabcode = 0x17; */
|
|
|
|
/*static int altcode = 0x40; */
|
|
|
|
/*static int pgupcode = 0x63; */
|
|
|
|
/*static int pgdowncode = 0x69; */
|
|
|
|
|
|
|
|
static void alttab(int shift);
|
|
|
|
|
|
|
|
void
|
|
|
|
keysetup(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int tabcode = XKeysymToKeycode(dpy, XK_Tab);
|
|
|
|
int dcode = XKeysymToKeycode(dpy, DESTROY_KEY);
|
|
|
|
int icode = XKeysymToKeycode(dpy, ICON_KEY);
|
2020-02-29 18:04:01 +00:00
|
|
|
int ucode = XKeysymToKeycode(dpy, UNHIDE_KEY);
|
2019-12-02 18:23:00 +00:00
|
|
|
int mcode = XKeysymToKeycode(dpy, MAX_KEY);
|
|
|
|
int vcode = XKeysymToKeycode(dpy, MOVE_KEY);
|
|
|
|
int rcode = XKeysymToKeycode(dpy, RESIZE_KEY);
|
2021-02-11 04:26:23 +00:00
|
|
|
int scode = XKeysymToKeycode(dpy, STICK_KEY);
|
2019-12-02 18:23:00 +00:00
|
|
|
int hcode = XKeysymToKeycode(dpy, SNAPLEFT_KEY);
|
|
|
|
int lcode = XKeysymToKeycode(dpy, SNAPRIGHT_KEY);
|
|
|
|
int jcode = XKeysymToKeycode(dpy, SNAPBOTTOM_KEY);
|
|
|
|
int kcode = XKeysymToKeycode(dpy, SNAPTOP_KEY);
|
|
|
|
int qcode = XKeysymToKeycode(dpy, SNAPTOPLEFT_KEY);
|
|
|
|
int wcode = XKeysymToKeycode(dpy, SNAPBOTTOMLEFT_KEY);
|
|
|
|
int ocode = XKeysymToKeycode(dpy, SNAPBOTTOMRIGHT_KEY);
|
|
|
|
int pcode = XKeysymToKeycode(dpy, SNAPTOPRIGHT_KEY);
|
|
|
|
int ccode = XKeysymToKeycode(dpy, SNAPCENTER_KEY);
|
|
|
|
int slcode = XKeysymToKeycode(dpy, LAUNCH_KEY);
|
|
|
|
int rightcode = XKeysymToKeycode(dpy, NEXTVIRT_KEY);
|
|
|
|
int leftcode = XKeysymToKeycode(dpy, PREVVIRT_KEY);
|
2021-02-21 23:13:58 +00:00
|
|
|
#ifdef DEVEL
|
|
|
|
int tcode = XKeysymToKeycode(dpy, STICKYTOFRONT_KEY);
|
|
|
|
int bcode = XKeysymToKeycode(dpy, STICKYTOBACK_KEY);
|
|
|
|
#endif
|
2019-12-02 18:23:00 +00:00
|
|
|
|
|
|
|
for(i=0; i<num_screens; i++){
|
|
|
|
XGrabKey(dpy, tabcode, Mod1Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, dcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, icode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
2020-02-29 18:04:01 +00:00
|
|
|
XGrabKey(dpy, ucode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
2019-12-02 18:23:00 +00:00
|
|
|
XGrabKey(dpy, rcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, vcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, mcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
2021-02-11 04:26:23 +00:00
|
|
|
XGrabKey(dpy, scode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
2019-12-02 18:23:00 +00:00
|
|
|
XGrabKey(dpy, hcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, lcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, jcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, kcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, qcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, wcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, ocode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, pcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, ccode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, leftcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, rightcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, slcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, tabcode, Mod1Mask|ShiftMask, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
2021-02-21 23:13:58 +00:00
|
|
|
#ifdef DEVEL
|
|
|
|
XGrabKey(dpy, tcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
XGrabKey(dpy, bcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync);
|
|
|
|
#endif
|
2019-12-02 18:23:00 +00:00
|
|
|
/* XGrabKey(dpy, pgupcode, Mod1Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); */
|
|
|
|
/* XGrabKey(dpy, pgdowncode, Mod1Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); */
|
|
|
|
/* XGrabKey(dpy, altcode, 0, screens[i].root, 0, GrabModeSync, GrabModeAsync); */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
keypress(XKeyEvent *e)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* process key press here
|
|
|
|
*/
|
|
|
|
int tabcode = XKeysymToKeycode(dpy, XK_Tab);
|
|
|
|
int dcode = XKeysymToKeycode(dpy, DESTROY_KEY);
|
|
|
|
int icode = XKeysymToKeycode(dpy, ICON_KEY);
|
2020-02-29 18:04:01 +00:00
|
|
|
int ucode = XKeysymToKeycode(dpy, UNHIDE_KEY);
|
2019-12-02 18:23:00 +00:00
|
|
|
int mcode = XKeysymToKeycode(dpy, MAX_KEY);
|
|
|
|
int vcode = XKeysymToKeycode(dpy, MOVE_KEY);
|
2021-02-11 04:26:23 +00:00
|
|
|
int scode = XKeysymToKeycode(dpy, STICK_KEY);
|
2019-12-02 18:23:00 +00:00
|
|
|
int rcode = XKeysymToKeycode(dpy, RESIZE_KEY);
|
|
|
|
int slcode = XKeysymToKeycode(dpy, LAUNCH_KEY);
|
|
|
|
int hcode = XKeysymToKeycode(dpy, SNAPLEFT_KEY);
|
|
|
|
int lcode = XKeysymToKeycode(dpy, SNAPRIGHT_KEY);
|
|
|
|
int jcode = XKeysymToKeycode(dpy, SNAPBOTTOM_KEY);
|
|
|
|
int kcode = XKeysymToKeycode(dpy, SNAPTOP_KEY);
|
|
|
|
int qcode = XKeysymToKeycode(dpy, SNAPTOPLEFT_KEY);
|
|
|
|
int wcode = XKeysymToKeycode(dpy, SNAPBOTTOMLEFT_KEY);
|
|
|
|
int ocode = XKeysymToKeycode(dpy, SNAPBOTTOMRIGHT_KEY);
|
|
|
|
int pcode = XKeysymToKeycode(dpy, SNAPTOPRIGHT_KEY);
|
|
|
|
int ccode = XKeysymToKeycode(dpy, SNAPCENTER_KEY);
|
|
|
|
int rightcode = XKeysymToKeycode(dpy, NEXTVIRT_KEY);
|
|
|
|
int leftcode = XKeysymToKeycode(dpy, PREVVIRT_KEY);
|
2021-02-21 23:13:58 +00:00
|
|
|
#ifdef DEVEL
|
|
|
|
int tcode = XKeysymToKeycode(dpy, STICKYTOFRONT_KEY);
|
|
|
|
int bcode = XKeysymToKeycode(dpy, STICKYTOBACK_KEY);
|
|
|
|
#endif
|
|
|
|
|
2019-12-05 01:17:43 +00:00
|
|
|
static XWindowAttributes ra;
|
2019-12-02 18:23:00 +00:00
|
|
|
XGetWindowAttributes(dpy, DefaultRootWindow(dpy), &ra);
|
|
|
|
|
|
|
|
|
|
|
|
/* basic wm functionality */
|
2019-12-05 05:34:54 +00:00
|
|
|
if(e->keycode == tabcode && (e->state&Mod1Mask) == (1<<3))
|
|
|
|
alttab(e->state&ShiftMask);
|
2019-12-02 18:23:00 +00:00
|
|
|
if(e->keycode == dcode && (e->state&SHORTCUTMOD) == (MODBITS))
|
|
|
|
delete(current, 0);
|
2020-02-29 15:38:12 +00:00
|
|
|
if (e->keycode == icode && (e->state&SHORTCUTMOD) == (MODBITS))
|
2019-12-02 18:23:00 +00:00
|
|
|
hide(current);
|
2020-02-29 18:05:10 +00:00
|
|
|
if (e->keycode == ucode && (e->state&SHORTCUTMOD) == (MODBITS))
|
2020-02-29 18:08:58 +00:00
|
|
|
unhide(0, 1);
|
2019-12-02 18:23:00 +00:00
|
|
|
if (e->keycode == vcode && (e->state&SHORTCUTMOD) == (MODBITS))
|
|
|
|
move(current, Button3);
|
|
|
|
if (e->keycode == rcode && (e->state&SHORTCUTMOD) == (MODBITS))
|
|
|
|
reshape(current, Button3, sweep, 0);
|
|
|
|
if (e->keycode == mcode && (e->state&SHORTCUTMOD) == (MODBITS))
|
2019-12-05 01:17:43 +00:00
|
|
|
quickreshape(current, -BORDER, -BORDER, ra.width + 2*BORDER, ra.height + 2*BORDER);
|
2021-02-11 04:26:23 +00:00
|
|
|
if (e->keycode == scode && (e->state&SHORTCUTMOD) == (MODBITS))
|
|
|
|
stick(current);
|
2019-12-02 18:23:00 +00:00
|
|
|
|
|
|
|
/* half snap */
|
|
|
|
if (e->keycode == hcode && (e->state&SHORTCUTMOD) == (MODBITS))
|
2021-02-24 20:50:29 +00:00
|
|
|
quickreshape(current, GAPSZ, GAPSZ, ra.width/2 - 2*GAPSZ, ra.height - 2*GAPSZ);
|
2019-12-02 18:23:00 +00:00
|
|
|
if (e->keycode == lcode && (e->state&SHORTCUTMOD) == (MODBITS))
|
2021-02-24 20:50:29 +00:00
|
|
|
quickreshape(current, ra.width/2 + GAPSZ, GAPSZ, ra.width/2 - 2*GAPSZ, ra.height - 2*GAPSZ);
|
2019-12-02 18:23:00 +00:00
|
|
|
if (e->keycode == jcode && (e->state&SHORTCUTMOD) == (MODBITS))
|
2021-02-24 20:50:29 +00:00
|
|
|
quickreshape(current, GAPSZ, ra.height/2 + GAPSZ, ra.width - 2*GAPSZ, ra.height/2 - 2*GAPSZ);
|
2019-12-02 18:23:00 +00:00
|
|
|
if (e->keycode == kcode && (e->state&SHORTCUTMOD) == (MODBITS))
|
2021-02-24 20:50:29 +00:00
|
|
|
quickreshape(current, GAPSZ, GAPSZ, ra.width - 2*GAPSZ, ra.height/2 - 2*GAPSZ);
|
2019-12-02 18:23:00 +00:00
|
|
|
|
|
|
|
/* quarter snap */
|
|
|
|
if (e->keycode == qcode && (e->state&SHORTCUTMOD) == (MODBITS))
|
2021-02-24 20:50:29 +00:00
|
|
|
quickreshape(current, GAPSZ, GAPSZ, ra.width/2 - 2*GAPSZ, ra.height/2 - 2*GAPSZ);
|
2019-12-02 18:23:00 +00:00
|
|
|
if (e->keycode == wcode && (e->state&SHORTCUTMOD) == (MODBITS))
|
2021-02-24 20:50:29 +00:00
|
|
|
quickreshape(current, GAPSZ, ra.height/2 + GAPSZ, ra.width/2 - 2*GAPSZ, ra.height/2 - 2*GAPSZ);
|
2019-12-02 18:23:00 +00:00
|
|
|
if (e->keycode == ocode && (e->state&SHORTCUTMOD) == (MODBITS))
|
2021-02-24 20:50:29 +00:00
|
|
|
quickreshape(current, ra.width/2 + GAPSZ, ra.height/2 + GAPSZ, ra.width/2 - 2*GAPSZ, ra.height/2 - 2*GAPSZ);
|
2019-12-02 18:23:00 +00:00
|
|
|
if (e->keycode == pcode && (e->state&SHORTCUTMOD) == (MODBITS))
|
2021-02-24 20:50:29 +00:00
|
|
|
quickreshape(current, ra.width/2 + GAPSZ, GAPSZ, ra.width/2 - 2*GAPSZ, ra.height/2 - 2*GAPSZ);
|
2019-12-02 18:23:00 +00:00
|
|
|
|
|
|
|
/* center snap */
|
|
|
|
if (e->keycode == ccode && (e->state&SHORTCUTMOD) == (MODBITS))
|
2019-12-05 05:34:54 +00:00
|
|
|
quickreshape(current, ra.width/5, ra.height/5, 3*ra.width/5, 3*ra.height/5);
|
2019-12-02 18:23:00 +00:00
|
|
|
|
2021-02-21 23:13:58 +00:00
|
|
|
#ifdef DEVEL
|
|
|
|
/* manage autostuck windows */
|
|
|
|
if (e->keycode == tcode && (e->state&SHORTCUTMOD) == (MODBITS))
|
|
|
|
stickystack(1);
|
|
|
|
if (e->keycode == bcode && (e->state&SHORTCUTMOD) == (MODBITS))
|
|
|
|
stickystack(0);
|
|
|
|
#endif
|
|
|
|
|
2019-12-02 18:23:00 +00:00
|
|
|
|
|
|
|
/* launch */
|
|
|
|
if (e->keycode == slcode && (e->state&SHORTCUTMOD) == (MODBITS)){
|
|
|
|
kbLaunch = 1;
|
|
|
|
if(fork() == 0){
|
|
|
|
close(ConnectionNumber(dpy));
|
|
|
|
if(dpy != '\0')
|
|
|
|
putenv(dpy);
|
|
|
|
signal(SIGINT, SIG_DFL);
|
|
|
|
signal(SIGTERM, SIG_DFL);
|
|
|
|
signal(SIGHUP, SIG_DFL);
|
|
|
|
if(termprog != NULL){
|
|
|
|
execl(shell, shell, "-c", termprog, (char*)0);
|
|
|
|
fprintf(stderr, "ryudo: exec %s", shell);
|
|
|
|
perror(" failed");
|
|
|
|
}
|
|
|
|
execlp("urxvt", "urxvt", (char*)0);
|
|
|
|
execlp("9term", "9term", scrolling ? "-ws" : "-w", (char*)0);
|
|
|
|
execlp("xterm", "xterm", "-ut", (char*)0);
|
2019-12-02 22:09:06 +00:00
|
|
|
perror("ryudo: exec urxvt/9term/xterm failed");
|
2019-12-02 18:23:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* switch virts */
|
2019-12-05 01:17:43 +00:00
|
|
|
if (e->keycode == rightcode && (e->state&SHORTCUTMOD) == (MODBITS))
|
2020-08-07 03:50:28 +00:00
|
|
|
if (numvirtuals > 1)
|
|
|
|
if (virt < numvirtuals - 1)
|
|
|
|
switch_to(virt + 1);
|
|
|
|
else
|
|
|
|
switch_to(0);
|
|
|
|
|
2019-12-05 01:17:43 +00:00
|
|
|
if (e->keycode == leftcode && (e->state&SHORTCUTMOD) == (MODBITS))
|
2020-08-07 03:50:28 +00:00
|
|
|
if (numvirtuals >1)
|
|
|
|
if (virt > 0)
|
|
|
|
switch_to(virt - 1);
|
|
|
|
else
|
|
|
|
switch_to(numvirtuals - 1);
|
2019-12-02 18:23:00 +00:00
|
|
|
|
|
|
|
XAllowEvents(dpy, SyncKeyboard, e->time);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
keyrelease(XKeyEvent *e)
|
|
|
|
{
|
|
|
|
XAllowEvents(dpy, SyncKeyboard, e->time);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
quickreshape(Client *c, int x, int y, int dx, int dy)
|
|
|
|
{
|
2020-02-29 15:38:12 +00:00
|
|
|
if (c == 0)
|
|
|
|
return;
|
2019-12-02 18:23:00 +00:00
|
|
|
XMoveResizeWindow(dpy, c->parent, x,y, dx, dy);
|
|
|
|
c->x = x + BORDER;
|
|
|
|
c->y = y + BORDER;
|
|
|
|
c->dx = dx-2*BORDER;
|
|
|
|
c->dy = dy-2*BORDER;
|
|
|
|
XMoveResizeWindow(dpy, c->window, BORDER, BORDER, c->dx, c->dy);
|
|
|
|
sendconfig(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
alttab(int shift)
|
|
|
|
{
|
|
|
|
shuffle(shift);
|
|
|
|
/* fprintf(stderr, "%sTab\n", shift ? "Back" : ""); */
|
|
|
|
}
|
|
|
|
|
2021-02-21 23:13:58 +00:00
|
|
|
#ifdef DEVEL
|
|
|
|
void
|
|
|
|
stickystack(int toTop)
|
|
|
|
{
|
|
|
|
Client *c;
|
|
|
|
if(toTop){
|
|
|
|
for(c = clients; c->next; c = c->next){
|
|
|
|
if(c && isautostick(c))
|
|
|
|
top(c);
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
for(c = clients; c->next; c = c->next){
|
|
|
|
if(c && !isautostick(c))
|
|
|
|
top(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|