wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit 29995771554d4f8cdb3b7722e710b44b4e3f4587
parent 7b1c1664f981b78375655c6a6ecda7d17df2f867
Author: Kris Maglione <jg@suckless.org>
Date:   Mon, 21 Jan 2008 17:28:23 -0500

Cleanup drag&drop, bar.c.

Diffstat:
cmd/wmii/bar.c | 148++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
cmd/wmii/dat.h | 1+
cmd/wmii/float.c | 4++--
cmd/wmii/fns.h | 2+-
cmd/wmii/main.c | 1-
cmd/wmii/xdnd.c | 75+++++++++++++++++++++++++++++++++++++++++++--------------------------------
include/x11.h | 141+++++++++++++++++++++++++++++++++++++++++--------------------------------------
7 files changed, 208 insertions(+), 164 deletions(-)

diff --git a/cmd/wmii/bar.c b/cmd/wmii/bar.c @@ -8,6 +8,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) { WinAttr wa; @@ -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_init(WMScreen *s) { Bar* bar_create(Bar **bp, const char *name) { static uint id = 1; + 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. */ - 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; - } + 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; + } 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) { + WMScreen *s; Bar *b; - - USED(w); /* 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); + 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); +} - 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; - } +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 @@ expose_event(Window *w, XExposeEvent *e) { static Handlers handlers = { .bdown = bdown_event, .bup = bup_event, + .dndmotion = dndmotion_event, .expose = expose_event, }; diff --git a/cmd/wmii/dat.h b/cmd/wmii/dat.h @@ -117,6 +117,7 @@ struct Bar { char buf[280]; char text[256]; char name[256]; + int bar; ushort id; Rectangle r; CTuple col; diff --git a/cmd/wmii/float.c b/cmd/wmii/float.c @@ -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 --git a/cmd/wmii/fns.h b/cmd/wmii/fns.h @@ -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 --git a/cmd/wmii/main.c b/cmd/wmii/main.c @@ -465,7 +465,6 @@ main(int argc, char *argv[]) { | CWCursor); bar_init(s); } - xdnd_init(); screen->focus = nil; setfocus(screen->barwin, RevertToParent); diff --git a/cmd/wmii/xdnd.c b/cmd/wmii/xdnd.c @@ -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 *e) { 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 --git a/include/x11.h b/include/x11.h @@ -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; -typedef struct Screen Screen; + +struct Point { + int x, y; +}; + +struct Rectangle { + Point min, max; +}; + +typedef struct CTuple CTuple; typedef struct Ewmh Ewmh; -typedef struct Window Window; -typedef struct WinHints WinHints; +typedef struct Font Font; typedef struct Handlers Handlers; +typedef struct Screen Screen; +typedef struct WinHints WinHints; typedef struct Window Image; -typedef struct Font Font; -typedef XSetWindowAttributes WinAttr; +typedef struct Window Window; 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 @@ -147,8 +156,6 @@ 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); Rectangle Rpt(Point min, Point max);