Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiline input #107

Closed
Lerchensporn opened this issue Mar 1, 2015 · 18 comments
Closed

Multiline input #107

Lerchensporn opened this issue Mar 1, 2015 · 18 comments

Comments

@Lerchensporn
Copy link

Lerchensporn commented Mar 1, 2015

EDIT: As you are hopefully able to learn from the first three posts, this issue is NOT about multi-line display, but about the BUG that the program fails to handle fast occurring input correctly (i. e., multi-line input).

Multi-line input is not handled correctly by the program. If a multi-line string is received, only the first line is recognized, instead of the last line. The problem occurs if a line is sent immediately after the previous one.
The reason is the use of fgets.

@LemonBoy
Copy link
Owner

LemonBoy commented Mar 3, 2015

That's the intended behaviour, bar is a single-line bar. I'm marking this as a item in the wish-list bucket to see if there's enough interest.

@Lerchensporn
Copy link
Author

I am not talking about a multi-line display on the screen, but about the input that bar receives. Bar is often used to display information that is updated, e. g. the window manager status or something like:

while true; do echo -ne "`date`\n"; done | bar

If there is too little time between the updates, multiple lines per poll event can be received and fgets only reads the first line. That means bar shows random behavior on fast updates.
For example, it is possible that bar does not show the latest update of a window manager if the workspaces are switched very fast (however, the probability is low). The bug is reproducible with a C program that pipes some text to a bar subprocess.

Here is a patch to fix the problem: https://gist.github.com/woho/990f83b0ac4277165c64

@LemonBoy
Copy link
Owner

LemonBoy commented Mar 6, 2015

I'm not sure of how does fgets behave when the underlying file descriptor is nonblocking

@Lerchensporn
Copy link
Author

When the file descriptor is non-blocking, fgets returns NULL if there is no data available. If the fd is blocking, fgets blocks, i. e. waits for data and only returns NULL if there is an eof or a real error. See man 2 read, error EWOULDBLOCK.

@LemonBoy
Copy link
Owner

Your patch seems to break my statusbar [1] for some reason

[1] http://ix.io/gTm

@Vouivre
Copy link

Vouivre commented Mar 19, 2015

I'm interested by a multi-line display. Do you want that I fill another bug report ?

@cpixl
Copy link

cpixl commented Apr 5, 2015

I'm also interested in a multiline display, so I can use it to also display a menu when the user clicks somewhere (dzen-like :D). I couldn't find many tools (other than dzen itself) to do this, so it would be cool to have one more alternative.

@LemonBoy
Copy link
Owner

LemonBoy commented Apr 9, 2015

I'm considering the idea of multiline input for a future bar version :)

@kigerpunk
Copy link

If only for the purpose of solving #113, I'm commenting to register interest. A vertical bar could be really useful on the 16:9 screens that are so common these days.

@xorbug
Copy link

xorbug commented Jan 30, 2016

Just as feedback, I agree with @woho: I'm implementing a little workspace bar for i3 window manager whose output is piped into lemonbar. Well, some events come in rapid sequence (always line by line, no multiline), too fast to be detected and handled by lemonbar, which shows the first only, leaving the bar with an inconsistent status. Also, this is not happening with low probability, but very often, due to how events are generated.

@Anachron
Copy link

Is there any update here? I too would enjoy a vertical bar.

@gavsiu
Copy link

gavsiu commented May 24, 2016

In case you want more input, +1 for multiline display.

I don't really want to install 2 different bars and I was contemplating switching to dzen2 and removing lemonbar. It would be a shame because lemonbar is still in active development and dzen2 hasn't been updated in github for 3 years.

@Lerchensporn
Copy link
Author

Please note that this issue is neither about vertical bars or multi-line displays whatsoever, but about a bug.

@LemonBoy I do not know why this patch breaks your statusbar and I do not investigate this issue myself because I have another setup. But I would have a look at it if I was provided a minimal example.

@CamilleScholtz
Copy link

CamilleScholtz commented May 25, 2016

Isn't it really easy to just do script or program | tr '\n' ' ' | lemonbar or am I missing something here?

tryone144 added a commit to tryone144/orangeslices that referenced this issue Jun 5, 2016
tryone144 added a commit to tryone144/orangeslices that referenced this issue Jun 5, 2016
tryone144 added a commit to tryone144/bar that referenced this issue Jun 8, 2016
tryone144 added a commit to tryone144/bar that referenced this issue Jun 8, 2016
Read input lines in non-blockin mode and parse the last one.
Should fix LemonBoy#107
@ThomasAdam
Copy link

You're still going to have the same problem with read() since that will still consume whatever is in the buffer -- there's no guarantee that if multiple messages are coming in at once, that you won't end up with a partial read of a line.

There's no realistic way around this other than to use a socket, where you can guarantee an actual message length, but I feel that this is completely unnecessary for lemonbar.

@domsson
Copy link

domsson commented Jun 11, 2020

I'm running into the same issue. I'm not sure I understand this fully, so just let me ask: does a solution exist (for example, the patch by shdown) or is ThomasAdam right in saying that this can't possibly be fixed?

@shdown
Copy link

shdown commented Jul 3, 2020

You're still going to have the same problem with read() since that will still consume whatever is in the buffer -- there's no guarantee that if multiple messages are coming in at once, that you won't end up with a partial read of a line.

There's no realistic way around this other than to use a socket, where you can guarantee an actual message length, but I feel that this is completely unnecessary for lemonbar.

You are wrong: shdown@eb0e9e7. The solution is simply to cache the partial reads in a buffer — exactly what stdio's FILE* does. The only difference is that you need to poll for changes on two fds, which is not supported by stdio — so reinvent the buffering yourself.

@ThomasAdam
Copy link

Indeed, @shdown. But consider the complexities here. I never said it wasn't possible, I was merely saying it's easier to use a different IPC mechanism.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.