added protocol killing stuff
This commit is contained in:
		
							parent
							
								
									272e15c4b7
								
							
						
					
					
						commit
						3399650076
					
				
							
								
								
									
										33
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								client.c
									
									
									
									
									
								
							| @ -10,8 +10,8 @@ | |||||||
| #include "util.h" | #include "util.h" | ||||||
| #include "wm.h" | #include "wm.h" | ||||||
| 
 | 
 | ||||||
| static void | void | ||||||
| update_client_name(Client *c) | update_name(Client *c) | ||||||
| { | { | ||||||
| 	XTextProperty name; | 	XTextProperty name; | ||||||
| 	int n; | 	int n; | ||||||
| @ -37,6 +37,20 @@ update_client_name(Client *c) | |||||||
| 	XFree(name.value); | 	XFree(name.value); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void | ||||||
|  | focus(Client *c) | ||||||
|  | { | ||||||
|  | 	Client **l; | ||||||
|  | 	for(l=&stack; *l && *l != c; l=&(*l)->snext); | ||||||
|  | 	eassert(*l == c); | ||||||
|  | 	*l = c->snext; | ||||||
|  | 	c->snext = stack; | ||||||
|  | 	stack = c; | ||||||
|  | 	XRaiseWindow(dpy, c->win); | ||||||
|  | 	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); | ||||||
|  | 	XFlush(dpy); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void | void | ||||||
| manage(Window w, XWindowAttributes *wa) | manage(Window w, XWindowAttributes *wa) | ||||||
| { | { | ||||||
| @ -59,7 +73,7 @@ manage(Window w, XWindowAttributes *wa) | |||||||
| 		(c->size.flags & PMinSize && c->size.flags & PMaxSize | 		(c->size.flags & PMinSize && c->size.flags & PMaxSize | ||||||
| 		 && c->size.min_width == c->size.max_width | 		 && c->size.min_width == c->size.max_width | ||||||
| 		 && c->size.min_height == c->size.max_height); | 		 && c->size.min_height == c->size.max_height); | ||||||
| 	update_client_name(c); | 	update_name(c); | ||||||
| 	twa.override_redirect = 1; | 	twa.override_redirect = 1; | ||||||
| 	twa.background_pixmap = ParentRelative; | 	twa.background_pixmap = ParentRelative; | ||||||
| 	twa.event_mask = ExposureMask; | 	twa.event_mask = ExposureMask; | ||||||
| @ -73,9 +87,10 @@ manage(Window w, XWindowAttributes *wa) | |||||||
| 	for(l=&clients; *l; l=&(*l)->next); | 	for(l=&clients; *l; l=&(*l)->next); | ||||||
| 	c->next = *l; /* *l == nil */ | 	c->next = *l; /* *l == nil */ | ||||||
| 	*l = c; | 	*l = c; | ||||||
| 	XMapRaised(dpy, c->win); | 	c->snext = stack; | ||||||
| 	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); | 	stack = c; | ||||||
| 	XFlush(dpy); | 	XMapWindow(dpy, c->win); | ||||||
|  | 	focus(c); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int | static int | ||||||
| @ -98,12 +113,15 @@ unmanage(Client *c) | |||||||
| 	for(l=&clients; *l && *l != c; l=&(*l)->next); | 	for(l=&clients; *l && *l != c; l=&(*l)->next); | ||||||
| 	eassert(*l == c); | 	eassert(*l == c); | ||||||
| 	*l = c->next; | 	*l = c->next; | ||||||
|  | 	for(l=&stack; *l && *l != c; l=&(*l)->snext); | ||||||
|  | 	eassert(*l == c); | ||||||
|  | 	*l = c->snext; | ||||||
| 	free(c); | 	free(c); | ||||||
| 
 | 
 | ||||||
| 	XFlush(dpy); | 	XFlush(dpy); | ||||||
| 	XSetErrorHandler(error_handler); | 	XSetErrorHandler(error_handler); | ||||||
| 	XUngrabServer(dpy); | 	XUngrabServer(dpy); | ||||||
| 	/*flush_masked_events(EnterWindowMask); ? */ | 	flush_events(EnterWindowMask); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -116,3 +134,4 @@ getclient(Window w) | |||||||
| 			return c; | 			return c; | ||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								cmd.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								cmd.c
									
									
									
									
									
								
							| @ -18,3 +18,17 @@ quit(char *arg) | |||||||
| 	fputs("quit\n", stderr); | 	fputs("quit\n", stderr); | ||||||
| 	running = False; | 	running = False; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | kill(char *arg) | ||||||
|  | { | ||||||
|  | 	Client *c = stack; | ||||||
|  | 
 | ||||||
|  | 	if(!c) | ||||||
|  | 		return; | ||||||
|  | 	if(c->proto & WM_PROTOCOL_DELWIN) | ||||||
|  | 		send_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]); | ||||||
|  | 	else | ||||||
|  | 		XKillClient(dpy, c->win); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | |||||||
							
								
								
									
										50
									
								
								event.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								event.c
									
									
									
									
									
								
							| @ -7,6 +7,7 @@ | |||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <X11/keysym.h> | #include <X11/keysym.h> | ||||||
|  | #include <X11/Xatom.h> | ||||||
| 
 | 
 | ||||||
| #include "wm.h" | #include "wm.h" | ||||||
| 
 | 
 | ||||||
| @ -35,7 +36,7 @@ void (*handler[LASTEvent]) (XEvent *) = { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| unsigned int | unsigned int | ||||||
| flush_masked_events(long even_mask) | flush_events(long even_mask) | ||||||
| { | { | ||||||
| 	XEvent ev; | 	XEvent ev; | ||||||
| 	unsigned int n = 0; | 	unsigned int n = 0; | ||||||
| @ -91,25 +92,18 @@ destroynotify(XEvent *e) | |||||||
| static void | static void | ||||||
| enternotify(XEvent *e) | enternotify(XEvent *e) | ||||||
| { | { | ||||||
| #if 0 |  | ||||||
| 	XCrossingEvent *ev = &e->xcrossing; | 	XCrossingEvent *ev = &e->xcrossing; | ||||||
| 	Client *c; | 	Client *c; | ||||||
| 
 | 
 | ||||||
| 	if(ev->mode != NotifyNormal || ev->detail == NotifyInferior) | 	if(ev->mode != NotifyNormal || ev->detail == NotifyInferior) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	if((c = client_of_win(ev->window))) { | 	if((c = getclient(ev->window))) | ||||||
| 		Frame *f = c->sel; | 		focus(c); | ||||||
| 		Area *a = f->area; |  | ||||||
| 		if(a->mode == Colmax) |  | ||||||
| 			c = a->sel->client; |  | ||||||
| 		focus(c, False); |  | ||||||
| 	} |  | ||||||
| 	else if(ev->window == root) { | 	else if(ev->window == root) { | ||||||
| 		sel_screen = True; | 		sel_screen = True; | ||||||
| 		draw_frames(); | 		/*draw_frames();*/ | ||||||
| 	} | 	} | ||||||
| #endif |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| @ -137,9 +131,7 @@ expose(XEvent *e) | |||||||
| static void | static void | ||||||
| keymapnotify(XEvent *e) | keymapnotify(XEvent *e) | ||||||
| { | { | ||||||
| #if 0 |  | ||||||
| 	update_keys(); | 	update_keys(); | ||||||
| #endif |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| @ -164,16 +156,40 @@ maprequest(XEvent *e) | |||||||
| static void | static void | ||||||
| propertynotify(XEvent *e) | propertynotify(XEvent *e) | ||||||
| { | { | ||||||
| #if 0 |  | ||||||
| 	XPropertyEvent *ev = &e->xproperty; | 	XPropertyEvent *ev = &e->xproperty; | ||||||
|  | 	long msize; | ||||||
| 	Client *c; | 	Client *c; | ||||||
| 
 | 
 | ||||||
| 	if(ev->state == PropertyDelete) | 	if(ev->state == PropertyDelete) | ||||||
| 		return; /* ignore */ | 		return; /* ignore */ | ||||||
| 
 | 
 | ||||||
| 	if((c = client_of_win(ev->window))) | 	if(ev->atom == wm_atom[WMProtocols]) { | ||||||
| 		prop_client(c, ev); | 		c->proto = win_proto(c->win); | ||||||
| #endif | 		return; | ||||||
|  | 	} | ||||||
|  | 	if((c = getclient(ev->window))) { | ||||||
|  | 		switch (ev->atom) { | ||||||
|  | 			default: break; | ||||||
|  | 			case XA_WM_TRANSIENT_FOR: | ||||||
|  | 				XGetTransientForHint(dpy, c->win, &c->trans); | ||||||
|  | 				break; | ||||||
|  | 			case XA_WM_NORMAL_HINTS: | ||||||
|  | 				if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) | ||||||
|  | 						|| !c->size.flags) | ||||||
|  | 					c->size.flags = PSize; | ||||||
|  | 				if(c->size.flags & PMinSize && c->size.flags & PMaxSize | ||||||
|  | 						&& c->size.min_width == c->size.max_width | ||||||
|  | 						&& c->size.min_height == c->size.max_height) | ||||||
|  | 					c->fixedsize = True; | ||||||
|  | 				else | ||||||
|  | 					c->fixedsize = False; | ||||||
|  | 				break; | ||||||
|  | 		} | ||||||
|  | 		if(ev->atom == XA_WM_NAME || ev->atom == net_atom[NetWMName]) { | ||||||
|  | 			update_name(c); | ||||||
|  | 			/*draw_frame(c->sel);*/ | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								menu.c
									
									
									
									
									
								
							| @ -304,7 +304,7 @@ kpress(XKeyEvent * e) | |||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		if((num == 1) && !iscntrl((int) buf[0])) { | 		if(num && !iscntrl((int) buf[0])) { | ||||||
| 			buf[num] = 0; | 			buf[num] = 0; | ||||||
| 			if(len > 0) | 			if(len > 0) | ||||||
| 				strncat(text, buf, sizeof(text)); | 				strncat(text, buf, sizeof(text)); | ||||||
|  | |||||||
							
								
								
									
										66
									
								
								wm.c
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								wm.c
									
									
									
									
									
								
							| @ -16,18 +16,18 @@ | |||||||
| /* X structs */ | /* X structs */ | ||||||
| Display *dpy; | Display *dpy; | ||||||
| Window root, barwin; | Window root, barwin; | ||||||
| Atom net_atom[NetLast]; | Atom wm_atom[WMLast], net_atom[NetLast]; | ||||||
| Cursor cursor[CurLast]; | Cursor cursor[CurLast]; | ||||||
| XRectangle rect, barrect; | XRectangle rect, barrect; | ||||||
| Bool running = True; | Bool running = True; | ||||||
|  | Bool sel_screen; | ||||||
| 
 | 
 | ||||||
| char *bartext, tag[256]; | char *bartext, tag[256]; | ||||||
| int screen, sel_screen; | int screen; | ||||||
| 
 | 
 | ||||||
| Brush brush = {0}; | Brush brush = {0}; | ||||||
| Client *clients = NULL; | Client *clients = NULL; | ||||||
| 
 | Client *stack = NULL; | ||||||
| enum { WM_PROTOCOL_DELWIN = 1 }; |  | ||||||
| 
 | 
 | ||||||
| static Bool other_wm_running; | static Bool other_wm_running; | ||||||
| static char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; | static char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; | ||||||
| @ -62,6 +62,62 @@ scan_wins() | |||||||
| 		XFree(wins); | 		XFree(wins); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static int | ||||||
|  | win_property(Window w, Atom a, Atom t, long l, unsigned char **prop) | ||||||
|  | { | ||||||
|  | 	Atom real; | ||||||
|  | 	int format; | ||||||
|  | 	unsigned long res, extra; | ||||||
|  | 	int status; | ||||||
|  | 
 | ||||||
|  | 	status = XGetWindowProperty(dpy, w, a, 0L, l, False, t, &real, &format, | ||||||
|  | 			&res, &extra, prop); | ||||||
|  | 
 | ||||||
|  | 	if(status != Success || *prop == 0) { | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 	if(res == 0) { | ||||||
|  | 		free((void *) *prop); | ||||||
|  | 	} | ||||||
|  | 	return res; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | win_proto(Window w) | ||||||
|  | { | ||||||
|  | 	Atom *protocols; | ||||||
|  | 	long res; | ||||||
|  | 	int protos = 0; | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	res = win_property(w, wm_atom[WMProtocols], XA_ATOM, 20L, | ||||||
|  | 			((unsigned char **) &protocols)); | ||||||
|  | 	if(res <= 0) { | ||||||
|  | 		return protos; | ||||||
|  | 	} | ||||||
|  | 	for(i = 0; i < res; i++) { | ||||||
|  | 		if(protocols[i] == wm_atom[WMDelete]) | ||||||
|  | 			protos |= WM_PROTOCOL_DELWIN; | ||||||
|  | 	} | ||||||
|  | 	free((char *) protocols); | ||||||
|  | 	return protos; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | send_message(Window w, Atom a, long value) | ||||||
|  | { | ||||||
|  | 	XEvent e; | ||||||
|  | 
 | ||||||
|  | 	e.type = ClientMessage; | ||||||
|  | 	e.xclient.window = w; | ||||||
|  | 	e.xclient.message_type = a; | ||||||
|  | 	e.xclient.format = 32; | ||||||
|  | 	e.xclient.data.l[0] = value; | ||||||
|  | 	e.xclient.data.l[1] = CurrentTime; | ||||||
|  | 	XSendEvent(dpy, w, False, NoEventMask, &e); | ||||||
|  | 	XFlush(dpy); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * There's no way to check accesses to destroyed windows, thus |  * There's no way to check accesses to destroyed windows, thus | ||||||
|  * those cases are ignored (especially on UnmapNotify's). |  * those cases are ignored (especially on UnmapNotify's). | ||||||
| @ -160,6 +216,8 @@ main(int argc, char *argv[]) | |||||||
| 	x_error_handler = XSetErrorHandler(error_handler); | 	x_error_handler = XSetErrorHandler(error_handler); | ||||||
| 
 | 
 | ||||||
| 	/* init atoms */ | 	/* init atoms */ | ||||||
|  | 	wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); | ||||||
|  | 	wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); | ||||||
| 	net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); | 	net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); | ||||||
| 	net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); | 	net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										22
									
								
								wm.h
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								wm.h
									
									
									
									
									
								
							| @ -9,7 +9,10 @@ | |||||||
| 
 | 
 | ||||||
| #include <X11/Xutil.h> | #include <X11/Xutil.h> | ||||||
| 
 | 
 | ||||||
|  | #define WM_PROTOCOL_DELWIN 1 | ||||||
|  | 
 | ||||||
| /* atoms */ | /* atoms */ | ||||||
|  | enum { WMProtocols, WMDelete, WMLast }; | ||||||
| enum { NetSupported, NetWMName, NetLast }; | enum { NetSupported, NetWMName, NetLast }; | ||||||
| 
 | 
 | ||||||
| /* cursor */ | /* cursor */ | ||||||
| @ -25,6 +28,7 @@ struct Client { | |||||||
| 	char name[256]; | 	char name[256]; | ||||||
| 	char tag[256]; | 	char tag[256]; | ||||||
| 	unsigned int border; | 	unsigned int border; | ||||||
|  | 	int proto; | ||||||
| 	Bool fixedsize; | 	Bool fixedsize; | ||||||
| 	Window win; | 	Window win; | ||||||
| 	Window trans; | 	Window trans; | ||||||
| @ -44,18 +48,17 @@ struct Key { | |||||||
| 
 | 
 | ||||||
| extern Display *dpy; | extern Display *dpy; | ||||||
| extern Window root, barwin; | extern Window root, barwin; | ||||||
| extern Atom net_atom[NetLast]; | extern Atom wm_atom[WMLast], net_atom[NetLast]; | ||||||
| extern Cursor cursor[CurLast]; | extern Cursor cursor[CurLast]; | ||||||
| extern XRectangle rect, barrect; | extern XRectangle rect, barrect; | ||||||
| extern Bool running; | extern Bool running, sel_screen, grid; | ||||||
| extern Bool grid; |  | ||||||
| extern void (*handler[LASTEvent]) (XEvent *); | extern void (*handler[LASTEvent]) (XEvent *); | ||||||
| 
 | 
 | ||||||
| extern int screen, sel_screen; | extern int screen; | ||||||
| extern char *bartext, tag[256]; | extern char *bartext, tag[256]; | ||||||
| 
 | 
 | ||||||
| extern Brush brush; | extern Brush brush; | ||||||
| extern Client *clients; | extern Client *clients, *stack; | ||||||
| 
 | 
 | ||||||
| /* bar.c */ | /* bar.c */ | ||||||
| extern void draw_bar(); | extern void draw_bar(); | ||||||
| @ -66,8 +69,13 @@ extern void quit(char *arg); | |||||||
| 
 | 
 | ||||||
| /* client.c */ | /* client.c */ | ||||||
| extern void manage(Window w, XWindowAttributes *wa); | extern void manage(Window w, XWindowAttributes *wa); | ||||||
| void unmanage(Client *c); | extern void unmanage(Client *c); | ||||||
| extern Client *getclient(Window w); | extern Client *getclient(Window w); | ||||||
|  | extern void focus(Client *c); | ||||||
|  | extern void update_name(Client *c); | ||||||
|  | 
 | ||||||
|  | /* event.c */ | ||||||
|  | extern unsigned int flush_events(long even_mask); | ||||||
| 
 | 
 | ||||||
| /* key.c */ | /* key.c */ | ||||||
| extern void update_keys(); | extern void update_keys(); | ||||||
| @ -75,3 +83,5 @@ extern void keypress(XEvent *e); | |||||||
| 
 | 
 | ||||||
| /* wm.c */ | /* wm.c */ | ||||||
| extern int error_handler(Display *dpy, XErrorEvent *error); | extern int error_handler(Display *dpy, XErrorEvent *error); | ||||||
|  | extern void send_message(Window w, Atom a, long value); | ||||||
|  | extern int win_proto(Window w); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Anselm R. Garbe
						Anselm R. Garbe