From 675a2008a6c9ad34d199aebdac6447d33a9cb53e Mon Sep 17 00:00:00 2001 From: phillbush Date: Tue, 28 Jul 2020 14:51:12 -0300 Subject: [PATCH] Fixing #7 Redrawing an icon every time the cursor moves between items costs a lot of time. So now each icon is drawn once, and s copied when needed. --- xmenu.c | 34 +++++++++++++++++++++++++++++----- xmenu.h | 1 + 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/xmenu.c b/xmenu.c index 9a61cb7..56a3dd4 100644 --- a/xmenu.c +++ b/xmenu.c @@ -546,8 +546,29 @@ setupitems(struct Menu *menu) menu->w = MAX(menu->w, itemwidth); /* create icon */ - if (item->file != NULL && !iflag) + if (item->file != NULL && !iflag) { item->icon = loadicon(item->file); + + item->sel = XCreatePixmap(dpy, menu->win, + config.iconsize, config.iconsize, + DefaultDepth(dpy, screen)); + XSetForeground(dpy, dc.gc, dc.selected[ColorBG].pixel); + XFillRectangle(dpy, item->sel, dc.gc, 0, 0, + config.iconsize, config.iconsize); + imlib_context_set_drawable(item->sel); + imlib_context_set_image(item->icon); + imlib_render_image_on_drawable(0, 0); + + item->unsel = XCreatePixmap(dpy, menu->win, + config.iconsize, config.iconsize, + DefaultDepth(dpy, screen)); + XSetForeground(dpy, dc.gc, dc.normal[ColorBG].pixel); + XFillRectangle(dpy, item->unsel, dc.gc, 0, 0, + config.iconsize, config.iconsize); + imlib_context_set_drawable(item->unsel); + imlib_context_set_image(item->icon); + imlib_render_image_on_drawable(0, 0); + } } } @@ -756,7 +777,7 @@ drawitem(struct Menu *menu, struct Item *item, XftColor *color) y = item->y + (item->h + dc.font->ascent) / 2; XSetForeground(dpy, dc.gc, color[ColorFG].pixel); XftDrawStringUtf8(menu->draw, &color[ColorFG], dc.font, - x, y, (XftChar8 *)item->label, item->labellen); + x, y, (XftChar8 *)item->label, item->labellen); /* draw triangle, if item contains a submenu */ if (item->submenu != NULL) { @@ -778,9 +799,12 @@ drawitem(struct Menu *menu, struct Item *item, XftColor *color) if (item->icon != NULL) { x = config.horzpadding; y = item->y + config.iconpadding; - imlib_context_set_drawable(menu->pixmap); - imlib_context_set_image(item->icon); - imlib_render_image_on_drawable(x, y); + if (color == dc.selected) + XCopyArea(dpy, item->sel, menu->pixmap, dc.gc, 0, 0, + menu->w, menu->h, x, y); + else + XCopyArea(dpy, item->unsel, menu->pixmap, dc.gc, 0, 0, + menu->w, menu->h, x, y); } } diff --git a/xmenu.h b/xmenu.h index 2ad68d6..efecca4 100644 --- a/xmenu.h +++ b/xmenu.h @@ -63,6 +63,7 @@ struct Item { struct Item *prev; /* previous item */ struct Item *next; /* next item */ struct Menu *submenu; /* submenu spawned by clicking on item */ + Drawable sel, unsel; /* pixmap for selected and unselected icons */ Imlib_Image icon; };