tadded protocol killing stuff - dwm - [fork] customized build of dwm, the dynam… | |
git clone git://src.adamsgaard.dk/dwm | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 33996500763b04119a6867dfa4040a4236c21a41 | |
parent 272e15c4b7bdeeb258caadb7c62e70c49c12b16d | |
Author: Anselm R. Garbe <[email protected]> | |
Date: Tue, 11 Jul 2006 16:14:22 +0200 | |
added protocol killing stuff | |
Diffstat: | |
M client.c | 33 ++++++++++++++++++++++++-----… | |
M cmd.c | 14 ++++++++++++++ | |
M event.c | 50 ++++++++++++++++++++---------… | |
M menu.c | 2 +- | |
M wm.c | 66 +++++++++++++++++++++++++++++… | |
M wm.h | 24 +++++++++++++++++------- | |
6 files changed, 153 insertions(+), 36 deletions(-) | |
--- | |
diff --git a/client.c b/client.c | |
t@@ -10,8 +10,8 @@ | |
#include "util.h" | |
#include "wm.h" | |
-static void | |
-update_client_name(Client *c) | |
+void | |
+update_name(Client *c) | |
{ | |
XTextProperty name; | |
int n; | |
t@@ -38,6 +38,20 @@ update_client_name(Client *c) | |
} | |
void | |
+focus(Client *c) | |
+{ | |
+ Client **l; | |
+ for(l=&stack; *l && *l != c; l=&(*l)->snext); | |
+ eassert(*l == c); | |
+ *l = c->snext; | |
+ c->snext = stack; | |
+ stack = c; | |
+ XRaiseWindow(dpy, c->win); | |
+ XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); | |
+ XFlush(dpy); | |
+} | |
+ | |
+void | |
manage(Window w, XWindowAttributes *wa) | |
{ | |
Client *c, **l; | |
t@@ -59,7 +73,7 @@ manage(Window w, XWindowAttributes *wa) | |
(c->size.flags & PMinSize && c->size.flags & PMaxSize | |
&& c->size.min_width == c->size.max_width | |
&& c->size.min_height == c->size.max_height); | |
- update_client_name(c); | |
+ update_name(c); | |
twa.override_redirect = 1; | |
twa.background_pixmap = ParentRelative; | |
twa.event_mask = ExposureMask; | |
t@@ -73,9 +87,10 @@ manage(Window w, XWindowAttributes *wa) | |
for(l=&clients; *l; l=&(*l)->next); | |
c->next = *l; /* *l == nil */ | |
*l = c; | |
- XMapRaised(dpy, c->win); | |
- XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); | |
- XFlush(dpy); | |
+ c->snext = stack; | |
+ stack = c; | |
+ XMapWindow(dpy, c->win); | |
+ focus(c); | |
} | |
static int | |
t@@ -98,12 +113,15 @@ unmanage(Client *c) | |
for(l=&clients; *l && *l != c; l=&(*l)->next); | |
eassert(*l == c); | |
*l = c->next; | |
+ for(l=&stack; *l && *l != c; l=&(*l)->snext); | |
+ eassert(*l == c); | |
+ *l = c->snext; | |
free(c); | |
XFlush(dpy); | |
XSetErrorHandler(error_handler); | |
XUngrabServer(dpy); | |
- /*flush_masked_events(EnterWindowMask); ? */ | |
+ flush_events(EnterWindowMask); | |
} | |
t@@ -116,3 +134,4 @@ getclient(Window w) | |
return c; | |
return NULL; | |
} | |
+ | |
diff --git a/cmd.c b/cmd.c | |
t@@ -18,3 +18,17 @@ quit(char *arg) | |
fputs("quit\n", stderr); | |
running = False; | |
} | |
+ | |
+void | |
+kill(char *arg) | |
+{ | |
+ Client *c = stack; | |
+ | |
+ if(!c) | |
+ return; | |
+ if(c->proto & WM_PROTOCOL_DELWIN) | |
+ send_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]); | |
+ else | |
+ XKillClient(dpy, c->win); | |
+} | |
+ | |
diff --git a/event.c b/event.c | |
t@@ -7,6 +7,7 @@ | |
#include <stdlib.h> | |
#include <string.h> | |
#include <X11/keysym.h> | |
+#include <X11/Xatom.h> | |
#include "wm.h" | |
t@@ -35,7 +36,7 @@ void (*handler[LASTEvent]) (XEvent *) = { | |
}; | |
unsigned int | |
-flush_masked_events(long even_mask) | |
+flush_events(long even_mask) | |
{ | |
XEvent ev; | |
unsigned int n = 0; | |
t@@ -91,25 +92,18 @@ destroynotify(XEvent *e) | |
static void | |
enternotify(XEvent *e) | |
{ | |
-#if 0 | |
XCrossingEvent *ev = &e->xcrossing; | |
Client *c; | |
if(ev->mode != NotifyNormal || ev->detail == NotifyInferior) | |
return; | |
- if((c = client_of_win(ev->window))) { | |
- Frame *f = c->sel; | |
- Area *a = f->area; | |
- if(a->mode == Colmax) | |
- c = a->sel->client; | |
- focus(c, False); | |
- } | |
+ if((c = getclient(ev->window))) | |
+ focus(c); | |
else if(ev->window == root) { | |
sel_screen = True; | |
- draw_frames(); | |
+ /*draw_frames();*/ | |
} | |
-#endif | |
} | |
static void | |
t@@ -137,9 +131,7 @@ expose(XEvent *e) | |
static void | |
keymapnotify(XEvent *e) | |
{ | |
-#if 0 | |
update_keys(); | |
-#endif | |
} | |
static void | |
t@@ -164,16 +156,40 @@ maprequest(XEvent *e) | |
static void | |
propertynotify(XEvent *e) | |
{ | |
-#if 0 | |
XPropertyEvent *ev = &e->xproperty; | |
+ long msize; | |
Client *c; | |
if(ev->state == PropertyDelete) | |
return; /* ignore */ | |
- if((c = client_of_win(ev->window))) | |
- prop_client(c, ev); | |
-#endif | |
+ if(ev->atom == wm_atom[WMProtocols]) { | |
+ c->proto = win_proto(c->win); | |
+ return; | |
+ } | |
+ if((c = getclient(ev->window))) { | |
+ switch (ev->atom) { | |
+ default: break; | |
+ case XA_WM_TRANSIENT_FOR: | |
+ XGetTransientForHint(dpy, c->win, &c->trans); | |
+ break; | |
+ case XA_WM_NORMAL_HINTS: | |
+ if(!XGetWMNormalHints(dpy, c->win, &c->size, &… | |
+ || !c->size.flags) | |
+ c->size.flags = PSize; | |
+ if(c->size.flags & PMinSize && c->size.flags &… | |
+ && c->size.min_width == c->siz… | |
+ && c->size.min_height == c->si… | |
+ c->fixedsize = True; | |
+ else | |
+ c->fixedsize = False; | |
+ break; | |
+ } | |
+ if(ev->atom == XA_WM_NAME || ev->atom == net_atom[NetWMName]) { | |
+ update_name(c); | |
+ /*draw_frame(c->sel);*/ | |
+ } | |
+ } | |
} | |
static void | |
diff --git a/menu.c b/menu.c | |
t@@ -304,7 +304,7 @@ kpress(XKeyEvent * e) | |
} | |
break; | |
default: | |
- if((num == 1) && !iscntrl((int) buf[0])) { | |
+ if(num && !iscntrl((int) buf[0])) { | |
buf[num] = 0; | |
if(len > 0) | |
strncat(text, buf, sizeof(text)); | |
diff --git a/wm.c b/wm.c | |
t@@ -16,18 +16,18 @@ | |
/* X structs */ | |
Display *dpy; | |
Window root, barwin; | |
-Atom net_atom[NetLast]; | |
+Atom wm_atom[WMLast], net_atom[NetLast]; | |
Cursor cursor[CurLast]; | |
XRectangle rect, barrect; | |
Bool running = True; | |
+Bool sel_screen; | |
char *bartext, tag[256]; | |
-int screen, sel_screen; | |
+int screen; | |
Brush brush = {0}; | |
Client *clients = NULL; | |
- | |
-enum { WM_PROTOCOL_DELWIN = 1 }; | |
+Client *stack = NULL; | |
static Bool other_wm_running; | |
static char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garb… | |
t@@ -62,6 +62,62 @@ 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(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; | |
+} | |
+ | |
+void | |
+send_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(dpy, w, False, NoEventMask, &e); | |
+ XFlush(dpy); | |
+} | |
+ | |
/* | |
* There's no way to check accesses to destroyed windows, thus | |
* those cases are ignored (especially on UnmapNotify's). | |
t@@ -160,6 +216,8 @@ main(int argc, char *argv[]) | |
x_error_handler = XSetErrorHandler(error_handler); | |
/* init atoms */ | |
+ wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); | |
+ wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); | |
net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); | |
net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); | |
diff --git a/wm.h b/wm.h | |
t@@ -9,7 +9,10 @@ | |
#include <X11/Xutil.h> | |
+#define WM_PROTOCOL_DELWIN 1 | |
+ | |
/* atoms */ | |
+enum { WMProtocols, WMDelete, WMLast }; | |
enum { NetSupported, NetWMName, NetLast }; | |
/* cursor */ | |
t@@ -25,6 +28,7 @@ struct Client { | |
char name[256]; | |
char tag[256]; | |
unsigned int border; | |
+ int proto; | |
Bool fixedsize; | |
Window win; | |
Window trans; | |
t@@ -44,18 +48,17 @@ struct Key { | |
extern Display *dpy; | |
extern Window root, barwin; | |
-extern Atom net_atom[NetLast]; | |
+extern Atom wm_atom[WMLast], net_atom[NetLast]; | |
extern Cursor cursor[CurLast]; | |
extern XRectangle rect, barrect; | |
-extern Bool running; | |
-extern Bool grid; | |
+extern Bool running, sel_screen, grid; | |
extern void (*handler[LASTEvent]) (XEvent *); | |
-extern int screen, sel_screen; | |
+extern int screen; | |
extern char *bartext, tag[256]; | |
extern Brush brush; | |
-extern Client *clients; | |
+extern Client *clients, *stack; | |
/* bar.c */ | |
extern void draw_bar(); | |
t@@ -66,8 +69,13 @@ extern void quit(char *arg); | |
/* client.c */ | |
extern void manage(Window w, XWindowAttributes *wa); | |
-void unmanage(Client *c); | |
-extern Client * getclient(Window w); | |
+extern void unmanage(Client *c); | |
+extern Client *getclient(Window w); | |
+extern void focus(Client *c); | |
+extern void update_name(Client *c); | |
+ | |
+/* event.c */ | |
+extern unsigned int flush_events(long even_mask); | |
/* key.c */ | |
extern void update_keys(); | |
t@@ -75,3 +83,5 @@ extern void keypress(XEvent *e); | |
/* wm.c */ | |
extern int error_handler(Display *dpy, XErrorEvent *error); | |
+extern void send_message(Window w, Atom a, long value); | |
+extern int win_proto(Window w); |