all repos — dwm @ d6e0e6e9879c144f5d374fca0c015fd6208fc27e

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 configurerequest(XEvent *e);
 16static void destroynotify(XEvent *e);
 17static void enternotify(XEvent *e);
 18static void leavenotify(XEvent *e);
 19static void expose(XEvent *e);
 20static void keymapnotify(XEvent *e);
 21static void maprequest(XEvent *e);
 22static void propertynotify(XEvent *e);
 23static void unmapnotify(XEvent *e);
 24
 25void (*handler[LASTEvent]) (XEvent *) = {
 26	[ConfigureRequest] = configurerequest,
 27	[DestroyNotify] = destroynotify,
 28	[EnterNotify] = enternotify,
 29	[LeaveNotify] = leavenotify,
 30	[Expose] = expose,
 31	[KeyPress] = keypress,
 32	[KeymapNotify] = keymapnotify,
 33	[MapRequest] = maprequest,
 34	[PropertyNotify] = propertynotify,
 35	[UnmapNotify] = unmapnotify
 36};
 37
 38unsigned int
 39flush_events(long even_mask)
 40{
 41	XEvent ev;
 42	unsigned int n = 0;
 43	while(XCheckMaskEvent(dpy, even_mask, &ev)) n++;
 44	return n;
 45}
 46
 47static void
 48configurerequest(XEvent *e)
 49{
 50	XConfigureRequestEvent *ev = &e->xconfigurerequest;
 51	XWindowChanges wc;
 52	Client *c;
 53
 54	c = getclient(ev->window);
 55	ev->value_mask &= ~CWSibling;
 56	if(c) {
 57		if(ev->value_mask & CWX)
 58			c->r[RFloat].x = ev->x;
 59		if(ev->value_mask & CWY)
 60			c->r[RFloat].y = ev->y;
 61		if(ev->value_mask & CWWidth)
 62			c->r[RFloat].width = ev->width;
 63		if(ev->value_mask & CWHeight)
 64			c->r[RFloat].height = ev->height;
 65		if(ev->value_mask & CWBorderWidth)
 66			c->border = ev->border_width;
 67	}
 68
 69	wc.x = ev->x;
 70	wc.y = ev->y;
 71	wc.width = ev->width;
 72	wc.height = ev->height;
 73	wc.border_width = 0;
 74	wc.sibling = None;
 75	wc.stack_mode = Above;
 76	ev->value_mask &= ~CWStackMode;
 77	ev->value_mask |= CWBorderWidth;
 78	XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
 79	XFlush(dpy);
 80}
 81
 82static void
 83destroynotify(XEvent *e)
 84{
 85	Client *c;
 86	XDestroyWindowEvent *ev = &e->xdestroywindow;
 87
 88	if((c = getclient(ev->window)))
 89		unmanage(c);
 90}
 91
 92static void
 93enternotify(XEvent *e)
 94{
 95	XCrossingEvent *ev = &e->xcrossing;
 96	Client *c;
 97
 98	if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
 99		return;
100
101	if((c = getclient(ev->window)))
102		focus(c);
103	else if(ev->window == root) {
104		sel_screen = True;
105		/*draw_frames();*/
106	}
107}
108
109static void
110leavenotify(XEvent *e)
111{
112	XCrossingEvent *ev = &e->xcrossing;
113
114	if((ev->window == root) && !ev->same_screen) {
115		sel_screen = True;
116		/*draw_frames();*/
117	}
118}
119
120static void
121expose(XEvent *e)
122{
123	XExposeEvent *ev = &e->xexpose;
124
125	if(ev->count == 0) {
126		if(ev->window == barwin)
127			draw_bar();
128	}
129}
130
131static void
132keymapnotify(XEvent *e)
133{
134	update_keys();
135}
136
137static void
138maprequest(XEvent *e)
139{
140	XMapRequestEvent *ev = &e->xmaprequest;
141	static XWindowAttributes wa;
142
143	if(!XGetWindowAttributes(dpy, ev->window, &wa))
144		return;
145
146	if(wa.override_redirect) {
147		XSelectInput(dpy, ev->window,
148				(StructureNotifyMask | PropertyChangeMask));
149		return;
150	}
151
152	if(!getclient(ev->window))
153		manage(ev->window, &wa);
154}
155
156static void
157propertynotify(XEvent *e)
158{
159	XPropertyEvent *ev = &e->xproperty;
160	long msize;
161	Client *c;
162
163	if(ev->state == PropertyDelete)
164		return; /* ignore */
165
166	if(ev->atom == wm_atom[WMProtocols]) {
167		c->proto = win_proto(c->win);
168		return;
169	}
170	if((c = getclient(ev->window))) {
171		switch (ev->atom) {
172			default: break;
173			case XA_WM_TRANSIENT_FOR:
174				XGetTransientForHint(dpy, c->win, &c->trans);
175				break;
176			case XA_WM_NORMAL_HINTS:
177				if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize)
178						|| !c->size.flags)
179					c->size.flags = PSize;
180				if(c->size.flags & PMinSize && c->size.flags & PMaxSize
181						&& c->size.min_width == c->size.max_width
182						&& c->size.min_height == c->size.max_height)
183					c->fixedsize = True;
184				else
185					c->fixedsize = False;
186				break;
187		}
188		if(ev->atom == XA_WM_NAME || ev->atom == net_atom[NetWMName]) {
189			update_name(c);
190		}
191	}
192}
193
194static void
195unmapnotify(XEvent *e)
196{
197	Client *c;
198	XUnmapEvent *ev = &e->xunmap;
199
200	if((c = getclient(ev->window)))
201		unmanage(c);
202}