Removing patches, using branches approach

This commit is contained in:
phillbush 2020-05-30 11:52:47 -03:00
parent a966c86682
commit 0dfd6fa00e
3 changed files with 4 additions and 325 deletions

14
README
View File

@ -22,20 +22,14 @@ The files are:
• ./xmenu.1: The manual file (man page) for XMenu. • ./xmenu.1: The manual file (man page) for XMenu.
• ./xmenu.c: The source code of XMenu. • ./xmenu.c: The source code of XMenu.
• ./xmenu.sh: A sample script illustrating how to use XMenu. • ./xmenu.sh: A sample script illustrating how to use XMenu.
• ./patches/ See the §Patches section
§ Patches § Branches
There are some patches that can be applied to XMenu in order to obtain There are other branches in this git repository that adds novel
novel functionalities. The patches are located at ./patches. There functionalities to XMenu.
are the following patches:
• ./patches/icons.diff: Add suport to image icons before menu entries. • icons: Add suport to image icons before menu entries.
To apply a patch, use the following command:
patch -p1 < patches/patch.diff
§ Installation § Installation

View File

@ -1,315 +0,0 @@
diff --git a/config.h b/config.h
index a3e4f95..ca7c903 100644
--- a/config.h
+++ b/config.h
@@ -18,3 +18,6 @@ static int separator_pixels = 3; /* space around separator */
/* geometry of the right-pointing isoceles triangle for submenus */
static const int triangle_width = 3;
static const int triangle_height = 7;
+
+/* sum of padding around both sides of the image */
+static const int imgpadding = 8;
diff --git a/config.mk b/config.mk
index f86aa34..0ffc8c5 100644
--- a/config.mk
+++ b/config.mk
@@ -14,8 +14,8 @@ FREETYPELIB = -lfontconfig -lXft
#FREETYPEINC = $(X11INC)/freetype2
# includes and libs
-INCS = -I${X11INC} -I${FREETYPEINC}
-LIBS = -L${X11LIB} -L${FREETYPELIB} -lX11
+INCS = -I/usr/local/include -I${X11INC} -I${FREETYPEINC}
+LIBS = -L/usr/local/lib -L${X11LIB} -L${FREETYPELIB} -lX11 -lImlib2
# flags
CPPFLAGS =
diff --git a/xmenu.1 b/xmenu.1
index d114668..5201032 100644
--- a/xmenu.1
+++ b/xmenu.1
@@ -13,17 +13,21 @@ and outputs the item selected to stdout.
Each item read from stdin has the following format:
.IP
.EX
-ITEM := [TABS] [LABEL [TABS OUTPUT]] NEWLINE
+ITEM := [TABS] [[IMAGE TABS] LABEL [TABS OUTPUT]] NEWLINE
.EE
.PP
That means that each item is composed by
-tabs, followed by a label, followed by more tabs, followed by an output,
+tabs, followed by an optional image specification, followed by tabs
+followed by a label, followed by more tabs, followed by an output,
and ended by a newline. Brackets group optional elements.
.IP
The initial tabs indicate the menu hierarchy:
items indented with a tab is shown in a submenu of the preceding item not indented.
An item without initial tabs is a top-level item.
.IP
+The image is a string of the form "IMG:/path/to/image.png".
+It specifies a image to be shown as icon at the left of the entry.
+.IP
The label is the string that will be shown as a item in the menu.
An item without label is considered a separator and is drawn as a thin line in the menu
separating the item above from the item below.
@@ -104,14 +108,14 @@ creating a command to be run by the shell.
cat <<EOF | xmenu | sh &
Applications
- Web Browser firefox
- Image editor gimp
-Terminal (xterm) xterm
-Terminal (urxvt) urxvt
-Terminal (st) st
+ IMG:./web.png Web Browser firefox
+ Image editor gimp
+Terminal (xterm) xterm
+Terminal (urxvt) urxvt
+Terminal (st) st
-Shutdown poweroff
-Reboot reboot
+Shutdown poweroff
+Reboot reboot
EOF
.EE
.PP
diff --git a/xmenu.c b/xmenu.c
index abab13d..d70c6b8 100644
--- a/xmenu.c
+++ b/xmenu.c
@@ -8,6 +8,7 @@
#include <X11/Xresource.h>
#include <X11/XKBlib.h>
#include <X11/Xft/Xft.h>
+#include <Imlib2.h>
#define PROGNAME "xmenu"
#define ITEMPREV 0
@@ -45,12 +46,14 @@ struct Geometry {
struct Item {
char *label; /* string to be drawed on menu */
char *output; /* string to be outputed when item is clicked */
+ char *file; /* filename of the image */
int y; /* item y position relative to menu */
int h; /* item height */
size_t labellen; /* strlen(label) */
struct Item *prev; /* previous item */
struct Item *next; /* next item */
struct Menu *submenu; /* submenu spawned by clicking on item */
+ Imlib_Image image;
};
/* menu structure */
@@ -71,9 +74,9 @@ static void getresources(void);
static void getcolor(const char *s, XftColor *color);
static void setupdc(void);
static void calcgeom(struct Geometry *geom);
-static struct Item *allocitem(const char *label, const char *output);
+static struct Item *allocitem(const char *label, const char *output, char *file);
static struct Menu *allocmenu(struct Menu *parent, struct Item *list, unsigned level);
-static struct Menu *buildmenutree(unsigned level, const char *label, const char *output);
+static struct Menu *buildmenutree(unsigned level, const char *label, const char *output, char *file);
static struct Menu *parsestdin(void);
static void calcmenu(struct Geometry *geom, struct Menu *menu);
static void grabpointer(void);
@@ -129,6 +132,13 @@ main(int argc, char *argv[])
rootwin = RootWindow(dpy, screen);
colormap = DefaultColormap(dpy, screen);
+ /* imlib2 stuff */
+ imlib_set_cache_size(2048 * 1024);
+ imlib_context_set_dither(1);
+ imlib_context_set_display(dpy);
+ imlib_context_set_visual(visual);
+ imlib_context_set_colormap(colormap);
+
/* setup */
getresources();
setupdc();
@@ -247,7 +257,7 @@ calcgeom(struct Geometry *geom)
/* allocate an item */
static struct Item *
-allocitem(const char *label, const char *output)
+allocitem(const char *label, const char *output, char *file)
{
struct Item *item;
@@ -266,6 +276,12 @@ allocitem(const char *label, const char *output)
err(1, "strdup");
}
}
+ if (file == NULL) {
+ item->file = NULL;
+ } else {
+ if ((item->file = strdup(file)) == NULL)
+ err(1, "strdup");
+ }
item->y = 0;
item->h = 0;
if (item->label == NULL)
@@ -274,6 +290,7 @@ allocitem(const char *label, const char *output)
item->labellen = strlen(item->label);
item->next = NULL;
item->submenu = NULL;
+ item->image = NULL;
return item;
}
@@ -314,7 +331,7 @@ allocmenu(struct Menu *parent, struct Item *list, unsigned level)
/* build the menu tree */
static struct Menu *
-buildmenutree(unsigned level, const char *label, const char *output)
+buildmenutree(unsigned level, const char *label, const char *output, char *file)
{
static struct Menu *prevmenu = NULL; /* menu the previous item was added to */
static struct Menu *rootmenu = NULL; /* menu to be returned */
@@ -324,7 +341,7 @@ buildmenutree(unsigned level, const char *label, const char *output)
unsigned i;
/* create the item */
- curritem = allocitem(label, output);
+ curritem = allocitem(label, output, file);
/* put the item in the menu tree */
if (prevmenu == NULL) { /* there is no menu yet */
@@ -377,7 +394,7 @@ parsestdin(void)
{
struct Menu *rootmenu;
char *s, buf[BUFSIZ];
- char *label, *output;
+ char *file, *label, *output;
unsigned level = 0;
rootmenu = NULL;
@@ -390,6 +407,13 @@ parsestdin(void)
s = level + buf;
label = strtok(s, "\t\n");
+ /* get the filename */
+ file = NULL;
+ if (label != NULL && strncmp(label, "IMG:", 4) == 0) {
+ file = label + 4;
+ label = strtok(NULL, "\t\n");
+ }
+
/* get the output */
output = strtok(NULL, "\n");
if (output == NULL) {
@@ -399,12 +423,36 @@ parsestdin(void)
output++;
}
- rootmenu = buildmenutree(level, label, output);
+ rootmenu = buildmenutree(level, label, output, file);
}
return rootmenu;
}
+/* load and scale image */
+static Imlib_Image
+loadimage(const char *file, int size)
+{
+ Imlib_Image image;
+ int width;
+ int height;
+ int imgsize;
+
+ image = imlib_load_image(file);
+ if (image == NULL)
+ errx(1, "cannot load image %s", file);
+
+ imlib_context_set_image(image);
+
+ width = imlib_image_get_width();
+ height = imlib_image_get_height();
+ imgsize = MIN(width, height);
+
+ image = imlib_create_cropped_scaled_image(0, 0, imgsize, imgsize, size, size);
+
+ return image;
+}
+
/* recursivelly calculate menu geometry and set window hints */
static void
calcmenu(struct Geometry *geom, struct Menu *menu)
@@ -430,8 +478,12 @@ calcmenu(struct Geometry *geom, struct Menu *menu)
XftTextExtentsUtf8(dpy, dc.font, (XftChar8 *)item->label,
item->labellen, &ext);
- labelwidth = ext.xOff + dc.font->height * 2;
+ labelwidth = ext.xOff + dc.font->height * 2 + imgpadding;
menu->w = MAX(menu->w, labelwidth);
+
+ /* create image */
+ if (item->file != NULL)
+ item->image = loadimage(item->file, dc.font->height);
}
/* calculate menu's x and y positions */
@@ -621,7 +673,7 @@ drawitem(struct Menu *menu, struct Item *item, XftColor *color)
{
int x, y;
- x = dc.font->height;
+ x = dc.font->height + imgpadding;
y = item->y + item->h/2 + dc.font->ascent/2 - 1;
XSetForeground(dpy, dc.gc, color[ColorFG].pixel);
XftDrawStringUtf8(menu->draw, &color[ColorFG], dc.font,
@@ -629,8 +681,8 @@ drawitem(struct Menu *menu, struct Item *item, XftColor *color)
/* draw triangle, if item contains a submenu */
if (item->submenu != NULL) {
- x = menu->w - dc.font->height/2 - triangle_width/2;
- y = item->y + item->h/2 - triangle_height/2 - 1;
+ x = menu->w - (dc.font->height - triangle_width) / 2;
+ y = item->y + (item->h - triangle_height) / 2;
XPoint triangle[] = {
{x, y},
@@ -642,6 +694,15 @@ drawitem(struct Menu *menu, struct Item *item, XftColor *color)
XFillPolygon(dpy, menu->pixmap, dc.gc, triangle, LEN(triangle),
Convex, CoordModeOrigin);
}
+
+ /* draw image */
+ if (item->file != NULL) {
+ x = imgpadding / 2;
+ y = item->y + (item->h - dc.font->height) / 2;
+ imlib_context_set_drawable(menu->pixmap);
+ imlib_context_set_image(item->image);
+ imlib_render_image_on_drawable(x, y);
+ }
}
/* draw items of the current menu and of its ancestors */
@@ -831,6 +892,13 @@ freemenu(struct Menu *menu)
if (tmp->label != tmp->output)
free(tmp->label);
free(tmp->output);
+ if (tmp->file != NULL) {
+ free(tmp->file);
+ if (item->image != NULL) {
+ imlib_context_set_image(item->image);
+ imlib_free_image();
+ }
+ }
free(tmp);
}
diff --git a/xmenu.sh b/xmenu.sh
index abd9a41..db08041 100755
--- a/xmenu.sh
+++ b/xmenu.sh
@@ -2,7 +2,7 @@
cat <<EOF | xmenu | sh &
Applications
- Web Browser firefox
+ IMG:./web.png Web Browser firefox
Image editor gimp
Terminal (xterm) xterm
Terminal (urxvt) urxvt

BIN
web.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB