all repos — dwm @ 59b4a5e4cac68dfe6d245b8b708c3cb805f49f6d

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