Re: [dev] [hack] Having dmenu provide hints about current selected entry

2010-11-28 Thread Connor Lane Smith
Hey,

On 29 November 2010 00:17, Christophe-Marie Duquesne
 wrote:
> I rewrote my proposal with select(). Now readstdin() will return if it
> cannot read data from stdin during more than 1 u_sec. It will set the
> static flag 'eof' to 1 if it has read the end of file character. This
> way while eof is 0, you know you should call readstdin() again.

Great, it's a lot cleaner this way. One problem with this approach,
though, is that if data is written to stdin it isn't displayed until
the next X event. This is likely fine for your use case, and
dmenu_run, but perhaps not for other cases. To fix that we'd have to
select between stdin and XConnectionNumber(dc->dpy).

I've also attached a slightly neater version of your patch, plus a bugfix.

Thanks,
cls
diff -r a79e4a9cb167 dmenu.c
--- a/dmenu.c	Sat Nov 20 09:25:08 2010 +
+++ b/dmenu.c	Mon Nov 29 01:40:44 2010 +
@@ -4,6 +4,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -54,11 +55,13 @@
 static unsigned long normcol[ColLast];
 static unsigned long selcol[ColLast];
 static Atom utf8;
+static Bool eof = False;
 static Bool topbar = True;
 static DC *dc;
 static Item *items = NULL;
 static Item *matches, *sel;
 static Item *prev, *curr, *next;
+static Item **end = &items;
 static Window root, win;
 
 static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
@@ -102,7 +105,6 @@
 
 	dc = initdc();
 	initfont(dc, font);
-	readstdin();
 	setup();
 	run();
 
@@ -433,9 +435,20 @@
 void
 readstdin(void) {
 	char buf[sizeof text], *p;
-	Item *item, **end;
+	fd_set fds;
+	int n;
+	struct timeval tv;
+	Item *item;
 
-	for(end = &items; fgets(buf, sizeof buf, stdin); *end = item, end = &item->next) {
+	while(!eof) {
+		tv.tv_sec = 0;
+		tv.tv_usec = 1;
+		FD_ZERO(&fds);
+		FD_SET(STDIN_FILENO, &fds);
+		if((n = select(1, &fds, NULL, NULL, &tv)) < 0)
+			eprintf("cannot select stdin\n");
+		if(n == 0 || (eof = !fgets(buf, sizeof buf, stdin)))
+			break;
 		if((p = strchr(buf, '\n')))
 			*p = '\0';
 		if(!(item = malloc(sizeof *item)))
@@ -444,6 +457,9 @@
 			eprintf("cannot strdup %u bytes\n", strlen(buf)+1);
 		item->next = item->left = item->right = NULL;
 		inputw = MAX(inputw, textw(dc, item->text));
+		*end = item;
+		end = &item->next;
+		match();
 	}
 }
 
@@ -451,7 +467,7 @@
 run(void) {
 	XEvent ev;
 
-	while(!XNextEvent(dc->dpy, &ev))
+	while(!XNextEvent(dc->dpy, &ev)) {
 		switch(ev.type) {
 		case Expose:
 			if(ev.xexpose.count == 0)
@@ -469,6 +485,8 @@
 XRaiseWindow(dc->dpy, win);
 			break;
 		}
+		readstdin();
+	}
 }
 
 void
@@ -531,7 +549,7 @@
 	promptw = prompt ? textw(dc, prompt) : 0;
 	XMapRaised(dc->dpy, win);
 	text[0] = '\0';
-	match();
+	drawmenu();
 }
 
 void


Re: [dev] [hack] Having dmenu provide hints about current selected entry

2010-11-28 Thread Christophe-Marie Duquesne
Hi,

I rewrote my proposal with select(). Now readstdin() will return if it
cannot read data from stdin during more than 1 u_sec. It will set the
static flag 'eof' to 1 if it has read the end of file character. This
way while eof is 0, you know you should call readstdin() again.

Attached is a patch that you can also pull from
https://bitbucket.org/chmduquesne/dmenu
diff -r a79e4a9cb167 dmenu.c
--- a/dmenu.c	Sat Nov 20 09:25:08 2010 +
+++ b/dmenu.c	Mon Nov 29 01:14:46 2010 +0100
@@ -10,6 +10,8 @@
 #ifdef XINERAMA
 #include 
 #endif
+#include 
+#include 
 #include "draw.h"
 
 #define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh))
@@ -44,6 +46,7 @@
 static int lines = 0;
 static int monitor = -1;
 static int promptw;
+static int eof = 0;
 static size_t cursor = 0;
 static const char *font = NULL;
 static const char *prompt = NULL;
@@ -59,6 +62,7 @@
 static Item *items = NULL;
 static Item *matches, *sel;
 static Item *prev, *curr, *next;
+static Item **end = &items;
 static Window root, win;
 
 static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
@@ -432,26 +436,44 @@
 
 void
 readstdin(void) {
+	fd_set rfds;
+	struct timeval tv;
+	int canread;
 	char buf[sizeof text], *p;
-	Item *item, **end;
+	Item *item;
 
-	for(end = &items; fgets(buf, sizeof buf, stdin); *end = item, end = &item->next) {
-		if((p = strchr(buf, '\n')))
-			*p = '\0';
-		if(!(item = malloc(sizeof *item)))
-			eprintf("cannot malloc %u bytes\n", sizeof *item);
-		if(!(item->text = strdup(buf)))
-			eprintf("cannot strdup %u bytes\n", strlen(buf)+1);
-		item->next = item->left = item->right = NULL;
-		inputw = MAX(inputw, textw(dc, item->text));
-	}
+	do {
+		tv.tv_sec = 0;
+		tv.tv_usec = 1;
+		FD_ZERO(&rfds);
+		FD_SET(0, &rfds);
+		canread = select(1, &rfds, NULL, NULL, &tv);
+		if(canread == -1)
+			perror("select()");
+		if(canread) {
+			eof = (fgets(buf, sizeof buf, stdin) == NULL);
+			if(!eof) {
+if((p = strchr(buf, '\n')))
+	*p = '\0';
+if(!(item = malloc(sizeof *item)))
+	eprintf("cannot malloc %u bytes\n", sizeof *item);
+if(!(item->text = strdup(buf)))
+	eprintf("cannot strdup %u bytes\n", strlen(buf)+1);
+item->next = item->left = item->right = NULL;
+inputw = MAX(inputw, textw(dc, item->text));
+
+*end = item;
+end = &item->next;
+			}
+		}
+	} while(canread && !eof);
 }
 
 void
 run(void) {
 	XEvent ev;
 
-	while(!XNextEvent(dc->dpy, &ev))
+	while(!XNextEvent(dc->dpy, &ev)) {
 		switch(ev.type) {
 		case Expose:
 			if(ev.xexpose.count == 0)
@@ -469,6 +491,9 @@
 XRaiseWindow(dc->dpy, win);
 			break;
 		}
+		if (!eof)
+			readstdin();
+	}
 }
 
 void


Re: [dev] [st] Fixed -e with support for spaces

2010-11-28 Thread Josh Rickmar
On Sun, Nov 28, 2010 at 04:20:21PM -0500, Joseph Xu wrote:
> 
> 
> On 11/28/2010 06:22 AM, Aur??lien Aptel wrote:
> > On Sat, Nov 27, 2010 at 12:35 AM, Joseph Xu  wrote:
> >> came up with. It relies on the shell that executes st to parse the
> >> arguments, so you can't run a command like st -e "touch arst", you have
> >> to run st -e touch arst. This also means you can't have any st arguments
> >> after the -e because they'll all be included in the command to run.
> > 
> > This breaks argument parsing. Why would you want to do that?
> > Josh's solution is better imo. I've pushed (a slight variation of) it to 
> > tip.
> 
> Not sure what you mean by breaking argument parsing. I think it's the
> simplest way to parse a command with complex quoted arguments correctly
> without having to run an extra shell process.
> 

Agree.  I prefer this patch to mine.  Mainly due to a bug(?) in
dmenu_run where everything is escaped before being executed by the
shell.  So, for example, I can't run `st -e "tmux a"` from dmenu_run,
since it parses it as st -e \"tmux a\" instead.  The xterm-like -e
behavior circumvents this issue.



Re: [dev] [st] Fixed -e with support for spaces

2010-11-28 Thread Moritz Wilhelmy
Excerpts from Joseph Xu's message of Sun Nov 28 22:20:21 +0100 2010:
> On 11/28/2010 06:22 AM, Aurélien Aptel wrote:
> > On Sat, Nov 27, 2010 at 12:35 AM, Joseph Xu  wrote:
> >> came up with. It relies on the shell that executes st to parse the
> >> arguments, so you can't run a command like st -e "touch arst", you have
> >> to run st -e touch arst. This also means you can't have any st arguments
> >> after the -e because they'll all be included in the command to run.
> > 
> > This breaks argument parsing. Why would you want to do that?
> > Josh's solution is better imo. I've pushed (a slight variation of) it to 
> > tip.
> 
> Not sure what you mean by breaking argument parsing. I think it's the
> simplest way to parse a command with complex quoted arguments correctly
> without having to run an extra shell process.

I agree with you on that. Furthermore, both urxvt and xterm do it the same way.
>From urxvt(1):

-e command [arguments]
Run the command with its command-line arguments in the urxvt
window; also sets the window title and icon name to be the
basename of the program being executed if neither -title (-T) nor
-n are given on the command line. If this option is used, it must
be the last on the command-line. If there is no -e option then the
default is to run the program specified by the SHELL environment
variable or, failing that, sh(1).

Please note that you must specify a program with arguments. If you
want to run shell commands, you have to specify the shell, like
this:

  urxvt -e sh -c "shell commands"

>From xterm(1):

-e program [ arguments ... ]
This  option specifies the program (and its command line argu‐
ments) to be run in the xterm window.  It also sets the window
title  and  icon  name to be the basename of the program being
executed if neither -T nor -n are given on the  command  line.
This must be the last option on the command line.

I think it makes sense and people are used to it that way.

Best regards,

Moritz



Re: [dev] [st] Fixed -e with support for spaces

2010-11-28 Thread Joseph Xu


On 11/28/2010 06:22 AM, Aurélien Aptel wrote:
> On Sat, Nov 27, 2010 at 12:35 AM, Joseph Xu  wrote:
>> came up with. It relies on the shell that executes st to parse the
>> arguments, so you can't run a command like st -e "touch arst", you have
>> to run st -e touch arst. This also means you can't have any st arguments
>> after the -e because they'll all be included in the command to run.
> 
> This breaks argument parsing. Why would you want to do that?
> Josh's solution is better imo. I've pushed (a slight variation of) it to tip.

Not sure what you mean by breaking argument parsing. I think it's the
simplest way to parse a command with complex quoted arguments correctly
without having to run an extra shell process.



Re: [dev] #wmii

2010-11-28 Thread Jacob Todd
qq
On Nov 28, 2010 11:15 AM, "Kurt H Maier"  wrote:
> hey kris if you're going to set the #wmii topic to channel all these
> stupid questions into #suckless can you at least show up in #suckless
>
> --
> # Kurt H Maier
>


[dev] #wmii

2010-11-28 Thread Kurt H Maier
hey kris if you're going to set the #wmii topic to channel all these
stupid questions into #suckless can you at least show up in #suckless

-- 
# Kurt H Maier



Re: [dev] [st] Fixed -e with support for spaces

2010-11-28 Thread Aurélien Aptel
On Sat, Nov 27, 2010 at 12:35 AM, Joseph Xu  wrote:
> came up with. It relies on the shell that executes st to parse the
> arguments, so you can't run a command like st -e "touch arst", you have
> to run st -e touch arst. This also means you can't have any st arguments
> after the -e because they'll all be included in the command to run.

This breaks argument parsing. Why would you want to do that?
Josh's solution is better imo. I've pushed (a slight variation of) it to tip.