all repos — dwm @ a05beb6585713aeb661cf30c080e77fbfdb28867

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
147	if(ev->count == 0) {
148		if(ev->window == barwin)
149			draw_bar();
150	}
151}
152
153static void
154keymapnotify(XEvent *e)
155{
156	update_keys();
157}
158
159static void
160maprequest(XEvent *e)
161{
162	XMapRequestEvent *ev = &e->xmaprequest;
163	static XWindowAttributes wa;
164
165	if(!XGetWindowAttributes(dpy, ev->window, &wa))
166		return;
167
168	if(wa.override_redirect) {
169		XSelectInput(dpy, ev->window,
170				(StructureNotifyMask | PropertyChangeMask));
171		return;
172	}
173
174	if(!getclient(ev->window))
175		manage(ev->window, &wa);
176}
177
178static void
179propertynotify(XEvent *e)
180{
181	XPropertyEvent *ev = &e->xproperty;
182	Client *c;
183
184	if(ev->state == PropertyDelete)
185		return; /* ignore */
186
187	if(ev->atom == wm_atom[WMProtocols]) {
188		c->proto = win_proto(c->win);
189		return;
190	}
191	if((c = getclient(ev->window))) {
192		switch (ev->atom) {
193			default: break;
194			case XA_WM_TRANSIENT_FOR:
195				XGetTransientForHint(dpy, c->win, &c->trans);
196				break;
197				update_size(c);
198			case XA_WM_NORMAL_HINTS:
199				update_size(c);
200				break;
201		}
202		if(ev->atom == XA_WM_NAME || ev->atom == net_atom[NetWMName]) {
203			update_name(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}