aewl

changeset 13:5cc5e55a132d

added protocol killing stuff
author Anselm R. Garbe <garbeam@wmii.de>
date Tue, 11 Jul 2006 16:14:22 +0200
parents a2b399582afe
children 5c078b66347b
files client.c cmd.c event.c menu.c wm.c wm.h
diffstat 6 files changed, 153 insertions(+), 36 deletions(-) [+]
line diff
     1.1 --- a/client.c	Tue Jul 11 14:53:22 2006 +0200
     1.2 +++ b/client.c	Tue Jul 11 16:14:22 2006 +0200
     1.3 @@ -10,8 +10,8 @@
     1.4  #include "util.h"
     1.5  #include "wm.h"
     1.6  
     1.7 -static void
     1.8 -update_client_name(Client *c)
     1.9 +void
    1.10 +update_name(Client *c)
    1.11  {
    1.12  	XTextProperty name;
    1.13  	int n;
    1.14 @@ -38,6 +38,20 @@
    1.15  }
    1.16  
    1.17  void
    1.18 +focus(Client *c)
    1.19 +{
    1.20 +	Client **l;
    1.21 +	for(l=&stack; *l && *l != c; l=&(*l)->snext);
    1.22 +	eassert(*l == c);
    1.23 +	*l = c->snext;
    1.24 +	c->snext = stack;
    1.25 +	stack = c;
    1.26 +	XRaiseWindow(dpy, c->win);
    1.27 +	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
    1.28 +	XFlush(dpy);
    1.29 +}
    1.30 +
    1.31 +void
    1.32  manage(Window w, XWindowAttributes *wa)
    1.33  {
    1.34  	Client *c, **l;
    1.35 @@ -59,7 +73,7 @@
    1.36  		(c->size.flags & PMinSize && c->size.flags & PMaxSize
    1.37  		 && c->size.min_width == c->size.max_width
    1.38  		 && c->size.min_height == c->size.max_height);
    1.39 -	update_client_name(c);
    1.40 +	update_name(c);
    1.41  	twa.override_redirect = 1;
    1.42  	twa.background_pixmap = ParentRelative;
    1.43  	twa.event_mask = ExposureMask;
    1.44 @@ -73,9 +87,10 @@
    1.45  	for(l=&clients; *l; l=&(*l)->next);
    1.46  	c->next = *l; /* *l == nil */
    1.47  	*l = c;
    1.48 -	XMapRaised(dpy, c->win);
    1.49 -	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
    1.50 -	XFlush(dpy);
    1.51 +	c->snext = stack;
    1.52 +	stack = c;
    1.53 +	XMapWindow(dpy, c->win);
    1.54 +	focus(c);
    1.55  }
    1.56  
    1.57  static int
    1.58 @@ -98,12 +113,15 @@
    1.59  	for(l=&clients; *l && *l != c; l=&(*l)->next);
    1.60  	eassert(*l == c);
    1.61  	*l = c->next;
    1.62 +	for(l=&stack; *l && *l != c; l=&(*l)->snext);
    1.63 +	eassert(*l == c);
    1.64 +	*l = c->snext;
    1.65  	free(c);
    1.66  
    1.67  	XFlush(dpy);
    1.68  	XSetErrorHandler(error_handler);
    1.69  	XUngrabServer(dpy);
    1.70 -	/*flush_masked_events(EnterWindowMask); ? */
    1.71 +	flush_events(EnterWindowMask);
    1.72  }
    1.73  
    1.74  
    1.75 @@ -116,3 +134,4 @@
    1.76  			return c;
    1.77  	return NULL;
    1.78  }
    1.79 +
     2.1 --- a/cmd.c	Tue Jul 11 14:53:22 2006 +0200
     2.2 +++ b/cmd.c	Tue Jul 11 16:14:22 2006 +0200
     2.3 @@ -18,3 +18,17 @@
     2.4  	fputs("quit\n", stderr);
     2.5  	running = False;
     2.6  }
     2.7 +
     2.8 +void
     2.9 +kill(char *arg)
    2.10 +{
    2.11 +	Client *c = stack;
    2.12 +
    2.13 +	if(!c)
    2.14 +		return;
    2.15 +	if(c->proto & WM_PROTOCOL_DELWIN)
    2.16 +		send_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
    2.17 +	else
    2.18 +		XKillClient(dpy, c->win);
    2.19 +}
    2.20 +
     3.1 --- a/event.c	Tue Jul 11 14:53:22 2006 +0200
     3.2 +++ b/event.c	Tue Jul 11 16:14:22 2006 +0200
     3.3 @@ -7,6 +7,7 @@
     3.4  #include <stdlib.h>
     3.5  #include <string.h>
     3.6  #include <X11/keysym.h>
     3.7 +#include <X11/Xatom.h>
     3.8  
     3.9  #include "wm.h"
    3.10  
    3.11 @@ -35,7 +36,7 @@
    3.12  };
    3.13  
    3.14  unsigned int
    3.15 -flush_masked_events(long even_mask)
    3.16 +flush_events(long even_mask)
    3.17  {
    3.18  	XEvent ev;
    3.19  	unsigned int n = 0;
    3.20 @@ -91,25 +92,18 @@
    3.21  static void
    3.22  enternotify(XEvent *e)
    3.23  {
    3.24 -#if 0
    3.25  	XCrossingEvent *ev = &e->xcrossing;
    3.26  	Client *c;
    3.27  
    3.28  	if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
    3.29  		return;
    3.30  
    3.31 -	if((c = client_of_win(ev->window))) {
    3.32 -		Frame *f = c->sel;
    3.33 -		Area *a = f->area;
    3.34 -		if(a->mode == Colmax)
    3.35 -			c = a->sel->client;
    3.36 -		focus(c, False);
    3.37 -	}
    3.38 +	if((c = getclient(ev->window)))
    3.39 +		focus(c);
    3.40  	else if(ev->window == root) {
    3.41  		sel_screen = True;
    3.42 -		draw_frames();
    3.43 +		/*draw_frames();*/
    3.44  	}
    3.45 -#endif
    3.46  }
    3.47  
    3.48  static void
    3.49 @@ -137,9 +131,7 @@
    3.50  static void
    3.51  keymapnotify(XEvent *e)
    3.52  {
    3.53 -#if 0
    3.54  	update_keys();
    3.55 -#endif
    3.56  }
    3.57  
    3.58  static void
    3.59 @@ -164,16 +156,40 @@
    3.60  static void
    3.61  propertynotify(XEvent *e)
    3.62  {
    3.63 -#if 0
    3.64  	XPropertyEvent *ev = &e->xproperty;
    3.65 +	long msize;
    3.66  	Client *c;
    3.67  
    3.68  	if(ev->state == PropertyDelete)
    3.69  		return; /* ignore */
    3.70  
    3.71 -	if((c = client_of_win(ev->window)))
    3.72 -		prop_client(c, ev);
    3.73 -#endif
    3.74 +	if(ev->atom == wm_atom[WMProtocols]) {
    3.75 +		c->proto = win_proto(c->win);
    3.76 +		return;
    3.77 +	}
    3.78 +	if((c = getclient(ev->window))) {
    3.79 +		switch (ev->atom) {
    3.80 +			default: break;
    3.81 +			case XA_WM_TRANSIENT_FOR:
    3.82 +				XGetTransientForHint(dpy, c->win, &c->trans);
    3.83 +				break;
    3.84 +			case XA_WM_NORMAL_HINTS:
    3.85 +				if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize)
    3.86 +						|| !c->size.flags)
    3.87 +					c->size.flags = PSize;
    3.88 +				if(c->size.flags & PMinSize && c->size.flags & PMaxSize
    3.89 +						&& c->size.min_width == c->size.max_width
    3.90 +						&& c->size.min_height == c->size.max_height)
    3.91 +					c->fixedsize = True;
    3.92 +				else
    3.93 +					c->fixedsize = False;
    3.94 +				break;
    3.95 +		}
    3.96 +		if(ev->atom == XA_WM_NAME || ev->atom == net_atom[NetWMName]) {
    3.97 +			update_name(c);
    3.98 +			/*draw_frame(c->sel);*/
    3.99 +		}
   3.100 +	}
   3.101  }
   3.102  
   3.103  static void
     4.1 --- a/menu.c	Tue Jul 11 14:53:22 2006 +0200
     4.2 +++ b/menu.c	Tue Jul 11 16:14:22 2006 +0200
     4.3 @@ -304,7 +304,7 @@
     4.4  		}
     4.5  		break;
     4.6  	default:
     4.7 -		if((num == 1) && !iscntrl((int) buf[0])) {
     4.8 +		if(num && !iscntrl((int) buf[0])) {
     4.9  			buf[num] = 0;
    4.10  			if(len > 0)
    4.11  				strncat(text, buf, sizeof(text));
     5.1 --- a/wm.c	Tue Jul 11 14:53:22 2006 +0200
     5.2 +++ b/wm.c	Tue Jul 11 16:14:22 2006 +0200
     5.3 @@ -16,18 +16,18 @@
     5.4  /* X structs */
     5.5  Display *dpy;
     5.6  Window root, barwin;
     5.7 -Atom net_atom[NetLast];
     5.8 +Atom wm_atom[WMLast], net_atom[NetLast];
     5.9  Cursor cursor[CurLast];
    5.10  XRectangle rect, barrect;
    5.11  Bool running = True;
    5.12 +Bool sel_screen;
    5.13  
    5.14  char *bartext, tag[256];
    5.15 -int screen, sel_screen;
    5.16 +int screen;
    5.17  
    5.18  Brush brush = {0};
    5.19  Client *clients = NULL;
    5.20 -
    5.21 -enum { WM_PROTOCOL_DELWIN = 1 };
    5.22 +Client *stack = NULL;
    5.23  
    5.24  static Bool other_wm_running;
    5.25  static char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
    5.26 @@ -62,6 +62,62 @@
    5.27  		XFree(wins);
    5.28  }
    5.29  
    5.30 +static int
    5.31 +win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
    5.32 +{
    5.33 +	Atom real;
    5.34 +	int format;
    5.35 +	unsigned long res, extra;
    5.36 +	int status;
    5.37 +
    5.38 +	status = XGetWindowProperty(dpy, w, a, 0L, l, False, t, &real, &format,
    5.39 +			&res, &extra, prop);
    5.40 +
    5.41 +	if(status != Success || *prop == 0) {
    5.42 +		return 0;
    5.43 +	}
    5.44 +	if(res == 0) {
    5.45 +		free((void *) *prop);
    5.46 +	}
    5.47 +	return res;
    5.48 +}
    5.49 +
    5.50 +int
    5.51 +win_proto(Window w)
    5.52 +{
    5.53 +	Atom *protocols;
    5.54 +	long res;
    5.55 +	int protos = 0;
    5.56 +	int i;
    5.57 +
    5.58 +	res = win_property(w, wm_atom[WMProtocols], XA_ATOM, 20L,
    5.59 +			((unsigned char **) &protocols));
    5.60 +	if(res <= 0) {
    5.61 +		return protos;
    5.62 +	}
    5.63 +	for(i = 0; i < res; i++) {
    5.64 +		if(protocols[i] == wm_atom[WMDelete])
    5.65 +			protos |= WM_PROTOCOL_DELWIN;
    5.66 +	}
    5.67 +	free((char *) protocols);
    5.68 +	return protos;
    5.69 +}
    5.70 +
    5.71 +void
    5.72 +send_message(Window w, Atom a, long value)
    5.73 +{
    5.74 +	XEvent e;
    5.75 +
    5.76 +	e.type = ClientMessage;
    5.77 +	e.xclient.window = w;
    5.78 +	e.xclient.message_type = a;
    5.79 +	e.xclient.format = 32;
    5.80 +	e.xclient.data.l[0] = value;
    5.81 +	e.xclient.data.l[1] = CurrentTime;
    5.82 +	XSendEvent(dpy, w, False, NoEventMask, &e);
    5.83 +	XFlush(dpy);
    5.84 +}
    5.85 +
    5.86  /*
    5.87   * There's no way to check accesses to destroyed windows, thus
    5.88   * those cases are ignored (especially on UnmapNotify's).
    5.89 @@ -160,6 +216,8 @@
    5.90  	x_error_handler = XSetErrorHandler(error_handler);
    5.91  
    5.92  	/* init atoms */
    5.93 +	wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
    5.94 +	wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
    5.95  	net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
    5.96  	net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
    5.97  
     6.1 --- a/wm.h	Tue Jul 11 14:53:22 2006 +0200
     6.2 +++ b/wm.h	Tue Jul 11 16:14:22 2006 +0200
     6.3 @@ -9,7 +9,10 @@
     6.4  
     6.5  #include <X11/Xutil.h>
     6.6  
     6.7 +#define WM_PROTOCOL_DELWIN 1
     6.8 +
     6.9  /* atoms */
    6.10 +enum { WMProtocols, WMDelete, WMLast };
    6.11  enum { NetSupported, NetWMName, NetLast };
    6.12  
    6.13  /* cursor */
    6.14 @@ -25,6 +28,7 @@
    6.15  	char name[256];
    6.16  	char tag[256];
    6.17  	unsigned int border;
    6.18 +	int proto;
    6.19  	Bool fixedsize;
    6.20  	Window win;
    6.21  	Window trans;
    6.22 @@ -44,18 +48,17 @@
    6.23  
    6.24  extern Display *dpy;
    6.25  extern Window root, barwin;
    6.26 -extern Atom net_atom[NetLast];
    6.27 +extern Atom wm_atom[WMLast], net_atom[NetLast];
    6.28  extern Cursor cursor[CurLast];
    6.29  extern XRectangle rect, barrect;
    6.30 -extern Bool running;
    6.31 -extern Bool grid;
    6.32 +extern Bool running, sel_screen, grid;
    6.33  extern void (*handler[LASTEvent]) (XEvent *);
    6.34  
    6.35 -extern int screen, sel_screen;
    6.36 +extern int screen;
    6.37  extern char *bartext, tag[256];
    6.38  
    6.39  extern Brush brush;
    6.40 -extern Client *clients;
    6.41 +extern Client *clients, *stack;
    6.42  
    6.43  /* bar.c */
    6.44  extern void draw_bar();
    6.45 @@ -66,8 +69,13 @@
    6.46  
    6.47  /* client.c */
    6.48  extern void manage(Window w, XWindowAttributes *wa);
    6.49 -void unmanage(Client *c);
    6.50 -extern Client * getclient(Window w);
    6.51 +extern void unmanage(Client *c);
    6.52 +extern Client *getclient(Window w);
    6.53 +extern void focus(Client *c);
    6.54 +extern void update_name(Client *c);
    6.55 +
    6.56 +/* event.c */
    6.57 +extern unsigned int flush_events(long even_mask);
    6.58  
    6.59  /* key.c */
    6.60  extern void update_keys();
    6.61 @@ -75,3 +83,5 @@
    6.62  
    6.63  /* wm.c */
    6.64  extern int error_handler(Display *dpy, XErrorEvent *error);
    6.65 +extern void send_message(Window w, Atom a, long value);
    6.66 +extern int win_proto(Window w);