Compare commits

..

No commits in common. "master" and "4.6" have entirely different histories.
master ... 4.6

13 changed files with 1675 additions and 2535 deletions

51
.hgtags Normal file
View File

@ -0,0 +1,51 @@
d31b5ad96b0ba7b5b0a30928fcf000428339a577 0.1
0a6472e2203994bc5738d40a340d26f7ec9d6062 0.2
7e66082e5092fb0bccd18a3695a0bec52c80fdb2 0.3
eb3165734f00fe7f7da8aeebaed00e60a57caac9 0.4
22213b9a2114167ee8ba019a012e27da0422a61a 0.5
c11f86db4550cac5d0a648a3fe4d6d3b9a4fcf7e 0.6
3fb41412e2492f66476d92ce8f007a8b48fb1d2a 0.7
cd15de32e173f8ce97bfe1c9b6607937b59056b4 0.8
fae61afa861755636c4a1070694209ace8efbb6c 0.9
bbc98e77ae89a7c9232a5be0835f60ea00d8036e 1.0
44a55e6e46bf6c231780b09d919977d6f01083de 1.1
e3179ce2b90451d2807cd53b589d768412b8666b 1.2
f5f5cbf016a94b48a8fe9c47f0736e96d166d5d4 1.3
3cff9403766bf83a9fc2a0aef230115d68de2a8e 1.4
728c9089b079721b43c3347124639a29baa22a97 1.5
ad3fa2d185426c51fd5deceae809770363f8d33c 1.6
4dbdb61c8b8ce21dee5c7050a6b103855964ed20 1.7
d5ad819f2a66a40fa75dd2e44429f3bfc884d07b 1.7.1
c71952fa3c7ca848ec38a6923b5c6d0e18fff431 1.8
a5567a0d30112822db2627a04a2e7aa3b6c38148 1.9
12deea36603da407e3f32640048846a3bd74a9ec 2.0
a2c465098a3b972bbed00feda9804b6aae1e9531 2.1
7e92f58754ae6edb3225f26d754bd89c1ff458cf 2.2
719b37b37b0df829d7cf017ac70e353088fe5849 2.3
32b246925086910d63147483160281a91a47479f 2.4
dcbbfabc8ecc5f33a6cc950584de87da1a368045 2.5
c7f84f23ec5aef29988dcdc4ec22a7352ee8f58e 2.5.1
5308dd22b6ee8e3218c81d9e7e4125f235bb5778 2.6
21951c0dfbae5af68ed77821a4d87253ee91803f 2.7
107719a9ce3bd0c79f9f1f626596eb338a276561 2.8
3a5910fac3ccb522a98aeeba7af7008530b25092 2.9
76b58d21ea98257c05565a3b9c850b9b26a32968 3.0
e1c8bef05e6e48df4f26471ea0712aa43ab9d949 3.1
4ce65f61f01b055fa6c2901c6d2527ef741aa4bf 3.2
f2cabc83a18f9b5b548159329ddd4dee904fa31f 3.2.1
d3876aa792923f9a95f7ad0c7f0134533404df35 3.2.2
0f91934037b04221ff5d1ba3a6c39c1ff26e3661 3.3
9ede7b2d2450537e750d5505789fbe63960e97e6 3.4
63ad05e7f9e1f4f1881fb02f529cb6c6ae81e693 3.5
75b1b25fe0d7e29400baf30568153f668324928b 3.6
20ec6976cee1fcfee0c2f354ae382ee3f9f68efa 3.6.1
baee494346e520f8dee2cee9491b8350064770d2 3.7
2ea201354cf016407ea93e1e390d1422940d29b0 3.8
55478328b2422c700c5404a774c85e77322f41a3 3.9
018c3846842291cb6c009dc087e7fe2f0ef53bea 4.0
00f4180df72b49aadb2933804fde4bfb33e5666d 4.1
c13cb8c6b7a56af74cc88346e71d2490470b546f 4.2
e0ec0d5d8b1ef3ee04a83c7c0fee5853aa2ac6a6 4.3
408014d2126153d2b0fce26a13ba707db222b7b9 4.4
7c117df5d202530e85066d8b1ab02cef605c79ad 4.4.1
2acc60d6dfe28c101a8cd44a8aa710a38ae3607c 4.5

21
LICENSE
View File

@ -1,23 +1,10 @@
MIT/X Consortium License MIT/X Consortium License
© 2006-2019 Anselm R Garbe <anselm@garbe.ca> © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
© 2006-2009 Jukka Salmi <jukka at salmi dot ch>
© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
© 2007-2011 Peter Hartlich <sgkkr at hartlich dot com> © 2006-2007 Jukka Salmi <jukka at salmi dot ch>
© 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com> © 2007 Premysl Hruby <dfenze at gmail dot com>
© 2007-2009 Christof Musik <christof at sendfax dot de> © 2007 Szabolcs Nagy <nszabolcs at gmail dot com>
© 2007-2009 Premysl Hruby <dfenze at gmail dot com>
© 2007-2008 Enno Gottox Boland <gottox at s01 dot de>
© 2008 Martin Hurton <martin dot hurton at gmail dot com>
© 2008 Neale Pickett <neale dot woozle dot org>
© 2009 Mate Nagy <mnagy at port70 dot net>
© 2010-2016 Hiltjo Posthuma <hiltjo@codemadness.org>
© 2010-2012 Connor Lane Smith <cls@lubutu.com>
© 2011 Christoph Lohmann <20h@r-36.net>
© 2015-2016 Quentin Rameau <quinq@fifth.space>
© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
© 2020-2022 Chris Down <chris@chrisdown.name>
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),

View File

@ -1,45 +1,60 @@
# dwm - dynamic window manager # dwm - dynamic window manager
# See LICENSE file for copyright and license details. # © 2006-2007 Anselm R. Garbe, Sander van Dijk
include config.mk include config.mk
SRC = drw.c dwm.c util.c SRC = dwm.c
OBJ = ${SRC:.c=.o} OBJ = ${SRC:.c=.o}
all: dwm all: options dwm
options:
@echo dwm build options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
.c.o: .c.o:
${CC} -c ${CFLAGS} $< @echo CC $<
@${CC} -c ${CFLAGS} $<
${OBJ}: config.h config.mk ${OBJ}: config.h config.mk
config.h: config.h:
cp config.def.h $@ @echo creating $@ from config.def.h
@cp config.def.h $@
dwm: ${OBJ} dwm: ${OBJ}
${CC} -o $@ ${OBJ} ${LDFLAGS} @echo CC -o $@
@${CC} -o $@ ${OBJ} ${LDFLAGS}
clean: clean:
rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz @echo cleaning
@rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
dist: clean dist: clean
mkdir -p dwm-${VERSION} @echo creating dist tarball
cp -R LICENSE Makefile README config.def.h config.mk\ @mkdir -p dwm-${VERSION}
dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION} @cp -R LICENSE Makefile README config.def.h config.mk \
tar -cf dwm-${VERSION}.tar dwm-${VERSION} dwm.1 ${SRC} dwm-${VERSION}
gzip dwm-${VERSION}.tar @tar -cf dwm-${VERSION}.tar dwm-${VERSION}
rm -rf dwm-${VERSION} @gzip dwm-${VERSION}.tar
@rm -rf dwm-${VERSION}
install: all install: all
mkdir -p ${DESTDIR}${PREFIX}/bin @echo installing executable file to ${DESTDIR}${PREFIX}/bin
cp -f dwm ${DESTDIR}${PREFIX}/bin @mkdir -p ${DESTDIR}${PREFIX}/bin
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm @cp -f dwm ${DESTDIR}${PREFIX}/bin
mkdir -p ${DESTDIR}${MANPREFIX}/man1 @chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1 @echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1 @mkdir -p ${DESTDIR}${MANPREFIX}/man1
@sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
@chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
uninstall: uninstall:
rm -f ${DESTDIR}${PREFIX}/bin/dwm\ @echo removing executable file from ${DESTDIR}${PREFIX}/bin
${DESTDIR}${MANPREFIX}/man1/dwm.1 @rm -f ${DESTDIR}${PREFIX}/bin/dwm
@echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
@rm -f ${DESTDIR}${MANPREFIX}/man1/dwm.1
.PHONY: all clean dist install uninstall .PHONY: all options clean dist install uninstall

9
README
View File

@ -18,6 +18,9 @@ necessary as root):
make clean install make clean install
If you are going to use the default bluegray color scheme it is highly
recommended to also install the bluegray files shipped in the dextra package.
Running dwm Running dwm
----------- -----------
@ -35,11 +38,11 @@ the DISPLAY environment variable is set correctly, e.g.:
In order to display status info in the bar, you can do something In order to display status info in the bar, you can do something
like this in your .xinitrc: like this in your .xinitrc:
while xsetroot -name "`date` `uptime | sed 's/.*,//'`" while true
do do
echo `date` `uptime | sed 's/.*,//'`
sleep 1 sleep 1
done & done | dwm
exec dwm
Configuration Configuration

View File

@ -1,116 +1,93 @@
/* See LICENSE file for copyright and license details. */ /* See LICENSE file for copyright and license details. */
/* appearance */ /* appearance */
static const unsigned int borderpx = 1; /* border pixel of windows */ #define BARPOS BarTop /* BarBot, BarOff */
static const unsigned int snap = 32; /* snap pixel */ #define BORDERPX 1
static const int showbar = 1; /* 0 means no bar */ #define FONT "-*-terminus-medium-*-*-*-*-*-*-*-*-*-*-*"
static const int topbar = 1; /* 0 means bottom bar */ #define NORMBORDERCOLOR "#cccccc"
static const char *fonts[] = { "monospace:size=10" }; #define NORMBGCOLOR "#cccccc"
static const char dmenufont[] = "monospace:size=10"; #define NORMFGCOLOR "#000000"
static const char col_gray1[] = "#222222"; #define SELBORDERCOLOR "#0066ff"
static const char col_gray2[] = "#444444"; #define SELBGCOLOR "#0066ff"
static const char col_gray3[] = "#bbbbbb"; #define SELFGCOLOR "#ffffff"
static const char col_gray4[] = "#eeeeee";
static const char col_cyan[] = "#005577";
static const char *colors[][3] = {
/* fg bg border */
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
};
/* tagging */ /* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "www" };
Rule rules[] = {
static const Rule rules[] = { /* class:instance:title regex tags regex isfloating */
/* xprop(1): { "Firefox", "www", False },
* WM_CLASS(STRING) = instance, class { "Gimp", NULL, True },
* WM_NAME(STRING) = title { "MPlayer", NULL, True },
*/ { "Acroread", NULL, True },
/* class instance title tags mask isfloating monitor */
{ "Gimp", NULL, NULL, 0, 1, -1 },
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
}; };
/* layout(s) */ /* layout(s) */
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ #define ISTILE isarrange(tile) /* || isarrange(<custom>) */
static const int nmaster = 1; /* number of clients in master area */ #define MWFACT 0.6 /* master width factor [0.1 .. 0.9] */
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ #define SNAP 32 /* snap pixel */
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ Layout layouts[] = {
/* symbol function */
static const Layout layouts[] = {
/* symbol arrange function */
{ "[]=", tile }, /* first entry is default */ { "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */ { "><>", floating },
{ "[M]", monocle },
}; };
/* key definitions */ /* key definitions */
#define MODKEY Mod1Mask #define MODKEY Mod1Mask
#define TAGKEYS(KEY,TAG) \ #define KEYS \
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \ Key keys[] = { \
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ /* modifier key function argument */ \
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ { MODKEY, XK_p, spawn, \
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, "exe=`dmenu_path | dmenu -fn '"FONT"' -nb '"NORMBGCOLOR"' -nf '"NORMFGCOLOR"'" \
" -sb '"SELBGCOLOR"' -sf '"SELFGCOLOR"'` && exec $exe" }, \
/* helper for spawning shell commands in the pre dwm-5.0 fashion */ { MODKEY|ShiftMask, XK_Return, spawn, "exec uxterm" }, \
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } { MODKEY, XK_space, setlayout, NULL }, \
{ MODKEY, XK_b, togglebar, NULL }, \
/* commands */ { MODKEY, XK_j, focusnext, NULL }, \
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ { MODKEY, XK_k, focusprev, NULL }, \
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; { MODKEY, XK_h, setmwfact, "-0.05" }, \
static const char *termcmd[] = { "st", NULL }; { MODKEY, XK_l, setmwfact, "+0.05" }, \
{ MODKEY, XK_m, togglemax, NULL }, \
static const Key keys[] = { { MODKEY, XK_Return, zoom, NULL }, \
/* modifier key function argument */ { MODKEY, XK_Tab, viewprevtag, NULL }, \
{ MODKEY, XK_p, spawn, {.v = dmenucmd } }, { MODKEY|ShiftMask, XK_space, togglefloating, NULL }, \
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, { MODKEY|ShiftMask, XK_c, killclient, NULL }, \
{ MODKEY, XK_b, togglebar, {0} }, { MODKEY, XK_0, view, NULL }, \
{ MODKEY, XK_j, focusstack, {.i = +1 } }, { MODKEY, XK_1, view, tags[0] }, \
{ MODKEY, XK_k, focusstack, {.i = -1 } }, { MODKEY, XK_2, view, tags[1] }, \
{ MODKEY, XK_i, incnmaster, {.i = +1 } }, { MODKEY, XK_3, view, tags[2] }, \
{ MODKEY, XK_d, incnmaster, {.i = -1 } }, { MODKEY, XK_4, view, tags[3] }, \
{ MODKEY, XK_h, setmfact, {.f = -0.05} }, { MODKEY, XK_5, view, tags[4] }, \
{ MODKEY, XK_l, setmfact, {.f = +0.05} }, { MODKEY, XK_6, view, tags[5] }, \
{ MODKEY, XK_Return, zoom, {0} }, { MODKEY, XK_7, view, tags[6] }, \
{ MODKEY, XK_Tab, view, {0} }, { MODKEY, XK_8, view, tags[7] }, \
{ MODKEY|ShiftMask, XK_c, killclient, {0} }, { MODKEY, XK_9, view, tags[8] }, \
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, { MODKEY|ControlMask, XK_1, toggleview, tags[0] }, \
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, { MODKEY|ControlMask, XK_2, toggleview, tags[1] }, \
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, { MODKEY|ControlMask, XK_3, toggleview, tags[2] }, \
{ MODKEY, XK_space, setlayout, {0} }, { MODKEY|ControlMask, XK_4, toggleview, tags[3] }, \
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} }, { MODKEY|ControlMask, XK_5, toggleview, tags[4] }, \
{ MODKEY, XK_0, view, {.ui = ~0 } }, { MODKEY|ControlMask, XK_6, toggleview, tags[5] }, \
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, { MODKEY|ControlMask, XK_7, toggleview, tags[6] }, \
{ MODKEY, XK_comma, focusmon, {.i = -1 } }, { MODKEY|ControlMask, XK_8, toggleview, tags[7] }, \
{ MODKEY, XK_period, focusmon, {.i = +1 } }, { MODKEY|ControlMask, XK_9, toggleview, tags[8] }, \
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, { MODKEY|ShiftMask, XK_0, tag, NULL }, \
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, { MODKEY|ShiftMask, XK_1, tag, tags[0] }, \
TAGKEYS( XK_1, 0) { MODKEY|ShiftMask, XK_2, tag, tags[1] }, \
TAGKEYS( XK_2, 1) { MODKEY|ShiftMask, XK_3, tag, tags[2] }, \
TAGKEYS( XK_3, 2) { MODKEY|ShiftMask, XK_4, tag, tags[3] }, \
TAGKEYS( XK_4, 3) { MODKEY|ShiftMask, XK_5, tag, tags[4] }, \
TAGKEYS( XK_5, 4) { MODKEY|ShiftMask, XK_6, tag, tags[5] }, \
TAGKEYS( XK_6, 5) { MODKEY|ShiftMask, XK_7, tag, tags[6] }, \
TAGKEYS( XK_7, 6) { MODKEY|ShiftMask, XK_8, tag, tags[7] }, \
TAGKEYS( XK_8, 7) { MODKEY|ShiftMask, XK_9, tag, tags[8] }, \
TAGKEYS( XK_9, 8) { MODKEY|ControlMask|ShiftMask, XK_1, toggletag, tags[0] }, \
{ MODKEY|ShiftMask, XK_q, quit, {0} }, { MODKEY|ControlMask|ShiftMask, XK_2, toggletag, tags[1] }, \
{ MODKEY|ControlMask|ShiftMask, XK_3, toggletag, tags[2] }, \
{ MODKEY|ControlMask|ShiftMask, XK_4, toggletag, tags[3] }, \
{ MODKEY|ControlMask|ShiftMask, XK_5, toggletag, tags[4] }, \
{ MODKEY|ControlMask|ShiftMask, XK_6, toggletag, tags[5] }, \
{ MODKEY|ControlMask|ShiftMask, XK_7, toggletag, tags[6] }, \
{ MODKEY|ControlMask|ShiftMask, XK_8, toggletag, tags[7] }, \
{ MODKEY|ControlMask|ShiftMask, XK_9, toggletag, tags[8] }, \
{ MODKEY|ShiftMask, XK_q, quit, NULL }, \
}; };
/* button definitions */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static const Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
{ ClkTagBar, 0, Button1, view, {0} },
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
};

View File

@ -1,5 +1,5 @@
# dwm version # dwm version
VERSION = 6.5 VERSION = 4.6
# Customize below to fit your system # Customize below to fit your system
@ -10,30 +10,20 @@ MANPREFIX = ${PREFIX}/share/man
X11INC = /usr/X11R6/include X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib X11LIB = /usr/X11R6/lib
# Xinerama, comment if you don't want it
XINERAMALIBS = -lXinerama
XINERAMAFLAGS = -DXINERAMA
# freetype
FREETYPELIBS = -lfontconfig -lXft
FREETYPEINC = /usr/include/freetype2
# OpenBSD (uncomment)
#FREETYPEINC = ${X11INC}/freetype2
#MANPREFIX = ${PREFIX}/man
# includes and libs # includes and libs
INCS = -I${X11INC} -I${FREETYPEINC} INCS = -I. -I/usr/include -I${X11INC}
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} LIBS = -L/usr/lib -lc -L${X11LIB} -lX11
# flags # flags
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\"
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS}
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} #CFLAGS = -g -std=c99 -pedantic -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
LDFLAGS = ${LIBS} #LDFLAGS = -g ${LIBS}
# Solaris # Solaris
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = ${LIBS} #LDFLAGS = ${LIBS}
#CFLAGS += -xtarget=ultra
# compiler and linker # compiler and linker
CC = cc CC = cc

448
drw.c
View File

@ -1,448 +0,0 @@
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
#include "drw.h"
#include "util.h"
#define UTF_INVALID 0xFFFD
static int
utf8decode(const char *s_in, long *u, int *err)
{
static const unsigned char lens[] = {
/* 0XXXX */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/* 10XXX */ 0, 0, 0, 0, 0, 0, 0, 0, /* invalid */
/* 110XX */ 2, 2, 2, 2,
/* 1110X */ 3, 3,
/* 11110 */ 4,
/* 11111 */ 0, /* invalid */
};
static const unsigned char leading_mask[] = { 0x7F, 0x1F, 0x0F, 0x07 };
static const unsigned int overlong[] = { 0x0, 0x80, 0x0800, 0x10000 };
const unsigned char *s = (const unsigned char *)s_in;
int len = lens[*s >> 3];
*u = UTF_INVALID;
*err = 1;
if (len == 0)
return 1;
long cp = s[0] & leading_mask[len - 1];
for (int i = 1; i < len; ++i) {
if (s[i] == '\0' || (s[i] & 0xC0) != 0x80)
return i;
cp = (cp << 6) | (s[i] & 0x3F);
}
/* out of range, surrogate, overlong encoding */
if (cp > 0x10FFFF || (cp >> 11) == 0x1B || cp < overlong[len - 1])
return len;
*err = 0;
*u = cp;
return len;
}
Drw *
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
{
Drw *drw = ecalloc(1, sizeof(Drw));
drw->dpy = dpy;
drw->screen = screen;
drw->root = root;
drw->w = w;
drw->h = h;
drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
drw->gc = XCreateGC(dpy, root, 0, NULL);
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
return drw;
}
void
drw_resize(Drw *drw, unsigned int w, unsigned int h)
{
if (!drw)
return;
drw->w = w;
drw->h = h;
if (drw->drawable)
XFreePixmap(drw->dpy, drw->drawable);
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
}
void
drw_free(Drw *drw)
{
XFreePixmap(drw->dpy, drw->drawable);
XFreeGC(drw->dpy, drw->gc);
drw_fontset_free(drw->fonts);
free(drw);
}
/* This function is an implementation detail. Library users should use
* drw_fontset_create instead.
*/
static Fnt *
xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
{
Fnt *font;
XftFont *xfont = NULL;
FcPattern *pattern = NULL;
if (fontname) {
/* Using the pattern found at font->xfont->pattern does not yield the
* same substitution results as using the pattern returned by
* FcNameParse; using the latter results in the desired fallback
* behaviour whereas the former just results in missing-character
* rectangles being drawn, at least with some fonts. */
if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
return NULL;
}
if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
XftFontClose(drw->dpy, xfont);
return NULL;
}
} else if (fontpattern) {
if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
fprintf(stderr, "error, cannot load font from pattern.\n");
return NULL;
}
} else {
die("no font specified.");
}
font = ecalloc(1, sizeof(Fnt));
font->xfont = xfont;
font->pattern = pattern;
font->h = xfont->ascent + xfont->descent;
font->dpy = drw->dpy;
return font;
}
static void
xfont_free(Fnt *font)
{
if (!font)
return;
if (font->pattern)
FcPatternDestroy(font->pattern);
XftFontClose(font->dpy, font->xfont);
free(font);
}
Fnt*
drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
{
Fnt *cur, *ret = NULL;
size_t i;
if (!drw || !fonts)
return NULL;
for (i = 1; i <= fontcount; i++) {
if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
cur->next = ret;
ret = cur;
}
}
return (drw->fonts = ret);
}
void
drw_fontset_free(Fnt *font)
{
if (font) {
drw_fontset_free(font->next);
xfont_free(font);
}
}
void
drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
{
if (!drw || !dest || !clrname)
return;
if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen),
clrname, dest))
die("error, cannot allocate color '%s'", clrname);
}
/* Wrapper to create color schemes. The caller has to call free(3) on the
* returned color scheme when done using it. */
Clr *
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
{
size_t i;
Clr *ret;
/* need at least two colors for a scheme */
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
return NULL;
for (i = 0; i < clrcount; i++)
drw_clr_create(drw, &ret[i], clrnames[i]);
return ret;
}
void
drw_setfontset(Drw *drw, Fnt *set)
{
if (drw)
drw->fonts = set;
}
void
drw_setscheme(Drw *drw, Clr *scm)
{
if (drw)
drw->scheme = scm;
}
void
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
{
if (!drw || !drw->scheme)
return;
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
if (filled)
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
else
XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
}
int
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
{
int ty, ellipsis_x = 0;
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, hash, h0, h1;
XftDraw *d = NULL;
Fnt *usedfont, *curfont, *nextfont;
int utf8strlen, utf8charlen, utf8err, render = x || y || w || h;
long utf8codepoint = 0;
const char *utf8str;
FcCharSet *fccharset;
FcPattern *fcpattern;
FcPattern *match;
XftResult result;
int charexists = 0, overflow = 0;
/* keep track of a couple codepoints for which we have no match. */
static unsigned int nomatches[128], ellipsis_width, invalid_width;
static const char invalid[] = "<EFBFBD>";
if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
return 0;
if (!render) {
w = invert ? invert : ~invert;
} else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
if (w < lpad)
return x + w;
d = XftDrawCreate(drw->dpy, drw->drawable,
DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen));
x += lpad;
w -= lpad;
}
usedfont = drw->fonts;
if (!ellipsis_width && render)
ellipsis_width = drw_fontset_getwidth(drw, "...");
if (!invalid_width && render)
invalid_width = drw_fontset_getwidth(drw, invalid);
while (1) {
ew = ellipsis_len = utf8err = utf8charlen = utf8strlen = 0;
utf8str = text;
nextfont = NULL;
while (*text) {
utf8charlen = utf8decode(text, &utf8codepoint, &utf8err);
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
if (charexists) {
drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL);
if (ew + ellipsis_width <= w) {
/* keep track where the ellipsis still fits */
ellipsis_x = x + ew;
ellipsis_w = w - ew;
ellipsis_len = utf8strlen;
}
if (ew + tmpw > w) {
overflow = 1;
/* called from drw_fontset_getwidth_clamp():
* it wants the width AFTER the overflow
*/
if (!render)
x += tmpw;
else
utf8strlen = ellipsis_len;
} else if (curfont == usedfont) {
text += utf8charlen;
utf8strlen += utf8err ? 0 : utf8charlen;
ew += utf8err ? 0 : tmpw;
} else {
nextfont = curfont;
}
break;
}
}
if (overflow || !charexists || nextfont || utf8err)
break;
else
charexists = 0;
}
if (utf8strlen) {
if (render) {
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen);
}
x += ew;
w -= ew;
}
if (utf8err && (!render || invalid_width < w)) {
if (render)
drw_text(drw, x, y, w, h, 0, invalid, invert);
x += invalid_width;
w -= invalid_width;
}
if (render && overflow)
drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
if (!*text || overflow) {
break;
} else if (nextfont) {
charexists = 0;
usedfont = nextfont;
} else {
/* Regardless of whether or not a fallback font is found, the
* character must be drawn. */
charexists = 1;
hash = (unsigned int)utf8codepoint;
hash = ((hash >> 16) ^ hash) * 0x21F0AAAD;
hash = ((hash >> 15) ^ hash) * 0xD35A2D97;
h0 = ((hash >> 15) ^ hash) % LENGTH(nomatches);
h1 = (hash >> 17) % LENGTH(nomatches);
/* avoid expensive XftFontMatch call when we know we won't find a match */
if (nomatches[h0] == utf8codepoint || nomatches[h1] == utf8codepoint)
goto no_match;
fccharset = FcCharSetCreate();
FcCharSetAddChar(fccharset, utf8codepoint);
if (!drw->fonts->pattern) {
/* Refer to the comment in xfont_create for more information. */
die("the first font in the cache must be loaded from a font string.");
}
fcpattern = FcPatternDuplicate(drw->fonts->pattern);
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
FcDefaultSubstitute(fcpattern);
match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
FcCharSetDestroy(fccharset);
FcPatternDestroy(fcpattern);
if (match) {
usedfont = xfont_create(drw, NULL, match);
if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
; /* NOP */
curfont->next = usedfont;
} else {
xfont_free(usedfont);
nomatches[nomatches[h0] ? h1 : h0] = utf8codepoint;
no_match:
usedfont = drw->fonts;
}
}
}
}
if (d)
XftDrawDestroy(d);
return x + (render ? w : 0);
}
void
drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
{
if (!drw)
return;
XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
XSync(drw->dpy, False);
}
unsigned int
drw_fontset_getwidth(Drw *drw, const char *text)
{
if (!drw || !drw->fonts || !text)
return 0;
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
}
unsigned int
drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n)
{
unsigned int tmp = 0;
if (drw && drw->fonts && text && n)
tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n);
return MIN(n, tmp);
}
void
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
{
XGlyphInfo ext;
if (!font || !text)
return;
XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
if (w)
*w = ext.xOff;
if (h)
*h = font->h;
}
Cur *
drw_cur_create(Drw *drw, int shape)
{
Cur *cur;
if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
return NULL;
cur->cursor = XCreateFontCursor(drw->dpy, shape);
return cur;
}
void
drw_cur_free(Drw *drw, Cur *cursor)
{
if (!cursor)
return;
XFreeCursor(drw->dpy, cursor->cursor);
free(cursor);
}

58
drw.h
View File

@ -1,58 +0,0 @@
/* See LICENSE file for copyright and license details. */
typedef struct {
Cursor cursor;
} Cur;
typedef struct Fnt {
Display *dpy;
unsigned int h;
XftFont *xfont;
FcPattern *pattern;
struct Fnt *next;
} Fnt;
enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */
typedef XftColor Clr;
typedef struct {
unsigned int w, h;
Display *dpy;
int screen;
Window root;
Drawable drawable;
GC gc;
Clr *scheme;
Fnt *fonts;
} Drw;
/* Drawable abstraction */
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
void drw_free(Drw *drw);
/* Fnt abstraction */
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
void drw_fontset_free(Fnt* set);
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n);
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
/* Colorscheme abstraction */
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
/* Cursor abstraction */
Cur *drw_cur_create(Drw *drw, int shape);
void drw_cur_free(Drw *drw, Cur *cursor);
/* Drawing context manipulation */
void drw_setfontset(Drw *drw, Fnt *set);
void drw_setscheme(Drw *drw, Clr *scm);
/* Drawing functions */
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
/* Map functions */
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);

168
dwm.1
View File

@ -5,42 +5,38 @@ dwm \- dynamic window manager
.B dwm .B dwm
.RB [ \-v ] .RB [ \-v ]
.SH DESCRIPTION .SH DESCRIPTION
dwm is a dynamic window manager for X. It manages windows in tiled, monocle dwm is a dynamic window manager for X. It manages windows in tiled and
and floating layouts. Either layout can be applied dynamically, optimising the floating layouts. Either layout can be applied dynamically, optimizing the
environment for the application in use and the task performed. environment for the application in use and the task performed.
.P .P
In tiled layouts windows are managed in a master and stacking area. The master In tiled layout windows are managed in a master and stacking area. The master
area on the left contains one window by default, and the stacking area on the area contains the window which currently needs most attention, whereas the
right contains all other windows. The number of master area windows can be stacking area contains all other windows. In floating layout windows can be
adjusted from zero to an arbitrary number. In monocle layout all windows are resized and moved freely. Dialog windows are always managed floating,
maximised to the screen size. In floating layout windows can be resized and regardless of the layout applied.
moved freely. Dialog windows are always managed floating, regardless of the
layout applied.
.P .P
Windows are grouped by tags. Each window can be tagged with one or multiple Windows are grouped by tags. Each window can be tagged with one or multiple
tags. Selecting certain tags displays all windows with these tags. tags. Selecting certain tags displays all windows with these tags.
.P .P
Each screen contains a small status bar which displays all available tags, the dwm contains a small status bar which displays all available tags, the layout,
layout, the title of the focused window, and the text read from the root window the title of the focused window, and the text read from standard input. A
name property, if the screen is focused. A floating window is indicated with an floating window is indicated with an empty square and a maximized
empty square and a maximised floating window is indicated with a filled square floating window is indicated with a filled square before the windows
before the windows title. The selected tags are indicated with a different title. The selected tags are indicated with a different color. The tags of
color. The tags of the focused window are indicated with a filled square in the the focused window are indicated with a filled square in the top left
top left corner. The tags which are applied to one or more windows are corner. The tags which are applied to one or more windows are indicated
indicated with an empty square in the top left corner. with an empty square in the top left corner.
.P .P
dwm draws a small border around windows to indicate the focus state. dwm draws a small border around windows to indicate the focus state.
.SH OPTIONS .SH OPTIONS
.TP .TP
.B \-v .B \-v
prints version information to stderr, then exits. prints version information to standard output, then exits.
.SH USAGE .SH USAGE
.SS Status bar .SS Status bar
.TP .TP
.B X root window name .B Standard input
is read and displayed in the status text area. It can be set with the is read and displayed in the status text area.
.BR xsetroot (1)
command.
.TP .TP
.B Button1 .B Button1
click on a tag label to display all windows with that tag, click on the layout click on a tag label to display all windows with that tag, click on the layout
@ -58,39 +54,19 @@ click on a tag label adds/removes that tag to/from the focused window.
.TP .TP
.B Mod1\-Shift\-Return .B Mod1\-Shift\-Return
Start Start
.BR st(1). .BR xterm.
.TP .TP
.B Mod1\-p .B Mod1\-Return
Spawn Zooms/cycles current window to/from master area (tiled layout only).
.BR dmenu(1)
for launching other programs.
.TP .TP
.B Mod1\-, .B Mod1\-Tab
Focus previous screen, if any. Toggles to the previously selected tags.
.TP
.B Mod1\-.
Focus next screen, if any.
.TP
.B Mod1\-Shift\-,
Send focused window to previous screen, if any.
.TP
.B Mod1\-Shift\-.
Send focused window to next screen, if any.
.TP .TP
.B Mod1\-b .B Mod1\-b
Toggles bar on and off. Shows/hides the status bar.
.TP .TP
.B Mod1\-t .B Mod1\-h
Sets tiled layout. Decreases the master area width about 5% (tiled layout only).
.TP
.B Mod1\-f
Sets floating layout.
.TP
.B Mod1\-m
Sets monocle layout.
.TP
.B Mod1\-space
Toggles between current and previous layout.
.TP .TP
.B Mod1\-j .B Mod1\-j
Focus next window. Focus next window.
@ -98,79 +74,83 @@ Focus next window.
.B Mod1\-k .B Mod1\-k
Focus previous window. Focus previous window.
.TP .TP
.B Mod1\-i
Increase number of windows in master area.
.TP
.B Mod1\-d
Decrease number of windows in master area.
.TP
.B Mod1\-l .B Mod1\-l
Increase master area size. Increases the master area width about 5% (tiled layout only).
.TP .TP
.B Mod1\-h .B Mod1\-m
Decrease master area size. Toggles maximization of current window.
.TP .TP
.B Mod1\-Return .B Mod1\-Shift\-[1..n]
Zooms/cycles focused window to/from master area (tiled layouts only). Apply
.RB nth
tag to current window.
.TP
.B Mod1\-Shift\-0
Apply all tags to current window.
.TP
.B Mod1\-Control\-Shift\-[1..n]
Add/remove
.B nth
tag to/from current window.
.TP .TP
.B Mod1\-Shift\-c .B Mod1\-Shift\-c
Close focused window. Close focused window.
.TP .TP
.B Mod1\-space
Toggle between tiled and floating layout (affects all windows).
.TP
.B Mod1\-Shift\-space .B Mod1\-Shift\-space
Toggle focused window between tiled and floating state. Toggle focused window between tiled and floating state.
.TP .TP
.B Mod1\-Tab
Toggles to the previously selected tags.
.TP
.B Mod1\-Shift\-[1..n]
Apply nth tag to focused window.
.TP
.B Mod1\-Shift\-0
Apply all tags to focused window.
.TP
.B Mod1\-Control\-Shift\-[1..n]
Add/remove nth tag to/from focused window.
.TP
.B Mod1\-[1..n] .B Mod1\-[1..n]
View all windows with nth tag. View all windows with
.BR nth
tag.
.TP .TP
.B Mod1\-0 .B Mod1\-0
View all windows with any tag. View all windows with any tag.
.TP .TP
.B Mod1\-Control\-[1..n] .B Mod1\-Control\-[1..n]
Add/remove all windows with nth tag to/from the view. Add/remove all windows with
.BR nth
tag to/from the view.
.TP .TP
.B Mod1\-Shift\-q .B Mod1\-Shift\-q
Quit dwm. Quit dwm.
.SS Mouse commands .SS Mouse commands
.TP .TP
.B Mod1\-Button1 .B Mod1\-Button1
Move focused window while dragging. Tiled windows will be toggled to the floating state. Move current window while dragging. Tiled windows will be toggled to the floating state.
.TP .TP
.B Mod1\-Button2 .B Mod1\-Button2
Toggles focused window between floating and tiled state. Zooms/cycles current window to/from master area. If it is floating (but not fixed) it will be toggled to the tiled state instead.
.TP .TP
.B Mod1\-Button3 .B Mod1\-Button3
Resize focused window while dragging. Tiled windows will be toggled to the floating state. Resize current window while dragging. Tiled windows will be toggled to the floating state.
.SH CUSTOMIZATION .SH CUSTOMIZATION
dwm is customized by creating a custom config.h and (re)compiling the source dwm is customized by creating a custom config.h and (re)compiling the source
code. This keeps it fast, secure and simple. code. This keeps it fast, secure and simple.
.SH SEE ALSO .SH SEE ALSO
.BR dmenu (1), .BR dmenu (1)
.BR st (1) .SH BUGS
.SH ISSUES The status bar may display
.BR "EOF"
when dwm has been started by an X session manager like
.BR xdm (1),
because those close standard output before executing dwm.
.P
Java applications which use the XToolkit/XAWT backend may draw grey windows Java applications which use the XToolkit/XAWT backend may draw grey windows
only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early
JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds JDK 1.6 versions, because it assumes a reparenting window manager. As a workaround
are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the you can use JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or you
environment variable can set the following environment variable (to use the older Motif
.BR AWT_TOOLKIT=MToolkit backend instead):
(to use the older Motif backend instead) or running .BR AWT_TOOLKIT=MToolkit .
.B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D .P
or Recent GTK 2.10.9+ versions contain a broken
.B wmname LG3D .BR Save\-As
(to pretend that a non-reparenting window manager is running that the file dialog implementation,
XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable which requests to reconfigure its window size in an endless loop. However, its
.BR _JAVA_AWT_WM_NONREPARENTING=1 . window is still respondable during this state, so you can simply ignore the flicker
.SH BUGS until a new GTK version appears, which will fix this bug, approximately
Send all bug reports with a patch to hackers@suckless.org. GTK 2.10.12+ versions.

3017
dwm.c

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +0,0 @@
/* cc transient.c -o transient -lX11 */
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
int main(void) {
Display *d;
Window r, f, t = None;
XSizeHints h;
XEvent e;
d = XOpenDisplay(NULL);
if (!d)
exit(1);
r = DefaultRootWindow(d);
f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0);
h.min_width = h.max_width = h.min_height = h.max_height = 400;
h.flags = PMinSize | PMaxSize;
XSetWMNormalHints(d, f, &h);
XStoreName(d, f, "floating");
XMapWindow(d, f);
XSelectInput(d, f, ExposureMask);
while (1) {
XNextEvent(d, &e);
if (t == None) {
sleep(5);
t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0);
XSetTransientForHint(d, t, f);
XStoreName(d, t, "transient");
XMapWindow(d, t);
XSelectInput(d, t, ExposureMask);
}
}
XCloseDisplay(d);
exit(0);
}

37
util.c
View File

@ -1,37 +0,0 @@
/* See LICENSE file for copyright and license details. */
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
void
die(const char *fmt, ...)
{
va_list ap;
int saved_errno;
saved_errno = errno;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
if (fmt[0] && fmt[strlen(fmt)-1] == ':')
fprintf(stderr, " %s", strerror(saved_errno));
fputc('\n', stderr);
exit(1);
}
void *
ecalloc(size_t nmemb, size_t size)
{
void *p;
if (!(p = calloc(nmemb, size)))
die("calloc:");
return p;
}

9
util.h
View File

@ -1,9 +0,0 @@
/* See LICENSE file for copyright and license details. */
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
#define LENGTH(X) (sizeof (X) / sizeof (X)[0])
void die(const char *fmt, ...);
void *ecalloc(size_t nmemb, size_t size);