Advertisement
Twilypastes

xrectsel (drawterm)

Jan 1st, 2015
574
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.81 KB | None | 0 0
  1. "xrectsel" is used to draw an rectangle and return the X,Y,W,H
  2. "drawterm" is used w/ a hotkey to trigger xrectsel and spawn the terminal at given position
  3.  
  4. instructions on compilation and installation below xrectsel.c
  5.  
  6.  
  7.  
  8.  
  9. ** note: slop "https://github.com/naelstrof/slop" can be used instead of xrectsel
  10.               (see 'drawterm' below xrectsel.c)
  11.  
  12.  
  13.  
  14.  
  15.  
  16. /*  ----------------------------- xrectsel.c ------------------------------- */
  17. #include<stdio.h>
  18. #include<stdlib.h>
  19. #include<X11/Xlib.h>
  20. #include<X11/cursorfont.h>
  21.  
  22. int main(void)
  23. {
  24.   int rx = 0, ry = 0, rw = 0, rh = 0;
  25.   int rect_x = 0, rect_y = 0, rect_w = 0, rect_h = 0;
  26.   int btn_pressed = 0, done = 0;
  27.  
  28.   XEvent ev;
  29.   Display *disp = XOpenDisplay(NULL);
  30.  
  31.   if(!disp)
  32.     return EXIT_FAILURE;
  33.  
  34.   Screen *scr = NULL;
  35.   scr = ScreenOfDisplay(disp, DefaultScreen(disp));
  36.  
  37.   Window root = 0;
  38.   root = RootWindow(disp, XScreenNumberOfScreen(scr));
  39.  
  40.   Cursor cursor, cursor2;
  41.   cursor = XCreateFontCursor(disp, XC_left_ptr);
  42.   cursor2 = XCreateFontCursor(disp, XC_lr_angle);
  43.  
  44.   XGCValues gcval;
  45.   gcval.foreground = XWhitePixel(disp, 0);
  46.   gcval.function = GXxor;
  47.   gcval.background = XBlackPixel(disp, 0);
  48.   gcval.plane_mask = gcval.background ^ gcval.foreground;
  49.   gcval.subwindow_mode = IncludeInferiors;
  50.  
  51.   GC gc;
  52.   gc = XCreateGC(disp, root,
  53.                  GCFunction | GCForeground | GCBackground | GCSubwindowMode,
  54.                  &gcval);
  55.  
  56.   /* this XGrab* stuff makes XPending true ? */
  57.   if ((XGrabPointer
  58.        (disp, root, False,
  59.         ButtonMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync,
  60.         GrabModeAsync, root, cursor, CurrentTime) != GrabSuccess))
  61.     printf("couldn't grab pointer:");
  62.  
  63.   if ((XGrabKeyboard
  64.        (disp, root, False, GrabModeAsync, GrabModeAsync,
  65.         CurrentTime) != GrabSuccess))
  66.     printf("couldn't grab keyboard:");
  67.  
  68.   while (!done) {
  69.     while (!done && XPending(disp)) {
  70.       XNextEvent(disp, &ev);
  71.       switch (ev.type) {
  72.         case MotionNotify:
  73.         /* this case is purely for drawing rect on screen */
  74.           if (btn_pressed) {
  75.             if (rect_w) {
  76.               /* re-draw the last rect to clear it */
  77.               XDrawRectangle(disp, root, gc, rect_x, rect_y, rect_w, rect_h);
  78.             } else {
  79.               /* Change the cursor to show we're selecting a region */
  80.               XChangeActivePointerGrab(disp,
  81.                                        ButtonMotionMask | ButtonReleaseMask,
  82.                                        cursor2, CurrentTime);
  83.             }
  84.             rect_x = rx;
  85.             rect_y = ry;
  86.             rect_w = ev.xmotion.x - rect_x;
  87.             rect_h = ev.xmotion.y - rect_y;
  88.  
  89.             if (rect_w < 0) {
  90.               rect_x += rect_w;
  91.               rect_w = 0 - rect_w;
  92.             }
  93.             if (rect_h < 0) {
  94.               rect_y += rect_h;
  95.               rect_h = 0 - rect_h;
  96.             }
  97.             /* draw rectangle */
  98.             XDrawRectangle(disp, root, gc, rect_x, rect_y, rect_w, rect_h);
  99.             XFlush(disp);
  100.           }
  101.           break;
  102.         case ButtonPress:
  103.           btn_pressed = 1;
  104.           rx = ev.xbutton.x;
  105.           ry = ev.xbutton.y;
  106.           break;
  107.         case ButtonRelease:
  108.           done = 1;
  109.           break;
  110.       }
  111.     }
  112.   }
  113.   /* clear the drawn rectangle */
  114.   if (rect_w) {
  115.     XDrawRectangle(disp, root, gc, rect_x, rect_y, rect_w, rect_h);
  116.     XFlush(disp);
  117.   }
  118.   rw = ev.xbutton.x - rx;
  119.   rh = ev.xbutton.y - ry;
  120.   /* cursor moves backwards */
  121.   if (rw < 0) {
  122.     rx += rw;
  123.     rw = 0 - rw;
  124.   }
  125.   if (rh < 0) {
  126.     ry += rh;
  127.     rh = 0 - rh;
  128.   }
  129.  
  130.   XCloseDisplay(disp);
  131.  
  132.   printf("%d %d %d %d\n",rw,rh,rx,ry);
  133.  
  134.   return EXIT_SUCCESS;
  135. }
  136.  
  137. /*  ----------------------------- xrectsel.c ------------------------------- */
  138.  
  139. COMPILE:      $ gcc -Wall -lX11 xrectsel.c -o xrectsel
  140. Copy to PATH: $ sudo cp xrectsel /usr/local/bin/
  141.  
  142. SOURCE:  https://bbs.archlinux.org/viewtopic.php?id=85378
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149. /*  ----------------------------- drawterm ------------------------------- */
  150. #!/bin/bash
  151. #
  152. #   Author:         Twily                                           2015
  153. #   Description:    Spawn a new terminal window inside a drawn rectangle
  154. #   Requires:       slop (or xrectsel: http://pastebin.com/eeLRBed6), urxvt
  155. #   Usage:          Bind hotkey to $ sh ./drawterm
  156. #
  157. #   Note:           if using compton w/ shadows, exclude "class_g = 'slop'"
  158. #
  159.  
  160. M=2                 # slop border width
  161.  
  162. REC=$(slop -t 0 -b $M -c 1,1,1,1 -f "%w %h %x %y" --nokeyboard) || exit 1
  163. #REC=$(xrectsel) || exit 1
  164.  
  165. IFS=' ' read -r W H X Y <<< "$REC"
  166.  
  167. aX=$(( $X - $M )) && aY=$(( $Y - $M ))
  168. aW=$(( $W + ( $M * 2 ) )) && aH=$(( $H + ( $M * 2 ) ))
  169.  
  170. if [ "$W" -gt "1" ]; then
  171.     # Calculate width and height to block/font size
  172.     let W=$(( $W / 7 ))-2
  173.     let H=$(( $H / 15 ))-1
  174.  
  175.     urxvt -g $W"x"$H"+"$X"+"$Y &
  176.  
  177.     for i in {0..49}; do # timeout
  178.         if ps -p $! >/dev/null; then
  179.             sleep .1
  180.  
  181.             wmctrl -r :ACTIVE: -e 0,$aX,$aY,$aW,$aH
  182.             break
  183.         fi
  184.     done
  185. fi
  186.  
  187. exit 0
  188. /*  ----------------------------- drawterm ------------------------------- */
  189.  
  190.  
  191.  
  192.  
  193. for "Snap grid" see http://twily.info/snap.grid#Openbox
  194. (+"grid" and "ext.grid" for more tiling scripts)
  195.  
  196.  
  197.  
  198. /*  ----------------------------- snap.all ------------------------------- */
  199. #!/bin/bash
  200. #
  201. #   Author:         Twily                                                       2015
  202. #   Description:    Uses 'snap.grid' to snap all visible windows into a virtual grid
  203. #   Requires:       xdotool, snap.grid
  204. #   Usage:          $ sh ./snap.all
  205. #
  206.  
  207. for w in $(xdotool search --onlyvisible --desktop $(xdotool get_desktop) --name ""); do
  208.     sh ~/scripts/snap.grid $w
  209. done
  210.  
  211. exit 0
  212. /*  ----------------------------- snap.all ------------------------------- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement