[wiki] [sites] dmenu mouse patch: merge multisel with mouse patch || Hiltjo Posthuma

From: <git_AT_suckless.org>
Date: Sat, 02 Jul 2016 12:26:53 +0200

commit 9bf2bda6bb17149f3ac364c0b4f130362d5026e7
Author: Hiltjo Posthuma <hiltjo_AT_codemadness.org>
Date: Sat Jul 2 12:24:18 2016 +0200

    dmenu mouse patch: merge multisel with mouse patch
    
    ... also add a version based on the latest git.
    
    Thanks Xarchus for the multisel idea!

diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.6-mouse-support-msel.diff b/tools.suckless.org/dmenu/patches/dmenu-4.6-mouse-support-msel.diff
deleted file mode 100644
index 74490ba..0000000
--- a/tools.suckless.org/dmenu/patches/dmenu-4.6-mouse-support-msel.diff
+++ /dev/null
_AT_@ -1,154 +0,0 @@
-diff --git a/dmenu.c b/dmenu.c
-index a07f8e3..1de62c1 100644
---- a/dmenu.c
-+++ b/dmenu.c
-_AT_@ -277,6 +277,129 @@ nextrune(int inc)
- return n;
- }
-
-+void
-+buttonpress(XEvent *e)
-+{
-+ struct item *item;
-+ XButtonPressedEvent *ev = &e->xbutton;
-+ int xpos, ypos, wpos, hpos;
-+
-+ if(ev->window != win)
-+ return;
-+
-+ /* right-click: exit */
-+ if(ev->button == Button3)
-+ exit(EXIT_FAILURE);
-+
-+ xpos = 0;
-+ ypos = 0;
-+ hpos = bh;
-+
-+ if(prompt && *prompt) {
-+ wpos = promptw;
-+ xpos = wpos;
-+ }
-+ /* input field */
-+ wpos = (lines > 0 || !matches) ? mw - xpos : inputw;
-+
-+ /* left-click on input: clear input,
-+ * NOTE: if there is no left-arrow the space for < is reserved so
-+ * add that to the input width */
-+ if(ev->button == Button1 &&
-+ ((lines <= 0 && ev->x >= 0 && ev->x <= xpos + wpos +
-+ ((!prev || !curr->left) ? TEXTW("<") : 0)) ||
-+ (lines > 0 && ev->y >= ypos && ev->y <= ypos + hpos))) {
-+ insert(NULL, 0 - cursor);
-+ drawmenu();
-+ return;
-+ }
-+ /* middle-mouse click: paste selection */
-+ if(ev->button == Button2) {
-+ XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
-+ utf8, utf8, win, CurrentTime);
-+ drawmenu();
-+ return;
-+ }
-+ /* scroll up */
-+ if(ev->button == Button4 && prev) {
-+ sel = curr = prev;
-+ calcoffsets();
-+ drawmenu();
-+ return;
-+ }
-+ /* scroll down */
-+ if(ev->button == Button5 && next) {
-+ sel = curr = next;
-+ calcoffsets();
-+ drawmenu();
-+ return;
-+ }
-+ if(ev->button != Button1)
-+ return;
-+ if(ev->state & ~ControlMask)
-+ return;
-+ if(lines > 0) {
-+ /* vertical list: (ctrl-)left-click on item */
-+ wpos = mw - xpos;
-+ for(item = curr; item != next; item = item->right) {
-+ ypos += hpos;
-+ if(ev->y >= ypos && ev->y <= (ypos + hpos)) {
-+ puts(item->text);
-+ sel=item;
-+ if (!(ev->state & ControlMask)) {
-+ cleanup();
-+ exit(EXIT_SUCCESS);
-+ }
-+ if (sel) {
-+ sel->out = 1;
-+ drawmenu();
-+ }
-+ return;
-+ }
-+ }
-+ }
-+ else if(matches) {
-+ /* left-click on left arrow */
-+ xpos += inputw;
-+ wpos = TEXTW("<");
-+ if(prev && curr->left) {
-+ if(ev->x >= xpos && ev->x <= xpos + wpos) {
-+ sel = curr = prev;
-+ calcoffsets();
-+ drawmenu();
-+ return;
-+ }
-+ }
-+ /* horizontal list: (ctrl-)left-click on item */
-+ for(item = curr; item != next; item = item->right) {
-+ xpos += wpos;
-+ wpos = MIN(TEXTW(item->text), mw - xpos - TEXTW(">"));
-+ if(ev->x >= xpos && ev->x <= (xpos + wpos)) {
-+ puts(item->text);
-+ sel=item;
-+ if (!(ev->state & ControlMask)) {
-+ cleanup();
-+ exit(EXIT_SUCCESS);
-+ }
-+ if (sel) {
-+ sel->out = 1;
-+ drawmenu();
-+ }
-+ return;
-+ }
-+ }
-+ /* left-click on right arrow */
-+ wpos = TEXTW(">");
-+ xpos = mw - wpos;
-+ if(next && ev->x >= xpos && ev->x <= xpos + wpos) {
-+ sel = curr = next;
-+ calcoffsets();
-+ drawmenu();
-+ return;
-+ }
-+ }
-+}
-+
- static void
- keypress(XKeyEvent *ev)
- {
-_AT_@ -502,6 +625,9 @@ run(void)
- if (ev.xexpose.count == 0)
- drw_map(drw, win, 0, 0, mw, mh);
- break;
-+ case ButtonPress:
-+ buttonpress(&ev);
-+ break;
- case KeyPress:
- keypress(&ev.xkey);
- break;
-_AT_@ -589,7 +715,8 @@ setup(void)
- /* create menu window */
- swa.override_redirect = True;
- swa.background_pixel = scheme[SchemeNorm].bg->pix;
-- swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
-+ swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask |
-+ ButtonPressMask;
- win = XCreateWindow(dpy, root, x, y, mw, mh, 0,
- DefaultDepth(dpy, screen), CopyFromParent,
- DefaultVisual(dpy, screen),
diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.6-mouse-support.diff b/tools.suckless.org/dmenu/patches/dmenu-4.6-mouse-support.diff
deleted file mode 100644
index 3c42813..0000000
--- a/tools.suckless.org/dmenu/patches/dmenu-4.6-mouse-support.diff
+++ /dev/null
_AT_@ -1,143 +0,0 @@
-From cb154e0e93819cba9fee70f108dc95a168ab664e Mon Sep 17 00:00:00 2001
-From: Hiltjo Posthuma <hiltjo_AT_codemadness.org>
-Date: Fri, 17 Jun 2016 14:44:16 +0200
-Subject: [PATCH] dmenu mouse support
-
----
- dmenu.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 105 insertions(+), 1 deletion(-)
-
-diff --git a/dmenu.c b/dmenu.c
-index e0c2f80..7907ae9 100644
---- a/dmenu.c
-+++ b/dmenu.c
-_AT_@ -451,6 +451,106 @@ keypress(XKeyEvent *ev)
- }
- 
- static void
-+buttonpress(XEvent *e)
-+{
-+	int curpos;
-+	struct item *item;
-+	XButtonPressedEvent *ev = &e->xbutton;
-+	int x = 0, y = 0, h = bh, w;
-+
-+	if (ev->window != win)
-+		return;
-+
-+	/* right-click: exit */
-+	if (ev->button == Button3)
-+		exit(1);
-+
-+	if (prompt && *prompt)
-+		x += promptw;
-+
-+	/* input field */
-+	w = (lines > 0 || !matches) ? mw - x : inputw;
-+	if ((curpos = TEXTNW(text, cursor) + bh / 2 - 2) < w)
-+		;
-+
-+	/* left-click on input: clear input,
-+	 * NOTE: if there is no left-arrow the space for < is reserved so
-+	 *       add that to the input width */
-+	if (ev->button == Button1 &&
-+	   ((lines <= 0 && ev->x >= 0 && ev->x <= x + w +
-+	   ((!prev || !curr->left) ? TEXTW("<") : 0)) ||
-+	   (lines > 0 && ev->y >= y && ev->y <= y + h))) {
-+		insert(NULL, -cursor);
-+		drawmenu();
-+		return;
-+	}
-+	/* middle-mouse click: paste selection */
-+	if (ev->button == Button2) {
-+		XConvertSelection(drw->dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
-+		                  utf8, utf8, win, CurrentTime);
-+		drawmenu();
-+		return;
-+	}
-+	/* scroll up */
-+	if (ev->button == Button4 && prev) {
-+		sel = curr = prev;
-+		calcoffsets();
-+		drawmenu();
-+		return;
-+	}
-+	/* scroll down */
-+	if (ev->button == Button5 && next) {
-+		sel = curr = next;
-+		calcoffsets();
-+		drawmenu();
-+		return;
-+	}
-+	if (ev->button != Button1)
-+		return;
-+	if (lines > 0) {
-+		/* vertical list: left-click on item */
-+		w = mw - x;
-+		for (item = curr; item != next; item = item->right) {
-+			y += h;
-+			if (ev->y >= y && ev->y <= y + h) {
-+				puts(item->text);
-+				exit(0);
-+			}
-+		}
-+	} else if (matches) {
-+		/* left-click on left arrow */
-+		x += inputw;
-+		w = TEXTW("<");
-+		if (prev && curr->left) {
-+			if (ev->x >= x && ev->x <= x + w) {
-+				sel = curr = prev;
-+				calcoffsets();
-+				drawmenu();
-+				return;
-+			}
-+		}
-+		/* horizontal list: left-click on item */
-+		for (item = curr; item != next; item = item->right) {
-+			x += w;
-+			w = MIN(TEXTW(item->text), mw - x - TEXTW(">"));
-+			if (ev->x >= x && ev->x <= x + w) {
-+				puts(item->text);
-+				exit(0);
-+			}
-+		}
-+		/* left-click on right arrow */
-+		w = TEXTW(">");
-+		x = mw - w;
-+		if (next && ev->x >= x && ev->x <= x + w) {
-+			sel = curr = next;
-+			calcoffsets();
-+			drawmenu();
-+			return;
-+		}
-+	}
-+}
-+
-+static void
- paste(void)
- {
- 	char *p, *q;
-_AT_@ -500,6 +600,9 @@ run(void)
- 		if (XFilterEvent(&ev, win))
- 			continue;
- 		switch(ev.type) {
-+		case ButtonPress:
-+			buttonpress(&ev);
-+			break;
- 		case Expose:
- 			if (ev.xexpose.count == 0)
- 				drw_map(drw, win, 0, 0, mw, mh);
-_AT_@ -591,7 +694,8 @@ setup(void)
- 	/* create menu window */
- 	swa.override_redirect = True;
- 	swa.background_pixel = scheme[SchemeNorm].bg->pix;
--	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
-+	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask |
-+	                 ButtonPressMask;
- 	win = XCreateWindow(dpy, root, x, y, mw, mh, 0,
- 	                    DefaultDepth(dpy, screen), CopyFromParent,
- 	                    DefaultVisual(dpy, screen),
--- 
-2.8.3
-
diff --git a/tools.suckless.org/dmenu/patches/dmenu-mousesupport-20160702-3c91eed.diff b/tools.suckless.org/dmenu/patches/dmenu-mousesupport-20160702-3c91eed.diff
new file mode 100644
index 0000000..ba17061
--- /dev/null
+++ b/tools.suckless.org/dmenu/patches/dmenu-mousesupport-20160702-3c91eed.diff
_AT_@ -0,0 +1,156 @@
+From e9057c96463a3fdf97c0aca9d8626f552fd29de1 Mon Sep 17 00:00:00 2001
+From: Hiltjo Posthuma <hiltjo_AT_codemadness.org>
+Date: Sat, 2 Jul 2016 12:15:02 +0200
+Subject: [PATCH] dmenu mouse support
+
+---
+ dmenu.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 118 insertions(+), 1 deletion(-)
+
+diff --git a/dmenu.c b/dmenu.c
+index e926eca..f5c173c 100644
+--- a/dmenu.c
++++ b/dmenu.c
+_AT_@ -440,6 +440,119 @@ keypress(XKeyEvent *ev)
+ }
+ 
+ static void
++buttonpress(XEvent *e)
++{
++	struct item *item;
++	XButtonPressedEvent *ev = &e->xbutton;
++	int x = 0, y = 0, h = bh, w;
++
++	if (ev->window != win)
++		return;
++
++	/* right-click: exit */
++	if (ev->button == Button3)
++		exit(1);
++
++	if (prompt && *prompt)
++		x += promptw;
++
++	/* input field */
++	w = (lines > 0 || !matches) ? mw - x : inputw;
++
++	/* left-click on input: clear input,
++	 * NOTE: if there is no left-arrow the space for < is reserved so
++	 *       add that to the input width */
++	if (ev->button == Button1 &&
++	   ((lines <= 0 && ev->x >= 0 && ev->x <= x + w +
++	   ((!prev || !curr->left) ? TEXTW("<") : 0)) ||
++	   (lines > 0 && ev->y >= y && ev->y <= y + h))) {
++		insert(NULL, -cursor);
++		drawmenu();
++		return;
++	}
++	/* middle-mouse click: paste selection */
++	if (ev->button == Button2) {
++		XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
++		                  utf8, utf8, win, CurrentTime);
++		drawmenu();
++		return;
++	}
++	/* scroll up */
++	if (ev->button == Button4 && prev) {
++		sel = curr = prev;
++		calcoffsets();
++		drawmenu();
++		return;
++	}
++	/* scroll down */
++	if (ev->button == Button5 && next) {
++		sel = curr = next;
++		calcoffsets();
++		drawmenu();
++		return;
++	}
++	if (ev->button != Button1)
++		return;
++	if (ev->state & ~ControlMask)
++		return;
++	if (lines > 0) {
++		/* vertical list: (ctrl)left-click on item */
++		w = mw - x;
++		for (item = curr; item != next; item = item->right) {
++			y += h;
++			if (ev->y >= y && ev->y <= (y + h)) {
++				puts(item->text);
++				if (!(ev->state & ControlMask))
++					exit(0);
++				sel = item;
++				if (sel) {
++					sel->out = 1;
++					drawmenu();
++				}
++				return;
++			}
++		}
++	} else if (matches) {
++		/* left-click on left arrow */
++		x += inputw;
++		w = TEXTW("<");
++		if (prev && curr->left) {
++			if (ev->x >= x && ev->x <= x + w) {
++				sel = curr = prev;
++				calcoffsets();
++				drawmenu();
++				return;
++			}
++		}
++		/* horizontal list: (ctrl)left-click on item */
++		for (item = curr; item != next; item = item->right) {
++			x += w;
++			w = MIN(TEXTW(item->text), mw - x - TEXTW(">"));
++			if (ev->x >= x && ev->x <= x + w) {
++				puts(item->text);
++				if (!(ev->state & ControlMask))
++					exit(0);
++				sel = item;
++				if (sel) {
++					sel->out = 1;
++					drawmenu();
++				}
++				return;
++			}
++		}
++		/* left-click on right arrow */
++		w = TEXTW(">");
++		x = mw - w;
++		if (next && ev->x >= x && ev->x <= x + w) {
++			sel = curr = next;
++			calcoffsets();
++			drawmenu();
++			return;
++		}
++	}
++}
++
++static void
+ paste(void)
+ {
+ 	char *p, *q;
+_AT_@ -493,6 +606,9 @@ run(void)
+ 		if (XFilterEvent(&ev, win))
+ 			continue;
+ 		switch(ev.type) {
++		case ButtonPress:
++			buttonpress(&ev);
++			break;
+ 		case Expose:
+ 			if (ev.xexpose.count == 0)
+ 				drw_map(drw, win, 0, 0, mw, mh);
+_AT_@ -581,7 +697,8 @@ setup(void)
+ 	/* create menu window */
+ 	swa.override_redirect = True;
+ 	swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
+-	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
++	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask |
++	                 ButtonPressMask;;
+ 	win = XCreateWindow(dpy, root, x, y, mw, mh, 0,
+ 	                    DefaultDepth(dpy, screen), CopyFromParent,
+ 	                    DefaultVisual(dpy, screen),
+-- 
+2.8.4
+
diff --git a/tools.suckless.org/dmenu/patches/dmenu-mousesupport-4.6.diff b/tools.suckless.org/dmenu/patches/dmenu-mousesupport-4.6.diff
new file mode 100644
index 0000000..65b93d4
--- /dev/null
+++ b/tools.suckless.org/dmenu/patches/dmenu-mousesupport-4.6.diff
_AT_@ -0,0 +1,156 @@
+From 66df5f738c17ba5cf23ba99ce18313a39fdfd291 Mon Sep 17 00:00:00 2001
+From: Hiltjo Posthuma <hiltjo_AT_codemadness.org>
+Date: Fri, 17 Jun 2016 14:44:16 +0200
+Subject: [PATCH] dmenu mouse support
+
+---
+ dmenu.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 118 insertions(+), 1 deletion(-)
+
+diff --git a/dmenu.c b/dmenu.c
+index a07f8e3..b60037f 100644
+--- a/dmenu.c
++++ b/dmenu.c
+_AT_@ -449,6 +449,119 @@ keypress(XKeyEvent *ev)
+ }
+ 
+ static void
++buttonpress(XEvent *e)
++{
++	struct item *item;
++	XButtonPressedEvent *ev = &e->xbutton;
++	int x = 0, y = 0, h = bh, w;
++
++	if (ev->window != win)
++		return;
++
++	/* right-click: exit */
++	if (ev->button == Button3)
++		exit(1);
++
++	if (prompt && *prompt)
++		x += promptw;
++
++	/* input field */
++	w = (lines > 0 || !matches) ? mw - x : inputw;
++
++	/* left-click on input: clear input,
++	 * NOTE: if there is no left-arrow the space for < is reserved so
++	 *       add that to the input width */
++	if (ev->button == Button1 &&
++	   ((lines <= 0 && ev->x >= 0 && ev->x <= x + w +
++	   ((!prev || !curr->left) ? TEXTW("<") : 0)) ||
++	   (lines > 0 && ev->y >= y && ev->y <= y + h))) {
++		insert(NULL, -cursor);
++		drawmenu();
++		return;
++	}
++	/* middle-mouse click: paste selection */
++	if (ev->button == Button2) {
++		XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
++		                  utf8, utf8, win, CurrentTime);
++		drawmenu();
++		return;
++	}
++	/* scroll up */
++	if (ev->button == Button4 && prev) {
++		sel = curr = prev;
++		calcoffsets();
++		drawmenu();
++		return;
++	}
++	/* scroll down */
++	if (ev->button == Button5 && next) {
++		sel = curr = next;
++		calcoffsets();
++		drawmenu();
++		return;
++	}
++	if (ev->button != Button1)
++		return;
++	if (ev->state & ~ControlMask)
++		return;
++	if (lines > 0) {
++		/* vertical list: (ctrl)left-click on item */
++		w = mw - x;
++		for (item = curr; item != next; item = item->right) {
++			y += h;
++			if (ev->y >= y && ev->y <= (y + h)) {
++				puts(item->text);
++				if (!(ev->state & ControlMask))
++					exit(0);
++				sel = item;
++				if (sel) {
++					sel->out = 1;
++					drawmenu();
++				}
++				return;
++			}
++		}
++	} else if (matches) {
++		/* left-click on left arrow */
++		x += inputw;
++		w = TEXTW("<");
++		if (prev && curr->left) {
++			if (ev->x >= x && ev->x <= x + w) {
++				sel = curr = prev;
++				calcoffsets();
++				drawmenu();
++				return;
++			}
++		}
++		/* horizontal list: (ctrl)left-click on item */
++		for (item = curr; item != next; item = item->right) {
++			x += w;
++			w = MIN(TEXTW(item->text), mw - x - TEXTW(">"));
++			if (ev->x >= x && ev->x <= x + w) {
++				puts(item->text);
++				if (!(ev->state & ControlMask))
++					exit(0);
++				sel = item;
++				if (sel) {
++					sel->out = 1;
++					drawmenu();
++				}
++				return;
++			}
++		}
++		/* left-click on right arrow */
++		w = TEXTW(">");
++		x = mw - w;
++		if (next && ev->x >= x && ev->x <= x + w) {
++			sel = curr = next;
++			calcoffsets();
++			drawmenu();
++			return;
++		}
++	}
++}
++
++static void
+ paste(void)
+ {
+ 	char *p, *q;
+_AT_@ -498,6 +611,9 @@ run(void)
+ 		if (XFilterEvent(&ev, win))
+ 			continue;
+ 		switch(ev.type) {
++		case ButtonPress:
++			buttonpress(&ev);
++			break;
+ 		case Expose:
+ 			if (ev.xexpose.count == 0)
+ 				drw_map(drw, win, 0, 0, mw, mh);
+_AT_@ -589,7 +705,8 @@ setup(void)
+ 	/* create menu window */
+ 	swa.override_redirect = True;
+ 	swa.background_pixel = scheme[SchemeNorm].bg->pix;
+-	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
++	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask |
++	                 ButtonPressMask;
+ 	win = XCreateWindow(dpy, root, x, y, mw, mh, 0,
+ 	                    DefaultDepth(dpy, screen), CopyFromParent,
+ 	                    DefaultVisual(dpy, screen),
+-- 
+2.8.4
+
diff --git a/tools.suckless.org/dmenu/patches/mouse-support-msel.md b/tools.suckless.org/dmenu/patches/mouse-support-msel.md
deleted file mode 100644
index 01ac8c7..0000000
--- a/tools.suckless.org/dmenu/patches/mouse-support-msel.md
+++ /dev/null
_AT_@ -1,19 +0,0 @@
-Mouse support with multisel
-===========================
-
-This provides the basic mouse support described in the 'mouse support' patch,
-but against 4.6 (32f2564dbbbf5aeafb7190a3d35066142f34448f).
-
-In addition, multisel is supported via Ctrl-leftclick.
-(i.e. Ctrl-leftclick does for mouse operation what Ctrl-Return does for
-keyboard, as described in the 'multisel' patch; however, the 'multisel' patch
-itself is no longer needed in 4.6 because its functionality has been previously
-merged in and now it's part of the master)
-
-Download
---------
-* [dmenu-4.6-mouse-support-msel.diff](dmenu-4.6-mouse-support-msel.diff)
-
-Author
-------
-* Xarchus
diff --git a/tools.suckless.org/dmenu/patches/mouse-support.md b/tools.suckless.org/dmenu/patches/mouse-support.md
index 8540669..5bd081b 100644
--- a/tools.suckless.org/dmenu/patches/mouse-support.md
+++ b/tools.suckless.org/dmenu/patches/mouse-support.md
_AT_@ -9,6 +9,7 @@ Mouse actions supported:
     * On prompt and input field: clear input text and selection.
     * In horizontal and vertical mode on item: select and output item (same as pressing enter).
     * In horizontal mode on arrows: change items to show left or right.
+* Ctrl-left-mouse click: multisel modifier.
 * Right-mouse click: close.
 * Middle-mouse click:
     * Paste current selection.
_AT_@ -20,12 +21,14 @@ Mouse actions supported:
     * In horizontal mode: same as left-clicking on right arrow.
     * In vertical mode: show items below.
 
-The attached patch applies cleanly to latest dmenu 4.6.
 
 Download
 --------
-* [dmenu-4.6-mouse-support.diff](dmenu-4.6-mouse-support.diff)
+* [dmenu-mousesupport-4.6.diff](dmenu-mouse-support-4.6.diff)
+* [dmenu-mousesupport-20160702-3c91eed.diff](dmenu-mousesupport-20160702-3c91eed.diff)
+
 
 Author
 ------
 * Hiltjo Posthuma - <hiltjo_AT_codemadness.org>
+* Xarchus (for multisel support).
Received on Sat Jul 02 2016 - 12:26:53 CEST

This archive was generated by hypermail 2.3.0 : Sat Jul 02 2016 - 12:36:13 CEST