123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- /*
- * wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
- * For license, see COPYING.
- */
- #include "wmfs.h"
- #include "mouse.h"
- #include "barwin.h"
- #include "client.h"
- #include "draw.h"
- #define _REV_SBORDER(c) draw_reversed_rect(W->root, c, false);
- #define _REV_BORDER() \
- do { \
- FOREACH_NFCLIENT(gc, &c->tag->clients, tnext) \
- draw_reversed_rect(W->root, gc, true); \
- } while(/* CONSTCOND */ 0);
- static void
- mouse_resize(struct client *c)
- {
- struct client *gc;
- XEvent ev;
- Window w;
- int d, u, ox, oy, ix, iy;
- int mx, my;
- XQueryPointer(W->dpy, W->root, &w, &w, &ox, &oy, &d, &d, (unsigned int *)&u);
- XGrabServer(W->dpy);
- if(c->flags & CLIENT_FREE)
- {
- _REV_SBORDER(c);
- }
- else
- _REV_BORDER();
- if(c->flags & CLIENT_TABBED && !(c->flags & CLIENT_TABMASTER))
- c = c->tabmaster;
- ix = ox;
- iy = oy;
- c->flags |= CLIENT_MOUSE;
- do
- {
- XMaskEvent(W->dpy, MouseMask | SubstructureRedirectMask, &ev);
- if(ev.type != MotionNotify)
- continue;
- mx = ev.xmotion.x_root;
- my = ev.xmotion.y_root;
- if(c->flags & CLIENT_FREE)
- {
- _REV_SBORDER(c);
- mx -= c->screen->ugeo.x;
- my -= c->screen->ugeo.y;
- c->geo.w = ((mx - c->geo.x <= c->sizeh[MINW] + c->border + c->border)
- ? c->sizeh[MINW] + c->border + c->border
- : mx - c->geo.x);
- c->geo.h = ((my - c->geo.y <= (c->sizeh[MINH] + c->tbarw + c->border))
- ? c->sizeh[MINH] + c->tbarw + c->border
- : my - c->geo.y);
- client_geo_hints(&c->geo, (int*)c->sizeh);
- /* For border preview cohesion */
- c->geo.h += c->tbarw + c->border;
- c->geo.w += c->border + c->border;
- _REV_SBORDER(c);
- }
- else
- {
- _REV_BORDER();
- if(ix >= c->rgeo.x + (c->geo.w >> 1))
- _fac_resize(c, Right, mx - ox);
- else
- _fac_resize(c, Left, ox - mx);
- if(iy >= c->rgeo.y + (c->geo.h >> 1))
- _fac_resize(c, Bottom, my - oy);
- else
- _fac_resize(c, Top, oy - my);
- ox = mx;
- oy = my;
- _REV_BORDER();
- }
- XSync(W->dpy, false);
- } while(ev.type != ButtonRelease);
- if(c->flags & CLIENT_FREE)
- {
- _REV_SBORDER(c);
- client_moveresize(c, &c->geo);
- }
- else
- {
- _REV_BORDER();
- client_apply_tgeo(c->tag);
- layout_save_set(c->tag);
- }
- c->flags &= ~CLIENT_MOUSE;
- XUngrabServer(W->dpy);
- }
- static struct tag*
- mouse_drag_tag(struct client *c, Window w)
- {
- struct barwin *b;
- struct tag *t = NULL;
- Window rw;
- int d, u;
- XQueryPointer(W->dpy, w, &rw, &rw, &d, &d, &d, &d, (uint *)&u);
- SLIST_FOREACH(b, &W->h.barwin, next)
- if(b->win == rw
- && (t = (struct tag*)b->ptr)
- && t != c->tag)
- return t;
- return NULL;
- }
- void
- mouse_move(struct client *c, void (*func)(struct client*, struct client*))
- {
- struct client *c2 = NULL, *last = c;
- struct tag *t = NULL;
- XEvent ev;
- Window w;
- int d, u, ox, oy;
- int ocx, ocy;
- ocx = c->geo.x;
- ocy = c->geo.y;
- if(c->flags & CLIENT_TABBED && !(c->flags & CLIENT_TABMASTER))
- c = c->tabmaster;
- XQueryPointer(W->dpy, W->root, &w, &w, &ox, &oy, &d, &d, (uint *)&u);
- _REV_SBORDER(c);
- c->flags |= CLIENT_MOUSE;
- do
- {
- XMaskEvent(W->dpy, MouseMask | SubstructureRedirectMask, &ev);
- if(ev.type != MotionNotify)
- continue;
- if(!func && c->flags & CLIENT_FREE)
- {
- _REV_SBORDER(c);
- c->geo.x = (ocx + (ev.xmotion.x_root - ox));
- c->geo.y = (ocy + (ev.xmotion.y_root - oy));
- _REV_SBORDER(c);
- }
- else
- {
- c2 = NULL;
- XQueryPointer(W->dpy, W->root, &w, &w, &d, &d, &d, &d, (uint *)&u);
- if((c2 = client_gb_win(w)) || (c2 = client_gb_frame(w)) || (c2 = client_gb_titlebar(w)))
- {
- if(c2 != last)
- {
- _REV_SBORDER(last);
- _REV_SBORDER(c2);
- last = c2;
- }
- }
- else
- t = mouse_drag_tag(c, w);
- }
- XSync(W->dpy, false);
- } while(ev.type != ButtonRelease);
- if(c2)
- func(c, c2);
- else if(t && t != (struct tag*)c)
- tag_client(t, c);
- else
- {
- _REV_SBORDER(c);
- /* No func mean free client resize */
- if(!func)
- client_moveresize(c, &c->geo);
- }
- c->flags &= ~CLIENT_MOUSE;
- }
- void
- uicb_mouse_resize(Uicb cmd)
- {
- (void)cmd;
- if(W->client && mouse_check_client(W->client))
- mouse_resize(W->client);
- }
- void
- uicb_mouse_move(Uicb cmd)
- {
- (void)cmd;
- if(W->client && mouse_check_client(W->client))
- mouse_move(W->client, (W->client->flags & CLIENT_FREE ? NULL : client_swap2));
- }
- void
- uicb_mouse_tab(Uicb cmd)
- {
- (void)cmd;
- if(W->client && mouse_check_client(W->client))
- mouse_move(W->client, _client_tab);
- }
|