Re: [dev] [PATCH] update years in copyright notices
Heyho, Christoph Lohmann wrote: > Please don’t send tabbed patches to all authors, just to dev@suckless.org. This is just an effect of my --cc-cmd, which extracts the adresses of all original committers of the modified lines. In this case it was useless, but when I changed some code, I would like to notify the original authors about the change with a cc, since some people don't read every mail they get from a mailing list. --Markus
[dev] [tabbed] Port to libdraw
Hi people, as threatened on IRC, I ported tabbed to DWM's libdraw. I removed the cursor handling functions from libdraw to reduce the SLOC count, but taking {drw,util}.[ch] verbatim from DWM works. This way, changes in DWM's drawing, such as the XFT or Pango patches, can trivially be applied to tabbed. -- Gregor Best >From d1165b7701c9957912a191da4d5b981da5eb4513 Mon Sep 17 00:00:00 2001 From: Gregor Best Date: Wed, 22 Jan 2014 16:06:53 +0100 Subject: [PATCH] Port drawing to dwm's libdraw Signed-off-by: Gregor Best --- Makefile | 9 ++- drw.c| 207 drw.h| 61 ++ tabbed.c | 214 ++- util.c | 17 + util.h | 6 ++ 6 files changed, 342 insertions(+), 172 deletions(-) create mode 100644 drw.c create mode 100644 drw.h create mode 100644 util.c create mode 100644 util.h diff --git a/Makefile b/Makefile index 32cc25b..998e58d 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,9 @@ include config.mk -SRC = tabbed.c +SRC = tabbed.c \ + drw.c \ + util.c OBJ = ${SRC:.c=.o} all: options tabbed @@ -24,9 +26,10 @@ config.h: @echo creating $@ from config.def.h @cp config.def.h $@ -tabbed: tabbed.o +# TODO explicit deps suck +tabbed: tabbed.o drw.o drw.h util.c util.h util.o @echo CC -o $@ - @${CC} -o $@ tabbed.o ${LDFLAGS} + @${CC} -o $@ tabbed.o drw.o util.o ${LDFLAGS} clean: @echo cleaning diff --git a/drw.c b/drw.c new file mode 100644 index 000..749795d --- /dev/null +++ b/drw.c @@ -0,0 +1,207 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include + +#include "drw.h" +#include "util.h" + +Drw * +drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) { + Drw *drw = (Drw *)calloc(1, sizeof(Drw)); + if(!drw) + return NULL; + 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 != 0) + 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); + free(drw); +} + +Fnt * +drw_font_create(Display *dpy, const char *fontname) { + Fnt *font; + char *def, **missing; + int n; + + font = (Fnt *)calloc(1, sizeof(Fnt)); + if(!font) + return NULL; + font->set = XCreateFontSet(dpy, fontname, &missing, &n, &def); + if(missing) { + while(n--) + fprintf(stderr, "drw: missing fontset: %s\n", missing[n]); + XFreeStringList(missing); + } + if(font->set) { + XFontStruct **xfonts; + char **font_names; + XExtentsOfFontSet(font->set); + n = XFontsOfFontSet(font->set, &xfonts, &font_names); + while(n--) { + font->ascent = MAX(font->ascent, (*xfonts)->ascent); + font->descent = MAX(font->descent,(*xfonts)->descent); + xfonts++; + } + } + else { + if(!(font->xfont = XLoadQueryFont(dpy, fontname)) + && !(font->xfont = XLoadQueryFont(dpy, "fixed"))) + die("error, cannot load font: '%s'\n", fontname); + font->ascent = font->xfont->ascent; + font->descent = font->xfont->descent; + } + font->h = font->ascent + font->descent; + return font; +} + +void +drw_font_free(Display *dpy, Fnt *font) { + if(!font) + return; + if(font->set) + XFreeFontSet(dpy, font->set); + else + XFreeFont(dpy, font->xfont); + free(font); +} + +Clr * +drw_clr_create(Drw *drw, const char *clrname) { + Clr *clr; + Colormap cmap; + XColor color; + + if(!drw) + return NULL; + clr = (Clr *)calloc(1, sizeof(Clr)); + if(!clr) + return NULL; + cmap = DefaultColormap(drw->dpy, drw->screen); + if(!XAllocNamedColor(drw->dpy, cmap, clrname, &color, &color)) + die("error, cannot allocate color '%s'\n", clrname); + clr->rgb = color.pixel; + return clr; +} + +void +drw_clr_free(Clr *clr) { + free(clr); +} + +void +drw_
[dev] [dmenu] Unintentional fallthrough in xft-patch
Hi, The patch on [1] introduces an unintentional fallthrough in a case-statement. Here is the relevant part of the patch: @@ -359,7 +376,8 @@ keypress(XKeyEvent *ev) { case XK_Return: case XK_KP_Enter: puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); - exit(EXIT_SUCCESS); + ret = EXIT_SUCCESS; + running = False; case XK_Right: You can see that the exit is replaced by two lines but no break. This means that everytime the user selects an entry, instead of exiting right away, dmenu selects the next entry (behaviour of XK_Right), redraws and exits immediately afterwards. Normally, one wouldn't notice the last redraw because the time is too short, but compositing managers such as compton have a fade-out effect that takes the last image of a closed window and fade it out slowly. Which means that you get to see the wrongly selected entry. Attached is a patch that fixes the problem and can be applied on top of the xft-patch itself. I also attach a new xft-patch that includes my changes for your convenience. Please note that I haven't ported the xft-patch to git-dmenu, yet. So like the original patch under [1], both are only meant for 4.5. There is also a gentoo bug about this isssue: [2] Regards, HP [1] http://tools.suckless.org/dmenu/patches/xft [2] https://bugs.gentoo.org/show_bug.cgi?id=498924 diff --git a/dmenu.c b/dmenu.c index 72c1c97..e1767c7 100644 --- a/dmenu.c +++ b/dmenu.c @@ -337,8 +337,9 @@ keypress(XKeyEvent *ev) { sel = matchend; break; case XK_Escape: -ret = EXIT_FAILURE; -running = False; + ret = EXIT_FAILURE; + running = False; + break; case XK_Home: if(sel == matches) { cursor = 0; @@ -378,6 +379,7 @@ keypress(XKeyEvent *ev) { puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); ret = EXIT_SUCCESS; running = False; + break; case XK_Right: if(text[cursor] != '\0') { cursor = nextrune(+1); diff --git a/config.mk b/config.mk index 92a5e63..a8ebf75 100644 --- a/config.mk +++ b/config.mk @@ -12,9 +12,13 @@ X11LIB = /usr/X11R6/lib XINERAMALIBS = -lXinerama XINERAMAFLAGS = -DXINERAMA +# Xft, comment if you don't want it +XFTINC = -I/usr/local/include/freetype2 +XFTLIBS = -lXft -lXrender -lfreetype -lz -lfontconfig + # includes and libs -INCS = -I${X11INC} -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} +INCS = -I${X11INC} ${XFTINC} +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS} # flags CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} diff --git a/dmenu.1 b/dmenu.1 index 0784cd9..f29ca36 100644 --- a/dmenu.1 +++ b/dmenu.1 @@ -53,7 +53,7 @@ dmenu lists items vertically, with the given number of lines. defines the prompt to be displayed to the left of the input field. .TP .BI \-fn " font" -defines the font or font set used. +defines the font or font set used. eg. "fixed" or "Monospace-12:normal" (an xft font) .TP .BI \-nb " color" defines the normal background color. diff --git a/dmenu.c b/dmenu.c index 4ea95f8..e1767c7 100644 --- a/dmenu.c +++ b/dmenu.c @@ -17,6 +17,7 @@ * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define DEFFONT "fixed" /* xft example: "Monospace-11" */ typedef struct Item Item; struct Item { @@ -26,6 +27,7 @@ struct Item { static void appenditem(Item *item, Item **list, Item **last); static void calcoffsets(void); +static void cleanup(void); static char *cistrstr(const char *s, const char *sub); static void drawmenu(void); static void grabkeyboard(void); @@ -50,10 +52,12 @@ static const char *normfgcolor = "#bb"; static const char *selbgcolor = "#005577"; static const char *selfgcolor = "#ee"; static unsigned int lines = 0; -static unsigned long normcol[ColLast]; -static unsigned long selcol[ColLast]; +static ColorSet *normcol; +static ColorSet *selcol; static Atom clip, utf8; static Bool topbar = True; +static Bool running = True; +static int ret = 0; static DC *dc; static Item *items = NULL; static Item *matches, *matchend; @@ -104,7 +108,9 @@ main(int argc, char *argv[]) { usage(); dc = initdc(); - initfont(dc, font); + initfont(dc, font ? font : DEFFONT); + normcol = initcolor(dc, normfgcolor, normbgcolor); + selcol = initcolor(dc, selfgcolor, selbgcolor); if(fast) { grabkeyboard(); @@ -117,7 +123,8 @@ main(int argc, char *argv[]) { setup(); run(); - return 1; /* unreachable */ + cleanup(); + return ret; } void @@ -160,6 +167,15 @@ cistrstr(const char *s, const char *sub) { } void +cleanup(void) { +freecol(dc, normcol); +freecol(dc, selcol); +XDestroyWindow(dc->dpy, win); +XUngrabKeyboard(dc->dpy, CurrentTime); +freedc(dc); +} + +void drawmenu(void) { int curpos; Item *item; @@ -167,7 +183,7 @@ drawmenu(void) { dc->x = 0;