Compare commits

...

20 Commits
5.3 ... 5.4.1

Author SHA1 Message Date
90687482ad fixed an issue reported by Nibble, also fixed s/2008/2009/ 2009-02-08 12:11:22 +00:00
5ab627c06c Added tag 5.4 for changeset 8b7836a471f8 2009-02-08 09:47:02 +00:00
76d7e80fc4 avoid reverting the border if it's not necessary (avoids some flashing on view()) 2009-02-08 09:46:23 +00:00
af8049bce8 spotted missing spaces 2008-12-20 12:02:14 +00:00
2bb51b3246 reverting some border patches 2008-12-20 00:02:56 +00:00
b16d8282be changed adjustborder to be a macro 2008-12-19 23:56:00 +00:00
fef4614772 applied yiyus applyrules() patch 2008-12-19 23:41:31 +00:00
be39dddcc5 implemented noborder for 1 client in the view 2008-12-17 21:25:32 +00:00
6d209b9b29 made status script example of .xinitrc more useful 2008-12-13 20:20:26 +00:00
57a0788bd8 ok, using signal.h for portability reasons 2008-12-13 17:44:29 +00:00
3ad906eede removed unnecessary closure of stdin reported by Frederic Chardon, thx 2008-12-13 17:27:48 +00:00
0be9fb8797 added sys/signal.h inclusion for BSD compliance 2008-12-13 16:35:34 +00:00
62a491e36d re-applied Neale's spawn patch, credited Neale in LICENSE 2008-12-12 19:55:03 +00:00
0b5dcf229f applied Neale Pickett's xprop status reading patch, updated README and dwm.1 accordingly 2008-12-12 19:49:06 +00:00
fda92f46aa applied yiyus fix 2008-12-06 16:20:14 +00:00
a62ea4062f fix 2008-12-06 11:22:30 +00:00
7dc28d130f Added tag 5.3.1 for changeset 335301ed102f 2008-12-06 09:33:58 +00:00
fbce733532 integrated yiyus clearurgent refactoring 2008-12-06 09:32:32 +00:00
e7572804fa reverted spawn 2008-12-06 09:16:48 +00:00
ed1bef1241 Added tag 5.3 for changeset 4004d6116035 2008-12-04 20:23:08 +00:00
7 changed files with 84 additions and 103 deletions

View File

@ -56,3 +56,6 @@ d6d3085307d8d98b8b012b669e858fd787befeb1 4.7
06eb9644e2dad7667d97495eb7d7bc62aa0429e8 5.0
ce355cea9bb89e162f61913737a46908cdfa7e45 5.1
e4bcaca8e6ef13d2c3b81f1218ad15e5da4d68bd 5.2
4004d61160355d869a7d2672561caad440751ba0 5.3
335301ed102fec9b1a15d06bfa0184d53b38fa54 5.3.1
8b7836a471f8f9ee61bec980df00971888d76343 5.4

View File

@ -1,6 +1,6 @@
MIT/X Consortium License
© 2006-2008 Anselm R Garbe <garbeam at gmail dot com>
© 2006-2009 Anselm R Garbe <garbeam at gmail dot com>
© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
© 2006-2007 Jukka Salmi <jukka at salmi dot ch>
© 2007 Premysl Hruby <dfenze at gmail dot com>
@ -9,6 +9,7 @@ MIT/X Consortium License
© 2007-2008 Enno Gottox Boland <gottox at s01 dot de>
© 2007-2008 Peter Hartlich <sgkkr at hartlich dot com>
© 2008 Martin Hurton <martin dot hurton at gmail dot com>
© 2008 Neale Pickett <neale dot woozle dot org>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),

5
README
View File

@ -40,9 +40,10 @@ like this in your .xinitrc:
while true
do
echo `date` `uptime | sed 's/.*,//'`
xsetroot -name "`date` `uptime | sed 's/.*,//'`"
sleep 1
done | dwm
done &
exec dwm
Configuration

View File

@ -12,7 +12,6 @@ static unsigned int borderpx = 1; /* border pixel of windows */
static unsigned int snap = 32; /* snap pixel */
static Bool showbar = True; /* False means no bar */
static Bool topbar = True; /* False means bottom bar */
static Bool readin = True; /* False means do not read stdin */
static Bool usegrab = False; /* True means grabbing the X server
during mouse-based resizals */

View File

@ -1,5 +1,5 @@
# dwm version
VERSION = 5.3
VERSION = 5.4.1
# Customize below to fit your system

14
dwm.1
View File

@ -20,13 +20,13 @@ Windows are grouped by tags. Each window can be tagged with one or multiple
tags. Selecting certain tags displays all windows with these tags.
.P
dwm contains a small status bar which displays all available tags, the layout,
the title of the focused window, and the text read from standard input. A
floating window is indicated with an empty square and a maximised
floating window is indicated with a filled square before the windows
title. The selected tags are indicated with a different color. The tags of
the focused window are indicated with a filled square in the top left
corner. The tags which are applied to one or more windows are indicated
with an empty square in the top left corner.
the title of the focused window, and the text read from the root window name
property. A floating window is indicated with an empty square and a maximised
floating window is indicated with a filled square before the windows title.
The selected tags are indicated with a different color. The tags of the focused
window are indicated with a filled square in the top left corner. The tags
which are applied to one or more windows are indicated with an empty square in
the top left corner.
.P
dwm draws a small border around windows to indicate the focus state.
.SH OPTIONS

159
dwm.c
View File

@ -6,12 +6,9 @@
* events about window (dis-)appearance. Only one X connection at a time is
* allowed to select for this event mask.
*
* Calls to fetch an X event from the event queue are blocking. Due reading
* status text from standard input, a select()-driven main loop has been
* implemented which selects for reads on the X connection and STDIN_FILENO to
* handle all data smoothly. The event handlers of dwm are organized in an
* array which is accessed whenever a new event has been fetched. This allows
* event dispatching in O(1) time.
* The event handlers of dwm are organized in an array which is accessed
* whenever a new event has been fetched. This allows event dispatching
* in O(1) time.
*
* Each child of the root window is called a client, except windows which have
* set the override_redirect flag. Clients are organized in a global
@ -26,11 +23,11 @@
#include <errno.h>
#include <locale.h>
#include <stdarg.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <X11/cursorfont.h>
@ -131,6 +128,7 @@ typedef struct {
} Rule;
/* function declarations */
static void adjustborder(Client *c, unsigned int bw);
static void applyrules(Client *c);
static void arrange(void);
static void attach(Client *c);
@ -138,7 +136,7 @@ static void attachstack(Client *c);
static void buttonpress(XEvent *e);
static void checkotherwm(void);
static void cleanup(void);
static void clearurgent(void);
static void clearurgent(Client *c);
static void configure(Client *c);
static void configurenotify(XEvent *e);
static void configurerequest(XEvent *e);
@ -181,7 +179,7 @@ static void setclientstate(Client *c, long state);
static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg);
static void setup(void);
static void showhide(Client *c);
static void showhide(Client *c, unsigned int ntiled);
static void sigchld(int signal);
static void spawn(const Arg *arg);
static void tag(const Arg *arg);
@ -197,6 +195,7 @@ static void updatebar(void);
static void updategeom(void);
static void updatenumlockmask(void);
static void updatesizehints(Client *c);
static void updatestatus(void);
static void updatetitle(Client *c);
static void updatewmhints(Client *c);
static void view(const Arg *arg);
@ -246,6 +245,16 @@ static Window root, barwin;
struct NumTags { char limitexceeded[sizeof(unsigned int) * 8 < LENGTH(tags) ? -1 : 1]; };
/* function implementations */
void
adjustborder(Client *c, unsigned int bw) {
XWindowChanges wc;
if(c->bw != bw) {
c->bw = wc.border_width = bw;
XConfigureWindow(dpy, c->win, CWBorderWidth, &wc);
}
}
void
applyrules(Client *c) {
unsigned int i;
@ -260,7 +269,7 @@ applyrules(Client *c) {
&& (!r->class || (ch.res_class && strstr(ch.res_class, r->class)))
&& (!r->instance || (ch.res_name && strstr(ch.res_name, r->instance)))) {
c->isfloating = r->isfloating;
c->tags |= r->tags & TAGMASK;
c->tags |= r->tags & TAGMASK ? r->tags & TAGMASK : tagset[seltags];
}
}
if(ch.res_class)
@ -274,7 +283,11 @@ applyrules(Client *c) {
void
arrange(void) {
showhide(stack);
unsigned int nt;
Client *c;
for(nt = 0, c = nexttiled(clients); c; c = nexttiled(c->next), nt++);
showhide(stack, nt);
focus(NULL);
if(lt[sellt]->arrange)
lt[sellt]->arrange();
@ -345,7 +358,6 @@ cleanup(void) {
Arg a = {.ui = ~0};
Layout foo = { "", NULL };
close(STDIN_FILENO);
view(&a);
lt[sellt] = &foo;
while(stack)
@ -366,20 +378,15 @@ cleanup(void) {
}
void
clearurgent(void) {
clearurgent(Client *c) {
XWMHints *wmh;
Client *c;
for(c = clients; c; c = c->next)
if(ISVISIBLE(c) && c->isurgent) {
c->isurgent = False;
if (!(wmh = XGetWMHints(dpy, c->win)))
continue;
wmh->flags &= ~XUrgencyHint;
XSetWMHints(dpy, c->win, wmh);
XFree(wmh);
}
c->isurgent = False;
if(!(wmh = XGetWMHints(dpy, c->win)))
return;
wmh->flags &= ~XUrgencyHint;
XSetWMHints(dpy, c->win, wmh);
XFree(wmh);
}
void
@ -618,6 +625,8 @@ focus(Client *c) {
XSetWindowBorder(dpy, sel->win, dc.norm[ColBorder]);
}
if(c) {
if(c->isurgent)
clearurgent(c);
detachstack(c);
attachstack(c);
grabbuttons(c, True);
@ -930,10 +939,14 @@ maprequest(XEvent *e) {
void
monocle(void) {
unsigned int n;
Client *c;
for(c = nexttiled(clients); c; c = nexttiled(c->next))
for(n = 0, c = nexttiled(clients); c && n < 2; c = nexttiled(c->next), n++);
for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
adjustborder(c, n == 1 ? 0 : borderpx);
resize(c, wx, wy, ww - 2 * c->bw, wh - 2 * c->bw, resizehints);
}
}
void
@ -1002,9 +1015,11 @@ propertynotify(XEvent *e) {
Window trans;
XPropertyEvent *ev = &e->xproperty;
if(ev->state == PropertyDelete)
if((ev->window == root) && (ev->atom = XA_WM_NAME))
updatestatus();
else if(ev->state == PropertyDelete)
return; /* ignore */
if((c = getclient(ev->window))) {
else if((c = getclient(ev->window))) {
switch (ev->atom) {
default: break;
case XA_WM_TRANSIENT_FOR:
@ -1030,7 +1045,7 @@ propertynotify(XEvent *e) {
void
quit(const Arg *arg) {
readin = running = False;
running = False;
}
void
@ -1136,8 +1151,8 @@ resizemouse(const Arg *arg) {
handler[ev.type](&ev);
break;
case MotionNotify:
nw = MAX(ev.xmotion.x - ocx - 2*c->bw + 1, 1);
nh = MAX(ev.xmotion.y - ocy - 2*c->bw + 1, 1);
nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
if(snap && nw >= wx && nw <= wx + ww
&& nh >= wy && nh <= wy + wh) {
@ -1184,60 +1199,13 @@ restack(void) {
void
run(void) {
char *p;
char sbuf[sizeof stext];
fd_set rd;
int r, xfd;
unsigned int len, offset;
XEvent ev;
/* main event loop, also reads status text from stdin */
/* main event loop */
XSync(dpy, False);
xfd = ConnectionNumber(dpy);
offset = 0;
len = sizeof stext - 1;
sbuf[len] = stext[len] = '\0'; /* 0-terminator is never touched */
while(running) {
FD_ZERO(&rd);
if(readin)
FD_SET(STDIN_FILENO, &rd);
FD_SET(xfd, &rd);
if(select(xfd + 1, &rd, NULL, NULL, NULL) == -1) {
if(errno == EINTR)
continue;
die("select failed\n");
}
if(FD_ISSET(STDIN_FILENO, &rd)) {
switch((r = read(STDIN_FILENO, sbuf + offset, len - offset))) {
case -1:
strncpy(stext, strerror(errno), len);
readin = False;
break;
case 0:
strncpy(stext, "EOF", 4);
readin = False;
break;
default:
for(p = sbuf + offset; r > 0; p++, r--, offset++)
if(*p == '\n' || *p == '\0') {
*p = '\0';
strncpy(stext, sbuf, len);
p += r - 1; /* p is sbuf + offset + r - 1 */
for(r = 0; *(p - r) && *(p - r) != '\n'; r++);
offset = r;
if(r)
memmove(sbuf, p - r + 1, r);
break;
}
break;
}
drawbar();
}
while(XPending(dpy)) {
XNextEvent(dpy, &ev);
if(handler[ev.type])
(handler[ev.type])(&ev); /* call handler */
}
while(running && !XNextEvent(dpy, &ev)) {
if(handler[ev.type])
(handler[ev.type])(&ev); /* call handler */
}
}
@ -1360,8 +1328,7 @@ setup(void) {
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
XDefineCursor(dpy, barwin, cursor[CurNormal]);
XMapRaised(dpy, barwin);
strcpy(stext, "dwm-"VERSION);
drawbar();
updatestatus();
/* EWMH support per view */
XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
@ -1369,7 +1336,8 @@ setup(void) {
/* select for events */
wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask|ButtonPressMask
|EnterWindowMask|LeaveWindowMask|StructureNotifyMask;
|EnterWindowMask|LeaveWindowMask|StructureNotifyMask
|PropertyChangeMask;
XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
XSelectInput(dpy, root, wa.event_mask);
@ -1377,17 +1345,19 @@ setup(void) {
}
void
showhide(Client *c) {
showhide(Client *c, unsigned int ntiled) {
if(!c)
return;
if(ISVISIBLE(c)) { /* show clients top down */
if(c->isfloating || ntiled > 1) /* avoid unnecessary border reverts */
adjustborder(c, borderpx);
XMoveWindow(dpy, c->win, c->x, c->y);
if(!lt[sellt]->arrange || c->isfloating)
resize(c, c->x, c->y, c->w, c->h, True);
showhide(c->snext);
showhide(c->snext, ntiled);
}
else { /* hide clients bottom up */
showhide(c->snext);
showhide(c->snext, ntiled);
XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
}
}
@ -1444,6 +1414,7 @@ tile(void) {
/* master */
c = nexttiled(clients);
mw = mfact * ww;
adjustborder(c, n == 1 ? 0 : borderpx);
resize(c, wx, wy, (n == 1 ? ww : mw) - 2 * c->bw, wh - 2 * c->bw, resizehints);
if(--n == 0)
@ -1458,6 +1429,7 @@ tile(void) {
h = wh;
for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) {
adjustborder(c, borderpx);
resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n)
? wy + wh - y - 2 * c->bw : h - 2 * c->bw), resizehints);
if(h != wh)
@ -1503,7 +1475,6 @@ toggleview(const Arg *arg) {
if(mask) {
tagset[seltags] = mask;
clearurgent();
arrange();
}
}
@ -1653,12 +1624,19 @@ updatetitle(Client *c) {
gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name);
}
void
updatestatus() {
if(!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
strcpy(stext, "dwm-"VERSION);
drawbar();
}
void
updatewmhints(Client *c) {
XWMHints *wmh;
if((wmh = XGetWMHints(dpy, c->win))) {
if(ISVISIBLE(c) && wmh->flags & XUrgencyHint) {
if(c == sel && wmh->flags & XUrgencyHint) {
wmh->flags &= ~XUrgencyHint;
XSetWMHints(dpy, c->win, wmh);
}
@ -1676,7 +1654,6 @@ view(const Arg *arg) {
seltags ^= 1; /* toggle sel tagset */
if(arg->ui & TAGMASK)
tagset[seltags] = arg->ui & TAGMASK;
clearurgent();
arrange();
}
@ -1731,7 +1708,7 @@ zoom(const Arg *arg) {
int
main(int argc, char *argv[]) {
if(argc == 2 && !strcmp("-v", argv[1]))
die("dwm-"VERSION", © 2006-2008 dwm engineers, see LICENSE for details\n");
die("dwm-"VERSION", © 2006-2009 dwm engineers, see LICENSE for details\n");
else if(argc != 1)
die("usage: dwm [-v]\n");