Another copy of my dotfiles. Because I don't completely trust GitHub.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
4.5 KiB

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