dwm

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

floatpos.c (4936B)


      1 void
      2 floatpos(const Arg *arg)
      3 {
      4 	Client *c = selmon->sel;
      5 
      6 	if (!c || (selmon->lt[selmon->sellt]->arrange && !c->isfloating))
      7 		return;
      8 
      9 	setfloatpos(c, (char *)arg->v);
     10 	resizeclient(c, c->x, c->y, c->w, c->h);
     11 
     12 	#if !FOCUSONCLICK_PATCH
     13 	XRaiseWindow(dpy, c->win);
     14 	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2);
     15 	#endif // FOCUSONCLICK_PATCH
     16 }
     17 
     18 void
     19 setfloatpos(Client *c, const char *floatpos)
     20 {
     21 	char xCh, yCh, wCh, hCh;
     22 	int x, y, w, h, wx, ww, wy, wh;
     23 	#if FLOATPOS_RESPECT_GAPS_PATCH && VANITYGAPS_PATCH
     24 	int oh, ov, ih, iv;
     25 	unsigned int n;
     26 	#endif // FLOATPOS_RESPECT_GAPS_PATCH | VANITYGAPS_PATCH
     27 
     28 	if (!c || !floatpos)
     29 		return;
     30 	if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
     31 		return;
     32 
     33 	switch(sscanf(floatpos, "%d%c %d%c %d%c %d%c", &x, &xCh, &y, &yCh, &w, &wCh, &h, &hCh)) {
     34 		case 4:
     35 			if (xCh == 'w' || xCh == 'W') {
     36 				w = x; wCh = xCh;
     37 				h = y; hCh = yCh;
     38 				x = -1; xCh = 'C';
     39 				y = -1; yCh = 'C';
     40 			} else if (xCh == 'p' || xCh == 'P') {
     41 				w = x; wCh = xCh;
     42 				h = y; hCh = yCh;
     43 				x = 0; xCh = 'G';
     44 				y = 0; yCh = 'G';
     45 			} else if (xCh == 'm' || xCh == 'M') {
     46 				getrootptr(&x, &y);
     47 			} else {
     48 				w = 0; wCh = 0;
     49 				h = 0; hCh = 0;
     50 			}
     51 			break;
     52 		case 8:
     53 			if (xCh == 'm' || xCh == 'M')
     54 				getrootptr(&x, &y);
     55 			break;
     56 		default:
     57 			return;
     58 	}
     59 
     60 	#if FLOATPOS_RESPECT_GAPS_PATCH && VANITYGAPS_PATCH
     61 	getgaps(c->mon, &oh, &ov, &ih, &iv, &n);
     62 	wx = c->mon->wx + ov;
     63 	wy = c->mon->wy + oh;
     64 	ww = c->mon->ww - 2*ov;
     65 	wh = c->mon->wh - 2*oh;
     66 	#else
     67 	wx = c->mon->wx;
     68 	wy = c->mon->wy;
     69 	ww = c->mon->ww;
     70 	wh = c->mon->wh;
     71 	#endif // FLOATPOS_RESPECT_GAPS_PATCH | VANITYGAPS_PATCH
     72 
     73 	getfloatpos(x, xCh, w, wCh, wx, ww, c->x, c->w, c->bw, floatposgrid_x, &c->x, &c->w);
     74 	getfloatpos(y, yCh, h, hCh, wy, wh, c->y, c->h, c->bw, floatposgrid_y, &c->y, &c->h);
     75 }
     76 
     77 /* p - position, s - size, cp and cs represents current position and size */
     78 void
     79 getfloatpos(int pos, char pCh, int size, char sCh, int min_p, int max_s, int cp, int cs, int cbw, int defgrid, int *out_p, int *out_s)
     80 {
     81 	int abs_p, abs_s, i, delta, rest;
     82 
     83 	abs_p = pCh == 'A' || pCh == 'a';
     84 	abs_s = sCh == 'A' || sCh == 'a';
     85 
     86 	cs += 2*cbw;
     87 
     88 	switch(pCh) {
     89 	case 'A': // absolute position
     90 		cp = pos;
     91 		break;
     92 	case 'a': // absolute relative position
     93 		cp += pos;
     94 		break;
     95 	case 'y':
     96 	case 'x': // client relative position
     97 		cp = MIN(cp + pos, min_p + max_s);
     98 		break;
     99 	case 'Y':
    100 	case 'X': // client position relative to monitor
    101 		cp = min_p + MIN(pos, max_s);
    102 		break;
    103 	case 'S': // fixed client position (sticky)
    104 	case 'C': // fixed client position (center)
    105 	case 'Z': // fixed client right-hand position (position + size)
    106 		if (pos == -1)
    107 			break;
    108 		pos = MAX(MIN(pos, max_s), 0);
    109 		if (pCh == 'Z')
    110 			cs = abs((cp + cs) - (min_p + pos));
    111 		else if (pCh == 'C')
    112 			cs = abs((cp + cs / 2) - (min_p + pos));
    113 		else
    114 			cs = abs(cp - (min_p + pos));
    115 		cp = min_p + pos;
    116 		sCh = 0; // size determined by position, override defined size
    117 		break;
    118 	case 'G': // grid
    119 		if (pos <= 0)
    120 			pos = defgrid; // default configurable
    121 		if (size == 0 || pos < 2 || (sCh != 'p' && sCh != 'P'))
    122 			break;
    123 		delta = (max_s - cs) / (pos - 1);
    124 		rest = max_s - cs - delta * (pos - 1);
    125 		if (sCh == 'P') {
    126 			if (size < 1 || size > pos)
    127 				break;
    128 			cp = min_p + delta * (size - 1);
    129 		} else {
    130 			for (i = 0; i < pos && cp >= min_p + delta * i + (i > pos - rest ? i + rest - pos + 1 : 0); i++);
    131 			cp = min_p + delta * (MAX(MIN(i + size, pos), 1) - 1) + (i > pos - rest ? i + rest - pos + 1 : 0);
    132 		}
    133 		break;
    134 	}
    135 
    136 	switch(sCh) {
    137 	case 'A': // absolute size
    138 		cs = size;
    139 		break;
    140 	case 'a': // absolute relative size
    141 		cs = MAX(1, cs + size);
    142 		break;
    143 	case '%': // client size percentage in relation to monitor window area size
    144 		if (size <= 0)
    145 			break;
    146 		size = max_s * MIN(size, 100) / 100;
    147 		/* falls through */
    148 	case 'h':
    149 	case 'w': // size relative to client
    150 		if (sCh == 'w' || sCh == 'h') {
    151 			if (size == 0)
    152 				break;
    153 			size += cs;
    154 		}
    155 		/* falls through */
    156 	case 'H':
    157 	case 'W': // normal size, position takes precedence
    158 		if (pCh == 'S' && cp + size > min_p + max_s)
    159 			size = min_p + max_s - cp;
    160 		else if (size > max_s)
    161 			size = max_s;
    162 
    163 		if (pCh == 'C') { // fixed client center, expand or contract client
    164 			delta = size - cs;
    165 			if (delta < 0 || (cp - delta / 2 + size <= min_p + max_s))
    166 				cp -= delta / 2;
    167 			else if (cp - delta / 2 < min_p)
    168 				cp = min_p;
    169 			else if (delta)
    170 				cp = min_p + max_s;
    171 		} else if (pCh == 'Z')
    172 			cp -= size - cs;
    173 
    174 		cs = size;
    175 		break;
    176 	}
    177 
    178 	if (pCh == '%') // client mid-point position in relation to monitor window area size
    179 		cp = min_p + max_s * MAX(MIN(pos, 100), 0) / 100 - (cs) / 2;
    180 	if (pCh == 'm' || pCh == 'M')
    181 		cp = pos - cs / 2;
    182 
    183 	if (!abs_p && cp < min_p)
    184 		cp = min_p;
    185 	if (cp + cs > min_p + max_s && !(abs_p && abs_s)) {
    186 		if (abs_p || cp == min_p)
    187 			cs = min_p + max_s - cp;
    188 		else
    189 			cp = min_p + max_s - cs;
    190 	}
    191 
    192 	*out_p = cp;
    193 	*out_s = MAX(cs - 2*cbw, 1);
    194 }
    195