wmii

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

commit a27463d6038cc9b7e6517df603a82ad202c91d68
parent fbc572a6a80239f91d2a1f83d1cd51fec7d05af2
Author: Kris Maglione <jg@suckless.org>
Date:   Fri,  2 Mar 2007 03:13:32 -0500

Implemented the Aspect hint, as well as some moderate cleanup.

Diffstat:
client.c | 221+++++++++++++++++++++++++++++++++++++++++--------------------------------------
column.c | 2+-
event.c | 2+-
frame.c | 37+++++++++++++++++++++++++------------
mouse.c | 24++++++++++++++----------
wmii.h | 6++++--
6 files changed, 159 insertions(+), 133 deletions(-)

diff --git a/client.c b/client.c @@ -26,7 +26,6 @@ Client * create_client(Window w, XWindowAttributes *wa) { Client **t, *c; XSetWindowAttributes fwa; - long msize; c = emallocz(sizeof(Client)); c->win = w; @@ -35,23 +34,16 @@ create_client(Window w, XWindowAttributes *wa) { c->border = wa->border_width; c->rect.width = wa->width; c->rect.height = wa->height; + c->proto = win_proto(c->win); - update_client_name(c); - - c->fixedsize = False; - XGetTransientForHint(blz.dpy, c->win, &c->trans); - if(!XGetWMNormalHints(blz.dpy, c->win, &c->size, &msize) || !c->size.flags) - c->size.flags = PSize; - if(c->size.flags & PMinSize && c->size.flags & PMaxSize - && c->size.min_width == c->size.max_width - && c->size.min_height == c->size.max_height) - c->fixedsize = True; - if(c->rect.width == screen->rect.width - && c->rect.height == screen->rect.height) - c->fullscreen = True; + prop_client(c, XA_WM_TRANSIENT_FOR); + prop_client(c, XA_WM_NORMAL_HINTS); + prop_client(c, XA_WM_HINTS); + prop_client(c, XA_WM_NAME); XSetWindowBorderWidth(blz.dpy, c->win, 0); XAddToSaveSet(blz.dpy, c->win); + fwa.override_redirect = 1; fwa.background_pixmap = ParentRelative; fwa.event_mask = @@ -77,6 +69,7 @@ create_client(Window w, XWindowAttributes *wa) { /* valuemask */ CWOverrideRedirect | CWEventMask | CWBackPixmap, /* attributes */&fwa ); + c->gc = XCreateGC(blz.dpy, c->framewin, 0, 0); XSync(blz.dpy, False); @@ -93,12 +86,12 @@ create_client(Window w, XWindowAttributes *wa) { void manage_client(Client *c) { - XTextProperty tags; + XTextProperty tags = { 0 }; Client *trans; - tags.nitems = 0; XGetTextProperty(blz.dpy, c->win, &tags, tags_atom); - if((c->trans) && (trans = client_of_win(c->trans))) + + if((trans = client_of_win(c->trans))) strncpy(c->tags, trans->tags, sizeof(c->tags)); else if(tags.nitems) strncpy(c->tags, (char *)tags.value, sizeof(c->tags)); @@ -381,26 +374,28 @@ set_urgent(Client *c, Bool urgent, Bool write) { } void -prop_client(Client *c, XPropertyEvent *e) { +prop_client(Client *c, Atom a) { XWMHints *wmh; long msize; - if(e->atom == wm_atom[WMProtocols]) { + if(a == wm_atom[WMProtocols]) c->proto = win_proto(c->win); - return; - } - switch (e->atom) { + else if(a== net_atom[NetWMName]) { +wmname: + update_client_name(c); + if(c->frame) + draw_frame(c->sel); + }else switch (a) { case XA_WM_TRANSIENT_FOR: XGetTransientForHint(blz.dpy, c->win, &c->trans); break; case XA_WM_NORMAL_HINTS: - if(!XGetWMNormalHints(blz.dpy, c->win, &c->size, &msize) || !c->size.flags) { + if(!XGetWMNormalHints(blz.dpy, c->win, &c->size, &msize) || !c->size.flags) c->size.flags = PSize; - } c->fixedsize = False; - if(c->size.flags & PMinSize && c->size.flags & PMaxSize - && c->size.min_width == c->size.max_width - && c->size.min_height == c->size.max_height) + if((c->size.flags & PMinSize) && (c->size.flags & PMaxSize) + &&(c->size.min_width == c->size.max_width) + &&(c->size.min_height == c->size.max_height)) c->fixedsize = True; break; case XA_WM_HINTS: @@ -410,11 +405,8 @@ prop_client(Client *c, XPropertyEvent *e) { XFree(wmh); } break; - } - if(e->atom == XA_WM_NAME || e->atom == net_atom[NetWMName]) { - update_client_name(c); - if(c->frame) - draw_frame(c->sel); + case XA_WM_NAME: + goto wmname; } } @@ -491,7 +483,9 @@ destroy_client(Client *c) { Client **tc; XGrabServer(blz.dpy); + /* In case the client is already unmapped */ XSetErrorHandler(dummy_error_handler); + for(tc=&client; *tc; tc=&(*tc)->next) if(*tc == c) { *tc = c->next; @@ -504,6 +498,7 @@ destroy_client(Client *c) { unmap_client(c, WithdrawnState); gravitate_client(c, True); reparent_client(c, blz.root, c->rect.x, c->rect.y); + XFreeGC(blz.dpy, c->gc); XDestroyWindow(blz.dpy, c->framewin); XSync(blz.dpy, False); @@ -517,69 +512,78 @@ destroy_client(Client *c) { } void -match_sizehints(Client *c, XRectangle *r, Bool floating, BlitzAlign sticky) { +apply_sizehints(Client *c, XRectangle *r, Bool floating, Bool frame, BlitzAlign sticky) { XSizeHints *s; - uint dx, dy; - uint hdiff, wdiff; - + XRectangle orig; + uint bw, bh; + s = &c->size; - dx = 2 * def.border; - dy = def.border + labelh(&def.font); - - if(floating && (s->flags & PMinSize)) { - if(r->width < s->min_width + dx) { - wdiff = (s->min_width + dx) - r->width; - r->width += wdiff; - if((sticky & EAST) && !(sticky & WEST)) - r->x -= wdiff; - } - if(r->height < s->min_height + dy) { - hdiff = (s->min_height + dy) - r->height; - r->height += hdiff; - if((sticky & SOUTH) && !(sticky & NORTH)) - r->y -= hdiff; + orig = *r; + if(frame) + frame2client(r); + bw = 0; + bh = 0; + + if(s->flags & PMinSize) { + bw = s->min_width; + bh = s->min_height; + if(floating) { + if(r->width < s->min_width) + r->width = s->min_width; + if(r->height < s->min_height) + r->height = s->min_height; } } - if(floating && (s->flags & PMaxSize)) { - if(r->width > s->max_width + dx) { - wdiff = r->width - (s->max_width + dx); - r->width -= wdiff; - if((sticky & EAST) && !(sticky & WEST)) - r->x += wdiff; - } - if(r->height > s->max_height + dy) { - hdiff = r->height - (s->max_height + dy); - r->height -= hdiff; - if((sticky & SOUTH) && !(sticky & NORTH)) - r->y += hdiff; - } + if(s->flags & PMaxSize) { + if(r->width > s->max_width) + r->width = s->max_width; + if(r->height > s->max_height) + r->height = s->max_height; } + + if(s->flags & PBaseSize) { + bw = s->base_width; + bh = s->base_height; + } + if(s->flags & PResizeInc) { - int w = 0, h = 0; - if(s->flags & PBaseSize) { - w = s->base_width; - h = s->base_height; - } else if(s->flags & PMinSize) { - /* base_{width,height} default to min_{width,height} */ - w = s->min_width; - h = s->min_height; - } - /* client_width = base_width + i * s->width_inc for an integer i */ - w = r->width - dx - w; - if(s->width_inc > 0) { - wdiff = w % s->width_inc; - r->width -= wdiff; - if((sticky & EAST) && !(sticky & WEST)) - r->x += wdiff; - } - h = r->height - dy - h; - if(s->height_inc > 0) { - hdiff = h % s->height_inc; - r->height -= hdiff; - if((sticky & SOUTH) && !(sticky & NORTH)) - r->y += hdiff; - } + if(s->width_inc > 0) + r->width -= (r->width - bw) % s->width_inc; + if(s->height_inc > 0) + r->height -= (r->height - bh) % s->height_inc; } + + if((s->flags & (PBaseSize|PMinSize)) == PMinSize) { + bw = 0; + bh = 0; + } + + if(s->flags & PAspect) { + double min, max, initial; + + min = (double)s->min_aspect.x / s->min_aspect.y; + max = (double)s->max_aspect.x / s->max_aspect.y; + initial = (double)(r->width - bw) / (r->height - bh); + if(initial < min) + r->height = bh + (r->width - bw) / min; + if(initial > max) + r->width = bw + (r->height - bh) * max; + } + + if(frame) + client2frame(r); + + if(!(s->flags & PMinSize) || !floating) { + if(r->width > orig.width) + r->width = orig.width; + if(r->height > orig.height) + r->height = orig.height; + } + + if((sticky & (EAST|WEST)) == EAST) + r->x = r_east(&orig) - r->width; + if((sticky & (NORTH|SOUTH)) == SOUTH) + r->y = r_south(&orig) - r->height; } void @@ -587,8 +591,7 @@ focus_client(Client *c) { if(verbose) fprintf(stderr, "focus_client(%p) => %s\n", c, (c ? c->name : nil)); if(screen->focus != c) { - if(c) - if(verbose) + if(c && verbose) fprintf(stderr, "\t%s => %s\n", (screen->focus ? screen->focus->name : "<nil>"), (c ? c->name : "<nil>")); if(c) { @@ -619,8 +622,8 @@ resize_client(Client *c, XRectangle *r) { c->rect = f->crect; c->rect.x += f->rect.x; c->rect.y += f->rect.y; - if(f->area->mode == Colmax - && f->area->sel != f) { + if((f->area->mode == Colmax) + && (f->area->sel != f)) { unmap_frame(c); unmap_client(c, IconicState); }else if(f->collapsed) { @@ -793,12 +796,13 @@ update_client_views(Client *c, char **tags) { if(cmp >= 0) break; } + f = *fp; detach_from_area(f); *fp = f->cnext; - free(f); if(c->sel == f) c->sel = *fp; + free(f); } if(*tags) { if(!*fp || cmp > 0) { @@ -888,9 +892,12 @@ apply_tags(Client *c, const char *tags) { break; } } + c->tags[0] = '\0'; + if(!j) + return; qsort(toks, j, sizeof(char *), compare_tags); - if(!j) return; + for(i=0, n=0; i < j; i++) if(!n || strcmp(toks[i], toks[n-1])) { if(i) @@ -899,26 +906,26 @@ apply_tags(Client *c, const char *tags) { toks[n++] = toks[i]; } toks[n] = nil; + update_client_views(c, toks); XChangeProperty(blz.dpy, c->win, tags_atom, XA_STRING, 8, PropModeReplace, (uchar *)c->tags, strlen(c->tags)); } -static void -match_tags(Client *c, const char *prop) { - Rule *r; - regmatch_t tmpregm; - - for(r=def.tagrules.rule; r; r=r->next) - if(!regexec(&r->regex, prop, 1, &tmpregm, 0)) - if(!strlen(c->tags) || !strncmp(c->tags, "nil", 4)) - apply_tags(c, r->value); -} - void apply_rules(Client *c) { - if(def.tagrules.string) - match_tags(c, c->props); + Rule *r; + regmatch_t rm; + + if(strlen(c->tags)) + return; + if(def.tagrules.string) + for(r=def.tagrules.rule; r; r=r->next) + if(!regexec(&r->regex, c->props, 1, &rm, 0)) { + apply_tags(c, r->value); + if(strlen(c->tags) && strcmp(c->tags, "nil")) + break; + } if(!strlen(c->tags)) apply_tags(c, "nil"); } diff --git a/column.c b/column.c @@ -122,7 +122,7 @@ scale_column(Area *a) { if(!i) f->rect.height = surplus; f->rect.height += min_height + frame_delta_h(); - match_sizehints(f->client, &f->rect, False, NWEST); + apply_sizehints(f->client, &f->rect, False, True, NWEST); dy -= f->crect.height; surplus -= f->rect.height - frame_delta_h() - min_height; diff --git a/event.c b/event.c @@ -364,7 +364,7 @@ propertynotify(XEvent *e) { if(ev->state == PropertyDelete) return; /* ignore */ if((c = client_of_win(ev->window))) - prop_client(c, ev); + prop_client(c, ev->atom); } static void diff --git a/frame.c b/frame.c @@ -68,6 +68,18 @@ insert_frame(Frame *pos, Frame *f, Bool before) { } void +frame2client(XRectangle *r) { + r->width = max(r->width - def.border * 2, 1); + r->height = max(r->height - frame_delta_h(), 1); +} + +void +client2frame(XRectangle *r) { + r->width += def.border * 2; + r->height += frame_delta_h(); +} + +void resize_frame(Frame *f, XRectangle *r) { BlitzAlign stickycorner; Client *c; @@ -75,33 +87,34 @@ resize_frame(Frame *f, XRectangle *r) { c = f->client; stickycorner = get_sticky(&f->rect, r); + if(c->fullscreen) + send_to_area(f->area->view->area, f); + f->rect = *r; f->crect = *r; - match_sizehints(c, &f->crect, f->area->floating, stickycorner); + apply_sizehints(c, &f->crect, f->area->floating, True, stickycorner); if(f->area->floating) f->rect = f->crect; - if(f->rect.height < frame_delta_h() + labelh(&def.font)) { + frame2client(&f->crect); + + if(f->crect.height < labelh(&def.font)) { f->rect.height = frame_delta_h(); f->collapsed = True; }else f->collapsed = False; - if(f->rect.width < labelh(&def.font)) { + if(f->crect.width < labelh(&def.font)) { f->rect.width = frame_delta_h(); f->collapsed = True; } - if(!f->collapsed) { - f->crect.width -= def.border * 2; - f->crect.height -= frame_delta_h(); - } + if(f->collapsed) + f->crect = f->rect; f->crect.y = labelh(&def.font); f->crect.x = (f->rect.width - f->crect.width) / 2; - - if(f->collapsed) - f->rect.height = labelh(&def.font); + if(f->area->floating) { if(c->fullscreen) { @@ -312,8 +325,8 @@ check_frame_constraints(XRectangle *rect) { rect->x = screen->rect.width - barheight; if(rect->y + barheight > max_height) rect->y = max_height - barheight; - if(rect->x + rect->width < barheight) + if(r_east(rect) < barheight) rect->x = barheight - rect->width; - if(rect->y + rect->height < barheight) + if(r_south(rect) < barheight) rect->y = barheight - rect->height; } diff --git a/mouse.c b/mouse.c @@ -106,12 +106,12 @@ snap_line(SnapArgs *a) { } BlitzAlign -snap_rect(XRectangle *rects, int num, XRectangle *current, - BlitzAlign *mask, int snap) -{ +snap_rect(XRectangle *rects, int num, XRectangle *current, BlitzAlign *mask, int snap) { SnapArgs a = { rects, num, 0, 0, 0, 0, *mask, nil }; - int dx = snap + 1, dy = snap + 1; + int dx, dy; BlitzAlign ret; + + dx = dy = snap + 1; a.x1 = current->x; a.x2 = r_east(current); @@ -137,8 +137,10 @@ snap_rect(XRectangle *rects, int num, XRectangle *current, snap_line(&a); } - rect_morph_xy(current, abs(dx) <= snap ? dx : 0, - abs(dy) <= snap ? dy : 0, mask); + rect_morph_xy(current, + abs(dx) <= snap ? dx : 0, + abs(dy) <= snap ? dy : 0, + mask); ret = *mask; if(abs(dx) <= snap) @@ -159,6 +161,7 @@ draw_xor_border(XRectangle *r) { xor.height = xor.height > 4 ? xor.height - 4 : 0; XSetLineAttributes(blz.dpy, xorgc, 1, LineSolid, CapNotLast, JoinMiter); + XSetForeground(blz.dpy, xorgc, def.focuscolor.bg); if(xor.height > 4 && xor.width > 2) XDrawLine(blz.dpy, blz.root, xorgc, xor.x + 2, @@ -173,7 +176,6 @@ draw_xor_border(XRectangle *r) { r_south(&xor) - 2); XSetLineAttributes(blz.dpy, xorgc, 4, LineSolid, CapNotLast, JoinMiter); XDrawRectangles(blz.dpy, blz.root, xorgc, &xor, 1); - XSync(blz.dpy, False); } static void @@ -451,7 +453,8 @@ do_mouse_resize(Client *c, Bool grabbox, BlitzAlign align) { pt_y += dy; rect_morph_xy(&origin, dx, dy, &align); - if(align != CENTER) check_frame_constraints(&origin); + if(align != CENTER) + check_frame_constraints(&origin); frect = origin; if(floating) @@ -459,7 +462,7 @@ do_mouse_resize(Client *c, Bool grabbox, BlitzAlign align) { else grav = align ^ CENTER; - match_sizehints(c, &frect, floating, grav); + apply_sizehints(c, &frect, floating, True, grav); if(grabbox) { XMoveWindow(blz.dpy, c->framewin, frect.x, frect.y); @@ -472,7 +475,8 @@ do_mouse_resize(Client *c, Bool grabbox, BlitzAlign align) { case Expose: (handler[Expose])(&ev); break; - default: break; + default: + break; } } } diff --git a/wmii.h b/wmii.h @@ -289,7 +289,7 @@ Bar *bar_of_name(Bar *b_link, const char *name); Client *create_client(Window w, XWindowAttributes *wa); void destroy_client(Client *c); void configure_client(Client *c); -void prop_client(Client *c, XPropertyEvent *e); +void prop_client(Client *c, Atom a); void kill_client(Client *c); void gravitate_client(Client *c, Bool invert); void map_client(Client *c); @@ -303,7 +303,7 @@ void manage_client(Client *c); void focus(Client *c, Bool restack); void focus_client(Client *c); void resize_client(Client *c, XRectangle *r); -void match_sizehints(Client *c, XRectangle *r, Bool floating, BlitzAlign sticky); +void apply_sizehints(Client *c, XRectangle *r, Bool floating, Bool frame, BlitzAlign sticky); char *send_client(Frame *f, char *arg, Bool swap); char * message_client(Client *c, char *message); void move_client(Client *c, char *arg); @@ -351,6 +351,8 @@ Bool frame_to_top(Frame *f); void set_frame_cursor(Frame *f, int x, int y); void swap_frames(Frame *fa, Frame *fb); int frame_delta_h(); +void frame2client(XRectangle *r); +void client2frame(XRectangle *r); void draw_frame(Frame *f); void draw_frames(); void update_frame_widget_colors(Frame *f);