Explorar el Código

Add mouse.c/mouse.h with mouse_resize & mouse_move as uicb function. button1 on titlebar -> move button3 -> resize (hardcoded for now)

Martin Duquesnoy hace 12 años
padre
commit
55e80847b5
Se han modificado 6 ficheros con 186 adiciones y 0 borrados
  1. 1 0
      Makefile.in
  2. 16 0
      src/client.c
  3. 1 0
      src/client.h
  4. 5 0
      src/config.h
  5. 135 0
      src/mouse.c
  6. 28 0
      src/mouse.h

+ 1 - 0
Makefile.in

@@ -18,6 +18,7 @@ SRCS=                 \
       src/util.c      \
       src/fifo.c      \
       src/status.c    \
+      src/mouse.c     \
       src/wmfs.c
 
 

+ 16 - 0
src/client.c

@@ -12,6 +12,7 @@
 #include "barwin.h"
 #include "draw.h"
 #include "screen.h"
+#include "mouse.h"
 
 #define CLIENT_MOUSE_MOD Mod1Mask
 
@@ -148,6 +149,17 @@ client_gb_pos(struct tag *t, int x, int y)
      return NULL;
 }
 
+struct client*
+client_gb_titlebar(Window w)
+{
+     struct client *c = SLIST_FIRST(&W->h.client);
+
+     while(c && c->titlebar->win != w)
+          c = SLIST_NEXT(c, next);
+
+     return c;
+}
+
 /*
  * Get client left/right/top/bottom of selected client
  */
@@ -719,6 +731,10 @@ client_frame_new(struct client *c)
           /* TODO: Refer to titlebar config */
           barwin_mousebind_new(c->titlebar, Button1, false, g,
                                uicb_client_focus_with_wid, cmd);
+          barwin_mousebind_new(c->titlebar, Button1, false, g,
+                               uicb_mouse_move, cmd);
+          barwin_mousebind_new(c->titlebar, Button3, false, g,
+                               uicb_mouse_resize, cmd);
      }
 
      XReparentWindow(W->dpy, c->win, c->frame, c->border, c->tbarw);

+ 1 - 0
src/client.h

@@ -17,6 +17,7 @@ inline void client_configure(struct client *c);
 struct client *client_gb_win(Window w);
 struct client *client_gb_frame(Window w);
 struct client *client_gb_pos(struct tag *t, int x, int y);
+struct client *client_gb_titlebar(Window w);
 struct client *client_next_with_pos(struct client *bc, enum position p);
 void client_swap2(struct client *c1, struct client *c2);
 void client_swap(struct client *c, enum position p);

+ 5 - 0
src/config.h

@@ -15,6 +15,7 @@
 #include "tag.h"
 #include "client.h"
 #include "status.h"
+#include "mouse.h"
 
 #define THEME_DEFAULT (SLIST_FIRST(&W->h.theme))
 
@@ -69,6 +70,10 @@ static const struct { char *name; void (*func)(Uicb cmd); } uicb_list[] =
      /* Status */
      { "status" , uicb_status },
 
+     /* Mouse */
+     { "mouse_resize", uicb_mouse_resize },
+     { "mouse_move",   uicb_mouse_move },
+
      { NULL, NULL }
 };
 

+ 135 - 0
src/mouse.c

@@ -0,0 +1,135 @@
+/*
+ *  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 "client.h"
+#include "draw.h"
+
+#define _REV_BORDER()                                        \
+     do {                                                    \
+          SLIST_FOREACH(gc, &c->tag->clients, tnext)         \
+               draw_reversed_rect(W->root, &gc->tgeo);       \
+     } while(/* CONSTCOND */ 0);
+static void
+mouse_resize(struct client *c)
+{
+     struct client *gc;
+     XEvent ev;
+     Window w;
+     int d, u, ox, oy, ix, iy;
+
+     XQueryPointer(W->dpy, W->root, &w, &w, &ox, &oy, &d, &d, (uint *)&u);
+     XGrabServer(W->dpy);
+
+     _REV_BORDER();
+
+     if(c->flags & CLIENT_TABBED && !(c->flags & CLIENT_TABMASTER))
+          c = c->tabmaster;
+
+     ix = ox;
+     iy = oy;
+
+     do
+     {
+          XMaskEvent(W->dpy, MouseMask | SubstructureRedirectMask, &ev);
+
+          if(ev.type != MotionNotify)
+               continue;
+
+          _REV_BORDER();
+
+          if(ix >= c->geo.x + (c->geo.w >> 1))
+               _fac_resize(c, Right, ev.xmotion.x_root - ox);
+          else
+               _fac_resize(c, Left, ox - ev.xmotion.x_root);
+
+          if(iy >= c->geo.y + (c->geo.h >> 1))
+               _fac_resize(c, Bottom, ev.xmotion.y_root - oy);
+          else
+               _fac_resize(c, Top, oy - ev.xmotion.y_root);
+
+          ox = ev.xmotion.x_root;
+          oy = ev.xmotion.y_root;
+
+          _REV_BORDER();
+
+          XSync(W->dpy, false);
+
+     } while(ev.type != ButtonRelease);
+
+     _REV_BORDER();
+
+     client_apply_tgeo(c->tag);
+     layout_save_set(c->tag);
+
+     XUngrabServer(W->dpy);
+}
+
+#define _REV_SBORDER(c) draw_reversed_rect(W->root, &(c)->geo);
+void
+mouse_move(struct client *c)
+{
+     struct client *c2 = NULL, *last = c;
+     XEvent ev;
+     Window w;
+     int d, u;
+
+     XGrabServer(W->dpy);
+
+     if(c->flags & CLIENT_TABBED && !(c->flags & CLIENT_TABMASTER))
+          c = c->tabmaster;
+
+     _REV_SBORDER(c);
+
+     do
+     {
+          XMaskEvent(W->dpy, MouseMask | SubstructureRedirectMask, &ev);
+
+          if(ev.type != MotionNotify)
+               continue;
+
+          XQueryPointer(W->dpy, W->root, &w, &w, &d, &d, &d, &d, (uint *)&u);
+
+          if(!(c2 = client_gb_win(w)))
+               if(!(c2 = client_gb_frame(w)))
+                    c2 = client_gb_titlebar(w);
+
+          if(c2 && c2 != last)
+          {
+               _REV_SBORDER(last);
+               _REV_SBORDER(c2);
+               last = c2;
+          }
+
+          XSync(W->dpy, false);
+
+     } while(ev.type != ButtonRelease);
+
+     if(c2 && c2 != c)
+          client_swap2(c, c2);
+
+     XUngrabServer(W->dpy);
+}
+
+void
+uicb_mouse_resize(Uicb cmd)
+{
+     (void)cmd;
+
+     if(mouse_check_client(W->client))
+          if(W->client)
+               mouse_resize(W->client);
+}
+
+void
+uicb_mouse_move(Uicb cmd)
+{
+     (void)cmd;
+
+     if(mouse_check_client(W->client))
+          if(W->client)
+               mouse_move(W->client);
+}

+ 28 - 0
src/mouse.h

@@ -0,0 +1,28 @@
+/*
+ *  wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
+ *  For license, see COPYING.
+ */
+
+#ifndef MOUSE_H
+#define MOUSE_H
+
+#include "client.h"
+
+void uicb_mouse_resize(Uicb);
+void uicb_mouse_move(Uicb);
+
+static inline bool
+mouse_check_client(struct client *c)
+{
+     Window w;
+     int d;
+
+     XQueryPointer(W->dpy, W->root, &w, &w, &d, &d, &d, &d, (uint *)&d);
+
+     if(c == client_gb_win(w) || c == client_gb_titlebar(w) || c == client_gb_frame(w))
+          return true;
+
+     return false;
+}
+
+#endif /* MOUSE_H */