mirror of
https://github.com/0intro/wmii
synced 2024-11-25 23:30:24 +03:00
Cleanup drag&drop, bar.c.
This commit is contained in:
parent
7b1c1664f9
commit
2999577155
148
cmd/wmii/bar.c
148
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,
|
||||
};
|
||||
|
@ -117,6 +117,7 @@ struct Bar {
|
||||
char buf[280];
|
||||
char text[256];
|
||||
char name[256];
|
||||
int bar;
|
||||
ushort id;
|
||||
Rectangle r;
|
||||
CTuple col;
|
||||
|
@ -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++) {
|
||||
|
@ -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*);
|
||||
|
@ -465,7 +465,6 @@ main(int argc, char *argv[]) {
|
||||
| CWCursor);
|
||||
bar_init(s);
|
||||
}
|
||||
xdnd_init();
|
||||
|
||||
screen->focus = nil;
|
||||
setfocus(screen->barwin, RevertToParent);
|
||||
|
@ -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;
|
||||
}
|
||||
|
145
include/x11.h
145
include/x11.h
@ -27,26 +27,17 @@ enum Align {
|
||||
Center = NEast | SWest,
|
||||
};
|
||||
|
||||
enum WindowType {
|
||||
WWindow,
|
||||
WImage,
|
||||
};
|
||||
|
||||
typedef enum Align Align;
|
||||
|
||||
typedef struct CTuple CTuple;
|
||||
typedef struct Point Point;
|
||||
typedef struct Rectangle Rectangle;
|
||||
typedef struct Screen Screen;
|
||||
typedef struct Ewmh Ewmh;
|
||||
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;
|
||||
ulong fg;
|
||||
ulong border;
|
||||
char colstr[24]; /* #RRGGBB #RRGGBB #RRGGBB */
|
||||
};
|
||||
typedef struct Point Point;
|
||||
typedef struct Rectangle Rectangle;
|
||||
|
||||
struct Point {
|
||||
int x, y;
|
||||
@ -56,27 +47,54 @@ 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 WinHints WinHints;
|
||||
typedef struct Window Image;
|
||||
typedef struct Window Window;
|
||||
|
||||
struct CTuple {
|
||||
ulong bg;
|
||||
ulong fg;
|
||||
ulong border;
|
||||
char colstr[24]; /* #RRGGBB #RRGGBB #RRGGBB */
|
||||
};
|
||||
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user