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);