Title: [C] xrectsel (drawterm) Author: Twilypastes Pastebin link: http://pastebin.com/eeLRBed6 First Edit: Thursday 1st of January 2015 09:24:45 AM CDT Last Edit: Last edit on: Thursday 5th of March 2015 01:29:52 PM CDT "xrectsel" is used to draw an rectangle and return the X,Y,W,H "drawterm" is used w/ a hotkey to trigger xrectsel and spawn the terminal at given position   instructions on compilation and installation below xrectsel.c         ** note: slop "https://github.com/naelstrof/slop" can be used instead of xrectsel               (see 'drawterm' below xrectsel.c)           /*  ----------------------------- xrectsel.c ------------------------------- */ #include #include #include #include   int main(void) {   int rx = 0, ry = 0, rw = 0, rh = 0;   int rect_x = 0, rect_y = 0, rect_w = 0, rect_h = 0;   int btn_pressed = 0, done = 0;     XEvent ev;   Display *disp = XOpenDisplay(NULL);     if(!disp)     return EXIT_FAILURE;     Screen *scr = NULL;   scr = ScreenOfDisplay(disp, DefaultScreen(disp));     Window root = 0;   root = RootWindow(disp, XScreenNumberOfScreen(scr));     Cursor cursor, cursor2;   cursor = XCreateFontCursor(disp, XC_left_ptr);   cursor2 = XCreateFontCursor(disp, XC_lr_angle);     XGCValues gcval;   gcval.foreground = XWhitePixel(disp, 0);   gcval.function = GXxor;   gcval.background = XBlackPixel(disp, 0);   gcval.plane_mask = gcval.background ^ gcval.foreground;   gcval.subwindow_mode = IncludeInferiors;     GC gc;   gc = XCreateGC(disp, root,                  GCFunction | GCForeground | GCBackground | GCSubwindowMode,                  &gcval);     /* this XGrab* stuff makes XPending true ? */   if ((XGrabPointer        (disp, root, False,         ButtonMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync,         GrabModeAsync, root, cursor, CurrentTime) != GrabSuccess))     printf("couldn't grab pointer:");     if ((XGrabKeyboard        (disp, root, False, GrabModeAsync, GrabModeAsync,         CurrentTime) != GrabSuccess))     printf("couldn't grab keyboard:");     while (!done) {     while (!done && XPending(disp)) {       XNextEvent(disp, &ev);       switch (ev.type) {         case MotionNotify:         /* this case is purely for drawing rect on screen */           if (btn_pressed) {             if (rect_w) {               /* re-draw the last rect to clear it */               XDrawRectangle(disp, root, gc, rect_x, rect_y, rect_w, rect_h);             } else {               /* Change the cursor to show we're selecting a region */               XChangeActivePointerGrab(disp,                                        ButtonMotionMask | ButtonReleaseMask,                                        cursor2, CurrentTime);             }             rect_x = rx;             rect_y = ry;             rect_w = ev.xmotion.x - rect_x;             rect_h = ev.xmotion.y - rect_y;               if (rect_w < 0) {               rect_x += rect_w;               rect_w = 0 - rect_w;             }             if (rect_h < 0) {               rect_y += rect_h;               rect_h = 0 - rect_h;             }             /* draw rectangle */             XDrawRectangle(disp, root, gc, rect_x, rect_y, rect_w, rect_h);             XFlush(disp);           }           break;         case ButtonPress:           btn_pressed = 1;           rx = ev.xbutton.x;           ry = ev.xbutton.y;           break;         case ButtonRelease:           done = 1;           break;       }     }   }   /* clear the drawn rectangle */   if (rect_w) {     XDrawRectangle(disp, root, gc, rect_x, rect_y, rect_w, rect_h);     XFlush(disp);   }   rw = ev.xbutton.x - rx;   rh = ev.xbutton.y - ry;   /* cursor moves backwards */   if (rw < 0) {     rx += rw;     rw = 0 - rw;   }   if (rh < 0) {     ry += rh;     rh = 0 - rh;   }     XCloseDisplay(disp);     printf("%d %d %d %d\n",rw,rh,rx,ry);     return EXIT_SUCCESS; }   /*  ----------------------------- xrectsel.c ------------------------------- */   COMPILE:      $ gcc -Wall -lX11 xrectsel.c -o xrectsel Copy to PATH: $ sudo cp xrectsel /usr/local/bin/   SOURCE:  https://bbs.archlinux.org/viewtopic.php?id=85378             /*  ----------------------------- drawterm ------------------------------- */ #!/bin/bash # #   Author:         Twily                                           2015 #   Description:    Spawn a new terminal window inside a drawn rectangle #   Requires:       slop (or xrectsel: http://pastebin.com/eeLRBed6), urxvt #   Usage:          Bind hotkey to $ sh ./drawterm # #   Note:           if using compton w/ shadows, exclude "class_g = 'slop'" #   M=2                 # slop border width   REC=$(slop -t 0 -b $M -c 1,1,1,1 -f "%w %h %x %y" --nokeyboard) || exit 1 #REC=$(xrectsel) || exit 1   IFS=' ' read -r W H X Y <<< "$REC"   aX=$(( $X - $M )) && aY=$(( $Y - $M )) aW=$(( $W + ( $M * 2 ) )) && aH=$(( $H + ( $M * 2 ) ))   if [ "$W" -gt "1" ]; then     # Calculate width and height to block/font size     let W=$(( $W / 7 ))-2     let H=$(( $H / 15 ))-1       urxvt -g $W"x"$H"+"$X"+"$Y &       for i in {0..49}; do # timeout         if ps -p $! >/dev/null; then             sleep .1               wmctrl -r :ACTIVE: -e 0,$aX,$aY,$aW,$aH             break         fi     done fi   exit 0 /*  ----------------------------- drawterm ------------------------------- */         for "Snap grid" see http://twily.info/snap.grid#Openbox (+"grid" and "ext.grid" for more tiling scripts)       /*  ----------------------------- snap.all ------------------------------- */ #!/bin/bash # #   Author:         Twily                                                       2015 #   Description:    Uses 'snap.grid' to snap all visible windows into a virtual grid #   Requires:       xdotool, snap.grid #   Usage:          $ sh ./snap.all #   for w in $(xdotool search --onlyvisible --desktop $(xdotool get_desktop) --name ""); do     sh ~/scripts/snap.grid $w done   exit 0 /*  ----------------------------- snap.all ------------------------------- */