Mercurial > aewl
annotate event.c @ 75:f08271b7cb20
rearranged several stuff
author | Anselm R. Garbe <garbeam@wmii.de> |
---|---|
date | Sat, 15 Jul 2006 16:30:50 +0200 |
parents | 5370ef170cc9 |
children | 4bd49f404f10 |
rev | line source |
---|---|
5 | 1 /* |
2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | |
3 * See LICENSE file for license details. | |
4 */ | |
5 | |
6 #include <fcntl.h> | |
63
f14858218641
searching for a better way to discard enter notifies
Anselm R. Garbe <garbeam@wmii.de>
parents:
58
diff
changeset
|
7 #include <stdio.h> |
5 | 8 #include <stdlib.h> |
9 #include <string.h> | |
73 | 10 #include <unistd.h> |
5 | 11 #include <X11/keysym.h> |
13
5cc5e55a132d
added protocol killing stuff
Anselm R. Garbe <garbeam@wmii.de>
parents:
11
diff
changeset
|
12 #include <X11/Xatom.h> |
5 | 13 |
43 | 14 #include "dwm.h" |
5 | 15 |
73 | 16 #define ButtonMask (ButtonPressMask | ButtonReleaseMask) |
17 #define MouseMask (ButtonMask | PointerMotionMask) | |
18 | |
75 | 19 /********** CUSTOMIZE **********/ |
20 | |
21 const char *term[] = { | |
22 "urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn", | |
23 "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL | |
24 }; | |
25 const char *browse[] = { "firefox", NULL }; | |
26 const char *xlock[] = { "xlock", NULL }; | |
27 | |
28 Key key[] = { | |
29 /* modifier key function arguments */ | |
30 { Mod1Mask, XK_Return, zoom, { 0 } }, | |
31 { Mod1Mask, XK_k, focusprev, { 0 } }, | |
32 { Mod1Mask, XK_j, focusnext, { 0 } }, | |
33 { Mod1Mask, XK_m, maximize, { 0 } }, | |
34 { Mod1Mask, XK_0, view, { .i = Tscratch } }, | |
35 { Mod1Mask, XK_1, view, { .i = Tdev } }, | |
36 { Mod1Mask, XK_2, view, { .i = Twww } }, | |
37 { Mod1Mask, XK_3, view, { .i = Twork } }, | |
38 { Mod1Mask, XK_space, dotile, { 0 } }, | |
39 { Mod1Mask|ShiftMask, XK_space, dofloat, { 0 } }, | |
40 { Mod1Mask|ShiftMask, XK_0, replacetag, { .i = Tscratch } }, | |
41 { Mod1Mask|ShiftMask, XK_1, replacetag, { .i = Tdev } }, | |
42 { Mod1Mask|ShiftMask, XK_2, replacetag, { .i = Twww } }, | |
43 { Mod1Mask|ShiftMask, XK_3, replacetag, { .i = Twork } }, | |
44 { Mod1Mask|ShiftMask, XK_c, killclient, { 0 } }, | |
45 { Mod1Mask|ShiftMask, XK_q, quit, { 0 } }, | |
46 { Mod1Mask|ShiftMask, XK_Return, spawn, { .argv = term } }, | |
47 { Mod1Mask|ShiftMask, XK_w, spawn, { .argv = browse } }, | |
48 { Mod1Mask|ShiftMask, XK_l, spawn, { .argv = xlock } }, | |
49 { ControlMask, XK_0, appendtag, { .i = Tscratch } }, | |
50 { ControlMask, XK_1, appendtag, { .i = Tdev } }, | |
51 { ControlMask, XK_2, appendtag, { .i = Twww } }, | |
52 { ControlMask, XK_3, appendtag, { .i = Twork } }, | |
53 }; | |
54 | |
55 /********** CUSTOMIZE **********/ | |
56 | |
5 | 57 /* local functions */ |
18
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
58 static void buttonpress(XEvent *e); |
5 | 59 static void configurerequest(XEvent *e); |
60 static void destroynotify(XEvent *e); | |
61 static void enternotify(XEvent *e); | |
62 static void leavenotify(XEvent *e); | |
63 static void expose(XEvent *e); | |
75 | 64 static void keypress(XEvent *e); |
5 | 65 static void maprequest(XEvent *e); |
66 static void propertynotify(XEvent *e); | |
67 static void unmapnotify(XEvent *e); | |
68 | |
69 void (*handler[LASTEvent]) (XEvent *) = { | |
18
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
70 [ButtonPress] = buttonpress, |
5 | 71 [ConfigureRequest] = configurerequest, |
72 [DestroyNotify] = destroynotify, | |
73 [EnterNotify] = enternotify, | |
74 [LeaveNotify] = leavenotify, | |
75 [Expose] = expose, | |
76 [KeyPress] = keypress, | |
77 [MapRequest] = maprequest, | |
78 [PropertyNotify] = propertynotify, | |
79 [UnmapNotify] = unmapnotify | |
80 }; | |
81 | |
75 | 82 void |
83 grabkeys() | |
84 { | |
85 static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; | |
86 unsigned int i; | |
87 KeyCode code; | |
88 | |
89 for(i = 0; i < len; i++) { | |
90 code = XKeysymToKeycode(dpy, key[i].keysym); | |
91 XUngrabKey(dpy, code, key[i].mod, root); | |
92 XGrabKey(dpy, code, key[i].mod, root, True, | |
93 GrabModeAsync, GrabModeAsync); | |
94 } | |
95 } | |
96 | |
5 | 97 static void |
75 | 98 keypress(XEvent *e) |
99 { | |
100 XKeyEvent *ev = &e->xkey; | |
101 static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; | |
102 unsigned int i; | |
103 KeySym keysym; | |
104 | |
105 keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); | |
106 for(i = 0; i < len; i++) | |
107 if((keysym == key[i].keysym) && (key[i].mod == ev->state)) { | |
108 if(key[i].func) | |
109 key[i].func(&key[i].arg); | |
110 return; | |
111 } | |
112 } | |
113 | |
114 static void | |
115 resizemouse(Client *c) | |
73 | 116 { |
117 XEvent ev; | |
118 int ocx, ocy; | |
119 | |
120 ocx = c->x; | |
121 ocy = c->y; | |
122 if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync, | |
123 None, cursor[CurResize], CurrentTime) != GrabSuccess) | |
124 return; | |
125 XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h); | |
126 for(;;) { | |
127 XMaskEvent(dpy, MouseMask | ExposureMask, &ev); | |
128 switch(ev.type) { | |
129 default: break; | |
130 case Expose: | |
131 handler[Expose](&ev); | |
132 break; | |
133 case MotionNotify: | |
134 XFlush(dpy); | |
135 c->w = abs(ocx - ev.xmotion.x); | |
136 c->h = abs(ocy - ev.xmotion.y); | |
137 c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w; | |
138 c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h; | |
139 resize(c, True); | |
140 break; | |
141 case ButtonRelease: | |
142 XUngrabPointer(dpy, CurrentTime); | |
143 return; | |
144 } | |
145 } | |
146 } | |
147 | |
148 static void | |
75 | 149 movemouse(Client *c) |
73 | 150 { |
151 XEvent ev; | |
152 int x1, y1, ocx, ocy, di; | |
153 unsigned int dui; | |
154 Window dummy; | |
155 | |
156 ocx = c->x; | |
157 ocy = c->y; | |
158 if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync, | |
159 None, cursor[CurMove], CurrentTime) != GrabSuccess) | |
160 return; | |
161 XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); | |
162 for(;;) { | |
163 XMaskEvent(dpy, MouseMask | ExposureMask, &ev); | |
164 switch (ev.type) { | |
165 default: break; | |
166 case Expose: | |
167 handler[Expose](&ev); | |
168 break; | |
169 case MotionNotify: | |
170 XFlush(dpy); | |
171 c->x = ocx + (ev.xmotion.x - x1); | |
172 c->y = ocy + (ev.xmotion.y - y1); | |
173 resize(c, False); | |
174 break; | |
175 case ButtonRelease: | |
176 XUngrabPointer(dpy, CurrentTime); | |
177 return; | |
178 } | |
179 } | |
180 } | |
181 | |
182 static void | |
18
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
183 buttonpress(XEvent *e) |
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
184 { |
73 | 185 int x; |
186 Arg a; | |
18
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
187 XButtonPressedEvent *ev = &e->xbutton; |
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
188 Client *c; |
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
189 |
73 | 190 if(barwin == ev->window) { |
75 | 191 x = (arrange == dofloat) ? textw("~") : 0; |
73 | 192 for(a.i = 0; a.i < TLast; a.i++) { |
193 x += textw(tags[a.i]); | |
194 if(ev->x < x) { | |
195 view(&a); | |
196 break; | |
197 } | |
198 } | |
199 } | |
58
1269bd127551
made barclick to select the specific tag
Anselm R. Garbe <garbeam@wmii.de>
parents:
55
diff
changeset
|
200 else if((c = getclient(ev->window))) { |
75 | 201 if(arrange == dotile && !c->dofloat) |
73 | 202 return; |
74 | 203 higher(c); |
18
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
204 switch(ev->button) { |
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
205 default: |
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
206 break; |
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
207 case Button1: |
75 | 208 movemouse(c); |
18
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
209 break; |
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
210 case Button2: |
26
e8f627998d6f
simplified several portions of code through replacing rect structs with x,y,h,w counterparts (much more readable)
Anselm R. Garbe <garbeam@wmii.de>
parents:
25
diff
changeset
|
211 lower(c); |
18
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
212 break; |
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
213 case Button3: |
75 | 214 resizemouse(c); |
18
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
215 break; |
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
216 } |
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
217 } |
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
218 } |
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
219 |
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
220 static void |
5 | 221 configurerequest(XEvent *e) |
222 { | |
223 XConfigureRequestEvent *ev = &e->xconfigurerequest; | |
224 XWindowChanges wc; | |
225 Client *c; | |
226 | |
227 ev->value_mask &= ~CWSibling; | |
18
1efa34c6e1b6
added mouse-based resizals
Anselm R. Garbe <garbeam@wmii.de>
parents:
16
diff
changeset
|
228 if((c = getclient(ev->window))) { |
29 | 229 gravitate(c, True); |
5 | 230 if(ev->value_mask & CWX) |
20 | 231 c->x = ev->x; |
5 | 232 if(ev->value_mask & CWY) |
20 | 233 c->y = ev->y; |
5 | 234 if(ev->value_mask & CWWidth) |
20 | 235 c->w = ev->width; |
5 | 236 if(ev->value_mask & CWHeight) |
20 | 237 c->h = ev->height; |
29 | 238 if(ev->value_mask & CWBorderWidth) |
55 | 239 c->border = 1; |
29 | 240 gravitate(c, False); |
53 | 241 resize(c, True); |
5 | 242 } |
243 | |
244 wc.x = ev->x; | |
245 wc.y = ev->y; | |
246 wc.width = ev->width; | |
247 wc.height = ev->height; | |
25 | 248 wc.border_width = 1; |
5 | 249 wc.sibling = None; |
250 wc.stack_mode = Above; | |
251 ev->value_mask &= ~CWStackMode; | |
252 ev->value_mask |= CWBorderWidth; | |
253 XConfigureWindow(dpy, ev->window, ev->value_mask, &wc); | |
254 XFlush(dpy); | |
255 } | |
256 | |
257 static void | |
258 destroynotify(XEvent *e) | |
259 { | |
260 Client *c; | |
261 XDestroyWindowEvent *ev = &e->xdestroywindow; | |
262 | |
11 | 263 if((c = getclient(ev->window))) |
264 unmanage(c); | |
5 | 265 } |
266 | |
267 static void | |
268 enternotify(XEvent *e) | |
269 { | |
270 XCrossingEvent *ev = &e->xcrossing; | |
271 Client *c; | |
272 | |
273 if(ev->mode != NotifyNormal || ev->detail == NotifyInferior) | |
274 return; | |
275 | |
13
5cc5e55a132d
added protocol killing stuff
Anselm R. Garbe <garbeam@wmii.de>
parents:
11
diff
changeset
|
276 if((c = getclient(ev->window))) |
5cc5e55a132d
added protocol killing stuff
Anselm R. Garbe <garbeam@wmii.de>
parents:
11
diff
changeset
|
277 focus(c); |
26
e8f627998d6f
simplified several portions of code through replacing rect structs with x,y,h,w counterparts (much more readable)
Anselm R. Garbe <garbeam@wmii.de>
parents:
25
diff
changeset
|
278 else if(ev->window == root) |
31 | 279 issel = True; |
5 | 280 } |
281 | |
282 static void | |
283 leavenotify(XEvent *e) | |
284 { | |
285 XCrossingEvent *ev = &e->xcrossing; | |
286 | |
26
e8f627998d6f
simplified several portions of code through replacing rect structs with x,y,h,w counterparts (much more readable)
Anselm R. Garbe <garbeam@wmii.de>
parents:
25
diff
changeset
|
287 if((ev->window == root) && !ev->same_screen) |
31 | 288 issel = True; |
5 | 289 } |
290 | |
291 static void | |
292 expose(XEvent *e) | |
293 { | |
294 XExposeEvent *ev = &e->xexpose; | |
21
3ef108a5ca0a
implemented draw_client stuff
Anselm R. Garbe <garbeam@wmii.de>
parents:
20
diff
changeset
|
295 Client *c; |
5 | 296 |
297 if(ev->count == 0) { | |
70 | 298 if(barwin == ev->window) |
74 | 299 drawstatus(); |
75 | 300 else if((c = getctitle(ev->window))) |
74 | 301 drawtitle(c); |
5 | 302 } |
303 } | |
304 | |
305 static void | |
306 maprequest(XEvent *e) | |
307 { | |
308 XMapRequestEvent *ev = &e->xmaprequest; | |
309 static XWindowAttributes wa; | |
310 | |
311 if(!XGetWindowAttributes(dpy, ev->window, &wa)) | |
312 return; | |
313 | |
314 if(wa.override_redirect) { | |
315 XSelectInput(dpy, ev->window, | |
316 (StructureNotifyMask | PropertyChangeMask)); | |
317 return; | |
318 } | |
319 | |
10
703255003abb
changed how manage client works
Anselm R. Garbe <garbeam@wmii.de>
parents:
9
diff
changeset
|
320 if(!getclient(ev->window)) |
703255003abb
changed how manage client works
Anselm R. Garbe <garbeam@wmii.de>
parents:
9
diff
changeset
|
321 manage(ev->window, &wa); |
5 | 322 } |
323 | |
324 static void | |
325 propertynotify(XEvent *e) | |
326 { | |
327 XPropertyEvent *ev = &e->xproperty; | |
53 | 328 Window trans; |
5 | 329 Client *c; |
330 | |
331 if(ev->state == PropertyDelete) | |
332 return; /* ignore */ | |
333 | |
13
5cc5e55a132d
added protocol killing stuff
Anselm R. Garbe <garbeam@wmii.de>
parents:
11
diff
changeset
|
334 if((c = getclient(ev->window))) { |
30
2e0fb4130bfb
new stuff, fixed several issues
Anselm R. Garbe <garbeam@wmii.de>
parents:
29
diff
changeset
|
335 if(ev->atom == wm_atom[WMProtocols]) { |
75 | 336 c->proto = getproto(c->win); |
30
2e0fb4130bfb
new stuff, fixed several issues
Anselm R. Garbe <garbeam@wmii.de>
parents:
29
diff
changeset
|
337 return; |
2e0fb4130bfb
new stuff, fixed several issues
Anselm R. Garbe <garbeam@wmii.de>
parents:
29
diff
changeset
|
338 } |
13
5cc5e55a132d
added protocol killing stuff
Anselm R. Garbe <garbeam@wmii.de>
parents:
11
diff
changeset
|
339 switch (ev->atom) { |
5cc5e55a132d
added protocol killing stuff
Anselm R. Garbe <garbeam@wmii.de>
parents:
11
diff
changeset
|
340 default: break; |
5cc5e55a132d
added protocol killing stuff
Anselm R. Garbe <garbeam@wmii.de>
parents:
11
diff
changeset
|
341 case XA_WM_TRANSIENT_FOR: |
53 | 342 XGetTransientForHint(dpy, c->win, &trans); |
75 | 343 if(!c->dofloat && (c->dofloat = (trans != 0))) |
53 | 344 arrange(NULL); |
13
5cc5e55a132d
added protocol killing stuff
Anselm R. Garbe <garbeam@wmii.de>
parents:
11
diff
changeset
|
345 break; |
5cc5e55a132d
added protocol killing stuff
Anselm R. Garbe <garbeam@wmii.de>
parents:
11
diff
changeset
|
346 case XA_WM_NORMAL_HINTS: |
74 | 347 setsize(c); |
13
5cc5e55a132d
added protocol killing stuff
Anselm R. Garbe <garbeam@wmii.de>
parents:
11
diff
changeset
|
348 break; |
5cc5e55a132d
added protocol killing stuff
Anselm R. Garbe <garbeam@wmii.de>
parents:
11
diff
changeset
|
349 } |
5cc5e55a132d
added protocol killing stuff
Anselm R. Garbe <garbeam@wmii.de>
parents:
11
diff
changeset
|
350 if(ev->atom == XA_WM_NAME || ev->atom == net_atom[NetWMName]) { |
74 | 351 settitle(c); |
352 drawtitle(c); | |
13
5cc5e55a132d
added protocol killing stuff
Anselm R. Garbe <garbeam@wmii.de>
parents:
11
diff
changeset
|
353 } |
5cc5e55a132d
added protocol killing stuff
Anselm R. Garbe <garbeam@wmii.de>
parents:
11
diff
changeset
|
354 } |
5 | 355 } |
356 | |
357 static void | |
358 unmapnotify(XEvent *e) | |
359 { | |
360 Client *c; | |
361 XUnmapEvent *ev = &e->xunmap; | |
362 | |
10
703255003abb
changed how manage client works
Anselm R. Garbe <garbeam@wmii.de>
parents:
9
diff
changeset
|
363 if((c = getclient(ev->window))) |
703255003abb
changed how manage client works
Anselm R. Garbe <garbeam@wmii.de>
parents:
9
diff
changeset
|
364 unmanage(c); |
5 | 365 } |