wmii

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

commit aafc92f220922231428241a381c30dc311c3d5dd
parent b358f2a36ac6a5be00c6ce5d557b6b3825552ddd
Author: Kris Maglione <jg@suckless.org>
Date:   Sat, 14 Apr 2007 02:35:58 -0400

Improved column resizing.

Diffstat:
cmd/wmii/Makefile | 2+-
cmd/wmii/area.c | 2+-
cmd/wmii/bar.c | 1+
cmd/wmii/client.c | 6+++---
cmd/wmii/column.c | 268+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
cmd/wmii/dat.h | 25++++++++++++++++++-------
cmd/wmii/event.c | 42+++++++++++++++++++++++-------------------
cmd/wmii/fns.h | 13++++++++-----
cmd/wmii/frame.c | 2++
cmd/wmii/fs.c | 19++++++++++---------
cmd/wmii/mouse.c | 83++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
cmd/wmii/view.c | 32+++++++++++++++++++++++---------
12 files changed, 386 insertions(+), 109 deletions(-)

diff --git a/cmd/wmii/Makefile b/cmd/wmii/Makefile @@ -7,7 +7,7 @@ main.c: ${ROOT}/mk/wmii.mk TARG = wmii LIB = ${LIBIXP} -EXLDFLAGS = -lm ${LIBX11} +EXLDFLAGS = -lm ${LIBX11} -lXext EXCFLAGS = ${INCX11} OBJ = area \ bar \ diff --git a/cmd/wmii/area.c b/cmd/wmii/area.c @@ -213,7 +213,7 @@ detach_from_area(Frame *f) { else if(!a->frame) { if(c->trans) { /* focus area of transient, if possible */ - Client *cl = client_of_win(c->trans); + Client *cl = win2client(c->trans); if(cl && cl->frame) { a = cl->sel->area; if(a->view == v) diff --git a/cmd/wmii/bar.c b/cmd/wmii/bar.c @@ -54,6 +54,7 @@ resize_bar(WMScreen *s) { s->brect = s->rect; s->brect.height = labelh(&def.font); s->brect.y = s->rect.height - s->brect.height; + XMoveResizeWindow(blz.dpy, s->barwin, s->brect.x, s->brect.y, s->brect.width, s->brect.height); XSync(blz.dpy, False); draw_bar(s); diff --git a/cmd/wmii/client.c b/cmd/wmii/client.c @@ -139,7 +139,7 @@ manage_client(Client *c) { XGetTextProperty(blz.dpy, c->win, &tags, atom[TagsAtom]); - if((trans = client_of_win(c->trans))) + if((trans = win2client(c->trans))) strncpy(c->tags, trans->tags, sizeof(c->tags)); else if(tags.nitems) strncpy(c->tags, (char *)tags.value, sizeof(c->tags)); @@ -170,7 +170,7 @@ selclient() { } Client * -client_of_win(Window w) { +win2client(Window w) { Client *c; for(c=client; c; c=c->next) if(c->win == w) break; @@ -178,7 +178,7 @@ client_of_win(Window w) { } Frame * -frame_of_win(Window w) { +win2frame(Window w) { Client *c; for(c=client; c; c=c->next) if(c->framewin == w) break; diff --git a/cmd/wmii/column.c b/cmd/wmii/column.c @@ -4,38 +4,204 @@ */ #include <math.h> #include <string.h> +#include <X11/extensions/shape.h> #include <util.h> #include "dat.h" #include "fns.h" -char * -str_of_column_mode(int mode) { - switch(mode) { - case Coldefault: return "default"; break; - case Colstack: return "stack"; break; - case Colmax: return "max"; break; - default: break; - } +int divw, divh; +GC divgc; +GC maskgc; + +char *modes[] = { + [Coldefault] = "default", + [Colstack] = "stack", + [Colmax] = "max", +}; + +Divide * +win2div(Window w) { + Divide *d; + + for(d = divs; d; d = d->next) + if(d->w == w) return d; return nil; } int -column_mode_of_str(char *arg) { - if(!strncmp("default", arg, 8)) - return Coldefault; - if(!strncmp("stack", arg, 6)) - return Colstack; - if(!strncmp("max", arg, 4)) - return Colmax; +str2colmode(const char *str) { + int i; + + for(i = 0; i < nelem(modes); i++) + if(strcasecmp(str, modes[i])) + return i; return -1; } static void +draw_pmap(Pixmap pm, GC gc, Bool color) { + XPoint pt[4]; + + pt[0] = (XPoint){ 0, 0 }; + pt[1] = (XPoint){ divw/2 - 1, divw/2 - 1 }; + pt[2] = (XPoint){ divw/2, divw/2 - 1 }; + pt[3] = (XPoint){ divw - 1, 0 }; + + if(color) + XSetForeground(blz.dpy, gc, def.normcolor.bg); + else { + XSetForeground(blz.dpy, gc, 0); + XFillRectangle(blz.dpy, pm, gc, 0, 0, divw, divh); + XSetForeground(blz.dpy, gc, 1); + } + + XFillPolygon(blz.dpy, pm, gc, pt, nelem(pt), Convex, CoordModeOrigin); + + if(color) + XSetForeground(blz.dpy, gc, def.normcolor.border); + + XDrawLines(blz.dpy, pm, gc, pt, nelem(pt), CoordModeOrigin); + XDrawRectangle(blz.dpy, pm, gc, pt[1].x, pt[1].y, 1, screen->rect.height); +} + +void +update_dividers() { + if(divmap) { + XFreePixmap(blz.dpy, divmap); + XFreePixmap(blz.dpy, divmask); + XFreeGC(blz.dpy, divgc); + XFreeGC(blz.dpy, maskgc); + } + + divw = 2 * (labelh(&def.font) / 3); + divw = max(divw, 10); + divh = screen->rect.height; + + divmap = XCreatePixmap(blz.dpy, blz.root, + divw, divh, + DefaultDepth(blz.dpy, blz.screen)); + divmask = XCreatePixmap(blz.dpy, blz.root, + divw, divh, + 1); + divgc = XCreateGC(blz.dpy, divmap, 0, 0); + maskgc = XCreateGC(blz.dpy, divmask, 0, 0); + + draw_pmap(divmap, divgc, True); + draw_pmap(divmask, maskgc, False); +} + +static Divide* +get_div(Divide **dp) { + XSetWindowAttributes wa; + Divide *d; + + if(*dp) + return *dp; + + d = emallocz(sizeof *d); + + wa.override_redirect = True; + wa.background_pixmap = ParentRelative; + wa.event_mask = + SubstructureRedirectMask + | ExposureMask + | EnterWindowMask + | PointerMotionMask + | ButtonPressMask + | ButtonReleaseMask; + d->w = XCreateWindow( + /* display */ blz.dpy, + /* parent */ blz.root, + /* x, y */ 0, 0, + /* w, h */ 1, 1, + /* border */ 0, + /* depth */ DefaultDepth(blz.dpy, blz.screen), + /* class */ CopyFromParent, + /* visual */ DefaultVisual(blz.dpy, blz.screen), + /* valuemask */ CWOverrideRedirect | CWEventMask | CWBackPixmap, + /* attributes */&wa + ); + + *dp = d; + return d; +} + +static void +map_div(Divide *d) { + if(!d->mapped) + XMapWindow(blz.dpy, d->w); + d->mapped = 1; +} + +static void +unmap_div(Divide *d) { + if(d->mapped) + XUnmapWindow(blz.dpy, d->w); + d->mapped = 0; +} + +static void +move_div(Divide *d, int x) { + d->x = x - divw/2; + + XMoveResizeWindow(blz.dpy, + d->w, + d->x, 0, + divw, divh); + map_div(d); +} + +void +update_divs() { + Divide **dp, *d; + Area *a; + View *v; + + update_dividers(); + + v = screen->sel; + dp = &divs; + for(a = v->area->next; a; a = a->next) { + d = get_div(dp); + dp = &d->next; + d->x = a->rect.x - divw/2; + move_div(d, a->rect.x); + if(!a->next) { + d = get_div(dp); + dp = &d->next; + move_div(d, r_east(&a->rect)); + } + } + for(d = *dp; d; d = d->next) + unmap_div(d); +} + +void +draw_div(Divide *d) { + XCopyArea( + blz.dpy, + divmap, d->w, + divgc, + /* x, y */ 0, 0, + /* w, h */ divw, divh, + /* dest x, y */ 0, 0 + ); + XShapeCombineMask ( + /* dpy */ blz.dpy, + /* dst */ d->w, + /* type */ ShapeBounding, + /* off x, y */ 0, 0, + /* src */ divmask, + /* op */ ShapeSet + ); +} + +static void scale_column(Area *a) { Frame *f, **fp; - uint min_height, yoff, dy; - uint num_col, num_uncol; - uint col_h, uncol_h; + uint minh, yoff, dy; + uint ncol, nuncol; + uint colh, uncolh; int surplus, i, j; if(!a->frame) @@ -48,40 +214,40 @@ scale_column(Area *a) { * increment gaps can be equalized later */ /* Frames that can't be accomodated are pushed to the floating layer */ - min_height = labelh(&def.font); - col_h = labelh(&def.font); - uncol_h = min_height + frame_delta_h(); + minh = labelh(&def.font); + colh = labelh(&def.font); + uncolh = minh + frame_delta_h(); - num_col = 0; - num_uncol = 0; + ncol = 0; + nuncol = 0; dy = 0; for(f=a->frame; f; f=f->anext) if(f->collapsed) - num_col++; + ncol++; else - num_uncol++; + nuncol++; surplus = a->rect.height; - surplus -= num_col * col_h; - surplus -= num_uncol * uncol_h; + surplus -= ncol * colh; + surplus -= nuncol * uncolh; if(surplus < 0) { - i = ceil((float)(-surplus)/(uncol_h - col_h)); - if(i >= num_uncol) - i = num_uncol - 1; - num_uncol -= i; - num_col += i; - surplus += i * (uncol_h - col_h); + i = ceil((float)(-surplus)/(uncolh - colh)); + if(i >= nuncol) + i = nuncol - 1; + nuncol -= i; + ncol += i; + surplus += i * (uncolh - colh); } if(surplus < 0) { - i = ceil((float)(-surplus)/col_h); - if(i > num_col) - i = num_col; - num_col -= i; - surplus += i * col_h; + i = ceil((float)(-surplus)/colh); + if(i > ncol) + i = ncol; + ncol -= i; + surplus += i * colh; } - i = num_col - 1; - j = num_uncol - 1; + i = ncol - 1; + j = nuncol - 1; for(f=a->frame; f; f=f->anext) { if(f == a->sel) j++; @@ -89,10 +255,10 @@ scale_column(Area *a) { if(j < 0 && f != a->sel) f->collapsed = True; else { - if(f->crect.height <= min_height) + if(f->crect.height <= minh) f->crect.height = 1; else - f->crect.height -= min_height; + f->crect.height -= minh; dy += f->crect.height; } j--; @@ -113,7 +279,7 @@ scale_column(Area *a) { fp=&f->anext; } - i = num_uncol; + i = nuncol; for(f=a->frame; f; f=f->anext) { f->rect.x = a->rect.x; f->rect.width = a->rect.width; @@ -122,17 +288,17 @@ scale_column(Area *a) { f->rect.height = (float)f->crect.height / dy * surplus; if(!i) f->rect.height = surplus; - f->rect.height += min_height + frame_delta_h(); + f->rect.height += minh + frame_delta_h(); apply_sizehints(f->client, &f->rect, False, True, NWEST); dy -= f->crect.height; - surplus -= f->rect.height - frame_delta_h() - min_height; + surplus -= f->rect.height - frame_delta_h() - minh; }else f->rect.height = labelh(&def.font); } yoff = a->rect.y; - i = num_uncol; + i = nuncol; for(f=a->frame; f; f=f->anext) { f->rect.y = yoff; f->rect.x = a->rect.x; @@ -141,9 +307,9 @@ scale_column(Area *a) { yoff += f->rect.height; else{ i--; - f->rect.height += surplus / num_uncol; + f->rect.height += surplus / nuncol; if(!i) - f->rect.height += surplus % num_uncol; + f->rect.height += surplus % nuncol; yoff += f->rect.height; } } @@ -203,15 +369,14 @@ match_horiz(Area *a, XRectangle *r) { } void -resize_column(Client *c, XRectangle *new) { +resize_column(Frame *f, XRectangle *new) { Area *west, *east, *a; - Frame *north, *south, *f; + Frame *north, *south; View *v; BlitzAlign sticky; uint min_height; uint min_width; - f = c->sel; a = f->area; v = a->view; min_height = 2 * labelh(&def.font); @@ -262,7 +427,6 @@ resize_column(Client *c, XRectangle *new) { a->rect.width = r_east(new) - a->rect.x; match_horiz(a, &a->rect); match_horiz(east, &east->rect); - //relax_column(east); } AfterHorizontal: /* skip vertical resize unless the column is in equal mode */ diff --git a/cmd/wmii/dat.h b/cmd/wmii/dat.h @@ -89,6 +89,7 @@ typedef struct View View; typedef struct Area Area; typedef struct Frame Frame; typedef struct Client Client; +typedef struct Divide Divide; typedef struct Key Key; typedef struct Bar Bar; typedef struct Rule Rule; @@ -158,6 +159,13 @@ struct Client { GC gc; }; +struct Divide { + Divide *next; + Window w; + Bool mapped; + int x; +}; + struct Key { Key *next; Key *lnext; @@ -223,11 +231,11 @@ struct WMScreen { Client *client; View *view; Key *key; +Divide *divs; Client c_magic; Client c_root; -enum { BUFFER_SIZE = 8092 }; -char buffer[BUFFER_SIZE]; +char buffer[8092]; /* IXP */ IxpServer srv; @@ -235,18 +243,21 @@ Ixp9Srv p9srv; /* X11 */ uint num_screens; -Blitz blz; -GC xorgc; -char *user; -Atom atom[AtomLast]; -Cursor cursor[CurLast]; uint valid_mask; uint num_lock_mask; Bool sel_screen; + +Blitz blz; +GC xorgc; Pixmap pmap; +Pixmap divmap, divmask; + +Atom atom[AtomLast]; +Cursor cursor[CurLast]; void (*handler[LASTEvent]) (XEvent *); /* Misc */ Bool starting; Bool verbose; +char *user; char *execstr; diff --git a/cmd/wmii/event.c b/cmd/wmii/event.c @@ -47,17 +47,18 @@ buttonrelease(XEvent *e) { return; } } - else if((f = frame_of_win(ev->window))) + else if((f = win2frame(ev->window))) write_event("ClientClick 0x%x %d\n", f->client->win, ev->button); } static void buttonpress(XEvent *e) { XButtonPressedEvent *ev; + Divide *d; Frame *f; ev = &e->xbutton; - if((f = frame_of_win(ev->window))) { + if((f = win2frame(ev->window))) { if((ev->state & def.mod) == def.mod) { switch(ev->button) { case Button1: @@ -80,9 +81,6 @@ buttonpress(XEvent *e) { if(frame_to_top(f)) restack_view(f->view); - if(ingrabbox(f, ev->x, ev->y)) - do_mouse_resize(f->client, False, - quadrant(&f->rect, ev->x_root, ev->y_root) & (EAST|WEST)); else if(ptinrect(ev->x, ev->y, &f->grabbox)) do_mouse_resize(f->client, True, CENTER); else if(f->area->floating) @@ -103,7 +101,10 @@ buttonpress(XEvent *e) { write_event("ClientMouseDown 0x%x %d\n", f->client->win, ev->button); } } - }else + } + else if((d = win2div(ev->window))) + mouse_resizecol(d); + else XAllowEvents(blz.dpy, ReplayPointer, ev->time); } @@ -116,7 +117,7 @@ configurerequest(XEvent *e) { Frame *f; ev = &e->xconfigurerequest; - c = client_of_win(ev->window); + c = win2client(ev->window); if(c) { f = c->sel; gravitate_client(c, True); @@ -178,7 +179,7 @@ destroynotify(XEvent *e) { Client *c; ev = &e->xdestroywindow; - if((c = client_of_win(ev->window))) + if((c = win2client(ev->window))) destroy_client(c); } @@ -192,7 +193,7 @@ enternotify(XEvent *e) { if(ev->mode != NotifyNormal) return; - if((c = client_of_win(ev->window))) { + if((c = win2client(ev->window))) { if(ev->detail != NotifyInferior) { if(screen->focus != c) { if(verbose) fprintf(stderr, "enter_notify(c) => %s\n", c->name); @@ -201,7 +202,7 @@ enternotify(XEvent *e) { set_cursor(c, cursor[CurNormal]); }else if(verbose) fprintf(stderr, "enter_notify(c[NotifyInferior]) => %s\n", c->name); } - else if((f = frame_of_win(ev->window))) { + else if((f = win2frame(ev->window))) { if(screen->focus != c) { if(verbose) fprintf(stderr, "enter_notify(f) => %s\n", f->client->name); if(f->area->floating || !f->collapsed) @@ -261,7 +262,7 @@ focusin(XEvent *e) { return; old = screen->focus; - c = client_of_win(ev->window); + c = win2client(ev->window); if(c) { print_focus(c, c->name); if(ev->mode == NotifyGrab) @@ -307,7 +308,7 @@ focusout(XEvent *e) { if(ev->mode == NotifyUngrab) screen->hasgrab = nil; - c = client_of_win(ev->window); + c = win2client(ev->window); if(c) { if((ev->mode == NotifyWhileGrabbed) && (screen->hasgrab != &c_root)) { @@ -331,14 +332,17 @@ focusout(XEvent *e) { static void expose(XEvent *e) { XExposeEvent *ev; - static Frame *f; + Divide *d; + Frame *f; ev = &e->xexpose; if(ev->count == 0) { if(ev->window == screen->barwin) draw_bar(screen); - else if((f = frame_of_win(ev->window))) + else if((f = win2frame(ev->window))) draw_frame(f); + else if((d = win2div(ev->window))) + draw_div(d); } } @@ -375,7 +379,7 @@ maprequest(XEvent *e) { (StructureNotifyMask | PropertyChangeMask)); return; } - if(!client_of_win(ev->window)) + if(!win2client(ev->window)) manage_client(create_client(ev->window, &wa)); } @@ -385,7 +389,7 @@ motionnotify(XEvent *e) { Frame *f; ev = &e->xmotion; - if((f = frame_of_win(ev->window))) + if((f = win2frame(ev->window))) set_frame_cursor(f, ev->x, ev->y); } @@ -397,7 +401,7 @@ propertynotify(XEvent *e) { ev = &e->xproperty; if(ev->state == PropertyDelete) return; /* ignore */ - if((c = client_of_win(ev->window))) + if((c = win2client(ev->window))) prop_client(c, ev->atom); } @@ -407,7 +411,7 @@ mapnotify(XEvent *e) { Client *c; ev = &e->xmap; - if((c = client_of_win(ev->window))) + if((c = win2client(ev->window))) if(c == selclient()) focus_client(c); } @@ -418,7 +422,7 @@ unmapnotify(XEvent *e) { Client *c; ev = &e->xunmap; - if((c = client_of_win(ev->window))) + if((c = win2client(ev->window))) if(ev->send_event || (c->unmapped-- == 0)) destroy_client(c); } diff --git a/cmd/wmii/fns.h b/cmd/wmii/fns.h @@ -48,17 +48,20 @@ char * message_client(Client *c, char *message); void move_client(Client *c, char *arg); void size_client(Client *c, char *arg); Client *selclient(); -Frame *frame_of_win(Window w); -Client *client_of_win(Window w); +Frame *win2frame(Window w); +Client *win2client(Window w); void update_client_grab(Client *c); void apply_rules(Client *c); void apply_tags(Client *c, const char *tags); /* column.c */ +Divide *win2div(Window w); +void update_dividers(); +void update_divs(); +void draw_div(Divide *d); void arrange_column(Area *a, Bool dirty); -void resize_column(Client *c, XRectangle *r); -int column_mode_of_str(char *arg); -char *str_of_column_mode(int mode); +void resize_column(Frame *f, XRectangle *r); +int str2colmode(const char *str); Area *new_column(View *v, Area *pos, uint w); /* draw.c */ diff --git a/cmd/wmii/frame.c b/cmd/wmii/frame.c @@ -341,6 +341,7 @@ draw_frame(Frame *f) { f->grabbox = br.rect; draw_tile(&br); +#if 0 if(!f->area->floating) { XSetLineAttributes(blz.dpy, br.gc, 1, LineSolid, CapButt, JoinMiter); h = labelh(&def.font) / 3; @@ -364,6 +365,7 @@ draw_frame(Frame *f) { XDrawLines(blz.dpy, br.drawable, br.gc, pt, 2, CoordModeOrigin); } } +#endif XCopyArea( /* display */ blz.dpy, diff --git a/cmd/wmii/fs.c b/cmd/wmii/fs.c @@ -224,14 +224,15 @@ message_root(char *message) uint n; if(!strchr(message, ' ')) { - snprintf(buffer, BUFFER_SIZE, "%s ", message); + snprintf(buffer, sizeof(buffer), "%s ", message); message = buffer; } if(!strcmp(message, "quit ")) srv.running = 0; else if(!strncmp(message, "exec ", 5)) { srv.running = 0; - execstr = estrdup(&message[5]); + execstr = emalloc(strlen(&message[5]) + sizeof("exec ")); + sprintf(execstr, "exec %s", &message[5]); message += strlen(message); } else if(!strncmp(message, "view ", 5)) @@ -283,12 +284,12 @@ char * read_root_ctl() { uint i = 0; if(screen->sel) - i += snprintf(&buffer[i], (BUFFER_SIZE - i), "view %s\n", screen->sel->name); - i += snprintf(&buffer[i], (BUFFER_SIZE - i), "focuscolors %s\n", def.focuscolor.colstr); - i += snprintf(&buffer[i], (BUFFER_SIZE - i), "normcolors %s\n", def.normcolor.colstr); - i += snprintf(&buffer[i], (BUFFER_SIZE - i), "font %s\n", def.font.fontstr); - i += snprintf(&buffer[i], (BUFFER_SIZE - i), "grabmod %s\n", def.grabmod); - i += snprintf(&buffer[i], (BUFFER_SIZE - i), "border %d\n", def.border); + i += snprintf(&buffer[i], (sizeof(buffer) - i), "view %s\n", screen->sel->name); + i += snprintf(&buffer[i], (sizeof(buffer) - i), "focuscolors %s\n", def.focuscolor.colstr); + i += snprintf(&buffer[i], (sizeof(buffer) - i), "normcolors %s\n", def.normcolor.colstr); + i += snprintf(&buffer[i], (sizeof(buffer) - i), "font %s\n", def.font.fontstr); + i += snprintf(&buffer[i], (sizeof(buffer) - i), "grabmod %s\n", def.grabmod); + i += snprintf(&buffer[i], (sizeof(buffer) - i), "border %d\n", def.border); return buffer; } @@ -316,7 +317,7 @@ write_event(char *format, ...) { Ixp9Req *req; va_start(ap, format); - vsnprintf(buffer, BUFFER_SIZE, format, ap); + vsnprintf(buffer, sizeof(buffer), format, ap); va_end(ap); if(!(len = strlen(buffer))) return; diff --git a/cmd/wmii/mouse.c b/cmd/wmii/mouse.c @@ -355,6 +355,81 @@ do_managed_move(Client *c) { } void +mouse_resizecol(Divide *d) { + XSetWindowAttributes wa; + XEvent ev; + Window cwin; + XRectangle r; + Divide *dp; + View *v; + Area *a; + uint w, minw; + int x; + + v = screen->sel; + + for(a = v->area->next, dp = divs; a; a = a->next, dp = dp->next) + if(dp->next == d) break; + + /* Fix later */ + if(dp == nil || d->next == nil) + return; + + minw = screen->rect.width/NCOL; + + x = a->rect.x + minw; + w = r_east(&a->next->rect) - minw; + w -= x; + + cwin = XCreateWindow(blz.dpy, blz.root, + x, 0, w, 1, + /* border */ 0, + /* depth */ CopyFromParent, + /* class */ InputOnly, + /* visual */ CopyFromParent, + /* valuemask */ 0, + /* attrib */ &wa + ); + XMapWindow(blz.dpy, cwin); + + if(XGrabPointer( + blz.dpy, blz.root, + /* owner_events*/ False, + /* event_mask */ MouseMask, + /* kbd, mouse */ GrabModeAsync, GrabModeAsync, + /* confine_to */ cwin, + /* cursor */ cursor[CurInvisible], + /* time */ CurrentTime + ) != GrabSuccess) + goto done; + + for(;;) { + XMaskEvent(blz.dpy, MouseMask | ExposureMask, &ev); + switch (ev.type) { + case ButtonRelease: + r = a->rect; + r.width = x - r.x; + resize_column(a->frame, &r); + + XUngrabPointer(blz.dpy, CurrentTime); + XSync(blz.dpy, False); + goto done; + case MotionNotify: + x = ev.xmotion.x_root; + + XMoveWindow(blz.dpy, d->w, x, 0); + break; + case Expose: + dispatch_event(&ev); + break; + default: break; + } + } +done: + XDestroyWindow(blz.dpy, cwin); +} + +void do_mouse_resize(Client *c, Bool opaque, BlitzAlign align) { BlitzAlign grav; Window dummy; @@ -428,8 +503,10 @@ do_mouse_resize(Client *c, Bool opaque, BlitzAlign align) { return; } else if(!opaque) { - hrx = (double)(screen->rect.width + frect.width - 2 * labelh(&def.font)) / screen->rect.width; - hry = (double)(screen->rect.height + frect.height - 3 * labelh(&def.font)) / screen->rect.height; + hrx = (double)(screen->rect.width + frect.width - 2 * labelh(&def.font)) + / screen->rect.width; + hry = (double)(screen->rect.height + frect.height - 3 * labelh(&def.font)) + / screen->rect.height; pt_x = r_east(&frect) - labelh(&def.font); pt_y = r_south(&frect) - labelh(&def.font); warppointer(pt_x / hrx, pt_y / hry); @@ -451,7 +528,7 @@ do_mouse_resize(Client *c, Bool opaque, BlitzAlign align) { xorborder(&frect); if(!floating) - resize_column(c, &frect); + resize_column(c->sel, &frect); else resize_client(c, &frect); diff --git a/cmd/wmii/view.c b/cmd/wmii/view.c @@ -120,6 +120,7 @@ focus_view(WMScreen *s, View *v) { XGrabServer(blz.dpy); assign_sel_view(v); update_frame_selectors(v); + update_divs(); for(c=client; c; c=c->next) if((f = c->sel)) { if(f->view == v) { @@ -130,6 +131,7 @@ focus_view(WMScreen *s, View *v) { unmap_client(c, IconicState); } } + restack_view(v); focus_area(v->sel); draw_frames(); @@ -168,9 +170,10 @@ void restack_view(View *v) { static Window *wins = nil; static uint winssz = 0; - Area *a; + Divide *d; Frame *f; Client *c; + Area *a; uint n, i; if(v != screen->sel) @@ -179,31 +182,39 @@ restack_view(View *v) { i = 0; n = 0; - for(c=client; c; c=c->next) + for(c = client; c; c = c->next) i++; if(i == 0) return; + + for(a = v->area; a; a = a->next) + i++; + if(i >= winssz) { winssz = 2 * i; wins = erealloc(wins, sizeof(Window) * winssz); } wins[n++] = screen->barwin; - for(f=v->area->stack; f; f=f->snext) + for(f = v->area->frame; f; f = f->anext) if(f->client->fullscreen) { n--; break; } + for(f=v->area->stack; f; f=f->snext) wins[n++] = f->client->framewin; - for(a=v->area->next; a; a=a->next) { + + for(d = divs; d && d->mapped; d = d->next) + wins[n++] = d->w; + + for(a=v->area->next; a; a=a->next) if(a->frame) { wins[n++] = a->sel->client->framewin; for(f=a->frame; f; f=f->anext) if(f != a->sel) wins[n++] = f->client->framewin; } - } if(n) XRestackWindows(blz.dpy, wins, n); } @@ -294,7 +305,7 @@ view_index(View *v) { Frame *f; Area *a; - len = BUFFER_SIZE; + len = sizeof(buffer); buf_i = 0; for((a = v->area), (a_i = 0); a && len > 0; (a=a->next), (a_i++)) { if(a->floating) @@ -365,7 +376,7 @@ area_of_message(View *v, char *message, uint *next) { char * message_view(View *v, char *message) { - uint n, i; + int n, i; Client *c; Frame *f; Area *a; @@ -388,13 +399,16 @@ message_view(View *v, char *message) { } if(!strncmp(message, "colmode ", 8)) { message += 8; - if(!(a = area_of_message(v, message, &n)) || a == v->area) + if((a = area_of_message(v, message, &n)) == nil + || a->floating) return Ebadvalue; - if((i = column_mode_of_str(&message[n])) == -1) + if((i = str2colmode(&message[n])) == -1) return Ebadvalue; + a->mode = i; arrange_column(a, True); restack_view(v); + if(v == screen->sel) focus_view(screen, v); draw_frames();