dwm-meillo

annotate event.c @ 73:c2ddb9dbbd10

rearranged
author Anselm R. Garbe <garbeam@wmii.de>
date Fri, 14 Jul 2006 22:33:38 +0200
parents e5fff8249705
children 5370ef170cc9
rev   line source
garbeam@5 1 /*
garbeam@5 2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
garbeam@5 3 * See LICENSE file for license details.
garbeam@5 4 */
garbeam@5 5
garbeam@5 6 #include <fcntl.h>
garbeam@63 7 #include <stdio.h>
garbeam@5 8 #include <stdlib.h>
garbeam@5 9 #include <string.h>
garbeam@73 10 #include <unistd.h>
garbeam@5 11 #include <X11/keysym.h>
garbeam@13 12 #include <X11/Xatom.h>
garbeam@5 13
garbeam@43 14 #include "dwm.h"
garbeam@5 15
garbeam@73 16 #define ButtonMask (ButtonPressMask | ButtonReleaseMask)
garbeam@73 17 #define MouseMask (ButtonMask | PointerMotionMask)
garbeam@73 18
garbeam@5 19 /* local functions */
garbeam@18 20 static void buttonpress(XEvent *e);
garbeam@5 21 static void configurerequest(XEvent *e);
garbeam@5 22 static void destroynotify(XEvent *e);
garbeam@5 23 static void enternotify(XEvent *e);
garbeam@5 24 static void leavenotify(XEvent *e);
garbeam@5 25 static void expose(XEvent *e);
garbeam@5 26 static void maprequest(XEvent *e);
garbeam@5 27 static void propertynotify(XEvent *e);
garbeam@5 28 static void unmapnotify(XEvent *e);
garbeam@5 29
garbeam@5 30 void (*handler[LASTEvent]) (XEvent *) = {
garbeam@18 31 [ButtonPress] = buttonpress,
garbeam@5 32 [ConfigureRequest] = configurerequest,
garbeam@5 33 [DestroyNotify] = destroynotify,
garbeam@5 34 [EnterNotify] = enternotify,
garbeam@5 35 [LeaveNotify] = leavenotify,
garbeam@5 36 [Expose] = expose,
garbeam@5 37 [KeyPress] = keypress,
garbeam@5 38 [MapRequest] = maprequest,
garbeam@5 39 [PropertyNotify] = propertynotify,
garbeam@5 40 [UnmapNotify] = unmapnotify
garbeam@5 41 };
garbeam@5 42
garbeam@5 43 static void
garbeam@73 44 mresize(Client *c)
garbeam@73 45 {
garbeam@73 46 XEvent ev;
garbeam@73 47 int ocx, ocy;
garbeam@73 48
garbeam@73 49 ocx = c->x;
garbeam@73 50 ocy = c->y;
garbeam@73 51 if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
garbeam@73 52 None, cursor[CurResize], CurrentTime) != GrabSuccess)
garbeam@73 53 return;
garbeam@73 54 XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
garbeam@73 55 for(;;) {
garbeam@73 56 XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
garbeam@73 57 switch(ev.type) {
garbeam@73 58 default: break;
garbeam@73 59 case Expose:
garbeam@73 60 handler[Expose](&ev);
garbeam@73 61 break;
garbeam@73 62 case MotionNotify:
garbeam@73 63 XFlush(dpy);
garbeam@73 64 c->w = abs(ocx - ev.xmotion.x);
garbeam@73 65 c->h = abs(ocy - ev.xmotion.y);
garbeam@73 66 c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w;
garbeam@73 67 c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h;
garbeam@73 68 resize(c, True);
garbeam@73 69 break;
garbeam@73 70 case ButtonRelease:
garbeam@73 71 XUngrabPointer(dpy, CurrentTime);
garbeam@73 72 return;
garbeam@73 73 }
garbeam@73 74 }
garbeam@73 75 }
garbeam@73 76
garbeam@73 77 static void
garbeam@73 78 mmove(Client *c)
garbeam@73 79 {
garbeam@73 80 XEvent ev;
garbeam@73 81 int x1, y1, ocx, ocy, di;
garbeam@73 82 unsigned int dui;
garbeam@73 83 Window dummy;
garbeam@73 84
garbeam@73 85 ocx = c->x;
garbeam@73 86 ocy = c->y;
garbeam@73 87 if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
garbeam@73 88 None, cursor[CurMove], CurrentTime) != GrabSuccess)
garbeam@73 89 return;
garbeam@73 90 XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui);
garbeam@73 91 for(;;) {
garbeam@73 92 XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
garbeam@73 93 switch (ev.type) {
garbeam@73 94 default: break;
garbeam@73 95 case Expose:
garbeam@73 96 handler[Expose](&ev);
garbeam@73 97 break;
garbeam@73 98 case MotionNotify:
garbeam@73 99 XFlush(dpy);
garbeam@73 100 c->x = ocx + (ev.xmotion.x - x1);
garbeam@73 101 c->y = ocy + (ev.xmotion.y - y1);
garbeam@73 102 resize(c, False);
garbeam@73 103 break;
garbeam@73 104 case ButtonRelease:
garbeam@73 105 XUngrabPointer(dpy, CurrentTime);
garbeam@73 106 return;
garbeam@73 107 }
garbeam@73 108 }
garbeam@73 109 }
garbeam@73 110
garbeam@73 111 static void
garbeam@18 112 buttonpress(XEvent *e)
garbeam@18 113 {
garbeam@73 114 int x;
garbeam@73 115 Arg a;
garbeam@18 116 XButtonPressedEvent *ev = &e->xbutton;
garbeam@18 117 Client *c;
garbeam@18 118
garbeam@73 119 if(barwin == ev->window) {
garbeam@73 120 x = (arrange == floating) ? textw("~") : 0;
garbeam@73 121 for(a.i = 0; a.i < TLast; a.i++) {
garbeam@73 122 x += textw(tags[a.i]);
garbeam@73 123 if(ev->x < x) {
garbeam@73 124 view(&a);
garbeam@73 125 break;
garbeam@73 126 }
garbeam@73 127 }
garbeam@73 128 }
garbeam@58 129 else if((c = getclient(ev->window))) {
garbeam@73 130 if(arrange == tiling && !c->floating)
garbeam@73 131 return;
garbeam@32 132 craise(c);
garbeam@18 133 switch(ev->button) {
garbeam@18 134 default:
garbeam@18 135 break;
garbeam@18 136 case Button1:
garbeam@18 137 mmove(c);
garbeam@18 138 break;
garbeam@18 139 case Button2:
garbeam@26 140 lower(c);
garbeam@18 141 break;
garbeam@18 142 case Button3:
garbeam@18 143 mresize(c);
garbeam@18 144 break;
garbeam@18 145 }
garbeam@18 146 }
garbeam@18 147 }
garbeam@18 148
garbeam@18 149 static void
garbeam@5 150 configurerequest(XEvent *e)
garbeam@5 151 {
garbeam@5 152 XConfigureRequestEvent *ev = &e->xconfigurerequest;
garbeam@5 153 XWindowChanges wc;
garbeam@5 154 Client *c;
garbeam@5 155
garbeam@5 156 ev->value_mask &= ~CWSibling;
garbeam@18 157 if((c = getclient(ev->window))) {
garbeam@29 158 gravitate(c, True);
garbeam@5 159 if(ev->value_mask & CWX)
garbeam@20 160 c->x = ev->x;
garbeam@5 161 if(ev->value_mask & CWY)
garbeam@20 162 c->y = ev->y;
garbeam@5 163 if(ev->value_mask & CWWidth)
garbeam@20 164 c->w = ev->width;
garbeam@5 165 if(ev->value_mask & CWHeight)
garbeam@20 166 c->h = ev->height;
garbeam@29 167 if(ev->value_mask & CWBorderWidth)
garbeam@55 168 c->border = 1;
garbeam@29 169 gravitate(c, False);
garbeam@53 170 resize(c, True);
garbeam@5 171 }
garbeam@5 172
garbeam@5 173 wc.x = ev->x;
garbeam@5 174 wc.y = ev->y;
garbeam@5 175 wc.width = ev->width;
garbeam@5 176 wc.height = ev->height;
garbeam@25 177 wc.border_width = 1;
garbeam@5 178 wc.sibling = None;
garbeam@5 179 wc.stack_mode = Above;
garbeam@5 180 ev->value_mask &= ~CWStackMode;
garbeam@5 181 ev->value_mask |= CWBorderWidth;
garbeam@5 182 XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
garbeam@5 183 XFlush(dpy);
garbeam@5 184 }
garbeam@5 185
garbeam@5 186 static void
garbeam@5 187 destroynotify(XEvent *e)
garbeam@5 188 {
garbeam@5 189 Client *c;
garbeam@5 190 XDestroyWindowEvent *ev = &e->xdestroywindow;
garbeam@5 191
garbeam@11 192 if((c = getclient(ev->window)))
garbeam@11 193 unmanage(c);
garbeam@5 194 }
garbeam@5 195
garbeam@5 196 static void
garbeam@5 197 enternotify(XEvent *e)
garbeam@5 198 {
garbeam@5 199 XCrossingEvent *ev = &e->xcrossing;
garbeam@5 200 Client *c;
garbeam@5 201
garbeam@5 202 if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
garbeam@5 203 return;
garbeam@5 204
garbeam@13 205 if((c = getclient(ev->window)))
garbeam@13 206 focus(c);
garbeam@26 207 else if(ev->window == root)
garbeam@31 208 issel = True;
garbeam@5 209 }
garbeam@5 210
garbeam@5 211 static void
garbeam@5 212 leavenotify(XEvent *e)
garbeam@5 213 {
garbeam@5 214 XCrossingEvent *ev = &e->xcrossing;
garbeam@5 215
garbeam@26 216 if((ev->window == root) && !ev->same_screen)
garbeam@31 217 issel = True;
garbeam@5 218 }
garbeam@5 219
garbeam@5 220 static void
garbeam@5 221 expose(XEvent *e)
garbeam@5 222 {
garbeam@5 223 XExposeEvent *ev = &e->xexpose;
garbeam@21 224 Client *c;
garbeam@5 225
garbeam@5 226 if(ev->count == 0) {
garbeam@70 227 if(barwin == ev->window)
garbeam@70 228 draw_bar();
garbeam@70 229 else if((c = gettitle(ev->window)))
garbeam@21 230 draw_client(c);
garbeam@5 231 }
garbeam@5 232 }
garbeam@5 233
garbeam@5 234 static void
garbeam@5 235 maprequest(XEvent *e)
garbeam@5 236 {
garbeam@5 237 XMapRequestEvent *ev = &e->xmaprequest;
garbeam@5 238 static XWindowAttributes wa;
garbeam@5 239
garbeam@5 240 if(!XGetWindowAttributes(dpy, ev->window, &wa))
garbeam@5 241 return;
garbeam@5 242
garbeam@5 243 if(wa.override_redirect) {
garbeam@5 244 XSelectInput(dpy, ev->window,
garbeam@5 245 (StructureNotifyMask | PropertyChangeMask));
garbeam@5 246 return;
garbeam@5 247 }
garbeam@5 248
garbeam@10 249 if(!getclient(ev->window))
garbeam@10 250 manage(ev->window, &wa);
garbeam@5 251 }
garbeam@5 252
garbeam@5 253 static void
garbeam@5 254 propertynotify(XEvent *e)
garbeam@5 255 {
garbeam@5 256 XPropertyEvent *ev = &e->xproperty;
garbeam@53 257 Window trans;
garbeam@5 258 Client *c;
garbeam@5 259
garbeam@5 260 if(ev->state == PropertyDelete)
garbeam@5 261 return; /* ignore */
garbeam@5 262
garbeam@13 263 if((c = getclient(ev->window))) {
garbeam@30 264 if(ev->atom == wm_atom[WMProtocols]) {
garbeam@30 265 c->proto = win_proto(c->win);
garbeam@30 266 return;
garbeam@30 267 }
garbeam@13 268 switch (ev->atom) {
garbeam@13 269 default: break;
garbeam@13 270 case XA_WM_TRANSIENT_FOR:
garbeam@53 271 XGetTransientForHint(dpy, c->win, &trans);
garbeam@53 272 if(!c->floating && (c->floating = (trans != 0)))
garbeam@53 273 arrange(NULL);
garbeam@13 274 break;
garbeam@13 275 case XA_WM_NORMAL_HINTS:
garbeam@20 276 update_size(c);
garbeam@13 277 break;
garbeam@13 278 }
garbeam@13 279 if(ev->atom == XA_WM_NAME || ev->atom == net_atom[NetWMName]) {
garbeam@13 280 update_name(c);
garbeam@32 281 draw_client(c);
garbeam@13 282 }
garbeam@13 283 }
garbeam@5 284 }
garbeam@5 285
garbeam@5 286 static void
garbeam@5 287 unmapnotify(XEvent *e)
garbeam@5 288 {
garbeam@5 289 Client *c;
garbeam@5 290 XUnmapEvent *ev = &e->xunmap;
garbeam@5 291
garbeam@10 292 if((c = getclient(ev->window)))
garbeam@10 293 unmanage(c);
garbeam@5 294 }