all repos — dwm @ 6db5ffb6c9a9c0db5c425c64a96a3896a682c95e

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
 40void
 41discard_events(long even_mask)
 42{
 43	XEvent ev;
 44	while(XCheckMaskEvent(dpy, even_mask, &ev));
 45}
 46
 47static void
 48buttonpress(XEvent *e)
 49{
 50	XButtonPressedEvent *ev = &e->xbutton;
 51	Client *c;
 52
 53	if((c = getclient(ev->window))) {
 54		raise(c);
 55		switch(ev->button) {
 56		default:
 57			break;
 58		case Button1:
 59			mmove(c);
 60			break;
 61		case Button2:
 62			lower(c);
 63			break;
 64		case Button3:
 65			mresize(c);
 66			break;
 67		}
 68	}
 69}
 70
 71static void
 72configurerequest(XEvent *e)
 73{
 74	XConfigureRequestEvent *ev = &e->xconfigurerequest;
 75	XWindowChanges wc;
 76	Client *c;
 77
 78	ev->value_mask &= ~CWSibling;
 79	if((c = getclient(ev->window))) {
 80		if(ev->value_mask & CWX)
 81			c->x = ev->x;
 82		if(ev->value_mask & CWY)
 83			c->y = ev->y;
 84		if(ev->value_mask & CWWidth)
 85			c->w = ev->width;
 86		if(ev->value_mask & CWHeight)
 87			c->h = ev->height;
 88	}
 89
 90	wc.x = ev->x;
 91	wc.y = ev->y;
 92	wc.width = ev->width;
 93	wc.height = ev->height;
 94	wc.border_width = 1;
 95	wc.sibling = None;
 96	wc.stack_mode = Above;
 97	ev->value_mask &= ~CWStackMode;
 98	ev->value_mask |= CWBorderWidth;
 99	XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
100	XFlush(dpy);
101}
102
103static void
104destroynotify(XEvent *e)
105{
106	Client *c;
107	XDestroyWindowEvent *ev = &e->xdestroywindow;
108
109	if((c = getclient(ev->window)))
110		unmanage(c);
111}
112
113static void
114enternotify(XEvent *e)
115{
116	XCrossingEvent *ev = &e->xcrossing;
117	Client *c;
118
119	if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
120		return;
121
122	if((c = getclient(ev->window)))
123		focus(c);
124	else if(ev->window == root)
125		sel_screen = True;
126}
127
128static void
129leavenotify(XEvent *e)
130{
131	XCrossingEvent *ev = &e->xcrossing;
132
133	if((ev->window == root) && !ev->same_screen)
134		sel_screen = True;
135}
136
137static void
138expose(XEvent *e)
139{
140	XExposeEvent *ev = &e->xexpose;
141	Client *c;
142
143	if(ev->count == 0) {
144		if((c = gettitle(ev->window)))
145			draw_client(c);
146		else if(ev->window == barwin)
147			draw_bar();
148	}
149}
150
151static void
152keymapnotify(XEvent *e)
153{
154	update_keys();
155}
156
157static void
158maprequest(XEvent *e)
159{
160	XMapRequestEvent *ev = &e->xmaprequest;
161	static XWindowAttributes wa;
162
163	if(!XGetWindowAttributes(dpy, ev->window, &wa))
164		return;
165
166	if(wa.override_redirect) {
167		XSelectInput(dpy, ev->window,
168				(StructureNotifyMask | PropertyChangeMask));
169		return;
170	}
171
172	if(!getclient(ev->window))
173		manage(ev->window, &wa);
174}
175
176static void
177propertynotify(XEvent *e)
178{
179	XPropertyEvent *ev = &e->xproperty;
180	Client *c;
181
182	if(ev->state == PropertyDelete)
183		return; /* ignore */
184
185	if(ev->atom == wm_atom[WMProtocols]) {
186		c->proto = win_proto(c->win);
187		return;
188	}
189	if((c = getclient(ev->window))) {
190		switch (ev->atom) {
191			default: break;
192			case XA_WM_TRANSIENT_FOR:
193				XGetTransientForHint(dpy, c->win, &c->trans);
194				break;
195				update_size(c);
196			case XA_WM_NORMAL_HINTS:
197				update_size(c);
198				break;
199		}
200		if(ev->atom == XA_WM_NAME || ev->atom == net_atom[NetWMName]) {
201			update_name(c);
202			if(c == stack)
203				draw_bar();
204			else
205				draw_client(c);
206		}
207	}
208}
209
210static void
211unmapnotify(XEvent *e)
212{
213	Client *c;
214	XUnmapEvent *ev = &e->xunmap;
215
216	if((c = getclient(ev->window)))
217		unmanage(c);
218}