wmii

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

commit e8fbdc88464a363461dc86f6d2e1401b0a39df63
parent 7bb382a3966874a33cd619454ddca76d13c3670a
Author: Kris Maglione <jg@suckless.org>
Date:   Wed, 14 Feb 2007 23:20:47 -0500

New column scaling code. Fixed accidental resize on click of unfocused client. New public domain util.c. Some other stuff.


Diffstat:
Makefile | 2+-
area.c | 43+++++++++++++++++++++++--------------------
bar.c | 2+-
client.c | 79++++++++++++++++++++++++++-----------------------------------------------------
column.c | 226++++++++++++++++++++++++++++++++++++++++----------------------------------------
config.mk | 2+-
draw.c | 6++++--
event.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++------
frame.c | 37+++++++++++++++++++++++++++++++------
fs.c | 36++++++++++++++++++------------------
geom.c | 4++--
key.c | 9+++++----
libcext/estrdup.c | 21---------------------
main.c | 31+++++++++++++++++--------------
mouse.c | 10+++++-----
rule.c | 2+-
util.c | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
view.c | 9++++-----
wmii.h | 13++++++++++---
19 files changed, 384 insertions(+), 276 deletions(-)

diff --git a/Makefile b/Makefile @@ -4,7 +4,7 @@ include config.mk SRC = area.c bar.c client.c column.c draw.c event.c frame.c fs.c \ - geom.c key.c main.c mouse.c rule.c util.c view.c + geom.c key.c main.c mouse.c rule.c printevent.c util.c view.c OBJ = ${SRC:.c=.o} all: options wmiiwm diff --git a/area.c b/area.c @@ -48,7 +48,7 @@ create_area(View *v, Area *pos, uint w) { if(pos) scale_view(v, screen->rect.width - w); - a = ixp_emallocz(sizeof(Area)); + a = emallocz(sizeof(Area)); a->view = v; a->id = id++; a->rect = screen->rect; @@ -103,15 +103,17 @@ destroy_area(Area *a) { } void -send_to_area(Area *to, Area *from, Frame *f) { +send_to_area(Area *to, Frame *f) { + Area *from; assert(to->view == f->view); + from = f->area; if(to->floating != from->floating) { XRectangle temp = f->revert; f->revert = f->rect; f->rect = temp; } f->client->revert = from; - detach_from_area(from, f); + detach_from_area(f); attach_to_area(to, f, True); } @@ -128,42 +130,43 @@ attach_to_area(Area *a, Frame *f, Bool send) { f->area = a; - n_frame = 1; + n_frame = 0; for(ft=a->frame; ft; ft=ft->anext) n_frame++; + if(n_frame == 0) + n_frame = 1; c->floating = a->floating; - if(!a->floating) { - h = a->rect.height / n_frame; - if(a->frame) - scale_column(a, a->rect.height - h); - } - if(a->sel) - insert_frame(a->sel, f, False); - else - insert_frame(nil, f, False); - if(!a->floating) - f->rect.height = h; - else + f->rect.height = a->rect.height / n_frame; + + insert_frame(a->sel, f, False); + + if(a->floating) place_client(a, c); + focus_frame(f, False); + resize_frame(f, &f->rect); if(!a->floating) arrange_column(a, False); - focus_frame(f, False); + else + resize_client(f->client, &f->rect); update_client_grab(f->client); - assert(a->sel); + if(a->frame) + assert(a->sel); } void -detach_from_area(Area *a, Frame *f) { +detach_from_area(Frame *f) { Frame *pr; Client *c; + Area *a; View *v; Area *ta; uint i; + a = f->area; v = a->view; c = f->client; @@ -243,7 +246,7 @@ place_client(Area *a, Client *c) { if(!field) { mx = screen->rect.width / 8; my = screen->rect.height / 8; - field = ixp_emallocz(my * mx * sizeof(Bool)); + field = emallocz(my * mx * sizeof(Bool)); } for(y = 0; y < my; y++) for(x = 0; x < mx; x++) diff --git a/bar.c b/bar.c @@ -21,7 +21,7 @@ create_bar(Bar **b_link, char *name) { memset(b, 0, sizeof(*b)); } else - b = ixp_emallocz(sizeof(Bar)); + b = emallocz(sizeof(Bar)); b->id = id++; strncpy(b->name, name, sizeof(b->name)); b->brush = screen->bbrush; diff --git a/client.c b/client.c @@ -21,7 +21,7 @@ create_client(Window w, XWindowAttributes *wa) { XSetWindowAttributes fwa; long msize; - c = ixp_emallocz(sizeof(Client)); + c = emallocz(sizeof(Client)); c->win = w; c->rect.x = wa->x; c->rect.y = wa->y; @@ -259,19 +259,19 @@ reparent_client(Client *c, Window w, int x, int y) { void configure_client(Client *c) { XConfigureEvent e; - Frame *f = c->sel; + Frame *f; + + f = c->sel; + if(!f) + return; e.type = ConfigureNotify; e.event = c->win; e.window = c->win; - e.x = c->rect.x; - e.y = c->rect.y; - if(f) { - e.x += f->rect.x; - e.y += f->rect.y; - } - e.width = c->rect.width; - e.height = c->rect.height; + e.x = f->crect.x + f->rect.x - c->border; + e.y = f->crect.y + f->rect.y - c->border; + e.width = f->crect.width; + e.height = f->crect.height; e.border_width = c->border; e.above = None; e.override_redirect = False; @@ -477,8 +477,8 @@ destroy_client(Client *c) { XUngrabServer(blz.dpy); flush_masked_events(EnterWindowMask); - free(c); write_event("DestroyClient 0x%x\n", c->win); + free(c); } void @@ -547,33 +547,21 @@ match_sizehints(Client *c, XRectangle *r, Bool floating, BlitzAlign sticky) { void focus_client(Client *c) { if(screen->focus != c) { + screen->focus = c; if(c) XSetInputFocus(blz.dpy, c->win, RevertToParent, CurrentTime); else XSetInputFocus(blz.dpy, screen->barwin, RevertToParent, CurrentTime); - screen->focus = c; } } void resize_client(Client *c, XRectangle *r) { Frame *f; - Bool floating; f = c->sel; - floating = f->area->floating; - resize_frame(f, r); - if(floating) { - if((c->rect.width == screen->rect.width) && - (c->rect.height == screen->rect.height)) { - f->rect.x = -def.border; - f->rect.y = -labelh(&def.font); - }else - check_frame_constraints(&f->rect); - } - if(f->area->view == screen->sel) XMoveResizeWindow(blz.dpy, c->framewin, f->rect.x, f->rect.y, @@ -584,37 +572,22 @@ resize_client(Client *c, XRectangle *r) { return; } - if(f->area->sel != f) - switch(f->area->mode) { - case Colmax: - unmap_frame(c); - unmap_client(c, IconicState); - break; - case Colstack: - XMoveResizeWindow(blz.dpy, c->win, - c->rect.x, c->rect.y, - c->rect.width, c->rect.height); - map_frame(c); - unmap_client(c, IconicState); - break; - default: - goto ShowWindow; - } - else { - ShowWindow: - c->rect = f->rect; - c->rect.y = labelh(&def.font); - match_sizehints(c, &c->rect, False, NORTH|EAST); - c->rect.width -= def.border * 2; - c->rect.height -= labelh(&def.font) + def.border; - c->rect.x = (f->rect.width - c->rect.width) / 2; + c->rect = f->crect; + if(f->area->mode == Colmax + && f->area->sel != f) { + unmap_frame(c); + unmap_client(c, IconicState); + }else if(f->collapsed) { + map_frame(c); + unmap_client(c, IconicState); + }else { XMoveResizeWindow(blz.dpy, c->win, c->rect.x, c->rect.y, c->rect.width, c->rect.height); map_client(c); map_frame(c); - configure_client(c); } + configure_client(c); } void @@ -631,11 +604,11 @@ newcol_client(Client *c, char *arg) { for(to=v->area; to; to=to->next) if(to->next == a) break; to = new_column(v, to, 0); - send_to_area(to, a, f); + send_to_area(to, f); } else if(!strncmp(arg, "next", 5)) { to = new_column(v, a, 0); - send_to_area(to, a, f); + send_to_area(to, f); } else return; @@ -751,7 +724,7 @@ send_area: if(!to) return Ebadvalue; if(!swap) - send_to_area(to, a, f); + send_to_area(to, f); else if(to->sel) swap_frames(f, to->sel); @@ -775,7 +748,7 @@ update_client_views(Client *c, char **tags) { break; } f = *fp; - detach_from_area(f->area, f); + detach_from_area(f); *fp = f->cnext; free(f); if(c->sel == f) diff --git a/column.c b/column.c @@ -2,8 +2,10 @@ * See LICENSE file for license details. */ #include "wmii.h" +#include <assert.h> #include <stdlib.h> #include <string.h> +#include <math.h> char * str_of_column_mode(int mode) { @@ -28,155 +30,153 @@ column_mode_of_str(char *arg) { } static void -relax_column(Area *a) { - uint frame_size, yoff, h; - Frame *f; - int hdiff; - Bool fallthrough = False; +scale_column(Area *a) { + Frame *f, **fp; + uint min_height, yoff, dy; + uint num_col, num_uncol; + uint col_h, uncol_h; + int surplus, i, j; if(!a->frame) return; - frame_size = 0; + + /* This works by comparing heights based on a surplus of their + * minimum size. We start by subtracting the minimum size, then + * scale the surplus, and add back the minimum size later. This + * is based on the size of the client, rather than the frame, so + * 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(); + + num_col = 0; + num_uncol = 0; + dy = 0; for(f=a->frame; f; f=f->anext) - frame_size++; - switch(a->mode) { - case Coldefault: - h = a->rect.height / frame_size; - if(h < 2 * labelh(&def.font)) - fallthrough = True; - break; - case Colstack: - h = a->rect.height - (frame_size - 1) * labelh(&def.font); - if(h < 3 * labelh(&def.font)) - fallthrough = True; - default: - yoff = a->rect.y; - break; + if(f->collapsed) + num_col++; + else + num_uncol++; + + surplus = a->rect.height; + surplus -= num_col * col_h; + surplus -= num_uncol * uncol_h; + 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); } - if(fallthrough) { - for(f=a->frame; f; f=f->anext) { - f->rect.x = a->rect.x + (a->rect.width - f->rect.width) / 2; - f->rect.y = a->rect.y + (a->rect.height - f->rect.height) / 2; - } - return; + if(surplus < 0) { + i = ceil((float)(-surplus)/col_h); + if(i > num_col) + i = num_col; + num_col -= i; + surplus += i * col_h; } - /* some relaxing from potential increment gaps */ - h = 0; + + i = num_col - 1; + j = num_uncol - 1; for(f=a->frame; f; f=f->anext) { - if(a->mode == Colmax) { - if(h < f->rect.height) - h = f->rect.height; + if(f == a->sel) + j++; + if(!f->collapsed) { + if(j < 0 && f != a->sel) + f->collapsed = True; + else { + if(f->crect.height <= min_height) + f->crect.height = 1; + else + f->crect.height -= min_height; + dy += f->crect.height; + } + j--; } - else - h += f->rect.height; } - hdiff = a->rect.height - h; - if((a->mode == Coldefault) && (hdiff > 0)) { - int hx; - for(hx = 1; hx < hdiff; hx++) - for(f=a->frame; f && (hx < hdiff); f=f->anext) { - uint tmp = f->rect.height; - f->rect.height += hx; - hdiff -= (f->rect.height - tmp); + for(fp=&a->frame; *fp;) { + f = *fp; + if(f == a->sel) + i++; + if(f->collapsed) { + if(i < 0 && f != a->sel) { + f->collapsed = False; + send_to_area(f->view->area, f); + continue; } + i--; + } + fp=&f->anext; } - if(hdiff < 0) - hdiff = 0; - hdiff /= frame_size; - yoff = a->rect.y + hdiff / 2; + + i = num_uncol; for(f=a->frame; f; f=f->anext) { - f->rect.y = yoff; - if(a->mode != Colmax || f == a->sel) - yoff = r_south(&f->rect) + hdiff; - } -} + f->rect.x = a->rect.x; + f->rect.width = a->rect.width; + if(!f->collapsed) { + i--; + f->rect.height = (float)f->crect.height / dy * surplus; + if(!i) + f->rect.height = surplus; + f->rect.height += min_height + frame_delta_h(); + match_sizehints(f->client, &f->rect, False, NWEST); -void -scale_column(Area *a, float h) { - uint yoff, frame_size = 0; - Frame *f; - uint min_height = 2 * labelh(&def.font); - float scale, dy = 0; - int hdiff; + dy -= f->crect.height; + surplus -= f->rect.height - frame_delta_h() - min_height; + }else + f->rect.height = labelh(&def.font); + } - if(!a->frame) - return; - for(f=a->frame; f; f=f->anext, frame_size++) - dy += f->rect.height; - scale = h / dy; - yoff = 0; + yoff = a->rect.y; + i = num_uncol; for(f=a->frame; f; f=f->anext) { - f->rect.height *= scale; - if(!f->anext) - f->rect.height = h - yoff; - yoff += f->rect.height; - } - /* min_height can only be respected when there is enough space; the caller should guarantee this */ - if(frame_size * min_height > h) - return; - yoff = 0; - for(f=a->frame, frame_size--; f; f=f->anext, frame_size--) { - if(f->rect.height < min_height) - f->rect.height = min_height; - else if((hdiff = yoff + f->rect.height - h + frame_size * min_height) > 0) - f->rect.height -= hdiff; - if(!f->anext) - f->rect.height = h - yoff; - yoff += f->rect.height; + f->rect.y = yoff; + if(f->collapsed) + yoff += f->rect.height; + else{ + i--; + f->rect.height += surplus / num_uncol; + if(!i) + f->rect.height += surplus % num_uncol; + yoff += f->rect.height; + } } } void arrange_column(Area *a, Bool dirty) { Frame *f; - uint num_frames = 0, yoff = a->rect.y, h; - uint min_height = 2 * labelh(&def.font); if(a->floating || !a->frame) return; - for(f=a->frame; f; f=f->anext) - num_frames++; + switch(a->mode) { case Coldefault: - h = a->rect.height / num_frames; - if(h < min_height) - goto Fallthrough; - if(dirty) { - for(f=a->frame; f; f=f->anext) - f->rect.height = h; - } - scale_column(a, a->rect.height); for(f=a->frame; f; f=f->anext) { - f->rect.x = a->rect.x; - f->rect.y = yoff; - f->rect.width = a->rect.width; - yoff += f->rect.height; + f->collapsed = False; + if(dirty) + f->crect.height = 100; } break; case Colstack: - h = a->rect.height - (num_frames - 1) * labelh(&def.font); - if(h < 3 * labelh(&def.font)) - goto Fallthrough; for(f=a->frame; f; f=f->anext) { - f->rect = a->rect; - f->rect.y = yoff; + f->collapsed = True; if(f == a->sel) - f->rect.height = h; - else - f->rect.height = labelh(&def.font); - yoff += f->rect.height; + f->collapsed = False; } break; -Fallthrough: case Colmax: - for(f=a->frame; f; f=f->anext) { + for(f=a->frame; f; f=f->anext) f->rect = a->rect; - } - break; + goto resize; default: break; } - relax_column(a); + scale_column(a); +resize: for(f=a->frame; f; f=f->anext) resize_client(f->client, &f->rect); flush_masked_events(EnterWindowMask); @@ -245,7 +245,7 @@ resize_column(Client *c, XRectangle *new) { a->rect.x = new->x; match_horiz(a, &a->rect); match_horiz(west, &west->rect); - relax_column(west); + //relax_column(west); } if(east && !(sticky & EAST)) { east->rect.width -= r_east(new) - east->rect.x; @@ -253,7 +253,7 @@ 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); + //relax_column(east); } AfterHorizontal: /* skip vertical resize unless the column is in equal mode */ @@ -296,7 +296,7 @@ AfterHorizontal: resize_frame(south, &south->rect); } AfterVertical: - relax_column(a); + //relax_column(a); focus_view(screen, v); } diff --git a/config.mk b/config.mk @@ -14,7 +14,7 @@ X11LIB = /usr/X11R6/lib # includes and libs INCS = -I. -I${PREFIX}/include -I/usr/include -I${X11INC} -LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -L${PREFIX}/lib -lixp +LIBS = -L/usr/lib -lc -lm -L${X11LIB} -lX11 -L${PREFIX}/lib -lixp # flags #CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\" diff --git a/draw.c b/draw.c @@ -54,10 +54,10 @@ loadfont(Blitz *blitz, BlitzFont *font) { font->xfont = XLoadQueryFont(blitz->dpy, fontname); if (!font->xfont) { if(!strncmp(fontname, BLITZ_FONT, sizeof(BLITZ_FONT))) - ixp_eprint("wmiiwm: error, cannot load '%s' font\n", + fatal("wmiiwm: error, cannot load '%s' font\n", BLITZ_FONT); free(font->fontstr); - font->fontstr = ixp_estrdup(BLITZ_FONT); + font->fontstr = estrdup(BLITZ_FONT); loadfont(blitz, font); return; } @@ -108,6 +108,8 @@ draw_label(BlitzBrush *b, char *text) { buf[--len] = 0; shortened = True; } + if(!len) + return; if(w > b->rect.width) return; /* mark shortened info in the string */ diff --git a/event.c b/event.c @@ -6,6 +6,7 @@ #include <stdlib.h> #include <string.h> #include <X11/keysym.h> +#include "printevent.h" uint flush_masked_events(long even_mask) { @@ -70,7 +71,8 @@ buttonpress(XEvent *e) { restack_view(f->view); if(ispointinrect(ev->x, ev->y, &f->grabbox.rect)) do_mouse_resize(f->client, True, CENTER); - else if(!ispointinrect(ev->x, ev->y, &f->titlebar.rect)) + else if(!ev->subwindow + && !ispointinrect(ev->x, ev->y, &f->titlebar.rect)) do_mouse_resize(f->client, False, quadofcoord(&f->client->rect, ev->x, ev->y)); if(f->client != sel_client()) @@ -94,11 +96,8 @@ configurerequest(XEvent *e) { wc.y = ev->y; wc.width = ev->width; wc.height = ev->height; - wc.border_width = 0; - wc.sibling = None; - wc.stack_mode = Above; - ev->value_mask &= ~CWSibling; + ev->value_mask &= ~(CWSibling|CWStackMode); if(c) { gravitate_client(c, True); if(ev->value_mask & CWX) @@ -258,6 +257,52 @@ unmapnotify(XEvent *e) { destroy_client(c); } +static void +focusin(XEvent *e) { +#if 0 + Client *c; + XFocusChangeEvent *ev = &e->xfocus; + + c = client_of_win(ev->window); + if(ev->mode == NotifyGrab) { + screen->focus = nil; + if(!c) + focus_client(nil); + else + focus(c, False); + }if(ev->mode == NotifyUngrab) { + if(c) + focus(c, False); + screen->focus = c; + }else if(c) { + screen->focus = c; + if(c != sel_client()) { + focus_client(sel_client()); + } + } +#endif +} + +static void +focusout(XEvent *e) { +#if 0 + Client *c; + XFocusChangeEvent *ev = &e->xfocus; + + c = client_of_win(ev->window); + if(ev->mode == NotifyUngrab + || ev->mode == NotifyGrab) + return; + else if(c) { + screen->focus = c; + /* Don't let clients grab focus */ + if(c != sel_client()) { + focus_client(sel_client()); + } + } +#endif +} + void (*handler[LASTEvent]) (XEvent *) = { [ButtonPress] = buttonpress, [ButtonRelease] = buttonrelease, @@ -270,7 +315,9 @@ void (*handler[LASTEvent]) (XEvent *) = { [MappingNotify] = mappingnotify, [MapRequest] = maprequest, [PropertyNotify]= propertynotify, - [UnmapNotify] = unmapnotify + [UnmapNotify] = unmapnotify, + [FocusIn] = focusin, + [FocusOut] = focusout }; void @@ -278,6 +325,8 @@ check_x_event(IXPConn *c) { XEvent ev; while(XPending(blz.dpy)) { /* main event loop */ XNextEvent(blz.dpy, &ev); + if(verbose) + printevent(&ev); if(handler[ev.type]) (handler[ev.type]) (&ev); /* call handler */ } diff --git a/frame.c b/frame.c @@ -8,7 +8,7 @@ Frame * create_frame(Client *c, View *v) { static ushort id = 1; - Frame *f = ixp_emallocz(sizeof(Frame)); + Frame *f = emallocz(sizeof(Frame)); f->id = id++; f->client = c; @@ -21,7 +21,7 @@ create_frame(Client *c, View *v) { c->sel = f; f->revert = f->rect = c->rect; f->revert.width = f->rect.width += 2 * def.border; - f->revert.height = f->rect.height += def.border + labelh(&def.font); + f->revert.height = f->rect.height += frame_delta_h(); } f->collapsed = False; f->tile.blitz = &blz; @@ -84,8 +84,29 @@ resize_frame(Frame *f, XRectangle *r) { stickycorner = get_sticky(&f->rect, r); f->rect = *r; + f->crect = *r; + match_sizehints(c, &f->crect, f->area->floating, stickycorner); + if(f->area->floating) - match_sizehints(c, &f->rect, f->area->floating, stickycorner); + f->rect = f->crect; + if(!f->collapsed) { + f->crect.width -= def.border * 2; + f->crect.height -= frame_delta_h(); + } + 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((f->crect.width == screen->rect.width) && + (f->crect.height == screen->rect.height)) { + f->rect.x = -def.border; + f->rect.y = -labelh(&def.font); + }else + check_frame_constraints(&f->rect); + } } Bool @@ -180,10 +201,9 @@ focus_frame(Frame *f, Bool restack) { if(v != screen->sel) return; - if(a == old_a) { - focus_client(f->client); + focus_client(f->client); + if(a == old_a) draw_frame(f); - } else if(old_in_a) draw_frame(old_in_a); @@ -198,6 +218,11 @@ focus_frame(Frame *f, Bool restack) { restack_view(v); } +int +frame_delta_h() { + return def.border + labelh(&def.font); +} + void update_frame_widget_colors(Frame *f) { if(f->area->sel == f) { diff --git a/fs.c b/fs.c @@ -142,7 +142,7 @@ get_file() { FileId *temp; if(!free_fileid) { uint i = 15; - temp = ixp_emallocz(sizeof(FileId) * i); + temp = emallocz(sizeof(FileId) * i); for(; i; i--) { temp->next = free_fileid; free_fileid = temp++; @@ -181,7 +181,7 @@ write_buf(P9Req *r, void *buf, uint len) { len -= r->ifcall.offset; if(len > r->ifcall.count) len = r->ifcall.count; - r->ofcall.data = ixp_emalloc(len); + r->ofcall.data = emalloc(len); memcpy(r->ofcall.data, buf + r->ifcall.offset, len); r->ofcall.count = len; } @@ -204,7 +204,7 @@ write_to_buf(P9Req *r, void *buf, uint *len, uint max) { *len = offset + count; if(max == 0) { - *(void **)buf = ixp_erealloc(*(void **)buf, *len + 1); + *(void **)buf = erealloc(*(void **)buf, *len + 1); buf = *(void **)buf; } @@ -219,7 +219,7 @@ data_to_cstring(P9Req *r) { uint i; i = r->ifcall.count; if(!i || r->ifcall.data[i - 1] != '\n') - r->ifcall.data = ixp_erealloc(r->ifcall.data, ++i); + r->ifcall.data = erealloc(r->ifcall.data, ++i); assert(r->ifcall.data); r->ifcall.data[i - 1] = '\0'; } @@ -255,7 +255,7 @@ message_root(char *message) else if(!strncmp(message, "font ", 5)) { message += 5; free(def.font.fontstr); - def.font.fontstr = ixp_estrdup(message); + def.font.fontstr = estrdup(message); loadfont(&blz, &def.font); resize_bar(screen); } @@ -327,7 +327,7 @@ write_event(char *format, ...) { for(f=pending_event_fids; f; f=f->next) { fi = f->fid->aux; slen = fi->content.buf ? strlen(fi->content.buf) : 0; - fi->content.buf = (char *) ixp_erealloc(fi->content.buf, slen + len + 1); + fi->content.buf = (char *) erealloc(fi->content.buf, slen + len + 1); (fi->content.buf)[slen] = '\0'; strcat(fi->content.buf, buffer); } @@ -387,7 +387,7 @@ lookup_file(FileId *parent, char *name) file->id = c->win; file->index = c->win; file->tab = *dir; - file->tab.name = ixp_estrdup("sel"); + file->tab.name = estrdup("sel"); }if(name) goto LastItem; } if(name) { @@ -402,7 +402,7 @@ lookup_file(FileId *parent, char *name) file->content.client = c; file->id = c->win; file->tab = *dir; - file->tab.name = ixp_emallocz(16); + file->tab.name = emallocz(16); snprintf(file->tab.name, 16, "0x%x", (uint)c->win); if(name) goto LastItem; } @@ -417,7 +417,7 @@ lookup_file(FileId *parent, char *name) file->content.view = screen->sel; file->id = screen->sel->id; file->tab = *dir; - file->tab.name = ixp_estrdup("sel"); + file->tab.name = estrdup("sel"); }if(name) goto LastItem; } for(v=view; v; v=v->next) { @@ -428,7 +428,7 @@ lookup_file(FileId *parent, char *name) file->content.view = v; file->id = v->id; file->tab = *dir; - file->tab.name = ixp_estrdup(v->name); + file->tab.name = estrdup(v->name); if(name) goto LastItem; } } @@ -442,7 +442,7 @@ lookup_file(FileId *parent, char *name) file->content.bar = b; file->id = b->id; file->tab = *dir; - file->tab.name = ixp_estrdup(b->name); + file->tab.name = estrdup(b->name); if(name) goto LastItem; } } @@ -457,7 +457,7 @@ lookup_file(FileId *parent, char *name) file->content.ref = parent->content.ref; file->index = parent->index; file->tab = *dir; - file->tab.name = ixp_estrdup(file->tab.name); + file->tab.name = estrdup(file->tab.name); /* Special considerations: */ switch(file->tab.type) { case FsDBars: @@ -489,7 +489,7 @@ void fs_attach(P9Req *r) { FileId *f = get_file(); f->tab = dirtab[FsRoot][0]; - f->tab.name = ixp_estrdup("/"); + f->tab.name = estrdup("/"); f->content.ref = nil; /* shut up valgrind */ r->fid->aux = f; r->fid->qid.type = f->tab.qtype; @@ -575,7 +575,7 @@ fs_stat(P9Req *r) { dostat(&s, fs_size(r->fid->aux), r->fid->aux); r->ofcall.nstat = size = ixp_sizeof_stat(&s); - buf = ixp_emallocz(size); + buf = emallocz(size); r->ofcall.stat = buf; ixp_pack_stat(&buf, &size, &s); respond(r, nil); @@ -594,7 +594,7 @@ fs_read(P9Req *r) { Stat s; offset = 0; size = r->ifcall.count; - buf = ixp_emallocz(size); + buf = emallocz(size); r->ofcall.data = buf; tf = f = lookup_file(f, nil); /* Note: f->tab.name == "." so we skip it */ @@ -653,7 +653,7 @@ fs_read(P9Req *r) { respond(r, nil); return; } - r->ofcall.data = ixp_emallocz(16); + r->ofcall.data = emallocz(16); n = snprintf(r->ofcall.data, 16, "0x%x", (uint)f->index); assert(n >= 0); r->ofcall.count = n; @@ -732,7 +732,7 @@ fs_write(P9Req *r) { data_to_cstring(r); { uint n; char *toks[32]; - n = ixp_tokenize(toks, 32, r->ifcall.data, '\n'); + n = tokenize(toks, 32, r->ifcall.data, '\n'); for(i = 0; i < n; i++) { if(errstr) message_root(toks[i]); @@ -768,7 +768,7 @@ fs_open(P9Req *r) { switch(f->tab.type) { case FsFEvent: - fl = ixp_emallocz(sizeof(FidLink)); + fl = emallocz(sizeof(FidLink)); fl->fid = r->fid; fl->next = pending_event_fids; pending_event_fids = fl; diff --git a/geom.c b/geom.c @@ -5,8 +5,8 @@ Bool ispointinrect(int x, int y, XRectangle * r) { - return (x >= r->x) && (x <= r->x + r->width) - && (y >= r->y) && (y <= r->y + r->height); + return (x >= r->x) && (x <= r_east(r)) + && (y >= r->y) && (y <= r_south(r)); } BlitzAlign diff --git a/key.c b/key.c @@ -77,7 +77,8 @@ ungrab_key(Key *k) { static Key * name2key(const char *name) { Key *k; - for(k=key; k && strncmp(k->name, name, sizeof(k->name)); k=k->lnext); + for(k=key; k; k=k->lnext) + if(!strncmp(k->name, name, sizeof(k->name))) break; return k; } @@ -95,12 +96,12 @@ get_key(const char *name) { return k; } strncpy(buf, name, sizeof(buf)); - toks = ixp_tokenize(seq, 8, buf, ','); + toks = tokenize(seq, 8, buf, ','); for(i = 0; i < toks; i++) { if(!k) - r = k = ixp_emallocz(sizeof(Key)); + r = k = emallocz(sizeof(Key)); else { - k->next = ixp_emallocz(sizeof(Key)); + k->next = emallocz(sizeof(Key)); k = k->next; } strncpy(k->name, name, sizeof(k->name)); diff --git a/libcext/estrdup.c b/libcext/estrdup.c @@ -1,21 +0,0 @@ -/* - * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> - * See LICENSE file for license details. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include "cext.h" - -char * -cext_estrdup(const char *s) -{ - char *tmp; - - tmp = (char *) cext_emallocz(strlen(s) + 1); - strcpy(tmp, (char *) s); - - return tmp; -} diff --git a/main.c b/main.c @@ -27,7 +27,7 @@ static char version[] = "wmiiwm - " VERSION ", (C)opyright MMIV-MMVI Anselm R. G static void usage() { - ixp_eprint("usage: wmiiwm -a <address> [-r <wmiirc>] [-v]\n"); + fatal("usage: wmiiwm -a <address> [-r <wmiirc>] [-v]\n"); } static void @@ -157,7 +157,7 @@ init_screen(WMScreen *screen) { int wmii_error_handler(Display *dpy, XErrorEvent *error) { if(check_other_wm) - ixp_eprint("wmiiwm: another window manager is already running\n"); + fatal("wmiiwm: another window manager is already running\n"); if(error->error_code == BadWindow || (error->request_code == X_SetInputFocus && error->error_code == BadMatch) @@ -231,7 +231,7 @@ main(int argc, char *argv[]) { blz.dpy = XOpenDisplay(0); if(!blz.dpy) - ixp_eprint("wmiiwm: cannot open dpy\n"); + fatal("wmiiwm: cannot open dpy\n"); blz.screen = DefaultScreen(blz.dpy); blz.root = RootWindow(blz.dpy, blz.screen); @@ -244,19 +244,19 @@ main(int argc, char *argv[]) { /* Check namespace permissions */ if(!strncmp(address, "unix!", 5)) { struct stat st; - namespace = ixp_estrdup(&address[5]); + namespace = estrdup(&address[5]); for(i = strlen(namespace) - 1; i >= 0; i--) if(namespace[i] == '/') break; namespace[i+1] = '\0'; if(stat(namespace, &st)) - ixp_eprint("wmiiwm: can't stat namespace directory \"%s\": %s\n", + fatal("wmiiwm: can't stat namespace directory \"%s\": %s\n", namespace, strerror(errno)); if(getuid() != st.st_uid) - ixp_eprint("wmiiwm: namespace directory \"%s\" exists, " + fatal("wmiiwm: namespace directory \"%s\" exists, " "but is not owned by you", namespace); if(st.st_mode & 077) - ixp_eprint("wmiiwm: namespace directory \"%s\" exists, " + fatal("wmiiwm: namespace directory \"%s\" exists, " "but has group or world permissions", namespace); free(namespace); @@ -265,7 +265,7 @@ main(int argc, char *argv[]) { errstr = nil; i = ixp_create_sock(address, &errstr); if(i < 0) - ixp_eprint("wmiiwm: fatal: %s\n", errstr); + fatal("wmiiwm: fatal: %s\n", errstr); /* start wmiirc */ if(wmiirc) { @@ -275,12 +275,12 @@ main(int argc, char *argv[]) { switch(fork()) { case 0: if(setsid() == -1) - ixp_eprint("wmiiwm: can't setsid: %s\n", strerror(errno)); + fatal("wmiiwm: can't setsid: %s\n", strerror(errno)); close(i); close(ConnectionNumber(blz.dpy)); snprintf(execstr, name_len, "exec %s", wmiirc); execl("/bin/sh", "sh", "-c", execstr, nil); - ixp_eprint("wmiiwm: can't exec \"%s\": %s\n", wmiirc, strerror(errno)); + fatal("wmiiwm: can't exec \"%s\": %s\n", wmiirc, strerror(errno)); case -1: perror("wmiiwm: cannot fork wmiirc"); default: @@ -297,14 +297,14 @@ main(int argc, char *argv[]) { client = nil; key = nil; passwd = getpwuid(getuid()); - user = ixp_estrdup(passwd->pw_name); + user = estrdup(passwd->pw_name); def.colrules.string = nil; def.colrules.size = 0; def.tagrules.string = nil; def.tagrules.size = 0; def.keys = nil; def.keyssz = 0; - def.font.fontstr = ixp_estrdup(BLITZ_FONT); + def.font.fontstr = estrdup(BLITZ_FONT); def.border = 1; def.colmode = Coldefault; strncpy(def.selcolor.colstr, BLITZ_SELCOLORS, sizeof(def.selcolor.colstr)); @@ -318,7 +318,7 @@ main(int argc, char *argv[]) { loadfont(&blz, &def.font); init_lock_keys(); num_screens = 1; - screens = ixp_emallocz(num_screens * sizeof(*screens)); + screens = emallocz(num_screens * sizeof(*screens)); for(i = 0; i < num_screens; i++) { s = &screens[i]; s->lbar = nil; @@ -327,7 +327,8 @@ main(int argc, char *argv[]) { init_screen(s); pmap = XCreatePixmap(blz.dpy, blz.root, s->rect.width, s->rect.height, DefaultDepth(blz.dpy, blz.screen)); - wa.event_mask = SubstructureRedirectMask | EnterWindowMask | LeaveWindowMask; + wa.event_mask = SubstructureRedirectMask | EnterWindowMask | LeaveWindowMask + | FocusChangeMask; wa.cursor = cursor[CurNormal]; XChangeWindowAttributes(blz.dpy, blz.root, CWEventMask | CWCursor, &wa); wa.override_redirect = 1; @@ -359,6 +360,8 @@ main(int argc, char *argv[]) { screen = &screens[0]; + screen->focus = (void*)-1; + focus_client(nil); scan_wins(); starting = False; update_views(); diff --git a/mouse.c b/mouse.c @@ -191,7 +191,7 @@ find_droppoint(Frame *frame, int x, int y, XRectangle *rect, Bool do_move) { if(do_move) { a = new_column(v, a_prev, 0); - send_to_area(a, frame->area, frame); + send_to_area(a, frame); focus(frame->client, False); } return; @@ -202,7 +202,7 @@ find_droppoint(Frame *frame, int x, int y, XRectangle *rect, Bool do_move) { if(do_move) { a = new_column(v, a, 0); - send_to_area(a, frame->area, frame); + send_to_area(a, frame); focus(frame->client, False); } return; @@ -232,7 +232,7 @@ find_droppoint(Frame *frame, int x, int y, XRectangle *rect, Bool do_move) { if(frame == f) return; if(a != frame->area) - send_to_area(a, frame->area, frame); + send_to_area(a, frame); remove_frame(frame); insert_frame(f, frame, True); focus(frame->client, True); @@ -248,7 +248,7 @@ find_droppoint(Frame *frame, int x, int y, XRectangle *rect, Bool do_move) { if(frame == f) return; if(a != frame->area) - send_to_area(a, frame->area, frame); + send_to_area(a, frame); remove_frame(frame); insert_frame(f, frame, False); focus(frame->client, True); @@ -378,7 +378,7 @@ do_mouse_resize(Client *c, Bool grabbox, BlitzAlign align) { hr_x = screen->rect.width / 2; hr_y = screen->rect.height / 2; XWarpPointer(blz.dpy, None, blz.root, 0, 0, 0, 0, hr_x, hr_y); - while(XCheckMaskEvent(blz.dpy, MouseMask, &ev)); + while(XCheckMaskEvent(blz.dpy, PointerMotionMask, &ev)); } diff --git a/rule.c b/rule.c @@ -68,7 +68,7 @@ update_rules(Rule **rule, const char *data) { break; case VALUE: if(*p == '\n' || *p == 0) { - *rule = ixp_emallocz(sizeof(Rule)); + *rule = emallocz(sizeof(Rule)); *v = 0; trim(value, " \t/"); if(!regcomp(&(*rule)->regex, regex, 0)) { diff --git a/util.c b/util.c @@ -1,3 +1,70 @@ +/* Written by Kris Maglione <fbsdaemon at gmail dot com> */ +/* Public domain */ +#include "wmii.h" +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +void +fatal(const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + exit(1); +} + +void * +emalloc(uint size) { + void *ret = malloc(size); + if(!ret) + fatal("fatal: could not malloc() %d bytes\n", size); + return ret; +} + +void * +emallocz(uint size) { + void *ret = emalloc(size); + memset(ret, 0, size); + return ret; +} + +void * +erealloc(void *ptr, uint size) { + void *ret = realloc(ptr, size); + if(!ret) + fatal("fatal: could not realloc() %d bytes\n", size); + return ret; +} + +char * +estrdup(const char *str) { + void *ret = strdup(str); + if(!ret) + fatal("fatal: could not strdup() %u bytes\n", strlen(str)); + return ret; +} + +uint +tokenize(char *res[], uint reslen, char *str, char delim) { + char *s; + uint i; + + i = 0; + s = str; + while(i < reslen && *s) { + while(*s == delim) + *(s++) = '\0'; + if(*s) + res[i++] = s; + while(*s && *s != delim) + s++; + } + return i; +} int max(int a, int b) { diff --git a/view.c b/view.c @@ -58,7 +58,7 @@ get_view(const char *name) { View * create_view(const char *name) { static ushort id = 1; - View **i, *v = ixp_emallocz(sizeof(View)); + View **i, *v = emallocz(sizeof(View)); v->id = id++; strncpy(v->name, name, sizeof(v->name)); @@ -174,7 +174,7 @@ restack_view(View *v) { for(c=client; c; c=c->next, i++); if(i >= winssz) { winssz = 2 * i; - wins = ixp_erealloc(wins, sizeof(Window) * winssz); + wins = erealloc(wins, sizeof(Window) * winssz); } wins[0] = screen->barwin; @@ -259,8 +259,7 @@ rects_of_view(View *v, uint *num, Frame *ignore) { i = 2; for(f=v->area->frame; f; f=f->anext); i++; - result = ixp_emallocz(i * sizeof(XRectangle)); - + result = emallocz(i * sizeof(XRectangle)); i = 0; for(f=v->area->frame; f; f=f->anext) if(f != ignore) @@ -422,7 +421,7 @@ newcolw_of_view(View *v) { char buf[256]; char *toks[16]; strncpy(buf, r->value, sizeof(buf)); - n = ixp_tokenize(toks, 16, buf, '+'); + n = tokenize(toks, 16, buf, '+'); for(a=v->area, i=0; a; a=a->next) i++; if(n && n >= i) { diff --git a/wmii.h b/wmii.h @@ -137,6 +137,7 @@ struct Frame { Area *area; ushort id; XRectangle rect; + XRectangle crect; XRectangle revert; Client *client; Bool collapsed; @@ -269,9 +270,9 @@ extern void destroy_area(Area *a); extern Area *area_of_id(View *t, ushort id); extern void focus_area(Area *a); extern char *select_area(Area *a, char *arg); -extern void send_to_area(Area *to, Area *from, Frame *f); +extern void send_to_area(Area *to, Frame *f); extern void attach_to_area(Area *a, Frame *f, Bool send); -extern void detach_from_area(Area *a, Frame *f); +extern void detach_from_area(Frame *f); extern Client *sel_client_of_area(Area *a); /* bar.c */ @@ -313,7 +314,6 @@ extern void apply_tags(Client *c, const char *tags); /* column.c */ extern void arrange_column(Area *a, Bool dirty); -extern void scale_column(Area *a, float h); extern void resize_column(Client *c, XRectangle *r); extern int column_mode_of_str(char *arg); extern char *str_of_column_mode(int mode); @@ -346,6 +346,7 @@ extern void insert_frame(Frame *pos, Frame *f, Bool before); extern void resize_frame(Frame *f, XRectangle *r); extern Bool frame_to_top(Frame *f); extern void swap_frames(Frame *fa, Frame *fb); +extern int frame_delta_h(); extern void draw_frame(Frame *f); extern void draw_frames(); extern void update_frame_widget_colors(Frame *f); @@ -392,6 +393,12 @@ extern void update_rules(Rule **rule, const char *data); extern void trim(char *str, const char *chars); /* util.c */ +extern uint tokenize(char *res[], uint reslen, char *str, char delim); +extern char *estrdup(const char *str); +extern void *erealloc(void *ptr, uint size); +extern void *emallocz(uint size); +extern void *emalloc(uint size); +extern void fatal(const char *fmt, ...); extern int max(int a, int b); extern char *str_nil(char *s);