arg@644: /* (C)opyright MMVI-MMVII Anselm R. Garbe garbeam@0: * See LICENSE file for license details. arg@457: * arg@457: * dynamic window manager is designed like any other X client as well. It is arg@457: * driven through handling X events. In contrast to other X clients, a window arg@468: * manager selects for SubstructureRedirectMask on the root window, to receive arg@468: * events about window (dis-)appearance. Only one X connection at a time is arg@468: * allowed to select for this event mask. arg@457: * arg@468: * Calls to fetch an X event from the event queue are blocking. Due reading arg@469: * status text from standard input, a select()-driven main loop has been arg@468: * implemented which selects for reads on the X connection and STDIN_FILENO to arg@468: * handle all data smoothly. The event handlers of dwm are organized in an arg@468: * array which is accessed whenever a new event has been fetched. This allows arg@468: * event dispatching in O(1) time. arg@457: * arg@460: * Each child of the root window is called a client, except windows which have arg@460: * set the override_redirect flag. Clients are organized in a global arg@460: * doubly-linked client list, the focus history is remembered through a global arg@460: * stack list. Each client contains an array of Bools of the same size as the arg@460: * global tags array to indicate the tags of a client. For each client dwm arg@468: * creates a small title window, which is resized whenever the (_NET_)WM_NAME arg@468: * properties are updated or the client is moved/resized. arg@457: * arg@459: * Keys and tagging rules are organized as arrays and defined in the config.h arg@459: * file. These arrays are kept static in event.o and tag.o respectively, arg@459: * because no other part of dwm needs access to them. The current mode is arg@469: * represented by the arrange() function pointer, which wether points to arg@469: * dofloat() or dotile(). arg@457: * arg@468: * To understand everything else, start reading main.c:main(). garbeam@0: */ garbeam@0: arg@166: #include "config.h" garbeam@32: #include garbeam@32: arg@143: /* mask shorthands, used in event.c and client.c */ arg@150: #define BUTTONMASK (ButtonPressMask | ButtonReleaseMask) arg@143: arg@452: enum { NetSupported, NetWMName, NetLast }; /* EWMH atoms */ arg@725: enum { WMProtocols, WMDelete, WMState, WMLast }; /* default atoms */ arg@452: enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ arg@689: enum { ColBorder, ColFG, ColBG, ColLast }; /* color */ arg@452: arg@333: typedef union { arg@189: const char *cmd; garbeam@49: int i; arg@452: } Arg; /* argument type */ arg@99: arg@333: typedef struct { garbeam@32: int ascent; garbeam@32: int descent; garbeam@32: int height; garbeam@84: XFontSet set; garbeam@84: XFontStruct *xfont; arg@333: } Fnt; garbeam@32: arg@452: typedef struct { garbeam@32: int x, y, w, h; arg@353: unsigned long norm[ColLast]; arg@353: unsigned long sel[ColLast]; garbeam@84: Drawable drawable; garbeam@84: Fnt font; garbeam@84: GC gc; arg@452: } DC; /* draw context */ garbeam@32: arg@333: typedef struct Client Client; garbeam@0: struct Client { garbeam@31: char name[256]; arg@115: int x, y, w, h; arg@480: int rx, ry, rw, rh; /* revert geometry */ garbeam@20: int basew, baseh, incw, inch, maxw, maxh, minw, minh; arg@731: int minax, minay, maxax, maxay; arg@164: long flags; arg@573: unsigned int border; arg@734: Bool isfixed, isfloat, ismax; arg@178: Bool *tags; garbeam@84: Client *next; arg@127: Client *prev; arg@446: Client *snext; garbeam@0: Window win; garbeam@0: }; garbeam@0: arg@452: extern const char *tags[]; /* all tags */ arg@688: extern char stext[256]; /* status text */ arg@697: extern int bh, bmw; /* bar height, bar mode label width */ arg@524: extern int screen, sx, sy, sw, sh; /* screen geometry */ arg@565: extern int wax, way, wah, waw; /* windowarea geometry */ arg@650: extern unsigned int master, nmaster; /* master percent, number of master clients */ arg@650: extern unsigned int ntags, numlockmask; /* number of tags, dynamic lock mask */ arg@452: extern void (*handler[LASTEvent])(XEvent *); /* event handler */ arg@533: extern void (*arrange)(void); /* arrange function, indicates mode */ garbeam@84: extern Atom wmatom[WMLast], netatom[NetLast]; arg@716: extern Bool running, selscreen, *seltag; /* seltag is array of Bool */ arg@488: extern Client *clients, *sel, *stack; /* global client list and stack */ garbeam@84: extern Cursor cursor[CurLast]; arg@454: extern DC dc; /* global draw context */ garbeam@84: extern Display *dpy; garbeam@84: extern Window root, barwin; garbeam@3: garbeam@5: /* client.c */ arg@491: extern void configure(Client *c); /* send synthetic configure event */ arg@452: extern void focus(Client *c); /* focus c, c may be NULL */ arg@452: extern Client *getclient(Window w); /* return client of w */ arg@734: extern Bool isprotodel(Client *c); /* returns True if c->win supports wmatom[WMDelete] */ arg@452: extern void killclient(Arg *arg); /* kill c nicely */ arg@452: extern void manage(Window w, XWindowAttributes *wa); /* manage new client */ arg@708: extern void resize(Client *c, Bool sizehints); /* resize c*/ arg@640: extern void updatesizehints(Client *c); /* update the size hint variables of c */ arg@454: extern void updatetitle(Client *c); /* update the name of c */ arg@452: extern void unmanage(Client *c); /* destroy c */ garbeam@13: garbeam@33: /* draw.c */ arg@487: extern void drawstatus(void); /* draw the bar */ arg@452: extern unsigned long getcolor(const char *colstr); /* return color of colstr */ arg@452: extern void setfont(const char *fontstr); /* set the font for DC */ arg@456: extern unsigned int textw(const char *text); /* return the width of text in px*/ garbeam@33: garbeam@75: /* event.c */ arg@487: extern void grabkeys(void); /* grab all keys defined in config.h */ arg@487: extern void procevent(void); /* process pending X events */ garbeam@18: garbeam@43: /* main.c */ arg@452: extern void quit(Arg *arg); /* quit dwm nicely */ arg@452: extern void sendevent(Window w, Atom a, long value); /* send synthetic event to w */ arg@452: extern int xerror(Display *dsply, XErrorEvent *ee); /* dwm's X error handler */ garbeam@43: garbeam@75: /* tag.c */ arg@487: extern void initrregs(void); /* initialize regexps of rules defined in config.h */ arg@452: extern Client *getnext(Client *c); /* returns next visible client */ arg@452: extern Client *getprev(Client *c); /* returns previous visible client */ arg@454: extern void settags(Client *c, Client *trans); /* sets tags of c */ arg@456: extern void tag(Arg *arg); /* tags c with arg's index */ arg@456: extern void toggletag(Arg *arg); /* toggles c tags with arg's index */ meillo@749: extern void viewnext(Arg *arg); /* view next tag(s) */ garbeam@73: garbeam@32: /* util.c */ arg@452: extern void *emallocz(unsigned int size); /* allocates zero-initialized memory, exits on error */ arg@456: extern void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */ arg@456: extern void spawn(Arg *arg); /* forks a new subprocess with to arg's cmd */ arg@327: arg@327: /* view.c */ arg@452: extern void detach(Client *c); /* detaches c from global client list */ arg@533: extern void dofloat(void); /* arranges all windows floating */ arg@533: extern void dotile(void); /* arranges all windows tiled */ meillo@749: extern void domax(void); /* arranges all windows fullscreen */ arg@452: extern void focusnext(Arg *arg); /* focuses next visible client, arg is ignored */ arg@452: extern void focusprev(Arg *arg); /* focuses previous visible client, arg is ignored */ arg@650: extern void incnmaster(Arg *arg); /* increments nmaster with arg's index value */ arg@452: extern Bool isvisible(Client *c); /* returns True if client is visible */ arg@559: extern void resizemaster(Arg *arg); /* resizes the master percent with arg's index value */ arg@487: extern void restack(void); /* restores z layers of all clients */ arg@585: extern void togglefloat(Arg *arg); /* toggles focusesd client between floating/non-floating state */ arg@456: extern void togglemode(Arg *arg); /* toggles global arrange function (dotile/dofloat) */ arg@456: extern void toggleview(Arg *arg); /* toggles the tag with arg's index (in)visible */ arg@456: extern void view(Arg *arg); /* views the tag with arg's index */ arg@508: extern void zoom(Arg *arg); /* zooms the focused client to master area, arg is ignored */