Commit Diff


commit - fa5a6135a8a93244a1fa23746bbcfb6b9d8d0c17
commit + e5186d6b0b82449e564049bb3ddc13face30c606
blob - 875dc80f18b234350303bf0c4c30b3e62c55e347
blob + 33acdd45ef8d27c1bd3ad2ebc89e316c4541f682
--- mymenu.1
+++ mymenu.1
@@ -47,8 +47,15 @@ could be supplied. In addition to it, the special valu
 be used: in that case the window will be centered on the x axes.
 .It MyMenu.y
 The Y coordinate of the topmost left corner of the window. Like the X
-coordinate, pixel dimension, percentage dimension and the special
+coordinate a pixel dimension, percentage dimension or the special
 value "middle" could be supplied.
+.It MyMenu.padding
+Change the padding. In the horizontal layout the padding is the space
+between the rectangle of the completion and the text as well as the
+space between the prompt and the first completion. In the horizontal
+layout the padding is the horizontal spacing between the window edge
+and the text as well as the space up and down the text within the
+completion. The default value is 10.
 .It MyMenu.prompt.background
 The background of the prompt.
 .It MyMenu.prompt.foreground
blob - cd1d7f801a6e8ab04ab6a245e4266b717141b1bf
blob + b744f0b7bc36f67ad1d1a2941f783cba0de606b9
--- mymenu.c
+++ mymenu.c
@@ -84,6 +84,12 @@ enum text_type {PROMPT, COMPL, COMPL_HIGH};
 struct rendering {
   Display *d;
   Window w;
+  int width;
+  int height;
+  int padding;
+  bool horizontal_layout;
+  char *ps1;
+  int ps1len;
   GC prompt;
   GC prompt_bg;
   GC completion;
@@ -91,19 +97,14 @@ struct rendering {
   GC completion_highlighted;
   GC completion_highlighted_bg;
 #ifdef USE_XFT
+  XftFont *font;
   XftDraw *xftdraw;
   XftColor xft_prompt;
   XftColor xft_completion;
   XftColor xft_completion_highlighted;
-  XftFont *font;
 #else
   XFontSet *font;
 #endif
-  int width;
-  int height;
-  bool horizontal_layout;
-  char *ps1;
-  int ps1len;
 };
 
 struct completions {
@@ -364,10 +365,10 @@ int text_extents(char *str, int len, struct rendering 
 #ifdef USE_XFT
   XGlyphInfo gi;
   XftTextExtentsUtf8(r->d, r->font, str, len, &gi);
-  // Honestly I don't know why this won't work, but I found that this
-  // formula seems to work with various ttf font
   /* height = gi.height; */
-  height = (gi.height + (r->font->ascent - r->font->descent)/2) / 2;
+  /* height = (gi.height + (r->font->ascent - r->font->descent)/2) / 2; */
+  /* height = (r->font->ascent - r->font->descent)/2 + gi.height*2; */
+  height = r->font->ascent - r->font->descent;
   width = gi.width - gi.x;
 #else
   XRectangle rect;
@@ -420,19 +421,20 @@ char *strdupn(char *str) {
 // | 20 char text     | completion | completion | completion | compl |
 // |------------------|----------------------------------------------|
 void draw_horizontally(struct rendering *r, char *text, struct completions *cs) {
-  // TODO: make these dynamic?
   int prompt_width = 20; // char
-  int padding = 10;
 
   int width, height;
   char *ps1_dup = strdupn(r->ps1);
+  if (ps1_dup == nil)
+    return;
+
   ps1_dup = ps1_dup == nil ? r->ps1 : ps1_dup;
   int ps1xlen = text_extents(ps1_dup, r->ps1len, r, &width, &height);
   free(ps1_dup);
   int start_at = ps1xlen;
 
   start_at = text_extents("n", 1, r, nil, nil);
-  start_at = start_at * prompt_width + padding;
+  start_at = start_at * prompt_width + r->padding;
 
   int texty = (height + r->height) >>1;
 
@@ -441,8 +443,8 @@ void draw_horizontally(struct rendering *r, char *text
   int text_len = strlen(text);
   if (text_len > prompt_width)
     text = text + (text_len - prompt_width);
-  draw_string(r->ps1, r->ps1len, padding, texty, r, PROMPT);
-  draw_string(text, MIN(text_len, prompt_width), padding + ps1xlen, texty, r, PROMPT);
+  draw_string(r->ps1, r->ps1len, r->padding, texty, r, PROMPT);
+  draw_string(text, MIN(text_len, prompt_width), r->padding + ps1xlen, texty, r, PROMPT);
 
   XFillRectangle(r->d, r->w, r->completion_bg, start_at, 0, r->width, r->height);
 
@@ -453,11 +455,11 @@ void draw_horizontally(struct rendering *r, char *text
     int len = strlen(cs->completion);
     int text_width = text_extents(cs->completion, len, r, nil, nil);
 
-    XFillRectangle(r->d, r->w, h, start_at, 0, text_width + padding*2, r->height);
+    XFillRectangle(r->d, r->w, h, start_at, 0, text_width + r->padding*2, r->height);
 
-    draw_string(cs->completion, len, start_at + padding, texty, r, tt);
+    draw_string(cs->completion, len, start_at + r->padding, texty, r, tt);
 
-    start_at += text_width + padding * 2;
+    start_at += text_width + r->padding * 2;
 
     if (start_at > r->width)
       break; // don't draw completion if the space isn't enough
@@ -475,15 +477,10 @@ void draw_horizontally(struct rendering *r, char *text
 // |-----------------------------------------------------------------|
 // |  completion                                                     |
 // |-----------------------------------------------------------------|
-// TODO: dunno why but in the call to Xutf8DrawString, by logic,
-// should be padding and not padding*2, but the text doesn't seem to
-// be vertically centered otherwise....
-void draw_vertically(struct rendering *r, char *text, struct completions *cs) {
-  int padding = 10; // TODO make this dynamic
-
+void draw_vertically(struct rendering *r, char *text, struct completions *cs) {
   int height, width;
-  text_extents("fjpgl", 5, r, &width, &height);
-  int start_at = height + padding*2;
+  text_extents("fjpgl", 5, r, nil, &height);
+  int start_at = height + r->padding;
 
   XFillRectangle(r->d, r->w, r->completion_bg, 0, 0, r->width, r->height);
   XFillRectangle(r->d, r->w, r->prompt_bg, 0, 0, r->width, start_at);
@@ -493,8 +490,9 @@ void draw_vertically(struct rendering *r, char *text, 
   int ps1xlen = text_extents(ps1_dup, r->ps1len, r, nil, nil);
   free(ps1_dup);
 
-  draw_string(r->ps1, r->ps1len, padding, padding*2, r, PROMPT);
-  draw_string(text, strlen(text), padding + ps1xlen, padding*2, r, PROMPT);
+  draw_string(r->ps1, r->ps1len, r->padding, height + r->padding, r, PROMPT);
+  draw_string(text, strlen(text), r->padding + ps1xlen, height + r->padding, r, PROMPT);
+  start_at += r->padding;
 
   while (cs != nil) {
     enum text_type tt = cs->selected ? COMPL_HIGH : COMPL;
@@ -502,10 +500,10 @@ void draw_vertically(struct rendering *r, char *text, 
 
     int len = strlen(cs->completion);
     text_extents(cs->completion, len, r, &width, &height);
-    XFillRectangle(r->d, r->w, h, 0, start_at, r->width, height + padding*2);
-    draw_string(cs->completion, len, padding, start_at + padding*2, r, tt);
+    XFillRectangle(r->d, r->w, h, 0, start_at, r->width, height + r->padding*2);
+    draw_string(cs->completion, len, r->padding, start_at + height + r->padding, r, tt);
 
-    start_at += height + padding *2;
+    start_at += height + r->padding *2;
 
     if (start_at > r->height)
       break; // don't draw completion if the space isn't enough
@@ -676,6 +674,8 @@ int main() {
   int x = 0;
   int y = 0;
 
+  int padding = 10;
+
   char *ps1 = strdup("$ ");
   check_allocation(ps1);
 
@@ -793,13 +793,18 @@ int main() {
     if (XrmGetResource(xdb, "MyMenu.x", "*", datatype, &value) == true)
       x = parse_int_with_middle(value.addr, x, d_width, width);
     else
-      fprintf(stderr, "no x defined, using %d\n", width);
+      fprintf(stderr, "no x defined, using %d\n", x);
 
     if (XrmGetResource(xdb, "MyMenu.y", "*", datatype, &value) == true)
       y = parse_int_with_middle(value.addr, y, d_height, height);
     else
-      fprintf(stderr, "no y defined, using %d\n", height);
+      fprintf(stderr, "no y defined, using %d\n", y);
 
+    if (XrmGetResource(xdb, "MyMenu.padding", "*", datatype, &value) == true)
+      padding = parse_integer(value.addr, padding);
+    else
+      fprintf(stderr, "no y defined, using %d\n", padding);
+
     XColor tmp;
     // TODO: tmp needs to be free'd after every allocation?
 
@@ -921,6 +926,7 @@ int main() {
     .completion_highlighted_bg  = XCreateGC(d, w, 0, &values),
     .width                      = width,
     .height                     = height,
+    .padding                    = padding,
     .horizontal_layout          = horizontal_layout,
     .ps1                        = ps1,
     .ps1len                     = strlen(ps1)