void (*eventfns[LASTEvent])(XEvent*);
} XConf;
+enum {
+ F_WM_DELETE = (1 << 0)
+};
+
typedef struct Client {
struct Client* next;
char* name;
Window frame, win;
- int x, y, w, h;
+ int flags, x, y, w, h;
} Client;
enum {
void die(char* str);
void* ecalloc(size_t n, size_t sz);
void xfree(void* p);
+Atom atom(char* str);
+void sendmsg(Window win, Atom proto, Atom type);
client_readprops(c);
/* get normal hints ? */
- /* get registered protocols */
/* get transient_for property ? */
/* set client flags appropriately */
- /* get size and position */
- /* Find monitor, add to that monitors cspace */
+
+
+ /* get registered protocols */
+ Atom* protos;
+ int nprotos;
+ if (XGetWMProtocols(X.disp, c->win, &protos, &nprotos) != 0)
+ {
+ for (int i = 0; i < nprotos; i++)
+ {
+ if (protos[i] == atom("WM_DELETE_WINDOW"))
+ {
+ c->flags |= F_WM_DELETE;
+ }
+ }
+ xfree(protos);
+ }
+
/* Reparent the window if applicable */
c->frame = XCreateSimpleWindow(X.disp, X.root,
void client_close(Client* c)
{
- /* TODO: handle wm_delete client message here */
- XKillClient(X.disp, c->win);
+ if (c->flags & F_WM_DELETE)
+ {
+ sendmsg(c->win, atom("WM_PROTOCOLS"), atom("WM_DELETE_WINDOW"));
+ }
+ else
+ {
+ XKillClient(X.disp, c->win);
+ }
}
void client_focus(Client* c)
XFree(p);
}
}
+
+Atom atom(char* str)
+{
+ return XInternAtom(X.disp, str, False);
+}
+
+void sendmsg(Window win, Atom proto, Atom type)
+{
+ XEvent ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.xclient.type = ClientMessage;
+ ev.xclient.window = win;
+ ev.xclient.message_type = proto;
+ ev.xclient.format = 32;
+ ev.xclient.data.l[0] = type;
+ ev.xclient.data.l[1] = CurrentTime;
+ XSendEvent(X.disp, win, False, 0, &ev);
+ XSync(X.disp, False);
+}
+