diff --git a/README b/README index e61cc999..b88915d2 100644 --- a/README +++ b/README @@ -76,6 +76,7 @@ The following people have contributed especially to wmii in various ways: - Norman Golisz - Stefano K. Lee - Stefan Tibus +- Neptun References diff --git a/TODO.wmii-4 b/TODO.wmii-4 index 41980410..5d8c6199 100644 --- a/TODO.wmii-4 +++ b/TODO.wmii-4 @@ -6,8 +6,9 @@ - tagbars - slot will be similiar to old wmi-10 slot, a separate window at the right side of the screen - MWM/EWMH handling to support borderless apps? -- implement client/id file, change /client/ namespace to /client// - consider a Focus event whenever a client is focused - screen dimension rescaling if screen resolution changes (even with Xrandr) - Xinerama support - partly EWMH support +- libixp: idea from PoP: implement a va_args method similiar to printf for + marshalling 9P messages, might reduce LOC drastically diff --git a/cmd/wm/area.c b/cmd/wm/area.c index 194d9386..f1f9e425 100644 --- a/cmd/wm/area.c +++ b/cmd/wm/area.c @@ -142,7 +142,7 @@ select_area(Area *a, char *arg) } new = v->area.data[i]; if(new->frame.size) - focus_client(new->frame.data[new->sel]->client); + focus_client(new->frame.data[new->sel]->client, True); v->sel = i; for(i = 0; i < a->frame.size; i++) draw_client(a->frame.data[i]->client); @@ -154,7 +154,7 @@ send_to_area(Area *to, Area *from, Client *c) c->revert = from; detach_from_area(from, c); attach_to_area(to, c); - focus_client(c); + focus_client(c, True); } void diff --git a/cmd/wm/client.c b/cmd/wm/client.c index 329f1172..9c8f0671 100644 --- a/cmd/wm/client.c +++ b/cmd/wm/client.c @@ -10,7 +10,7 @@ #include "wm.h" -#define CLIENT_MASK (StructureNotifyMask | PropertyChangeMask) +#define CLIENT_MASK (StructureNotifyMask | PropertyChangeMask | EnterWindowMask) static Vector * vector_of_clients(ClientVector *cv) @@ -75,7 +75,7 @@ create_client(Window w, XWindowAttributes *wa) fwa.override_redirect = 1; fwa.background_pixmap = ParentRelative; fwa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask - | EnterWindowMask | ExposureMask | ButtonPressMask | ButtonReleaseMask; + | ExposureMask | ButtonPressMask | ButtonReleaseMask; c->framewin = XCreateWindow(dpy, root, c->rect.x, c->rect.y, c->rect.width + 2 * def.border, @@ -101,24 +101,29 @@ set_client_state(Client * c, int state) } void -focus_client(Client *c) +focus_client(Client *c, Bool restack) { Client *old = sel_client(); Frame *f = c->frame.data[c->sel]; View *v = f->area->view; int i = idx_of_area(f->area); + static char buf[256]; v->sel = i; f->area->sel = idx_of_frame(f); if(old) draw_client(old); - restack_view(v); + if(restack) + restack_view(v); XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); draw_client(c); XSync(dpy, False); if(i > 0 && f->area->mode == Colstack) arrange_column(f->area, False); + snprintf(buf, sizeof(buf), "ClientFocus %d %s\n", + idx_of_client_id(c->id), c->name); + write_event(buf); } void @@ -364,7 +369,7 @@ manage_client(Client *c) reparent_client(c, c->framewin, c->rect.x, c->rect.y); update_views(); - flush_enter_events(); + flush_events(EnterWindowMask); } static int @@ -401,7 +406,7 @@ destroy_client(Client *c) XSync(dpy, False); XSetErrorHandler(wmii_error_handler); XUngrabServer(dpy); - flush_enter_events(); + flush_events(EnterWindowMask); } Client * @@ -508,8 +513,8 @@ select_client(Client *c, char *arg) if(errstr) return; } - focus_client(a->frame.data[i]->client); - flush_enter_events(); + focus_client(a->frame.data[i]->client, True); + flush_events(EnterWindowMask); } void @@ -565,8 +570,8 @@ Swaparea: } if(idx_of_area(a)) arrange_column(a, False); - focus_client(c); - flush_enter_events(); + focus_client(c, True); + flush_events(EnterWindowMask); } void @@ -616,7 +621,7 @@ send_client_to(Client *c, char *arg) to = v->area.data[i]; } send_to_area(to, a, c); - flush_enter_events(); + flush_events(EnterWindowMask); } void @@ -632,12 +637,12 @@ resize_all_clients() resize_client(c, &c->frame.data[c->sel]->rect, False); } } - flush_enter_events(); + flush_events(EnterWindowMask); } /* convenience function */ void -focus(Client *c) +focus(Client *c, Bool restack) { Frame *f = c->frame.size ? c->frame.data[c->sel] : nil; View *v; @@ -648,7 +653,7 @@ focus(Client *c) v = f->area->view; if(view.data[sel] != v) focus_view(v); - focus_client(c); + focus_client(c, restack); } int diff --git a/cmd/wm/column.c b/cmd/wm/column.c index 0573084a..731e1610 100644 --- a/cmd/wm/column.c +++ b/cmd/wm/column.c @@ -338,7 +338,7 @@ drop_moving(Frame *f, XRectangle *new, XPoint *pt) src->frame.data[j] = src->frame.data[i]; src->frame.data[i] = tmp; arrange_column(src, False); - focus_client(f->client); + focus_client(f->client, True); } } } diff --git a/cmd/wm/event.c b/cmd/wm/event.c index c12c7c9f..9d924040 100644 --- a/cmd/wm/event.c +++ b/cmd/wm/event.c @@ -57,10 +57,10 @@ check_x_event(IXPConn *c) } void -flush_enter_events() +flush_events(long even_mask) { XEvent ev; - while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); + while(XCheckMaskEvent(dpy, even_mask, &ev)); } static void @@ -97,7 +97,7 @@ handle_buttonpress(XEvent *e) if(ev->state & def.mod) { if((ev->button == Button1 || ev->button == Button3) && (sel_client() != c)) - focus(c); + focus(c, True); if(ev->button == Button1) do_mouse_move(c); else if (ev->button == Button3) { @@ -110,7 +110,7 @@ handle_buttonpress(XEvent *e) } else if(ev->button == Button1) { if(sel_client() != c) - focus(c); + focus(c, True); } } } @@ -211,9 +211,9 @@ handle_enternotify(XEvent *e) if(ev->mode != NotifyNormal || ev->detail == NotifyInferior) return; - if((c = frame_of_win(ev->window))) { + if((c = client_of_win(ev->window))) { if(c != sel_client_of_view(view.data[sel])) - focus(c); + focus(c, False); } } diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c index 414a99c1..28d9bbf4 100644 --- a/cmd/wm/fs.c +++ b/cmd/wm/fs.c @@ -62,6 +62,7 @@ enum { WMII_IOUNIT = 2048 }; * /view/1/mode FsFmode column mode * /view/1/sel/ FsDclient * /view/1/1/class FsFclass class:instance of client + * /view/1/1/index FsFindex index of client in /client * /view/1/1/name FsFname name of client * /view/1/1/tags FsFtags tag of client * /view/1/geom FsFgeom geometry of client @@ -216,15 +217,25 @@ qid2name(Qid *qid) return "tags"; break; case FsFclass: + case FsFindex: case FsFname: if((qid->dir_type == FsDclient) && (i1 == -1 || i2 == -1 || i3 == -1)) return nil; else if(i1 == -1) return nil; - if(type == FsFname) + switch(type) { + case FsFname: return "name"; - else + break; + case FsFclass: return "class"; + break; + case FsFindex: + return "index"; + break; + default: + break; + } break; case FsFmode: if((qid->dir_type == FsDarea) && (i1 == -1 || i2 == -1)) @@ -237,6 +248,7 @@ qid2name(Qid *qid) case FsFevent: return "event"; break; default: return nil; break; } + return nil; } static unsigned char @@ -259,8 +271,10 @@ name2type(char *name, unsigned char dir_type) return FsFctl; if(!strncmp(name, "event", 6)) return FsFevent; - if(!strncmp(name, "class", 5)) + if(!strncmp(name, "class", 6)) return FsFclass; + if(!strncmp(name, "index", 6)) + return FsFindex; if(!strncmp(name, "name", 5)) return FsFname; if(!strncmp(name, "border", 7)) @@ -413,6 +427,7 @@ mkqid(Qid *dir, char *wname, Qid *new) break; case FsFgeom: case FsFname: + case FsFindex: case FsFclass: if(dir_type == FsDroot) return -1; @@ -522,6 +537,15 @@ type2stat(Stat *stat, char *wname, Qid *dir) else return mkstat(stat, dir, wname, strlen(client.data[dir_i1]->classinst), IXP_DMREAD); break; + case FsFindex: + if(dir_type == FsDclient) { + f = view.data[dir_i1]->area.data[dir_i2]->frame.data[dir_i3]; + snprintf(buf, sizeof(buf), "%d", idx_of_client_id(f->client->id)); + } + else + snprintf(buf, sizeof(buf), "%d", dir_i1); + return mkstat(stat, dir, wname, strlen(buf), IXP_DMREAD); + break; case FsFname: if(dir_type == FsDclient) { f = view.data[dir_i1]->area.data[dir_i2]->frame.data[dir_i3]; @@ -1046,6 +1070,8 @@ xread(IXPConn *c, Fcall *fcall) p = ixp_enc_stat(p, &stat); fcall->count += type2stat(&stat, "name", &m->qid); p = ixp_enc_stat(p, &stat); + fcall->count += type2stat(&stat, "index", &m->qid); + p = ixp_enc_stat(p, &stat); fcall->count += type2stat(&stat, "tags", &m->qid); p = ixp_enc_stat(p, &stat); fcall->count += type2stat(&stat, "geom", &m->qid); @@ -1090,6 +1116,15 @@ xread(IXPConn *c, Fcall *fcall) memcpy(p, client.data[i1]->classinst, fcall->count); } break; + case FsFindex: + if(m->qid.dir_type == FsDclient) + snprintf(buf, sizeof(buf), "%d", + idx_of_client_id(view.data[i1]->area.data[i2]->frame.data[i3]->client->id)); + else + snprintf(buf, sizeof(buf), "%d", i1); + if((fcall->count = strlen(buf))) + memcpy(p, buf, fcall->count); + break; case FsFname: if(m->qid.dir_type == FsDclient) { if((fcall->count = strlen(view.data[i1]->area.data[i2]->frame.data[i3]->client->name))) diff --git a/cmd/wm/view.c b/cmd/wm/view.c index 0daca571..fce9413c 100644 --- a/cmd/wm/view.c +++ b/cmd/wm/view.c @@ -86,7 +86,7 @@ focus_view(View *v) /* gives all(!) clients proper geometry (for use of different tags) */ if((c = sel_client_of_view(v))) - focus_client(c); + focus_client(c, True); for(i = 0; i < client.size; i++) if(client.data[i]->frame.size) { Frame *f = client.data[i]->frame.data[client.data[i]->sel]; @@ -103,7 +103,7 @@ focus_view(View *v) update_view_bars(); XSync(dpy, False); XUngrabServer(dpy); - flush_enter_events(); + flush_events(EnterWindowMask); } XRectangle * diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h index e7755d4e..8388aea6 100644 --- a/cmd/wm/wm.h +++ b/cmd/wm/wm.h @@ -61,6 +61,7 @@ enum { FsFclass, FsFmode, FsFtags, + FsFindex, FsFcolw }; @@ -220,8 +221,8 @@ void unmap_client(Client *c); void map_client(Client *c); void reparent_client(Client *c, Window w, int x, int y); void manage_client(Client *c); -void focus_client(Client *c); -void focus(Client *c); +void focus_client(Client *c, Bool restack); +void focus(Client *c, Bool restack); void resize_client(Client *c, XRectangle *r, Bool ignore_xcall); void select_client(Client *c, char *arg); void send_client_to(Client *c, char *arg); @@ -244,7 +245,7 @@ Area *new_right_column(View *v); /* event.c */ void init_x_event_handler(); void check_x_event(IXPConn *c); -void flush_enter_events(); +void flush_events(long even_mask); /* frame.c */ Frame *create_frame(Area *a, Client *c); diff --git a/liblitz/font.c b/liblitz/font.c index d434bf1e..5bda1568 100644 --- a/liblitz/font.c +++ b/liblitz/font.c @@ -43,7 +43,7 @@ blitz_loadfont(Display *dpy, BlitzFont *font, char *fontstr) font->set = XCreateFontSet(dpy, fontname, &missing, &nmissing, &def); if(missing) { - while(nmissing--) + while(nmissing--) fprintf(stderr, "liblitz: missing fontset: %s\n", missing[nmissing]); XFreeStringList(missing); }