wmii

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

commit 4f13adf6fd52a77ee571433f6d442ef03d606de0
parent 874228cf1aaea0a1ac60ea0166df6b3dea94b166
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Tue, 11 Jul 2006 16:15:01 +0200

readded wm_atom's again, necessary to not kill complete apps when sending kill to a popup


Diffstat:
cmd/wm/client.c | 25++++++++++++++++++++++++-
cmd/wm/wm.c | 44++++++++++++++++++++++++++++++++++++++++++++
cmd/wm/wm.h | 10++++++++++
3 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/cmd/wm/client.c b/cmd/wm/client.c @@ -100,6 +100,7 @@ create_client(Window w, XWindowAttributes *wa) c->rect.width = wa->width; c->rect.height = wa->height; XSetWindowBorderWidth(blz.dpy, c->win, 0); + c->proto = win_proto(c->win); XGetTransientForHint(blz.dpy, c->win, &c->trans); if(!XGetWMNormalHints(blz.dpy, c->win, &c->size, &msize) || !c->size.flags) c->size.flags = PSize; @@ -240,10 +241,28 @@ configure_client(Client *c) XSync(blz.dpy, False); } +static void +send_client_message(Window w, Atom a, long value) +{ + XEvent e; + e.type = ClientMessage; + e.xclient.window = w; + e.xclient.message_type = a; + e.xclient.format = 32; + e.xclient.data.l[0] = value; + e.xclient.data.l[1] = CurrentTime; + + XSendEvent(blz.dpy, w, False, NoEventMask, &e); + XSync(blz.dpy, False); +} + void kill_client(Client * c) { - XKillClient(blz.dpy, c->win); + if(c->proto & WM_PROTOCOL_DELWIN) + send_client_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]); + else + XKillClient(blz.dpy, c->win); } void @@ -251,6 +270,10 @@ prop_client(Client *c, XPropertyEvent *e) { long msize; + if(e->atom == wm_atom[WMProtocols]) { + c->proto = win_proto(c->win); + return; + } switch (e->atom) { case XA_WM_TRANSIENT_FOR: XGetTransientForHint(blz.dpy, c->win, &c->trans); diff --git a/cmd/wm/wm.c b/cmd/wm/wm.c @@ -63,9 +63,53 @@ scan_wins() XFree(wins); } +static int +win_property(Window w, Atom a, Atom t, long l, unsigned char **prop) +{ + Atom real; + int format; + unsigned long res, extra; + int status; + + status = XGetWindowProperty(blz.dpy, w, a, 0L, l, False, t, &real, &format, + &res, &extra, prop); + + if(status != Success || *prop == 0) { + return 0; + } + if(res == 0) { + free((void *) *prop); + } + return res; +} + +int +win_proto(Window w) +{ + Atom *protocols; + long res; + int protos = 0; + int i; + + res = win_property(w, wm_atom[WMProtocols], XA_ATOM, 20L, + ((unsigned char **) &protocols)); + if(res <= 0) { + return protos; + } + for(i = 0; i < res; i++) { + if(protocols[i] == wm_atom[WMDelete]) + protos |= WM_PROTOCOL_DELWIN; + } + free((char *) protocols); + return protos; +} + + static void init_atoms() { + wm_atom[WMProtocols] = XInternAtom(blz.dpy, "WM_PROTOCOLS", False); + wm_atom[WMDelete] = XInternAtom(blz.dpy, "WM_DELETE_WINDOW", False); net_atom[NetSupported] = XInternAtom(blz.dpy, "_NET_SUPPORTED", False); net_atom[NetWMName] = XInternAtom(blz.dpy, "_NET_WM_NAME", False); tags_atom = XInternAtom(blz.dpy, "_WIN_TAGS", False); diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h @@ -11,6 +11,13 @@ #include <ixp.h> #include <blitz.h> +/* WM atoms */ +enum { + WMProtocols, + WMDelete, + WMLast +}; + /* NET atoms */ enum { NetSupported, @@ -94,6 +101,7 @@ struct Client { char props[512]; unsigned short id; unsigned int border; + int proto; Bool floating; Bool fixedsize; Window win; @@ -180,6 +188,7 @@ unsigned int num_screens; Blitz blz; GC xorgc; char *user; +Atom wm_atom[WMLast]; Atom net_atom[NetLast]; Atom tags_atom; Cursor cursor[CurLast]; @@ -315,3 +324,4 @@ unsigned int newcolw_of_view(View *v); /* wm.c */ int wmii_error_handler(Display *dpy, XErrorEvent *error); +int win_proto(Window w);