wmii

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

commit 625246858d0ce09215f5720f9d7822be57774392
parent fb1d7443a17a638b8912319d5f444e3986f22b09
Author: Kris Maglione <kris@suckless.org>
Date:   Wed,  2 Jun 2010 02:09:23 -0400

Ping clients regularly to make the "unresponsive" message more responsive. Please notify me of any performance problems caused by this change.

Diffstat:
cmd/wmii/client.c | 7+++----
cmd/wmii/dat.h | 4+++-
cmd/wmii/ewmh.c | 79+++++++++++++++++++++++++++++++++++--------------------------------------------
include/stuff/util.h | 1+
include/stuff/x11.h | 4++--
lib/libstuff/Makefile | 1+
lib/libstuff/util/nsec.c | 13+++++++++++++
lib/libwmii_hack/hack.c | 10+++++-----
rc/wmiirc.sh | 2+-
9 files changed, 64 insertions(+), 57 deletions(-)

diff --git a/cmd/wmii/client.c b/cmd/wmii/client.c @@ -624,7 +624,7 @@ client_configure(Client *c) { void client_message(Client *c, char *msg, long l2) { - sendmessage(&c->w, "WM_PROTOCOLS", xatom(msg), xtime, l2, 0, 0); + sendmessage(&c->w, "WM_PROTOCOLS", xatom(msg), event_xtime, l2, 0, 0); } void @@ -633,6 +633,7 @@ client_kill(Client *c, bool nice) { ulong *pid; long n; + c->dead = 1; if(!nice) { getprop_textlist(&c->w, "WM_CLIENT_MACHINE", &host); n = getprop_ulong(&c->w, Net("WM_PID"), "CARDINAL", 0, &pid, 1); @@ -643,10 +644,8 @@ client_kill(Client *c, bool nice) { XKillClient(display, c->w.xid); } - else if(c->proto & ProtoDelete) { + else if(c->proto & ProtoDelete) client_message(c, "WM_DELETE_WINDOW", 0); - ewmh_pingclient(c); - } else XKillClient(display, c->w.xid); } diff --git a/cmd/wmii/dat.h b/cmd/wmii/dat.h @@ -25,6 +25,8 @@ enum { PingTime = 10000, + PingPeriod = 2000, + PingPartition = 20, }; enum IncMode { @@ -166,6 +168,7 @@ struct Client { char props[512]; long proto; uint border; + int dead; int fullscreen; bool floating; bool fixedsize; @@ -345,7 +348,6 @@ EXTERN long ignoreenter; EXTERN bool resizing; EXTERN int starting; EXTERN char* user; -EXTERN long xtime; EXTERN Client* kludge; diff --git a/cmd/wmii/ewmh.c b/cmd/wmii/ewmh.c @@ -9,6 +9,7 @@ Window *ewmhwin; static void ewmh_getwinstate(Client*); static void ewmh_setstate(Client*, Atom, int); +static void tick(long, void*); static Handlers client_handlers; static Handlers root_handlers; @@ -27,12 +28,13 @@ ewmh_init(void) { changeprop_long(ewmhwin, Net("SUPPORTING_WM_CHECK"), "WINDOW", &win, 1); changeprop_string(ewmhwin, Net("WM_NAME"), myname); - long zz[] = {0, 0}; changeprop_long(&scr.root, Net("DESKTOP_VIEWPORT"), "CARDINAL", - zz, 2); + (long[2]){0, 0}, 2); pushhandler(&scr.root, &root_handlers, nil); + tick(0L, nil); + long supported[] = { /* Misc */ NET("SUPPORTED"), @@ -45,6 +47,7 @@ ewmh_init(void) { NET("WM_DESKTOP"), NET("WM_FULLSCREEN_MONITORS"), NET("WM_NAME"), + NET("WM_PID"), NET("WM_STRUT"), NET("WM_STRUT_PARTIAL"), /* States */ @@ -73,6 +76,31 @@ ewmh_init(void) { changeprop_long(&scr.root, Net("SUPPORTED"), "ATOM", supported, nelem(supported)); } +static void +tick(long id, void *v) { + static int count; + Client *c; + ulong time; + int mod, i; + + time = nsec() / 1000000; + count++; + mod = count % PingPartition; + for(i=0, c=client; c; c=c->next, i++) + if(c->proto & ProtoPing) { + if(c->dead == 1 && time - c->w.ewmh.ping > PingTime) { + event("Unresponsive %#C\n", c); + c->dead++; + } + if(i % PingPartition == mod) + sendmessage(&c->w, "WM_PROTOCOLS", NET("WM_PING"), time, c->w.xid, 0, 0); + if(i % PingPartition == mod) + Dprint(DEwmh, "_NET_WM_PING %#C %,uld\n", c, time); + } + + ixp_settimer(&srv, PingPeriod / PingPartition, tick, nil); +} + void ewmh_updateclientlist(void) { Vector_long vec; @@ -135,9 +163,6 @@ ewmh_destroyclient(Client *c) { ewmh_updateclientlist(); e = &c->w.ewmh; - if(e->timer) - if(!ixp_unsettimer(&srv, e->timer)) - fprint(2, "Badness: %#C: Can't unset timer\n", c); free(c->strut); } @@ -209,33 +234,6 @@ static Handlers client_handlers = { .property = event_client_property, }; -static void -pingtimeout(long id, void *v) { - Client *c; - - USED(id); - c = v; - event("Unresponsive %#C\n", c); - c->w.ewmh.ping = 0; - c->w.ewmh.timer = 0; -} - -void -ewmh_pingclient(Client *c) { - Ewmh *e; - - if(!(c->proto & ProtoPing)) - return; - - e = &c->w.ewmh; - if(e->ping) - return; - - client_message(c, Net("WM_PING"), c->w.xid); - e->ping = xtime++; - e->timer = ixp_settimer(&srv, PingTime, pingtimeout, c); -} - bool ewmh_prop(Client *c, Atom a) { if(a == NET("WM_WINDOW_TYPE")) @@ -402,7 +400,6 @@ ewmh_setstate(Client *c, Atom state, int action) { static bool event_root_clientmessage(Window *w, void *aux, XClientMessageEvent *e) { - Client *c; View *v; ulong *l; ulong msg; @@ -426,20 +423,14 @@ event_root_clientmessage(Window *w, void *aux, XClientMessageEvent *e) { if(msg == xatom("WM_PROTOCOLS")) { if(e->format != 32) return false; - Dprint(DEwmh, "\t%A\n", l[0]); if(l[0] == NET("WM_PING")) { if(e->window != scr.root.xid) return false; - c = win2client(l[2]); - if(c == nil) - return 1; - Dprint(DEwmh, "\tclient = [%#C]\"%C\"\n", c, c); - Dprint(DEwmh, "\ttimer = %ld, ping = %ld\n", - c->w.ewmh.timer, c->w.ewmh.ping); - if(c->w.ewmh.timer) - ixp_unsettimer(&srv, c->w.ewmh.timer); - c->w.ewmh.timer = 0; - c->w.ewmh.ping = 0; + if(!(w = findwin(l[2]))) + return false; + w->ewmh.ping = nsec() / 1000000; + w->ewmh.lag = (w->ewmh.ping & 0xffffffff) - (l[1] & 0xffffffff); + Dprint(DEwmh, "\twindow=%W lag=%,uld\n", w, w->ewmh.lag); return false; } return false; diff --git a/include/stuff/util.h b/include/stuff/util.h @@ -55,6 +55,7 @@ void grep(char**, Reprog*, int); char* join(char**, char*, Fmt*); int max(int, int); int min(int, int); +uvlong nsec(void); char* pathsearch(const char*, const char*, bool); void refree(Regex*); void reinit(Regex*, char*); diff --git a/include/stuff/x11.h b/include/stuff/x11.h @@ -75,8 +75,8 @@ struct ErrorCode { struct Ewmh { long type; - long ping; - long timer; + ulong ping; + ulong lag; }; struct Font { diff --git a/lib/libstuff/Makefile b/lib/libstuff/Makefile @@ -63,6 +63,7 @@ OBJ=\ util/max \ util/mfatal \ util/min \ + util/nsec \ util/pathsearch \ util/refree \ util/reinit \ diff --git a/lib/libstuff/util/nsec.c b/lib/libstuff/util/nsec.c @@ -0,0 +1,13 @@ +/* Written by Kris Maglione <maglione.k at Gmail> */ +/* Public domain */ +#include "util.h" +#include <sys/time.h> + +uvlong +nsec(void) { + struct timeval tv; + + gettimeofday(&tv, nil); + return (uvlong)tv.tv_sec * 1000000000 + (uvlong)tv.tv_sec * 1000; +} + diff --git a/lib/libwmii_hack/hack.c b/lib/libwmii_hack/hack.c @@ -26,7 +26,7 @@ static char** tags; static long pid; static long stime; static char hostname[256]; -static long nsec; +static long starttime; typedef Window (*mapfn)(Display*, Window); @@ -84,7 +84,7 @@ init(Display *d) { /* Hrm... assumes one display... */ } pid = getpid(); - gethostname(hostname, sizeof hostname); + gethostname(hostname, sizeof hostname - 1); } static void @@ -102,9 +102,9 @@ setprops(Display *d, Window w) { } /* Kludge. */ - if(nsec == 0) - nsec = time(0); - else if(time(0) > nsec + Timeout) + if(starttime == 0) + starttime = time(0); + else if(time(0) > starttime + Timeout) return; if(transient) diff --git a/rc/wmiirc.sh b/rc/wmiirc.sh @@ -93,7 +93,7 @@ Event Unresponsive client=$1; shift msg="The following client is not responding. What would you like to do?$wi_newline" resp=$(wihack -transient $client \ - xmessage -nearmouse -buttons Kill,Wait -print + xmessage -nearmouse -buttons Kill,Wait -print \ -fn "${WMII_FONT%%,*}" "$msg $(wmiir read /client/sel/label)") if [ "$resp" = Kill ]; then wmiir xwrite /client/$client/ctl slay &