commit b422751227f4f97c045ce4864b629a73faeab345
parent f4bff50f75d73c0fbf42a2a42da48857171fb4f7
Author: Kris Maglione <jg@suckless.org>
Date: Mon, 5 Feb 2007 00:26:02 -0500
New dragging code installed, with some cruft left behind. This is an RFC, please respond.
Diffstat:
| draw.c | | | 2 | +- |
| frame.c | | | 29 | +++++++++++++++++++++++++++++ |
| mouse.c | | | 156 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- |
| wmii.h | | | 1 | + |
4 files changed, 184 insertions(+), 4 deletions(-)
diff --git a/draw.c b/draw.c
@@ -57,7 +57,7 @@ loadfont(Blitz *blitz, BlitzFont *font) {
font->xfont = nil;
font->xfont = XLoadQueryFont(blitz->dpy, fontname);
if (!font->xfont) {
- fprintf(stderr, "%s", "wmii: error, cannot load 'fixed' font\n");
+ fprintf(stderr, "wmii: error, cannot load 'fixed' font\n");
exit(1);
}
font->ascent = font->xfont->ascent;
diff --git a/frame.c b/frame.c
@@ -61,6 +61,35 @@ insert_frame(Frame *pos, Frame *f, Bool before) {
}
void
+swap_frames(Frame *fa, Frame *fb) {
+ XRectangle trect;
+ Area *a;
+ Frame **fp_a, **fp_b, *ft;
+
+ if(fa == fb) return;
+ a = fa->area;
+ for(fp_a = &a->frame; *fp_a; fp_a=&(*fp_a)->anext)
+ if(*fp_a == fa) break;
+ a = fb->area;
+ for(fp_b = &a->frame; *fp_b; fp_b=&(*fp_b)->anext)
+ if(*fp_b == fb) break;
+
+ *fp_a = fb;
+ *fp_b = fa;
+
+ fb->area = fa->area;
+ fa->area = a;
+
+ ft = fa->anext;
+ fa->anext = fb->anext;
+ fb->anext = ft;
+
+ trect = fa->rect;
+ fa->rect = fb->rect;
+ fb->rect = trect;
+}
+
+void
update_frame_widget_colors(Frame *f) {
if(f->area->sel == f) {
if(sel_screen && (f->client == sel_client()))
diff --git a/mouse.c b/mouse.c
@@ -143,22 +143,169 @@ snap_rect(XRectangle *rects, int num, XRectangle *current,
static void
draw_xor_border(XRectangle *r) {
- XRectangle xor = *r;
+ XRectangle xor;
+ xor = *r;
xor.x += 2;
xor.y += 2;
xor.width = xor.width > 4 ? xor.width - 4 : 0;
xor.height = xor.height > 4 ? xor.height - 4 : 0;
+
XSetLineAttributes(blz.dpy, xorgc, 1, LineSolid, CapNotLast, JoinMiter);
- XDrawLine(blz.dpy, blz.root, xorgc, xor.x + 2, xor.y + xor.height / 2,
+ if(xor.height > 4 && xor.width > 2)
+ XDrawLine(blz.dpy, blz.root, xorgc, xor.x + 2, xor.y + xor.height / 2,
xor.x + xor.width - 2, xor.y + xor.height / 2);
- XDrawLine(blz.dpy, blz.root, xorgc, xor.x + xor.width / 2, xor.y + 2,
+ if(xor.width > 4 && xor.height > 2)
+ XDrawLine(blz.dpy, blz.root, xorgc, xor.x + xor.width / 2, xor.y + 2,
xor.x + xor.width / 2, xor.y + xor.height - 2);
XSetLineAttributes(blz.dpy, xorgc, 4, LineSolid, CapNotLast, JoinMiter);
XDrawRectangles(blz.dpy, blz.root, xorgc, &xor, 1);
XSync(blz.dpy, False);
}
+static void
+find_droppoint(Frame *frame, int x, int y, XRectangle *rect, Bool do_move) {
+ View *v;
+ Area *a, *a_prev;
+ Frame *f, *f_close;
+
+ v = frame->view;
+ rect->y = 0;
+ rect->height = screen->rect.height - screen->brect.height;
+
+ a_prev = v->area;
+ for(a = a_prev->next; a && a->next; a = a->next) {
+ if(x < (a->rect.x + a->rect.width))
+ break;
+ a_prev = a;
+ }
+ if(x < (a->rect.x + labelh(&def.font))) {
+ rect->x = a->rect.x - 4;
+ rect->width = 8;
+
+ if(do_move) {
+ a = new_column(v, a_prev, 0);
+ send_to_area(a, frame->area, frame);
+ focus(frame->client, False);
+ }
+ return;
+ }
+ if(x > (a->rect.x + a->rect.width - labelh(&def.font))) {
+ rect->x = a->rect.x + a->rect.width - 4;
+ rect->width = 8;
+
+ if(do_move) {
+ a = new_column(v, a, 0);
+ send_to_area(a, frame->area, frame);
+ focus(frame->client, False);
+ }
+ return;
+ }
+
+ rect->x = a->rect.x;
+ rect->width = a->rect.width;
+
+ f_close = nil;
+ for(f = a->frame; f; f = f->anext) {
+ if(y < f->rect.y)
+ break;
+ if(y < (f->rect.y + f->rect.height))
+ break;
+ f_close = f;
+ }
+ if(f == nil)
+ f = f_close;
+ if(y < (f->rect.y + labelh(&def.font))) {
+ rect->y = f->rect.y;
+ rect->height = 2;
+ if(f_close) {
+ rect->y = (f_close->rect.y + f_close->rect.height);
+ rect->height = f->rect.y - rect->y;
+ }
+ if(do_move) {
+ if(a != frame->area)
+ send_to_area(a, frame->area, frame);
+ remove_frame(frame);
+ insert_frame(f, frame, True);
+ focus(frame->client, True);
+ }
+ return;
+ }
+ if(y > (f->rect.y + f->rect.height - labelh(&def.font))) {
+ rect->y = f->rect.y + f->rect.height;
+ rect->height = (screen->rect.height - labelh(&def.font) - rect->y);
+ if(f->anext)
+ rect->height = (f->anext->rect.y - rect->y);
+ if(do_move) {
+ if(a != frame->area)
+ send_to_area(a, frame->area, frame);
+ remove_frame(frame);
+ insert_frame(f, frame, False);
+ focus(frame->client, True);
+ }
+ return;
+ }
+ *rect = f->rect;
+ if(do_move) {
+ swap_frames(frame, f);
+ focus(frame->client, False);
+ }
+}
+
+static void
+do_managed_move(Client *c) {
+ XRectangle frect, ofrect;
+ Window dummy;
+ XEvent ev;
+ Frame *f;
+ unsigned int di;
+ int x, y, i;
+
+ focus(c, False);
+ f = c->frame;
+
+ XSync(blz.dpy, False);
+ if(XGrabPointer(blz.dpy, c->framewin, False, MouseMask, GrabModeAsync, GrabModeAsync,
+ None, cursor[CurMove], CurrentTime) != GrabSuccess)
+ return;
+ XGrabServer(blz.dpy);
+
+ XQueryPointer(blz.dpy, blz.root, &dummy, &dummy, &i, &i, &x, &y, &di);
+
+ find_droppoint(f, x, y, &frect, False);
+ draw_xor_border(&frect);
+ for(;;) {
+ XMaskEvent(blz.dpy, MouseMask | ExposureMask, &ev);
+ switch (ev.type) {
+ case ButtonRelease:
+ draw_xor_border(&frect);
+
+ find_droppoint(f, x, y, &frect, True);
+
+ XUngrabServer(blz.dpy);
+ XUngrabPointer(blz.dpy, CurrentTime);
+ XSync(blz.dpy, False);
+ return;
+ case MotionNotify:
+ ofrect = frect;
+ x = ev.xmotion.x_root;
+ y = ev.xmotion.y_root;
+
+ find_droppoint(f, x, y, &frect, False);
+
+ if(memcmp(&frect, &ofrect, sizeof(frect))) {
+ draw_xor_border(&ofrect);
+ draw_xor_border(&frect);
+ }
+ break;
+ case Expose:
+ (handler[Expose])(&ev);
+ break;
+ default: break;
+ }
+ }
+}
+
void
do_mouse_resize(Client *c, BlitzAlign align) {
BlitzAlign grav;
@@ -176,6 +323,9 @@ do_mouse_resize(Client *c, BlitzAlign align) {
XRectangle origin = frect;
XPoint pt;
+ if(align == CENTER && !floating)
+ return do_managed_move(c);
+
XQueryPointer(blz.dpy, c->framewin, &dummy, &dummy, &i, &i, &pt_x, &pt_y, &di);
rx = (float)pt_x / frect.width;
ry = (float)pt_y / frect.height;
diff --git a/wmii.h b/wmii.h
@@ -318,6 +318,7 @@ extern unsigned int flush_masked_events(long even_mask);
extern Frame *create_frame(Client *c, View *v);
extern void remove_frame(Frame *f);
extern void insert_frame(Frame *pos, Frame *f, Bool before);
+void swap_frames(Frame *fa, Frame *fb);
extern void draw_frame(Frame *f);
extern void draw_frames();
extern void update_frame_widget_colors(Frame *f);