added protocol killing stuff 33996500
Anselm R. Garbe · 2006-07-11 16:14 6 file(s) · +153 −36
client.c +26 −7
10 10
#include "util.h"
11 11
#include "wm.h"
12 12
13 -
static void
14 -
update_client_name(Client *c)
13 +
void
14 +
update_name(Client *c)
15 15
{
16 16
	XTextProperty name;
17 17
	int n;
38 38
}
39 39
40 40
void
41 +
focus(Client *c)
42 +
{
43 +
	Client **l;
44 +
	for(l=&stack; *l && *l != c; l=&(*l)->snext);
45 +
	eassert(*l == c);
46 +
	*l = c->snext;
47 +
	c->snext = stack;
48 +
	stack = c;
49 +
	XRaiseWindow(dpy, c->win);
50 +
	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
51 +
	XFlush(dpy);
52 +
}
53 +
54 +
void
41 55
manage(Window w, XWindowAttributes *wa)
42 56
{
43 57
	Client *c, **l;
59 73
		(c->size.flags & PMinSize && c->size.flags & PMaxSize
60 74
		 && c->size.min_width == c->size.max_width
61 75
		 && c->size.min_height == c->size.max_height);
62 -
	update_client_name(c);
76 +
	update_name(c);
63 77
	twa.override_redirect = 1;
64 78
	twa.background_pixmap = ParentRelative;
65 79
	twa.event_mask = ExposureMask;
73 87
	for(l=&clients; *l; l=&(*l)->next);
74 88
	c->next = *l; /* *l == nil */
75 89
	*l = c;
76 -
	XMapRaised(dpy, c->win);
77 -
	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
78 -
	XFlush(dpy);
90 +
	c->snext = stack;
91 +
	stack = c;
92 +
	XMapWindow(dpy, c->win);
93 +
	focus(c);
79 94
}
80 95
81 96
static int
98 113
	for(l=&clients; *l && *l != c; l=&(*l)->next);
99 114
	eassert(*l == c);
100 115
	*l = c->next;
116 +
	for(l=&stack; *l && *l != c; l=&(*l)->snext);
117 +
	eassert(*l == c);
118 +
	*l = c->snext;
101 119
	free(c);
102 120
103 121
	XFlush(dpy);
104 122
	XSetErrorHandler(error_handler);
105 123
	XUngrabServer(dpy);
106 -
	/*flush_masked_events(EnterWindowMask); ? */
124 +
	flush_events(EnterWindowMask);
107 125
}
108 126
109 127
116 134
			return c;
117 135
	return NULL;
118 136
}
137 +
cmd.c +14 −0
18 18
	fputs("quit\n", stderr);
19 19
	running = False;
20 20
}
21 +
22 +
void
23 +
kill(char *arg)
24 +
{
25 +
	Client *c = stack;
26 +
27 +
	if(!c)
28 +
		return;
29 +
	if(c->proto & WM_PROTOCOL_DELWIN)
30 +
		send_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
31 +
	else
32 +
		XKillClient(dpy, c->win);
33 +
}
34 +
event.c +33 −17
7 7
#include <stdlib.h>
8 8
#include <string.h>
9 9
#include <X11/keysym.h>
10 +
#include <X11/Xatom.h>
10 11
11 12
#include "wm.h"
12 13
35 36
};
36 37
37 38
unsigned int
38 -
flush_masked_events(long even_mask)
39 +
flush_events(long even_mask)
39 40
{
40 41
	XEvent ev;
41 42
	unsigned int n = 0;
91 92
static void
92 93
enternotify(XEvent *e)
93 94
{
94 -
#if 0
95 95
	XCrossingEvent *ev = &e->xcrossing;
96 96
	Client *c;
97 97
98 98
	if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
99 99
		return;
100 100
101 -
	if((c = client_of_win(ev->window))) {
102 -
		Frame *f = c->sel;
103 -
		Area *a = f->area;
104 -
		if(a->mode == Colmax)
105 -
			c = a->sel->client;
106 -
		focus(c, False);
107 -
	}
101 +
	if((c = getclient(ev->window)))
102 +
		focus(c);
108 103
	else if(ev->window == root) {
109 104
		sel_screen = True;
110 -
		draw_frames();
105 +
		/*draw_frames();*/
111 106
	}
112 -
#endif
113 107
}
114 108
115 109
static void
137 131
static void
138 132
keymapnotify(XEvent *e)
139 133
{
140 -
#if 0
141 134
	update_keys();
142 -
#endif
143 135
}
144 136
145 137
static void
164 156
static void
165 157
propertynotify(XEvent *e)
166 158
{
167 -
#if 0
168 159
	XPropertyEvent *ev = &e->xproperty;
160 +
	long msize;
169 161
	Client *c;
170 162
171 163
	if(ev->state == PropertyDelete)
172 164
		return; /* ignore */
173 165
174 -
	if((c = client_of_win(ev->window)))
175 -
		prop_client(c, ev);
176 -
#endif
166 +
	if(ev->atom == wm_atom[WMProtocols]) {
167 +
		c->proto = win_proto(c->win);
168 +
		return;
169 +
	}
170 +
	if((c = getclient(ev->window))) {
171 +
		switch (ev->atom) {
172 +
			default: break;
173 +
			case XA_WM_TRANSIENT_FOR:
174 +
				XGetTransientForHint(dpy, c->win, &c->trans);
175 +
				break;
176 +
			case XA_WM_NORMAL_HINTS:
177 +
				if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize)
178 +
						|| !c->size.flags)
179 +
					c->size.flags = PSize;
180 +
				if(c->size.flags & PMinSize && c->size.flags & PMaxSize
181 +
						&& c->size.min_width == c->size.max_width
182 +
						&& c->size.min_height == c->size.max_height)
183 +
					c->fixedsize = True;
184 +
				else
185 +
					c->fixedsize = False;
186 +
				break;
187 +
		}
188 +
		if(ev->atom == XA_WM_NAME || ev->atom == net_atom[NetWMName]) {
189 +
			update_name(c);
190 +
			/*draw_frame(c->sel);*/
191 +
		}
192 +
	}
177 193
}
178 194
179 195
static void
menu.c +1 −1
304 304
		}
305 305
		break;
306 306
	default:
307 -
		if((num == 1) && !iscntrl((int) buf[0])) {
307 +
		if(num && !iscntrl((int) buf[0])) {
308 308
			buf[num] = 0;
309 309
			if(len > 0)
310 310
				strncat(text, buf, sizeof(text));
wm.c +62 −4
16 16
/* X structs */
17 17
Display *dpy;
18 18
Window root, barwin;
19 -
Atom net_atom[NetLast];
19 +
Atom wm_atom[WMLast], net_atom[NetLast];
20 20
Cursor cursor[CurLast];
21 21
XRectangle rect, barrect;
22 22
Bool running = True;
23 +
Bool sel_screen;
23 24
24 25
char *bartext, tag[256];
25 -
int screen, sel_screen;
26 +
int screen;
26 27
27 28
Brush brush = {0};
28 29
Client *clients = NULL;
29 -
30 -
enum { WM_PROTOCOL_DELWIN = 1 };
30 +
Client *stack = NULL;
31 31
32 32
static Bool other_wm_running;
33 33
static char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
62 62
		XFree(wins);
63 63
}
64 64
65 +
static int
66 +
win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
67 +
{
68 +
	Atom real;
69 +
	int format;
70 +
	unsigned long res, extra;
71 +
	int status;
72 +
73 +
	status = XGetWindowProperty(dpy, w, a, 0L, l, False, t, &real, &format,
74 +
			&res, &extra, prop);
75 +
76 +
	if(status != Success || *prop == 0) {
77 +
		return 0;
78 +
	}
79 +
	if(res == 0) {
80 +
		free((void *) *prop);
81 +
	}
82 +
	return res;
83 +
}
84 +
85 +
int
86 +
win_proto(Window w)
87 +
{
88 +
	Atom *protocols;
89 +
	long res;
90 +
	int protos = 0;
91 +
	int i;
92 +
93 +
	res = win_property(w, wm_atom[WMProtocols], XA_ATOM, 20L,
94 +
			((unsigned char **) &protocols));
95 +
	if(res <= 0) {
96 +
		return protos;
97 +
	}
98 +
	for(i = 0; i < res; i++) {
99 +
		if(protocols[i] == wm_atom[WMDelete])
100 +
			protos |= WM_PROTOCOL_DELWIN;
101 +
	}
102 +
	free((char *) protocols);
103 +
	return protos;
104 +
}
105 +
106 +
void
107 +
send_message(Window w, Atom a, long value)
108 +
{
109 +
	XEvent e;
110 +
111 +
	e.type = ClientMessage;
112 +
	e.xclient.window = w;
113 +
	e.xclient.message_type = a;
114 +
	e.xclient.format = 32;
115 +
	e.xclient.data.l[0] = value;
116 +
	e.xclient.data.l[1] = CurrentTime;
117 +
	XSendEvent(dpy, w, False, NoEventMask, &e);
118 +
	XFlush(dpy);
119 +
}
120 +
65 121
/*
66 122
 * There's no way to check accesses to destroyed windows, thus
67 123
 * those cases are ignored (especially on UnmapNotify's).
160 216
	x_error_handler = XSetErrorHandler(error_handler);
161 217
162 218
	/* init atoms */
219 +
	wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
220 +
	wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
163 221
	net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
164 222
	net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
165 223
wm.h +17 −7
9 9
10 10
#include <X11/Xutil.h>
11 11
12 +
#define WM_PROTOCOL_DELWIN 1
13 +
12 14
/* atoms */
15 +
enum { WMProtocols, WMDelete, WMLast };
13 16
enum { NetSupported, NetWMName, NetLast };
14 17
15 18
/* cursor */
25 28
	char name[256];
26 29
	char tag[256];
27 30
	unsigned int border;
31 +
	int proto;
28 32
	Bool fixedsize;
29 33
	Window win;
30 34
	Window trans;
44 48
45 49
extern Display *dpy;
46 50
extern Window root, barwin;
47 -
extern Atom net_atom[NetLast];
51 +
extern Atom wm_atom[WMLast], net_atom[NetLast];
48 52
extern Cursor cursor[CurLast];
49 53
extern XRectangle rect, barrect;
50 -
extern Bool running;
51 -
extern Bool grid;
54 +
extern Bool running, sel_screen, grid;
52 55
extern void (*handler[LASTEvent]) (XEvent *);
53 56
54 -
extern int screen, sel_screen;
57 +
extern int screen;
55 58
extern char *bartext, tag[256];
56 59
57 60
extern Brush brush;
58 -
extern Client *clients;
61 +
extern Client *clients, *stack;
59 62
60 63
/* bar.c */
61 64
extern void draw_bar();
66 69
67 70
/* client.c */
68 71
extern void manage(Window w, XWindowAttributes *wa);
69 -
void unmanage(Client *c);
70 -
extern Client * getclient(Window w);
72 +
extern void unmanage(Client *c);
73 +
extern Client *getclient(Window w);
74 +
extern void focus(Client *c);
75 +
extern void update_name(Client *c);
76 +
77 +
/* event.c */
78 +
extern unsigned int flush_events(long even_mask);
71 79
72 80
/* key.c */
73 81
extern void update_keys();
75 83
76 84
/* wm.c */
77 85
extern int error_handler(Display *dpy, XErrorEvent *error);
86 +
extern void send_message(Window w, Atom a, long value);
87 +
extern int win_proto(Window w);