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.

150 lines
3.4 KiB

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