xmenu now supports x resources
authorphillbush <phillbush@cock.li>
Sun, 17 May 2020 04:22:21 +0000 (01:22 -0300)
committerphillbush <phillbush@cock.li>
Sun, 17 May 2020 04:22:21 +0000 (01:22 -0300)
config.h
xmenu.1
xmenu.c

index 2dffcc7..6a37a74 100644 (file)
--- a/config.h
+++ b/config.h
@@ -1,11 +1,11 @@
-#define FONT            "-*-*-medium-*-*-*-14-*-*-*-*-*-*-*"
-#define UNPRESSEDBG     "#FFFFFF"
-#define UNPRESSEDFG     "#2E3436"
-#define PRESSEDBG       "#3584E4"
-#define PRESSEDFG       "#FFFFFF"
-#define DECORATIONBG    "#CDC7C2"
-#define DECORATIONFG    "#E6E6E6"
-#define ITEMW           130
-#define ITEMB           4
-#define BORDER          1
-#define SEPARATOR       1
+static const char *font = "-*-*-medium-*-*-*-14-*-*-*-*-*-*-*";
+static const char *background = "#FFFFFF";
+static const char *foreground = "#2E3436";
+static const char *selbackground = "#3584E4";
+static const char *selforeground = "#FFFFFF";
+static const char *separator = "#CDC7C2";
+static const char *border = "#E6E6E6";
+static int width = 130;
+static int itemborder = 4;
+static int menuborder = 1;
+static int separatorsize = 1;
diff --git a/xmenu.1 b/xmenu.1
index 0e01c44..de61a9e 100644 (file)
--- a/xmenu.1
+++ b/xmenu.1
@@ -37,6 +37,44 @@ separating the item above from the item below.
 The command is the string that will be output after selecting the item.
 .IP
 The newline terminates the item specification.
 The command is the string that will be output after selecting the item.
 .IP
 The newline terminates the item specification.
+.SH RESOURCES
+.B
+xmenu
+understands the following X resources.
+.TP
+.B xmenu.font
+The font in which the labels should be drawn.
+.TP
+.B xmenu.background
+The background color of non-selected itens in the menu.
+.TP
+.B xmenu.foreground
+The color of the label text of non-selected itens in the menu.
+.TP
+.B xmenu.selbackground
+The background color of selected itens in the menu.
+.TP
+.B xmenu.selforeground
+The color of the label text of selected itens in the menu.
+.TP
+.B xmenu.border
+The color of the border around the menu.
+.TP
+.B xmenu.separator
+The color of the separator between itens in the menu.
+.TP
+.B xmenu.width
+The minimum width, in pixels, of the items in the menu.
+.TP
+.B xmenu.itemborder
+The size in pixels of the border around the label text in items in the menu.
+.TP
+.B xmenu.menuborder
+The size in pixels of the border around the menu.
+.TP
+.B xmenu.separatorsize
+The size in pixels of the item separator.
+
 .SH EXAMPLES
 The following is an script exemplifying the use
 .BR xmenu .
 .SH EXAMPLES
 The following is an script exemplifying the use
 .BR xmenu .
diff --git a/xmenu.c b/xmenu.c
index 41303cc..0afaaa9 100644 (file)
--- a/xmenu.c
+++ b/xmenu.c
@@ -5,6 +5,7 @@
 #include <unistd.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <unistd.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
+#include <X11/Xresource.h>
 
 /* macros */
 #define LEN(x) (sizeof (x) / sizeof (x[0]))
 
 /* macros */
 #define LEN(x) (sizeof (x) / sizeof (x[0]))
@@ -16,8 +17,8 @@ enum {ColorFG, ColorBG, ColorLast};
 
 /* draw context structure */
 struct DC {
 
 /* draw context structure */
 struct DC {
-       unsigned long unpressed[ColorLast];
-       unsigned long pressed[ColorLast];
+       unsigned long normal[ColorLast];
+       unsigned long selected[ColorLast];
        unsigned long decoration[ColorLast];
 
        Drawable d;
        unsigned long decoration[ColorLast];
 
        Drawable d;
@@ -66,6 +67,7 @@ struct Menu {
 
 /* function declarations */
 static unsigned long getcolor(const char *s);
 
 /* function declarations */
 static unsigned long getcolor(const char *s);
+static void getresources(void);
 static void setupdc(void);
 static void setupgeom(void);
 static void setupgrab(void);
 static void setupdc(void);
 static void setupgeom(void);
 static void setupgrab(void);
@@ -128,6 +130,7 @@ main(int argc, char *argv[])
        colormap = DefaultColormap(dpy, screen);
 
        /* setup */
        colormap = DefaultColormap(dpy, screen);
 
        /* setup */
+       getresources();
        setupdc();
        setupgeom();
        setupgrab();
        setupdc();
        setupgeom();
        setupgrab();
@@ -151,6 +154,52 @@ main(int argc, char *argv[])
        return 0;
 }
 
        return 0;
 }
 
+/* read xrdb for configuration options */
+static void
+getresources(void)
+{
+       char *xrm;
+       long n;
+
+       XrmInitialize();
+       if ((xrm = XResourceManagerString(dpy))) {
+               char *type;
+               XrmDatabase xdb;
+               XrmValue xval;
+
+               xdb = XrmGetStringDatabase(xrm);
+
+               if (XrmGetResource(xdb, "xmenu.menuborder", "*", &type, &xval) == True)
+                       if ((n = strtol(xval.addr, NULL, 10)) > 0)
+                               menuborder = n;
+               if (XrmGetResource(xdb, "xmenu.separatorsize", "*", &type, &xval) == True)
+                       if ((n = strtol(xval.addr, NULL, 10)) > 0)
+                               separatorsize = n;
+               if (XrmGetResource(xdb, "xmenu.itemborder", "*", &type, &xval) == True)
+                       if ((n = strtol(xval.addr, NULL, 10)) > 0)
+                               itemborder = n;
+               if (XrmGetResource(xdb, "xmenu.width", "*", &type, &xval) == True)
+                       if ((n = strtol(xval.addr, NULL, 10)) > 0)
+                               width = n;
+               if (XrmGetResource(xdb, "xmenu.background", "*", &type, &xval) == True)
+                       background = strdup(xval.addr);
+               if (XrmGetResource(xdb, "xmenu.foreground", "*", &type, &xval) == True)
+                       foreground = strdup(xval.addr);
+               if (XrmGetResource(xdb, "xmenu.selbackground", "*", &type, &xval) == True)
+                       selbackground = strdup(xval.addr);
+               if (XrmGetResource(xdb, "xmenu.selforeground", "*", &type, &xval) == True)
+                       selforeground = strdup(xval.addr);
+               if (XrmGetResource(xdb, "xmenu.separator", "*", &type, &xval) == True)
+                       separator = strdup(xval.addr);
+               if (XrmGetResource(xdb, "xmenu.border", "*", &type, &xval) == True)
+                       border = strdup(xval.addr);
+               if (XrmGetResource(xdb, "xmenu.font", "*", &type, &xval) == True)
+                       font = strdup(xval.addr);
+
+               XrmDestroyDatabase(xdb);
+       }
+}
+
 /* get color from color string */
 static unsigned long
 getcolor(const char *s)
 /* get color from color string */
 static unsigned long
 getcolor(const char *s)
@@ -167,15 +216,15 @@ static void
 setupdc(void)
 {
        /* get color pixels */
 setupdc(void)
 {
        /* get color pixels */
-       dc.unpressed[ColorBG] = getcolor(UNPRESSEDBG);
-       dc.unpressed[ColorFG] = getcolor(UNPRESSEDFG);
-       dc.pressed[ColorBG] = getcolor(PRESSEDBG);
-       dc.pressed[ColorFG] = getcolor(PRESSEDFG);
-       dc.decoration[ColorBG] = getcolor(DECORATIONBG);
-       dc.decoration[ColorFG] = getcolor(DECORATIONFG);
+       dc.normal[ColorBG] = getcolor(background);
+       dc.normal[ColorFG] = getcolor(foreground);
+       dc.selected[ColorBG] = getcolor(selbackground);
+       dc.selected[ColorFG] = getcolor(selforeground);
+       dc.decoration[ColorBG] = getcolor(separator);
+       dc.decoration[ColorFG] = getcolor(border);
 
        /* try to get font */
 
        /* try to get font */
-       if ((dc.font = XLoadQueryFont(dpy, FONT)) == NULL)
+       if ((dc.font = XLoadQueryFont(dpy, font)) == NULL)
                errx(1, "cannot load font");
        dc.fonth = dc.font->ascent + dc.font->descent;
 
                errx(1, "cannot load font");
        dc.fonth = dc.font->ascent + dc.font->descent;
 
@@ -188,11 +237,11 @@ setupdc(void)
 static void
 setupgeom(void)
 {
 static void
 setupgeom(void)
 {
-       geom.itemb = ITEMB;
-       geom.itemh = dc.fonth + ITEMB * 2;
-       geom.itemw = ITEMW;
-       geom.border = BORDER;
-       geom.separator = SEPARATOR;
+       geom.itemb = itemborder;
+       geom.itemh = dc.fonth + itemborder * 2;
+       geom.itemw = width;
+       geom.border = menuborder;
+       geom.separator = separatorsize;
 }
 
 /* grab pointer */
 }
 
 /* grab pointer */
@@ -396,10 +445,10 @@ calcmenu(struct Menu *menu)
                for (item = menu->parent->list; item->submenu != menu; item = item->next)
                        ;
 
                for (item = menu->parent->list; item->submenu != menu; item = item->next)
                        ;
 
-               if (screengeom.screenw - (menu->parent->x + menu->parent->w) >= menu->w)
-                       menu->x = menu->parent->x + menu->parent->w;
-               else if (menu->parent->x > menu->w)
-                       menu->x = menu->parent->x - menu->w;
+               if (screengeom.screenw - (menu->parent->x + menu->parent->w + geom.border) >= menu->w)
+                       menu->x = menu->parent->x + menu->parent->w + geom.border;
+               else if (menu->parent->x > menu->w + geom.border)
+                       menu->x = menu->parent->x - menu->w - geom.border;
 
                if (screengeom.screenh - (item->y + menu->parent->y) > menu->h)
                        menu->y = item->y + menu->parent->y;
 
                if (screengeom.screenh - (item->y + menu->parent->y) > menu->h)
                        menu->y = item->y + menu->parent->y;
@@ -522,12 +571,14 @@ drawmenu(void)
                        int labelx, labely;
 
                        /* determine item color */
                        int labelx, labely;
 
                        /* determine item color */
-                       if (item->label == NULL)
-                               color = dc.decoration;
-                       else if (item == menu->selected)
-                               color = dc.pressed;
+                       if (item == menu->selected)
+                               color = dc.selected;
                        else
                        else
-                               color = dc.unpressed;
+                               color = dc.normal;
+
+                       /* continue if item is a separator */
+                       if (item->label == NULL)
+                               continue;
 
                        /* draw item box */
                        XSetForeground(dpy, dc.gc, color[ColorBG]);
 
                        /* draw item box */
                        XSetForeground(dpy, dc.gc, color[ColorBG]);
@@ -536,10 +587,6 @@ drawmenu(void)
                        XFillRectangle(dpy, menu->pixmap, dc.gc, 0, item->y,
                                       menu->w, item->h);
 
                        XFillRectangle(dpy, menu->pixmap, dc.gc, 0, item->y,
                                       menu->w, item->h);
 
-                       /* continue if item is a separator */
-                       if (item->label == NULL)
-                               continue;
-
                        /* draw item label */
                        labelx = 0 + dc.fonth;
                        labely = item->y + dc.fonth + geom.itemb;
                        /* draw item label */
                        labelx = 0 + dc.fonth;
                        labely = item->y + dc.fonth + geom.itemb;