/* TinyWM is written by Nick Welch <
[email protected]> in 2005 & 2011.
* This software is in the public domain and is provided AS IS with NO WARRANTY
*
* tfurrows: added actions for mod1+left click and mod1+middle click
* added exit(0) on mod1+right click at screen position 0,0
* added mod1+F2 to lower focus window
* added mod1+F3 to shrink window or restore
* added mod1+F4 to close/destroy window
*/
#include <X11/Xlib.h>
#include <stdlib.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define LCRUN "/usr/bin/xterm -fg white -bg black &"
#define MCRUN "/usr/bin/perl /home/jlyman/bin/deskpad &"
int main(void) {
Display * dpy;
XWindowAttributes attr;
XButtonEvent start;
XEvent ev;
if(!(dpy = XOpenDisplay(0x0))) return 1;
XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("F1")), Mod1Mask,
DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("F2")), Mod1Mask,
DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("F3")), Mod1Mask,
DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("F4")), Mod1Mask,
DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync);
XGrabButton(dpy, 1, Mod1Mask, DefaultRootWindow(dpy), True,
ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None);
XGrabButton(dpy, 2, Mod1Mask, DefaultRootWindow(dpy), True,
ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None);
XGrabButton(dpy, 3, Mod1Mask, DefaultRootWindow(dpy), True,
ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None);
start.subwindow = None;
for(;;) {
XNextEvent(dpy, &ev);
if(ev.type == KeyPress && ev.xkey.subwindow != None) {
switch(ev.xkey.keycode) {
case 0x43:
XRaiseWindow(dpy, ev.xkey.subwindow);
XSetInputFocus(dpy, ev.xkey.subwindow, RevertToPointerRoot, CurrentTime);
XSync(dpy,True);
break;
case 0x44:
XLowerWindow(dpy, ev.xkey.subwindow);
break;
case 0x45:
XGetWindowAttributes(dpy, ev.xbutton.subwindow, &attr);
if(attr.width == 150) {
XResizeWindow(dpy, ev.xkey.subwindow, 500, 300);
XRaiseWindow(dpy, ev.xkey.subwindow);
} else {
XResizeWindow(dpy, ev.xkey.subwindow, 150, 20);
XLowerWindow(dpy, ev.xkey.subwindow);
}
break;
case 0x46:
XDestroyWindow(dpy, ev.xkey.subwindow);
break;
}
} else if(ev.type == ButtonPress && ev.xbutton.subwindow != None) {
XGetWindowAttributes(dpy, ev.xbutton.subwindow, &attr);
start = ev.xbutton;
XRaiseWindow(dpy, start.subwindow);
XSetInputFocus(dpy, start.subwindow, RevertToPointerRoot, CurrentTime);
XSync(dpy,True);
} else if(ev.type == MotionNotify && start.subwindow != None) {
int xdiff = ev.xbutton.x_root - start.x_root;
int ydiff = ev.xbutton.y_root - start.y_root;
XMoveResizeWindow(dpy, start.subwindow,
attr.x + (start.button==1 ? xdiff : 0),
attr.y + (start.button==1 ? ydiff : 0),
MAX(1, attr.width + (start.button==3 ? xdiff : 0)),
MAX(1, attr.height + (start.button==3 ? ydiff : 0)));
} else if(ev.type == ButtonPress && ev.xbutton.subwindow == 0) {
switch(ev.xbutton.button) {
case Button1:
system(LCRUN);
break;
case Button2:
system(MCRUN);
break;
case Button3:
if(ev.xbutton.x == 0 && ev.xbutton.y == 0)
exit(0);
break;
}
} else if(ev.type == ButtonRelease) {
start.subwindow = None;
}
}
}