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:
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);