127 XSendEvent(dpy, w, False, NoEventMask, &e); |
143 XSendEvent(dpy, w, False, NoEventMask, &e); |
128 XFlush(dpy); |
144 XFlush(dpy); |
129 } |
145 } |
130 |
146 |
131 /* |
147 /* |
|
148 * Startup Error handler to check if another window manager |
|
149 * is already running. |
|
150 */ |
|
151 static int |
|
152 xerrorstart(Display *dsply, XErrorEvent *ee) |
|
153 { |
|
154 otherwm = True; |
|
155 return -1; |
|
156 } |
|
157 |
|
158 /* |
132 * There's no way to check accesses to destroyed windows, thus |
159 * There's no way to check accesses to destroyed windows, thus |
133 * those cases are ignored (especially on UnmapNotify's). |
160 * those cases are ignored (especially on UnmapNotify's). |
134 * Other types of errors call Xlib's default error handler, which |
161 * Other types of errors call Xlib's default error handler, which |
135 * calls exit(). |
162 * calls exit(). |
136 */ |
163 */ |
137 int |
164 int |
138 xerror(Display *dpy, XErrorEvent *error) |
165 xerror(Display *dpy, XErrorEvent *ee) |
139 { |
166 { |
140 if(error->error_code == BadWindow |
167 if(ee->error_code == BadWindow |
141 || (error->request_code == X_SetInputFocus |
168 || (ee->request_code == X_SetInputFocus |
142 && error->error_code == BadMatch) |
169 && ee->error_code == BadMatch) |
143 || (error->request_code == X_PolyText8 |
170 || (ee->request_code == X_PolyText8 |
144 && error->error_code == BadDrawable) |
171 && ee->error_code == BadDrawable) |
145 || (error->request_code == X_PolyFillRectangle |
172 || (ee->request_code == X_PolyFillRectangle |
146 && error->error_code == BadDrawable) |
173 && ee->error_code == BadDrawable) |
147 || (error->request_code == X_PolySegment |
174 || (ee->request_code == X_PolySegment |
148 && error->error_code == BadDrawable) |
175 && ee->error_code == BadDrawable) |
149 || (error->request_code == X_ConfigureWindow |
176 || (ee->request_code == X_ConfigureWindow |
150 && error->error_code == BadMatch) |
177 && ee->error_code == BadMatch) |
151 || (error->request_code == X_GrabKey |
178 || (ee->request_code == X_GrabKey |
152 && error->error_code == BadAccess)) |
179 && ee->error_code == BadAccess)) |
153 return 0; |
180 return 0; |
154 fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", |
181 fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", |
155 error->request_code, error->error_code); |
182 ee->request_code, ee->error_code); |
156 return x_xerror(dpy, error); /* may call exit() */ |
183 return xerrorxlib(dpy, ee); /* may call exit() */ |
157 } |
|
158 |
|
159 /* |
|
160 * Startup Error handler to check if another window manager |
|
161 * is already running. |
|
162 */ |
|
163 static int |
|
164 startup_xerror(Display *dpy, XErrorEvent *error) |
|
165 { |
|
166 other_wm_running = True; |
|
167 return -1; |
|
168 } |
|
169 |
|
170 static void |
|
171 cleanup() |
|
172 { |
|
173 while(sel) { |
|
174 resize(sel, True); |
|
175 unmanage(sel); |
|
176 } |
|
177 XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); |
|
178 } |
|
179 |
|
180 void |
|
181 quit(Arg *arg) |
|
182 { |
|
183 running = False; |
|
184 } |
184 } |
185 |
185 |
186 int |
186 int |
187 main(int argc, char *argv[]) |
187 main(int argc, char *argv[]) |
188 { |
188 { |
206 } |
206 } |
207 } |
207 } |
208 |
208 |
209 dpy = XOpenDisplay(0); |
209 dpy = XOpenDisplay(0); |
210 if(!dpy) |
210 if(!dpy) |
211 error("dwm: cannot connect X server\n"); |
211 eprint("dwm: cannot connect X server\n"); |
212 |
212 |
213 screen = DefaultScreen(dpy); |
213 screen = DefaultScreen(dpy); |
214 root = RootWindow(dpy, screen); |
214 root = RootWindow(dpy, screen); |
215 |
215 |
216 /* check if another WM is already running */ |
216 /* check if another WM is already running */ |
217 other_wm_running = False; |
217 otherwm = False; |
218 XSetErrorHandler(startup_xerror); |
218 XSetErrorHandler(xerrorstart); |
219 /* this causes an error if some other WM is running */ |
219 /* this causes an error if some other WM is running */ |
220 XSelectInput(dpy, root, SubstructureRedirectMask); |
220 XSelectInput(dpy, root, SubstructureRedirectMask); |
221 XFlush(dpy); |
221 XFlush(dpy); |
222 |
222 |
223 if(other_wm_running) |
223 if(otherwm) |
224 error("dwm: another window manager is already running\n"); |
224 eprint("dwm: another window manager is already running\n"); |
225 |
225 |
226 XSetErrorHandler(0); |
226 XSetErrorHandler(0); |
227 x_xerror = XSetErrorHandler(xerror); |
227 xerrorxlib = XSetErrorHandler(xerror); |
228 |
228 |
229 /* init atoms */ |
229 /* init atoms */ |
230 wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); |
230 wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); |
231 wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); |
231 wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); |
232 net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); |
232 net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); |
290 |
290 |
291 i = select(ConnectionNumber(dpy) + 1, &rd, 0, 0, 0); |
291 i = select(ConnectionNumber(dpy) + 1, &rd, 0, 0, 0); |
292 if(i == -1 && errno == EINTR) |
292 if(i == -1 && errno == EINTR) |
293 continue; |
293 continue; |
294 if(i < 0) |
294 if(i < 0) |
295 error("select failed\n"); |
295 eprint("select failed\n"); |
296 else if(i > 0) { |
296 else if(i > 0) { |
297 if(FD_ISSET(ConnectionNumber(dpy), &rd)) { |
297 if(FD_ISSET(ConnectionNumber(dpy), &rd)) { |
298 while(XPending(dpy)) { |
298 while(XPending(dpy)) { |
299 XNextEvent(dpy, &ev); |
299 XNextEvent(dpy, &ev); |
300 if(handler[ev.type]) |
300 if(handler[ev.type]) |