all repos — dwm @ 896f08d7d553f7def3877648c113cf03e6ca546a

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 <stdlib.h>
  8#include <string.h>
  9#include <X11/keysym.h>
 10#include <X11/Xatom.h>
 11
 12#include "wm.h"
 13
 14/* local functions */
 15static void buttonpress(XEvent *e);
 16static void configurerequest(XEvent *e);
 17static void destroynotify(XEvent *e);
 18static void enternotify(XEvent *e);
 19static void leavenotify(XEvent *e);
 20static void expose(XEvent *e);
 21static void keymapnotify(XEvent *e);
 22static void maprequest(XEvent *e);
 23static void propertynotify(XEvent *e);
 24static void unmapnotify(XEvent *e);
 25
 26void (*handler[LASTEvent]) (XEvent *) = {
 27	[ButtonPress] = buttonpress,
 28	[ConfigureRequest] = configurerequest,
 29	[DestroyNotify] = destroynotify,
 30	[EnterNotify] = enternotify,
 31	[LeaveNotify] = leavenotify,
 32	[Expose] = expose,
 33	[KeyPress] = keypress,
 34	[KeymapNotify] = keymapnotify,
 35	[MapRequest] = maprequest,
 36	[PropertyNotify] = propertynotify,
 37	[UnmapNotify] = unmapnotify
 38};
 39
 40unsigned int
 41discard_events(long even_mask)
 42{
 43	XEvent ev;
 44	unsigned int n = 0;
 45	while(XCheckMaskEvent(dpy, even_mask, &ev)) n++;
 46	return n;
 47}
 48
 49static void
 50buttonpress(XEvent *e)
 51{
 52	XButtonPressedEvent *ev = &e->xbutton;
 53	Client *c;
 54
 55	if((c = getclient(ev->window))) {
 56		switch(ev->button) {
 57		default:
 58			break;
 59		case Button1:
 60			mmove(c);
 61			break;
 62		case Button2:
 63			XLowerWindow(dpy, c->win);
 64			break;
 65		case Button3:
 66			mresize(c);
 67			break;
 68		}
 69	}
 70}
 71
 72static void
 73configurerequest(XEvent *e)
 74{
 75	XConfigureRequestEvent *ev = &e->xconfigurerequest;
 76	XWindowChanges wc;
 77	Client *c;
 78
 79	ev->value_mask &= ~CWSibling;
 80	if((c = getclient(ev->window))) {
 81		if(ev->value_mask & CWX)
 82			c->x = ev->x;
 83		if(ev->value_mask & CWY)
 84			c->y = ev->y;
 85		if(ev->value_mask & CWWidth)
 86			c->w = ev->width;
 87		if(ev->value_mask & CWHeight)
 88			c->h = ev->height;
 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 = 0;
 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		sel_screen = True;
127		/*draw_frames();*/
128	}
129}
130
131static void
132leavenotify(XEvent *e)
133{
134	XCrossingEvent *ev = &e->xcrossing;
135
136	if((ev->window == root) && !ev->same_screen) {
137		sel_screen = True;
138		/*draw_frames();*/
139	}
140}
141
142static void
143expose(XEvent *e)
144{
145	XExposeEvent *ev = &e->xexpose;
146	Client *c;
147
148	if(ev->count == 0) {
149		if((c = getclient(ev->window)))
150			draw_client(c);
151		else if(ev->window == barwin)
152			draw_bar();
153	}
154}
155
156static void
157keymapnotify(XEvent *e)
158{
159	update_keys();
160}
161
162static void
163maprequest(XEvent *e)
164{
165	XMapRequestEvent *ev = &e->xmaprequest;
166	static XWindowAttributes wa;
167
168	if(!XGetWindowAttributes(dpy, ev->window, &wa))
169		return;
170
171	if(wa.override_redirect) {
172		XSelectInput(dpy, ev->window,
173				(StructureNotifyMask | PropertyChangeMask));
174		return;
175	}
176
177	if(!getclient(ev->window))
178		manage(ev->window, &wa);
179}
180
181static void
182propertynotify(XEvent *e)
183{
184	XPropertyEvent *ev = &e->xproperty;
185	Client *c;
186
187	if(ev->state == PropertyDelete)
188		return; /* ignore */
189
190	if(ev->atom == wm_atom[WMProtocols]) {
191		c->proto = win_proto(c->win);
192		return;
193	}
194	if((c = getclient(ev->window))) {
195		switch (ev->atom) {
196			default: break;
197			case XA_WM_TRANSIENT_FOR:
198				XGetTransientForHint(dpy, c->win, &c->trans);
199				break;
200				update_size(c);
201			case XA_WM_NORMAL_HINTS:
202				update_size(c);
203				break;
204		}
205		if(ev->atom == XA_WM_NAME || ev->atom == net_atom[NetWMName]) {
206			update_name(c);
207			if(c == stack)
208				draw_bar();
209			else
210				draw_client(c);
211		}
212	}
213}
214
215static void
216unmapnotify(XEvent *e)
217{
218	Client *c;
219	XUnmapEvent *ev = &e->xunmap;
220
221	if((c = getclient(ev->window)))
222		unmanage(c);
223}