[hackers] [wmii] Cleanup drag&drop, bar.c.

From: Kris Maglione <jg_AT_suckless.org>
Date: Mon Jan 21 23:32:08 2008

changeset: 2249:ef5feea7aa84
tag: tip
user: Kris Maglione <jg_AT_suckless.org>
date: Mon Jan 21 17:28:23 2008 -0500
summary: Cleanup drag&drop, bar.c.

diff -r 07ebb6171586 -r ef5feea7aa84 cmd/wmii/bar.c
--- a/cmd/wmii/bar.c Mon Jan 21 16:18:17 2008 -0500
+++ b/cmd/wmii/bar.c Mon Jan 21 17:28:23 2008 -0500
@@ -7,6 +7,10 @@
 
 static Handlers handlers;
 static Bar *free_bars;
+
+#define foreach_bar(s, b) \
+ for(int __bar_n=0; __bar_n < nelem((s)->bar); __bar_n++) \
+ for((b)=(s)->bar[__bar_n]; (b); (b)=(b)->next)
 
 void
 bar_init(WMScreen *s) {
@@ -29,6 +33,8 @@ bar_init(WMScreen *s) {
                           CWOverrideRedirect
                         | CWBackPixmap
                         | CWEventMask);
+ s->barwin->aux = s;
+ xdnd_initwindow(s->barwin);
         sethandler(s->barwin, &handlers);
         mapwin(s->barwin);
 }
@@ -36,7 +42,9 @@ Bar*
 Bar*
 bar_create(Bar **bp, const char *name) {
         static uint id = 1;
- Bar *b;
+ WMScreen *s;
+ Bar *b;
+ uint i;
 
         b = bar_find(*bp, name);;
         if(b)
@@ -59,6 +67,13 @@ bar_create(Bar **bp, const char *name) {
                         break;
         b->next = *bp;
         *bp = b;
+
+ /* FIXME: Kludge. */
+ for(s=screens; s < screens+num_screens; s++) {
+ i = bp - s->bar;
+ if(i < nelem(s->bar))
+ b->bar = i;
+ }
 
         return b;
 }
@@ -95,33 +110,30 @@ bar_draw(WMScreen *s) {
         Bar *b, *tb, *largest, **pb;
         Rectangle r;
         Align align;
- uint width, tw, nb;
+ uint width, tw;
         float shrink;
 
         largest = nil;
         tw = width = 0;
- for(nb = 0; nb < nelem(s->bar); nb++)
- for(b = s->bar[nb]; b; b=b->next) {
- b->r.min = ZP;
- b->r.max.y = Dy(s->brect);
- b->r.max.x = def.font->height & ~1;
- if(b->text && strlen(b->text))
- b->r.max.x += textwidth(def.font, b->text);
-
- width += Dx(b->r);
+ foreach_bar(s, b) {
+ b->r.min = ZP;
+ b->r.max.y = Dy(s->brect);
+ b->r.max.x = def.font->height & ~1;
+ if(b->text && strlen(b->text))
+ b->r.max.x += textwidth(def.font, b->text);
+ width += Dx(b->r);
+ }
+
+ if(width > Dx(s->brect)) { /* Not enough room. Shrink bars until they all fit. */
+ foreach_bar(s, b) {
+ for(pb=&largest; *pb; pb=&pb[0]->smaller)
+ if(Dx(pb[0]->r) < Dx(b->r))
+ break;
+ b->smaller = *pb;
+ *pb = b;
                 }
-
- if(width > Dx(s->brect)) { /* Not enough room. Shrink bars until they all fit. */
- for(nb = 0; nb < nelem(s->bar); nb++)
- for(b = s->bar[nb]; b; b=b->next) {
- for(pb = &largest; *pb; pb = &pb[0]->smaller)
- if(Dx(pb[0]->r) < Dx(b->r))
- break;
- b->smaller = *pb;
- *pb = b;
- }
                 SET(shrink);
- for(tb = largest; tb; tb = tb->smaller) {
+ for(tb=largest; tb; tb=tb->smaller) {
                         width -= Dx(tb->r);
                         tw += Dx(tb->r);
                         shrink = (Dx(s->brect) - width) / (float)tw;
@@ -130,32 +142,30 @@ bar_draw(WMScreen *s) {
                                         break;
                 }
                 if(tb)
- for(b = largest; b != tb->smaller; b = b->smaller)
+ for(b=largest; b != tb->smaller; b=b->smaller)
                                 b->r.max.x *= shrink;
                 width += tw * shrink;
         }
 
         tb = nil;
- for(nb = 0; nb < nelem(s->bar); nb++)
- for(b = s->bar[nb]; b; tb=b, b=b->next) {
- if(b == s->bar[BarRight])
- b->r.max.x += Dx(s->brect) - width;
-
- if(tb)
- b->r = rectaddpt(b->r, Pt(tb->r.max.x, 0));
- }
+ foreach_bar(s, b) {
+ if(tb)
+ b->r = rectaddpt(b->r, Pt(tb->r.max.x, 0));
+ if(b == s->bar[BarRight])
+ b->r.max.x += Dx(s->brect) - width;
+ tb = b;
+ }
 
         r = rectsubpt(s->brect, s->brect.min);
         fill(screen->ibuf, r, def.normcolor.bg);
- for(nb = 0; nb < nelem(s->bar); nb++)
- for(b = s->bar[nb]; b; b=b->next) {
- align = Center;
- if(b == s->bar[BarRight])
- align = East;
- fill(screen->ibuf, b->r, b->col.bg);
- drawstring(screen->ibuf, def.font, b->r, align, b->text, b->col.fg);
- border(screen->ibuf, b->r, 1, b->col.border);
- }
+ foreach_bar(s, b) {
+ align = Center;
+ if(b == s->bar[BarRight])
+ align = East;
+ fill(screen->ibuf, b->r, b->col.bg);
+ drawstring(screen->ibuf, def.font, b->r, align, b->text, b->col.fg);
+ border(screen->ibuf, b->r, 1, b->col.border);
+ }
         copyimage(s->barwin, r, screen->ibuf, ZP);
         sync();
 }
@@ -170,44 +180,59 @@ bar_find(Bar *bp, const char *name) {
         return b;
 }
 
+static char *barside[] = {
+ [BarLeft] = "Left",
+ [BarRight] = "Right",
+};
+
+static Bar*
+findbar(WMScreen *s, Point p) {
+ Bar *b;
+
+ foreach_bar(s, b)
+ if(rect_haspoint_p(p, b->r))
+ return b;
+ return nil;
+}
+
 static void
 bdown_event(Window *w, XButtonPressedEvent *e) {
- Bar *b;
-
- USED(w);
+ WMScreen *s;
+ Bar *b;
 
         /* Ungrab so a menu can receive events before the button is released */
         XUngrabPointer(display, e->time);
         sync();
 
- for(b=screen->bar[BarLeft]; b; b=b->next)
- if(rect_haspoint_p(Pt(e->x, e->y), b->r)) {
- event("LeftBarMouseDown %d %s\n", e->button, b->name);
- return;
- }
- for(b=screen->bar[BarRight]; b; b=b->next)
- if(rect_haspoint_p(Pt(e->x, e->y), b->r)) {
- event("RightBarMouseDown %d %s\n", e->button, b->name);
- return;
- }
+ s = w->aux;
+ b = findbar(s, Pt(e->x, e->y));
+ if(b)
+ event("%sBarMouseDown %d %s\n", barside[b->bar], e->button, b->name);
 }
 
 static void
 bup_event(Window *w, XButtonPressedEvent *e) {
+ WMScreen *s;
         Bar *b;
         
- USED(w, e);
-
- for(b=screen->bar[BarLeft]; b; b=b->next)
- if(rect_haspoint_p(Pt(e->x, e->y), b->r)) {
- event("LeftBarClick %d %s\n", e->button, b->name);
- return;
- }
- for(b=screen->bar[BarRight]; b; b=b->next)
- if(rect_haspoint_p(Pt(e->x, e->y), b->r)) {
- event("RightBarClick %d %s\n", e->button, b->name);
- return;
- }
+ s = w->aux;
+ b = findbar(s, Pt(e->x, e->y));
+ if(b)
+ event("%sBarClick %d %s\n", barside[b->bar], e->button, b->name);
+}
+
+static Rectangle
+dndmotion_event(Window *w, Point p) {
+ WMScreen *s;
+ Bar *b;
+
+ s = w->aux;
+ b = findbar(s, p);
+ if(b) {
+ event("%sBarDND 1 %s\n", barside[b->bar], b->name);
+ return b->r;
+ }
+ return ZR;
 }
 
 static void
@@ -219,5 +244,6 @@ static Handlers handlers = {
 static Handlers handlers = {
         .bdown = bdown_event,
         .bup = bup_event,
+ .dndmotion = dndmotion_event,
         .expose = expose_event,
 };
diff -r 07ebb6171586 -r ef5feea7aa84 cmd/wmii/dat.h
--- a/cmd/wmii/dat.h Mon Jan 21 16:18:17 2008 -0500
+++ b/cmd/wmii/dat.h Mon Jan 21 17:28:23 2008 -0500
@@ -117,6 +117,7 @@ struct Bar {
         char buf[280];
         char text[256];
         char name[256];
+ int bar;
         ushort id;
         Rectangle r;
         CTuple col;
diff -r 07ebb6171586 -r ef5feea7aa84 cmd/wmii/float.c
--- a/cmd/wmii/float.c Mon Jan 21 16:18:17 2008 -0500
+++ b/cmd/wmii/float.c Mon Jan 21 17:28:23 2008 -0500
@@ -126,8 +126,8 @@ float_placeframe(Frame *f) {
 
         p = ZP; /* SET(p) */
         if(vp->n == 0) {
- p.x = random() % max(0, Dx(a->r) - dim.x);
- p.y = random() % max(0, Dy(a->r) - dim.y);
+ p.x = random() % max(1, Dx(a->r) - dim.x);
+ p.y = random() % max(1, Dy(a->r) - dim.y);
         }else {
                 area = LONG_MAX;
                 for(i=0; i < vp->n; i++) {
diff -r 07ebb6171586 -r ef5feea7aa84 cmd/wmii/fns.h
--- a/cmd/wmii/fns.h Mon Jan 21 16:18:17 2008 -0500
+++ b/cmd/wmii/fns.h Mon Jan 21 17:28:23 2008 -0500
@@ -211,7 +211,7 @@ char* toutf8n(const char*, size_t);
 
 /* xdnd.c */
 int xdnd_clientmessage(XClientMessageEvent*);
-void xdnd_init(void);
+void xdnd_initwindow(Window*);
 
 /* xext.c */
 void randr_event(XEvent*);
diff -r 07ebb6171586 -r ef5feea7aa84 cmd/wmii/main.c
--- a/cmd/wmii/main.c Mon Jan 21 16:18:17 2008 -0500
+++ b/cmd/wmii/main.c Mon Jan 21 17:28:23 2008 -0500
@@ -465,7 +465,6 @@ main(int argc, char *argv[]) {
                                 | CWCursor);
                 bar_init(s);
         }
- xdnd_init();
 
         screen->focus = nil;
         setfocus(screen->barwin, RevertToParent);
diff -r 07ebb6171586 -r ef5feea7aa84 cmd/wmii/xdnd.c
--- a/cmd/wmii/xdnd.c Mon Jan 21 16:18:17 2008 -0500
+++ b/cmd/wmii/xdnd.c Mon Jan 21 17:28:23 2008 -0500
@@ -5,23 +5,30 @@
 #include "fns.h"
 
 void
-xdnd_init(void) {
+xdnd_initwindow(Window *w) {
         long l;
 
         l = 3; /* They are insane. Why is this an ATOM?! */
- changeprop_long(screen->barwin, "XdndAware", "ATOM", &l, 1);
+ changeprop_long(w, "XdndAware", "ATOM", &l, 1);
 }
+
+typedef struct Dnd Dnd;
+struct Dnd {
+ XWindow source;
+ Rectangle r;
+};
 
 int
 xdnd_clientmessage(XClientMessageEvent *e) {
- static Bar *oldbar;
+ Window *w;
+ Dnd *dnd;
+ long *l;
         Rectangle r;
         Point p;
- long *l;
- Bar *b;
         long pos, siz;
         int msg;
 
+ dnd = nil;
         msg = e->message_type;
         l = e->data.l;
         Dprint(DDnd, "ClientMessage: %A\n", msg);
@@ -29,45 +36,49 @@ xdnd_clientmessage(XClientMessageEvent *
         if(msg == xatom("XdndEnter")) {
                 if(e->format != 32)
                         return -1;
- oldbar = nil;
+ w = findwin(e->window);
+ if(w) {
+ if(w->dnd == nil)
+ w->dnd = emallocz(sizeof *dnd);
+ dnd = w->dnd;
+ dnd->source = l[0];
+ dnd->r = ZR;
+ }
                 return 1;
         }else
         if(msg == xatom("XdndLeave")) {
                 if(e->format != 32)
                         return -1;
- oldbar = nil;
+ w = findwin(e->window);
+ if(w && w->dnd) {
+ free(w->dnd);
+ w->dnd = nil;
+ }
                 return 1;
         }else
         if(msg == xatom("XdndPosition")) {
                 if(e->format != 32)
                         return -1;
- p.x = (ulong)l[2] >> 16;
- p.y = (ulong)l[2] & 0xffff;
- p = subpt(p, screen->barwin->r.min);
- Dprint(DDnd, "\tp: %P\n", p);
- /* XXX: This should be done in bar.c. */
- for(b=screen->bar[BarLeft]; b; b=b->next)
- if(rect_haspoint_p(p, b->r)) {
- if(b != oldbar)
- event("LeftBarDND 1 %s\n", b->name);
- break;
- }
- if(b == nil)
- for(b=screen->bar[BarRight]; b; b=b->next)
- if(rect_haspoint_p(p, b->r)) {
- if(b != oldbar)
- event("RightBarDND 1 %s\n", b->name);
- break;
- }
- pos = 0;
- siz = 0;
- oldbar = b;
- if(b) {
- r = rectaddpt(b->r, screen->barwin->r.min);
+ r = ZR;
+ w = findwin(e->window);
+ if(w)
+ dnd = w->dnd;
+ if(dnd) {
+ p.x = (ulong)l[2] >> 16;
+ p.y = (ulong)l[2] & 0xffff;
+ p = subpt(p, w->r.min);
+ Dprint(DDnd, "\tw: %W\n", w);
+ Dprint(DDnd, "\tp: %P\n", p);
+ if(eqrect(dnd->r, ZR) || !rect_haspoint_p(p, dnd->r))
+ if(w->handler->dndmotion)
+ dnd->r = w->handler->dndmotion(w, p);
+ r = dnd->r;
+ if(!eqrect(r, ZR))
+ r = rectaddpt(r, w->r.min);
                         Dprint(DDnd, "\tr: %R\n", r);
- pos = (r.min.x<<16) | r.min.y;
- siz = (Dx(r)<<16) | Dy(r);
                 }
+ pos = (r.min.x<<16) | r.min.y;
+ siz = (Dx(r)<<16) | Dy(r);
                 sendmessage(window(l[0]), "XdndStatus", e->window, 0, pos, siz, 0);
                 return 1;
         }
diff -r 07ebb6171586 -r ef5feea7aa84 include/x11.h
--- a/include/x11.h Mon Jan 21 16:18:17 2008 -0500
+++ b/include/x11.h Mon Jan 21 17:28:23 2008 -0500
@@ -27,19 +27,34 @@ enum Align {
         Center = NEast | SWest,
 };
 
+enum WindowType {
+ WWindow,
+ WImage,
+};
+
 typedef enum Align Align;
 
-typedef struct CTuple CTuple;
+typedef XSetWindowAttributes WinAttr;
+
 typedef struct Point Point;
 typedef struct Rectangle Rectangle;
+
+struct Point {
+ int x, y;
+};
+
+struct Rectangle {
+ Point min, max;
+};
+
+typedef struct CTuple CTuple;
+typedef struct Ewmh Ewmh;
+typedef struct Font Font;
+typedef struct Handlers Handlers;
 typedef struct Screen Screen;
-typedef struct Ewmh Ewmh;
+typedef struct WinHints WinHints;
+typedef struct Window Image;
 typedef struct Window Window;
-typedef struct WinHints WinHints;
-typedef struct Handlers Handlers;
-typedef struct Window Image;
-typedef struct Font Font;
-typedef XSetWindowAttributes WinAttr;
 
 struct CTuple {
         ulong bg;
@@ -48,35 +63,38 @@ struct CTuple {
         char colstr[24]; /* #RRGGBB #RRGGBB #RRGGBB */
 };
 
-struct Point {
- int x, y;
-};
-
-struct Rectangle {
- Point min, max;
-};
-
 struct Ewmh {
         long type;
         long ping;
         long timer;
 };
 
-struct Window {
- int type;
- XWindow w;
- Window *parent;
- Drawable image;
- GC gc;
- Rectangle r;
- void *aux;
- Handlers *handler;
- Window *next, *prev;
- WinHints *hints;
- Ewmh ewmh;
- bool mapped;
- int unmapped;
- int depth;
+struct Font {
+ XFontStruct *xfont;
+ XFontSet set;
+ int ascent;
+ int descent;
+ uint height;
+ char *name;
+};
+
+struct Handlers {
+ Rectangle (*dndmotion)(Window*, Point);
+ void (*bdown)(Window*, XButtonEvent*);
+ void (*bup)(Window*, XButtonEvent*);
+ void (*configreq)(Window*, XConfigureRequestEvent*);
+ void (*destroy)(Window*, XDestroyWindowEvent*);
+ void (*enter)(Window*, XCrossingEvent*);
+ void (*expose)(Window*, XExposeEvent*);
+ void (*focusin)(Window*, XFocusChangeEvent*);
+ void (*focusout)(Window*, XFocusChangeEvent*);
+ void (*kdown)(Window*, XKeyEvent*);
+ void (*kup)(Window*, XKeyEvent*);
+ void (*leave)(Window*, XCrossingEvent*);
+ void (*map)(Window*, XMapEvent*);
+ void (*motion)(Window*, XMotionEvent*);
+ void (*property)(Window*, XPropertyEvent*);
+ void (*unmap)(Window*, XUnmapEvent*);
 };
 
 struct WinHints {
@@ -92,45 +110,36 @@ struct WinHints {
         bool position;
 };
 
-struct Handlers {
- void (*bdown)(Window*, XButtonEvent*);
- void (*bup)(Window*, XButtonEvent*);
- void (*kdown)(Window*, XKeyEvent*);
- void (*kup)(Window*, XKeyEvent*);
- void (*focusin)(Window*, XFocusChangeEvent*);
- void (*focusout)(Window*, XFocusChangeEvent*);
- void (*enter)(Window*, XCrossingEvent*);
- void (*leave)(Window*, XCrossingEvent*);
- void (*motion)(Window*, XMotionEvent*);
- void (*destroy)(Window*, XDestroyWindowEvent*);
- void (*configreq)(Window*, XConfigureRequestEvent*);
- void (*map)(Window*, XMapEvent*);
- void (*unmap)(Window*, XUnmapEvent*);
- void (*property)(Window*, XPropertyEvent*);
- void (*expose)(Window*, XExposeEvent*);
+struct Window {
+ int type;
+ XWindow w;
+ Drawable image;
+ GC gc;
+ Rectangle r;
+ Window* parent;
+ Window* next;
+ Window* prev;
+ Handlers* handler;
+ WinHints* hints;
+ Ewmh ewmh;
+ void* dnd;
+ void* aux;
+ bool mapped;
+ int unmapped;
+ int depth;
 };
 
 struct Screen {
- int screen;
- Window root;
- Colormap colormap;
- Visual *visual;
- Rectangle rect;
- GC gc;
- int depth;
- int fd;
- ulong black, white;
-};
-
-enum { WWindow, WImage };
-
-struct Font {
- XFontStruct *xfont;
- XFontSet set;
- int ascent;
- int descent;
- uint height;
- char *name;
+ int screen;
+ Window root;
+ GC gc;
+ Colormap colormap;
+ Visual* visual;
+ Rectangle rect;
+ int depth;
+ int fd;
+ ulong black;
+ ulong white;
 };
 
 #ifdef VARARGCK
@@ -146,8 +155,6 @@ extern Point ZP;
 extern Point ZP;
 extern Rectangle ZR;
 extern Window* pointerwin;
-
-Rectangle insetrect(Rectangle r, int n);
 
 Point Pt(int x, int y);
 Rectangle Rect(int x0, int y0, int x1, int y1);
Received on Mon Jan 21 2008 - 23:32:08 UTC

This archive was generated by hypermail 2.2.0 : Sun Jul 13 2008 - 15:59:05 UTC