X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=wm.c;h=837be3c949ec412182de5f3d9fa765e77d7c57ec;hb=b9da4b082eb658b4142b61c149212f414f7653b6;hp=ef4721d15566701ce82d9cf3bf9d7a33e7e5861b;hpb=005362043d8b0bbf856f301c231d4f10c519b8c4;p=dwm.git diff --git a/wm.c b/wm.c index ef4721d..837be3c 100644 --- a/wm.c +++ b/wm.c @@ -3,10 +3,15 @@ * See LICENSE file for license details. */ +#include + #include #include #include +#include +#include + #include #include #include @@ -16,23 +21,29 @@ /* 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; +char statustext[1024], tag[256]; +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"; +static const char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; static int (*x_error_handler) (Display *, XErrorEvent *); +static const char *status[] = { + "sh", "-c", "echo -n `date '+%Y/%m/%d %H:%M'`" + " `uptime | sed 's/.*://; s/,//g'`" + " `acpi | awk '{print $4}' | sed 's/,//'`", 0 +}; + static void usage() { @@ -62,6 +73,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). @@ -104,12 +171,9 @@ startup_error_handler(Display *dpy, XErrorEvent *error) static void cleanup() { - /* - Client *c; - for(c=client; c; c=c->next) - reparent_client(c, root, c->sel->rect.x, c->sel->rect.y); + while(clients) + unmanage(clients); XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); - */ } int @@ -120,6 +184,11 @@ main(int argc, char *argv[]) unsigned int mask; Window w; XEvent ev; + fd_set fds; + struct timeval t, timeout = { + .tv_usec = 0, + .tv_sec = STATUSDELAY, + }; /* command line args */ for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) { @@ -160,6 +229,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); @@ -193,9 +264,9 @@ main(int argc, char *argv[]) barrect.width, barrect.height, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - bartext = NULL; XDefineCursor(dpy, barwin, cursor[CurNormal]); XMapRaised(dpy, barwin); + pipe_spawn(statustext, sizeof(statustext), dpy, (char **)status); draw_bar(); wa.event_mask = SubstructureRedirectMask | EnterWindowMask \ @@ -206,9 +277,21 @@ main(int argc, char *argv[]) scan_wins(); while(running) { - XNextEvent(dpy, &ev); - if(handler[ev.type]) - (handler[ev.type]) (&ev); /* call handler */ + if(XPending(dpy) > 0) { + XNextEvent(dpy, &ev); + if(handler[ev.type]) + (handler[ev.type]) (&ev); /* call handler */ + continue; + } + FD_ZERO(&fds); + FD_SET(ConnectionNumber(dpy), &fds); + t = timeout; + if(select(ConnectionNumber(dpy) + 1, &fds, NULL, NULL, &t) > 0) + continue; + else if(errno != EINTR) { + pipe_spawn(statustext, sizeof(statustext), dpy, (char **)status); + draw_bar(); + } } cleanup();