all repos — dwm @ 7faa8a904208578672160d7b57a4b8df6520581e

fork of suckless dynamic window manager

event.c (view raw)

  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>
  7#include <stdio.h>
  8#include <stdlib.h>
  9#include <string.h>
 10#include <X11/keysym.h>
 11#include <X11/Xatom.h>
 12
 13#include "dwm.h"
 14
 15/* local functions */
 16static void buttonpress(XEvent *e);
 17static void configurerequest(XEvent *e);
 18static void destroynotify(XEvent *e);
 19static void enternotify(XEvent *e);
 20static void leavenotify(XEvent *e);
 21static void expose(XEvent *e);
 22static void keymapnotify(XEvent *e);
 23static void maprequest(XEvent *e);
 24static void propertynotify(XEvent *e);
 25static void unmapnotify(XEvent *e);
 26
 27void (*handler[LASTEvent]) (XEvent *) = {
 28	[ButtonPress] = buttonpress,
 29	[ConfigureRequest] = configurerequest,
 30	[DestroyNotify] = destroynotify,
 31	[EnterNotify] = enternotify,
 32	[LeaveNotify] = leavenotify,
 33	[Expose] = expose,
 34	[KeyPress] = keypress,
 35	[KeymapNotify] = keymapnotify,
 36	[MapRequest] = maprequest,
 37	[PropertyNotify] = propertynotify,
 38	[UnmapNotify] = unmapnotify
 39};
 40
 41static void
 42buttonpress(XEvent *e)
 43{
 44	XButtonPressedEvent *ev = &e->xbutton;
 45	Client *c;
 46
 47	if(barwin == ev->window)
 48		barclick(ev);
 49	else if((c = getclient(ev->window))) {
 50		craise(c);
 51		switch(ev->button) {
 52		default:
 53			break;
 54		case Button1:
 55			mmove(c);
 56			break;
 57		case Button2:
 58			lower(c);
 59			break;
 60		case Button3:
 61			mresize(c);
 62			break;
 63		}
 64	}
 65}
 66
 67static void
 68configurerequest(XEvent *e)
 69{
 70	XConfigureRequestEvent *ev = &e->xconfigurerequest;
 71	XWindowChanges wc;
 72	Client *c;
 73
 74	ev->value_mask &= ~CWSibling;
 75	if((c = getclient(ev->window))) {
 76		gravitate(c, True);
 77		if(ev->value_mask & CWX)
 78			c->x = ev->x;
 79		if(ev->value_mask & CWY)
 80			c->y = ev->y;
 81		if(ev->value_mask & CWWidth)
 82			c->w = ev->width;
 83		if(ev->value_mask & CWHeight)
 84			c->h = ev->height;
 85		if(ev->value_mask & CWBorderWidth)
 86			c->border = 1;
 87		gravitate(c, False);
 88		resize(c, True);
 89	}
 90
 91	wc.x = ev->x;
 92	wc.y = ev->y;
 93	wc.width = ev->width;
 94	wc.height = ev->height;
 95	wc.border_width = 1;
 96	wc.sibling = None;
 97	wc.stack_mode = Above;
 98	ev->value_mask &= ~CWStackMode;
 99	ev->value_mask |= CWBorderWidth;
100	XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
101	XFlush(dpy);
102}
103
104static void
105destroynotify(XEvent *e)
106{
107	Client *c;
108	XDestroyWindowEvent *ev = &e->xdestroywindow;
109
110	if((c = getclient(ev->window)))
111		unmanage(c);
112}
113
114static void
115enternotify(XEvent *e)
116{
117	XCrossingEvent *ev = &e->xcrossing;
118	Client *c;
119
120	if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
121		return;
122
123	if((c = getclient(ev->window)))
124		focus(c);
125	else if(ev->window == root)
126		issel = True;
127}
128
129static void
130leavenotify(XEvent *e)
131{
132	XCrossingEvent *ev = &e->xcrossing;
133
134	if((ev->window == root) && !ev->same_screen)
135		issel = True;
136}
137
138static void
139expose(XEvent *e)
140{
141	XExposeEvent *ev = &e->xexpose;
142	Client *c;
143
144	if(ev->count == 0) {
145		if((c = gettitle(ev->window)))
146			draw_client(c);
147	}
148}
149
150static void
151keymapnotify(XEvent *e)
152{
153	update_keys();
154}
155
156static void
157maprequest(XEvent *e)
158{
159	XMapRequestEvent *ev = &e->xmaprequest;
160	static XWindowAttributes wa;
161
162	if(!XGetWindowAttributes(dpy, ev->window, &wa))
163		return;
164
165	if(wa.override_redirect) {
166		XSelectInput(dpy, ev->window,
167				(StructureNotifyMask | PropertyChangeMask));
168		return;
169	}
170
171	if(!getclient(ev->window))
172		manage(ev->window, &wa);
173}
174
175static void
176propertynotify(XEvent *e)
177{
178	XPropertyEvent *ev = &e->xproperty;
179	Window trans;
180	Client *c;
181
182	if(ev->state == PropertyDelete)
183		return; /* ignore */
184
185	if((c = getclient(ev->window))) {
186		if(ev->atom == wm_atom[WMProtocols]) {
187			c->proto = win_proto(c->win);
188			return;
189		}
190		switch (ev->atom) {
191			default: break;
192			case XA_WM_TRANSIENT_FOR:
193				XGetTransientForHint(dpy, c->win, &trans);
194				if(!c->floating && (c->floating = (trans != 0)))
195					arrange(NULL);
196				break;
197			case XA_WM_NORMAL_HINTS:
198				update_size(c);
199				break;
200		}
201		if(ev->atom == XA_WM_NAME || ev->atom == net_atom[NetWMName]) {
202			update_name(c);
203			draw_client(c);
204		}
205	}
206}
207
208static void
209unmapnotify(XEvent *e)
210{
211	Client *c;
212	XUnmapEvent *ev = &e->xunmap;
213
214	if((c = getclient(ev->window)))
215		unmanage(c);
216}