/* TinyWM is written by Nick Welch 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 #include #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; } } }