dwm

Kris's build of dwm
git clone git clone https://git.krisyotam.com/krisyotam/dwm.git
Log | Files | Refs | README | LICENSE

placemouse.c (3326B)


      1 void
      2 moveorplace(const Arg *arg) {
      3 	if ((!selmon->lt[selmon->sellt]->arrange || (selmon->sel && selmon->sel->isfloating)))
      4 		movemouse(arg);
      5 	else
      6 		placemouse(arg);
      7 }
      8 
      9 void
     10 placemouse(const Arg *arg)
     11 {
     12 	int x, y, px, py, ocx, ocy, nx = -9999, ny = -9999, freemove = 0;
     13 	Client *c, *r = NULL, *at, *prevr;
     14 	Monitor *m;
     15 	XEvent ev;
     16 	XWindowAttributes wa;
     17 	Time lasttime = 0;
     18 	int attachmode, prevattachmode;
     19 	attachmode = prevattachmode = -1;
     20 
     21 	if (!(c = selmon->sel) || !c->mon->lt[c->mon->sellt]->arrange) /* no support for placemouse when floating layout is used */
     22 		return;
     23 	if (c->isfullscreen) /* no support placing fullscreen windows by mouse */
     24 		return;
     25 	restack(selmon);
     26 	prevr = c;
     27 	if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
     28 		None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
     29 		return;
     30 
     31 	c->isfloating = 0;
     32 	c->beingmoved = 1;
     33 
     34 	XGetWindowAttributes(dpy, c->win, &wa);
     35 	ocx = wa.x;
     36 	ocy = wa.y;
     37 
     38 	if (arg->i == 2) // warp cursor to client center
     39 		XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, WIDTH(c) / 2, HEIGHT(c) / 2);
     40 
     41 	if (!getrootptr(&x, &y))
     42 		return;
     43 
     44 	do {
     45 		XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
     46 		switch (ev.type) {
     47 		case ConfigureRequest:
     48 		case Expose:
     49 		case MapRequest:
     50 			handler[ev.type](&ev);
     51 			break;
     52 		case MotionNotify:
     53 			if ((ev.xmotion.time - lasttime) <= (1000 / refreshrate_placemouse))
     54 				continue;
     55 			lasttime = ev.xmotion.time;
     56 
     57 			nx = ocx + (ev.xmotion.x - x);
     58 			ny = ocy + (ev.xmotion.y - y);
     59 
     60 			if (!freemove && (abs(nx - ocx) > snap || abs(ny - ocy) > snap))
     61 				freemove = 1;
     62 
     63 			if (freemove)
     64 				XMoveWindow(dpy, c->win, nx, ny);
     65 
     66 			if ((m = recttomon(ev.xmotion.x, ev.xmotion.y, 1, 1)) && m != selmon)
     67 				selmon = m;
     68 
     69 			if (arg->i == 1) { // tiled position is relative to the client window center point
     70 				px = nx + wa.width / 2;
     71 				py = ny + wa.height / 2;
     72 			} else { // tiled position is relative to the mouse cursor
     73 				px = ev.xmotion.x;
     74 				py = ev.xmotion.y;
     75 			}
     76 
     77 			r = recttoclient(px, py, 1, 1, 0);
     78 
     79 			if (!r || r == c)
     80 				break;
     81 
     82 			if ((((float)(r->y + r->h - py) / r->h) > ((float)(r->x + r->w - px) / r->w)
     83 			    	&& (abs(r->y - py) < r->h / 2)) || (abs(r->x - px) < r->w / 2))
     84 				attachmode = 1; // above
     85 			else
     86 				attachmode = 0; // below
     87 
     88 			if ((r && r != prevr) || (attachmode != prevattachmode)) {
     89 				detachstack(c);
     90 				detach(c);
     91 				if (c->mon != r->mon) {
     92 					arrangemon(c->mon);
     93 					c->tags = r->mon->tagset[r->mon->seltags];
     94 				}
     95 
     96 				c->mon = r->mon;
     97 				r->mon->sel = r;
     98 
     99 				if (attachmode) {
    100 					if (r == r->mon->clients)
    101 						attach(c);
    102 					else {
    103 						for (at = r->mon->clients; at->next != r; at = at->next);
    104 						c->next = at->next;
    105 						at->next = c;
    106 					}
    107 				} else {
    108 					c->next = r->next;
    109 					r->next = c;
    110 				}
    111 
    112 				attachstack(c);
    113 				arrangemon(r->mon);
    114 				prevr = r;
    115 				prevattachmode = attachmode;
    116 			}
    117 			break;
    118 		}
    119 	} while (ev.type != ButtonRelease);
    120 	XUngrabPointer(dpy, CurrentTime);
    121 
    122 	if ((m = recttomon(ev.xmotion.x, ev.xmotion.y, 1, 1)) && m != c->mon) {
    123 		detach(c);
    124 		detachstack(c);
    125 		arrangemon(c->mon);
    126 		c->mon = m;
    127 		c->tags = m->tagset[m->seltags];
    128 		attach(c);
    129 		attachstack(c);
    130 		selmon = m;
    131 	}
    132 
    133 	focus(c);
    134 	c->beingmoved = 0;
    135 
    136 	if (nx != -9999)
    137 		resize(c, nx, ny, c->w, c->h, 0);
    138 	arrangemon(c->mon);
    139 }