1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/* aewm - a minimalistic X11 window manager. ------- vim:sw=4:et
* Copyright (c) 1998-2001 Decklin Foster <decklin@red-bean.com>
* Free software! Please see README for details and license. */
#include "aewm.h"
#include <X11/Xmd.h>
Client *head_client = NULL;
Client *find_client(Window w)
{
Client *c;
for (c = head_client; c; c = c->next)
if (c->window == w) return c;
return NULL;
}
void set_focus_on(Window w)
{
char *name;
XFetchName(dpy, w, &name);
if (name && strcmp(name, "skip")) {
XSetInputFocus(dpy, w, RevertToPointerRoot, CurrentTime);
#ifdef DEBUG
printf("aewm-drakx: adding %ld %s\n", w, name);
#endif
}
}
/* Attempt to follow the ICCCM by explicity specifying 32 bits for
* this property. Does this goof up on 64 bit systems? */
void set_wm_state(Client *c, int state)
{
CARD32 data[2];
data[0] = state;
data[1] = None; /* Icon? We don't need no steenking icon. */
XChangeProperty(dpy, c->window, wm_state, wm_state,
32, PropModeReplace, (unsigned char *)data, 2);
}
/* If we can't find a WM_STATE we're going to have to assume
* Withdrawn. This is not exactly optimal, since we can't really
* distinguish between the case where no WM has run yet and when the
* state was explicitly removed (Clients are allowed to either set the
* atom to Withdrawn or just remove it... yuck.) */
long get_wm_state(Client *c)
{
Atom real_type; int real_format;
unsigned long items_read, items_left;
long *data, state = WithdrawnState;
if (XGetWindowProperty(dpy, c->window, wm_state, 0L, 2L, False,
wm_state, &real_type, &real_format, &items_read, &items_left,
(unsigned char **) &data) == Success && items_read) {
state = *data;
XFree(data);
}
return state;
}
void remove_client(Client *c)
{
int ignore_xerror(Display *dpy, XErrorEvent *e) { return 0; }
Client *p;
XGrabServer(dpy);
XSetErrorHandler(ignore_xerror);
set_wm_state(c, WithdrawnState);
if (head_client == c) head_client = c->next;
else for (p = head_client; p && p->next; p = p->next)
if (p->next == c) p->next = c->next;
free(c);
if (head_client) set_focus_on(head_client->window);
XSync(dpy, False);
XSetErrorHandler(handle_xerror);
XUngrabServer(dpy);
}
void make_new_client(Window w)
{
Client *c;
XWindowAttributes attr;
c = malloc(sizeof *c);
c->next = head_client;
c->window = w;
head_client = c;
XGrabServer(dpy);
XGetWindowAttributes(dpy, w, &attr);
if (attr.map_state != IsViewable) {
XWMHints *hints;
set_wm_state(c, NormalState);
if ((hints = XGetWMHints(dpy, w))) {
if (hints->flags & StateHint) set_wm_state(c, hints->initial_state);
XFree(hints);
}
}
if (attr.map_state == IsViewable) {
XMapWindow(dpy, c->window);
set_wm_state(c, NormalState);
} else if (get_wm_state(c) == NormalState) {
XMapWindow(dpy, c->window);
}
set_focus_on(w);
XSync(dpy, False);
XUngrabServer(dpy);
}
|