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 "wm.h" | ||||
| 
 | ||||
| static void | ||||
| update_client_name(Client *c) | ||||
| void | ||||
| update_name(Client *c) | ||||
| { | ||||
| 	XTextProperty name; | ||||
| 	int n; | ||||
| @ -37,6 +37,20 @@ update_client_name(Client *c) | ||||
| 	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 | ||||
| manage(Window w, XWindowAttributes *wa) | ||||
| { | ||||
| @ -59,7 +73,7 @@ manage(Window w, XWindowAttributes *wa) | ||||
| 		(c->size.flags & PMinSize && c->size.flags & PMaxSize | ||||
| 		 && c->size.min_width == c->size.max_width | ||||
| 		 && c->size.min_height == c->size.max_height); | ||||
| 	update_client_name(c); | ||||
| 	update_name(c); | ||||
| 	twa.override_redirect = 1; | ||||
| 	twa.background_pixmap = ParentRelative; | ||||
| 	twa.event_mask = ExposureMask; | ||||
| @ -73,9 +87,10 @@ manage(Window w, XWindowAttributes *wa) | ||||
| 	for(l=&clients; *l; l=&(*l)->next); | ||||
| 	c->next = *l; /* *l == nil */ | ||||
| 	*l = c; | ||||
| 	XMapRaised(dpy, c->win); | ||||
| 	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); | ||||
| 	XFlush(dpy); | ||||
| 	c->snext = stack; | ||||
| 	stack = c; | ||||
| 	XMapWindow(dpy, c->win); | ||||
| 	focus(c); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| @ -98,12 +113,15 @@ unmanage(Client *c) | ||||
| 	for(l=&clients; *l && *l != c; l=&(*l)->next); | ||||
| 	eassert(*l == c); | ||||
| 	*l = c->next; | ||||
| 	for(l=&stack; *l && *l != c; l=&(*l)->snext); | ||||
| 	eassert(*l == c); | ||||
| 	*l = c->snext; | ||||
| 	free(c); | ||||
| 
 | ||||
| 	XFlush(dpy); | ||||
| 	XSetErrorHandler(error_handler); | ||||
| 	XUngrabServer(dpy); | ||||
| 	/*flush_masked_events(EnterWindowMask); ? */ | ||||
| 	flush_events(EnterWindowMask); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| @ -116,3 +134,4 @@ getclient(Window w) | ||||
| 			return c; | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										14
									
								
								cmd.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								cmd.c
									
									
									
									
									
								
							| @ -18,3 +18,17 @@ quit(char *arg) | ||||
| 	fputs("quit\n", stderr); | ||||
| 	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 <string.h> | ||||
| #include <X11/keysym.h> | ||||
| #include <X11/Xatom.h> | ||||
| 
 | ||||
| #include "wm.h" | ||||
| 
 | ||||
| @ -35,7 +36,7 @@ void (*handler[LASTEvent]) (XEvent *) = { | ||||
| }; | ||||
| 
 | ||||
| unsigned int | ||||
| flush_masked_events(long even_mask) | ||||
| flush_events(long even_mask) | ||||
| { | ||||
| 	XEvent ev; | ||||
| 	unsigned int n = 0; | ||||
| @ -91,25 +92,18 @@ destroynotify(XEvent *e) | ||||
| static void | ||||
| enternotify(XEvent *e) | ||||
| { | ||||
| #if 0 | ||||
| 	XCrossingEvent *ev = &e->xcrossing; | ||||
| 	Client *c; | ||||
| 
 | ||||
| 	if(ev->mode != NotifyNormal || ev->detail == NotifyInferior) | ||||
| 		return; | ||||
| 
 | ||||
| 	if((c = client_of_win(ev->window))) { | ||||
| 		Frame *f = c->sel; | ||||
| 		Area *a = f->area; | ||||
| 		if(a->mode == Colmax) | ||||
| 			c = a->sel->client; | ||||
| 		focus(c, False); | ||||
| 	} | ||||
| 	if((c = getclient(ev->window))) | ||||
| 		focus(c); | ||||
| 	else if(ev->window == root) { | ||||
| 		sel_screen = True; | ||||
| 		draw_frames(); | ||||
| 		/*draw_frames();*/ | ||||
| 	} | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @ -137,9 +131,7 @@ expose(XEvent *e) | ||||
| static void | ||||
| keymapnotify(XEvent *e) | ||||
| { | ||||
| #if 0 | ||||
| 	update_keys(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @ -164,16 +156,40 @@ maprequest(XEvent *e) | ||||
| static void | ||||
| propertynotify(XEvent *e) | ||||
| { | ||||
| #if 0 | ||||
| 	XPropertyEvent *ev = &e->xproperty; | ||||
| 	long msize; | ||||
| 	Client *c; | ||||
| 
 | ||||
| 	if(ev->state == PropertyDelete) | ||||
| 		return; /* ignore */ | ||||
| 
 | ||||
| 	if((c = client_of_win(ev->window))) | ||||
| 		prop_client(c, ev); | ||||
| #endif | ||||
| 	if(ev->atom == wm_atom[WMProtocols]) { | ||||
| 		c->proto = win_proto(c->win); | ||||
| 		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 | ||||
|  | ||||
							
								
								
									
										2
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								menu.c
									
									
									
									
									
								
							| @ -304,7 +304,7 @@ kpress(XKeyEvent * e) | ||||
| 		} | ||||
| 		break; | ||||
| 	default: | ||||
| 		if((num == 1) && !iscntrl((int) buf[0])) { | ||||
| 		if(num && !iscntrl((int) buf[0])) { | ||||
| 			buf[num] = 0; | ||||
| 			if(len > 0) | ||||
| 				strncat(text, buf, sizeof(text)); | ||||
|  | ||||
							
								
								
									
										66
									
								
								wm.c
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								wm.c
									
									
									
									
									
								
							| @ -16,18 +16,18 @@ | ||||
| /* X structs */ | ||||
| Display *dpy; | ||||
| Window root, barwin; | ||||
| Atom net_atom[NetLast]; | ||||
| Atom wm_atom[WMLast], net_atom[NetLast]; | ||||
| Cursor cursor[CurLast]; | ||||
| XRectangle rect, barrect; | ||||
| Bool running = True; | ||||
| Bool sel_screen; | ||||
| 
 | ||||
| char *bartext, tag[256]; | ||||
| int screen, sel_screen; | ||||
| int screen; | ||||
| 
 | ||||
| Brush brush = {0}; | ||||
| Client *clients = NULL; | ||||
| 
 | ||||
| enum { WM_PROTOCOL_DELWIN = 1 }; | ||||
| Client *stack = NULL; | ||||
| 
 | ||||
| static Bool other_wm_running; | ||||
| static char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; | ||||
| @ -62,6 +62,62 @@ scan_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 | ||||
|  * those cases are ignored (especially on UnmapNotify's). | ||||
| @ -160,6 +216,8 @@ main(int argc, char *argv[]) | ||||
| 	x_error_handler = XSetErrorHandler(error_handler); | ||||
| 
 | ||||
| 	/* 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[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										22
									
								
								wm.h
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								wm.h
									
									
									
									
									
								
							| @ -9,7 +9,10 @@ | ||||
| 
 | ||||
| #include <X11/Xutil.h> | ||||
| 
 | ||||
| #define WM_PROTOCOL_DELWIN 1 | ||||
| 
 | ||||
| /* atoms */ | ||||
| enum { WMProtocols, WMDelete, WMLast }; | ||||
| enum { NetSupported, NetWMName, NetLast }; | ||||
| 
 | ||||
| /* cursor */ | ||||
| @ -25,6 +28,7 @@ struct Client { | ||||
| 	char name[256]; | ||||
| 	char tag[256]; | ||||
| 	unsigned int border; | ||||
| 	int proto; | ||||
| 	Bool fixedsize; | ||||
| 	Window win; | ||||
| 	Window trans; | ||||
| @ -44,18 +48,17 @@ struct Key { | ||||
| 
 | ||||
| extern Display *dpy; | ||||
| extern Window root, barwin; | ||||
| extern Atom net_atom[NetLast]; | ||||
| extern Atom wm_atom[WMLast], net_atom[NetLast]; | ||||
| extern Cursor cursor[CurLast]; | ||||
| extern XRectangle rect, barrect; | ||||
| extern Bool running; | ||||
| extern Bool grid; | ||||
| extern Bool running, sel_screen, grid; | ||||
| extern void (*handler[LASTEvent]) (XEvent *); | ||||
| 
 | ||||
| extern int screen, sel_screen; | ||||
| extern int screen; | ||||
| extern char *bartext, tag[256]; | ||||
| 
 | ||||
| extern Brush brush; | ||||
| extern Client *clients; | ||||
| extern Client *clients, *stack; | ||||
| 
 | ||||
| /* bar.c */ | ||||
| extern void draw_bar(); | ||||
| @ -66,8 +69,13 @@ extern void quit(char *arg); | ||||
| 
 | ||||
| /* client.c */ | ||||
| extern void manage(Window w, XWindowAttributes *wa); | ||||
| void unmanage(Client *c); | ||||
| extern void unmanage(Client *c); | ||||
| 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 */ | ||||
| extern void update_keys(); | ||||
| @ -75,3 +83,5 @@ extern void keypress(XEvent *e); | ||||
| 
 | ||||
| /* wm.c */ | ||||
| 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