t* dwm + patches
       
   URI git clone git://git.codevoid.de/dwm-sdk
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 33996500763b04119a6867dfa4040a4236c21a41
   DIR parent 272e15c4b7bdeeb258caadb7c62e70c49c12b16d
   URI Author: Anselm R. Garbe <garbeam@wmii.de>
       Date:   Tue, 11 Jul 2006 16:14:22 +0200
       
       added protocol killing stuff
       
       Diffstat:
         M client.c                            |      33 ++++++++++++++++++++++++-------
         M cmd.c                               |      14 ++++++++++++++
         M event.c                             |      50 ++++++++++++++++++++-----------
         M menu.c                              |       2 +-
         M wm.c                                |      66 +++++++++++++++++++++++++++++--
         M wm.h                                |      24 +++++++++++++++++-------
       
       6 files changed, 153 insertions(+), 36 deletions(-)
       ---
   DIR diff --git a/client.c b/client.c
       t@@ -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;
       t@@ -38,6 +38,20 @@ update_client_name(Client *c)
        }
        
        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)
        {
                Client *c, **l;
       t@@ -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;
       t@@ -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
       t@@ -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);
        }
        
        
       t@@ -116,3 +134,4 @@ getclient(Window w)
                                return c;
                return NULL;
        }
       +
   DIR diff --git a/cmd.c b/cmd.c
       t@@ -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);
       +}
       +
   DIR diff --git a/event.c b/event.c
       t@@ -7,6 +7,7 @@
        #include <stdlib.h>
        #include <string.h>
        #include <X11/keysym.h>
       +#include <X11/Xatom.h>
        
        #include "wm.h"
        
       t@@ -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;
       t@@ -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
       t@@ -137,9 +131,7 @@ expose(XEvent *e)
        static void
        keymapnotify(XEvent *e)
        {
       -#if 0
                update_keys();
       -#endif
        }
        
        static void
       t@@ -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
   DIR diff --git a/menu.c b/menu.c
       t@@ -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));
   DIR diff --git a/wm.c b/wm.c
       t@@ -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";
       t@@ -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).
       t@@ -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);
        
   DIR diff --git a/wm.h b/wm.h
       t@@ -9,7 +9,10 @@
        
        #include <X11/Xutil.h>
        
       +#define WM_PROTOCOL_DELWIN 1
       +
        /* atoms */
       +enum { WMProtocols, WMDelete, WMLast };
        enum { NetSupported, NetWMName, NetLast };
        
        /* cursor */
       t@@ -25,6 +28,7 @@ struct Client {
                char name[256];
                char tag[256];
                unsigned int border;
       +        int proto;
                Bool fixedsize;
                Window win;
                Window trans;
       t@@ -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();
       t@@ -66,8 +69,13 @@ extern void quit(char *arg);
        
        /* client.c */
        extern void manage(Window w, XWindowAttributes *wa);
       -void unmanage(Client *c);
       -extern Client * getclient(Window w);
       +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();
       t@@ -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);