Commit Diff


commit - 0d836add15f19a060d0052830d0d1ec2ed42c6a4
commit + a8ca9c6d37f65303af174c40a64251e886a7997b
blob - 87c3a615620c6002cee935e34c93f387b85e9cb5
blob + 7350b40f8f6e62c104a85fb5ad448b4c551daa60
--- mymenu.1
+++ mymenu.1
@@ -167,11 +167,13 @@ horizontally centered;
 .It end
 Compute the correct value to make sure that mymenu will be right
 aligned.
+.It mx and my
+These stands for x and y coordinate of the mouse respectively.
 .El
 .It MyMenu.y
 The Y coordinate of the topmost left corner of the window. Like the X
 coordinate a pixel dimension, percentage dimension or the special
-value "start", "middle"/"center", "end" could be supplied.
+value "start", "middle"/"center", "end" or "mx"/"my" could be supplied.
 .It MyMenu.border.size
 A list of number separated by spaces to specify the border of the
 window. The field is parsed like some CSS properties (i.e. padding),
blob - 2614cfe00b435f178360885cffec255d8eb18f95
blob + fc0ca277eea8f8ac8e61306df6c6b45fb9d2cdb5
--- mymenu.1.md
+++ mymenu.1.md
@@ -248,11 +248,15 @@ MyMenu.x
 > > Compute the correct value to make sure that mymenu will be right
 > > aligned.
 
+> mx and my
+
+> > These stands for x and y coordinate of the mouse respectively.
+
 MyMenu.y
 
 > The Y coordinate of the topmost left corner of the window. Like the X
 > coordinate a pixel dimension, percentage dimension or the special
-> value "start", "middle"/"center", "end" could be supplied.
+> value "start", "middle"/"center", "end" or "mx"/"my" could be supplied.
 
 MyMenu.border.size
 
@@ -468,4 +472,6 @@ Omar Polo <omar.polo@europecom.net>
 	height of the window, remember to override the x and y coordinates as
 	well.
 
-Void Linux - October 19, 2019
+*	Clicking past the last item will be equivalent to clicking the last item.
+
+Void Linux - October 20, 2019
blob - 70f36f24d66b714fb89696aa740ecb25570d4832
blob + 460bde0dcafa60390e608766836ee79d866ab416
--- mymenu.c
+++ mymenu.c
@@ -1032,16 +1032,37 @@ parse_int_with_percentage(const char *str, int default
 
 	return parse_integer(str, default_value);
 }
+
+void
+get_mouse_coords(Display *d, int *x, int *y)
+{
+	Window w, root;
+	int i;
+	unsigned int u;
 
+	*x = *y = 0;
+	root = DefaultRootWindow(d);
+
+	if (!XQueryPointer(d, root, &root, &w, x, y, &i, &i, &u)) {
+		for (i = 0; i < ScreenCount(d); ++i) {
+			if (root == RootWindow(d, i))
+				break;
+		}
+	}
+}
+
 /*
  * Like parse_int_with_percentage but understands some special values:
  * - middle that is (max-self)/2
  * - center = middle
  * - start  that is 0
  * - end    that is (max-self)
+ * - mx     x coordinate of the mouse
+ * - my     y coordinate of the mouse
  */
 int
-parse_int_with_pos(const char *str, int default_value, int max, int self)
+parse_int_with_pos(
+	Display *d, const char *str, int default_value, int max, int self)
 {
 	if (!strcmp(str, "start"))
 		return 0;
@@ -1049,6 +1070,15 @@ parse_int_with_pos(const char *str, int default_value,
 		return (max - self) / 2;
 	if (!strcmp(str, "end"))
 		return max - self;
+	if (!strcmp(str, "mx") || !strcmp(str, "my")) {
+		int x, y;
+
+		get_mouse_coords(d, &x, &y);
+		if (!strcmp(str, "mx"))
+			return x;
+		else
+			return y;
+	}
 	return parse_int_with_percentage(str, default_value, max);
 }
 
@@ -1861,12 +1891,12 @@ main(int argc, char **argv)
 		if (XrmGetResource(xdb, "MyMenu.x", "*", datatype, &value)
 			== 1)
 			x = parse_int_with_pos(
-				value.addr, x, d_width, r.width);
+				r.d, value.addr, x, d_width, r.width);
 
 		if (XrmGetResource(xdb, "MyMenu.y", "*", datatype, &value)
 			== 1)
 			y = parse_int_with_pos(
-				value.addr, y, d_height, r.height);
+				r.d, value.addr, y, d_height, r.height);
 
 		if (XrmGetResource(
 			    xdb, "MyMenu.border.size", "*", datatype, &value)
@@ -2062,10 +2092,12 @@ main(int argc, char **argv)
 			break;
 		}
 		case 'x':
-			x = parse_int_with_pos(optarg, x, d_width, r.width);
+			x = parse_int_with_pos(
+				r.d, optarg, x, d_width, r.width);
 			break;
 		case 'y':
-			y = parse_int_with_pos(optarg, y, d_height, r.height);
+			y = parse_int_with_pos(
+				r.d, optarg, y, d_height, r.height);
 			break;
 		case 'P': {
 			char **paddings;