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

Blocks no longer render when output doesn't end with newline #403

Closed
shreve opened this issue Sep 17, 2019 · 8 comments
Closed

Blocks no longer render when output doesn't end with newline #403

shreve opened this issue Sep 17, 2019 · 8 comments

Comments

@shreve
Copy link

shreve commented Sep 17, 2019

About half of my blocks stopped rendering after updating today. I looked through i3blocks -vvv and noticed that only the blocks that were printing were getting log lines from line.c

<7>line.c:line_parse:65: &3:000: {{block output}}

Looking around there it seems i3blocks can only read lines if they end with a newline.

I added an extra echo to the end of all my missing blocks and they re-appeared.

I think a fix would be to accept the error indicating the end of the file descriptor as a valid endpoint to the line and break. I think this would be sufficient:

if (err) {
    if (err == -EAGAIN)
        break;
    return err;
}

I'm hesitant to submit a PR because I'm having problems getting the build to work.

Edit: I got the build working so I submitted a PR which fixed my problem.

@zsugabubus
Copy link

Doesn't it simpler and more straightforward to explicitly tell i3blocks where your line ends (for example by a new-line character?), than relying on such hacks?

If you have problems with extra echo-s just add the missing new-line characters to your prints.

@shreve
Copy link
Author

shreve commented Sep 20, 2019

@zsugabubus

  1. I colorize my blocks with a script that doesn't add newlines because it may want to color multiple things on the same line. I would have to print an extra newline after the color script regardless.
  2. Why tell i3blocks to create a new line? I'm not printing anything else on a new line. All my output is just the one line. As far as I know, i3blocks doesn't support multiple lines.
  3. I don't think "print the text I give you" is a hack.

@zsugabubus
Copy link

I colorize my blocks with a script that doesn't add newlines because it may want to color multiple things on the same line.

My bad, but I hardly can understand your scenario. Could you provide more details/or an example maybe?

Why tell i3blocks to create a new line?

It just marks the end of the text you want to be displayed/updated. Nobody wants multiple lines.

I'm not printing anything else on a new line.
I don't think "print the text I give you" is a hack.

while :; do
  echo -n a
  echo -n b
  sleep 1
done

What should it print? ab, b, or ababababababababa...? Perhaps b, aba than babababa...? When do you say that "whew, I'm ready with my line, hey i3blocks, I want it to be displayed on the screen"?

@shreve
Copy link
Author

shreve commented Sep 20, 2019

@zsugabubus That would never finish, so i3blocks would never read any of it. It spawns the process, waits for it to finish, then reads the content that was written.

You say "whew, I'm ready with my line, hey i3blocks, I want it to be displayed on the screen" by finishing the script or exit 0

@zsugabubus
Copy link

zsugabubus commented Sep 20, 2019

Oh my god... now I see what's everybody's issue. I supposed you use interval=persist because (I run almost all of my blocklets like this and) you mentioned EAGAIN and... and... I didn't dare to think about that it could be an issue.

Could you provide more details/or an example maybe?

[time]
command=echo -n $(date +%T)
interval=once

@skidnik
Copy link

skidnik commented Oct 1, 2019

@shreve, fyi:

As far as I know, i3blocks doesn't support multiple lines.

Does not display multiple lines, but i3blocks handles the following (from non-persistent blocks at least):

full text
short text
color

all strings must end with a newline in the 1.5 release.

@vivien
Copy link
Owner

vivien commented Oct 20, 2019

Sorry but I have trouble understanding where is the problem. Regardless the interval type or format, I expect each line from a block output to be newline terminated, for consistency. Although I should've mentioned that in the release note, and I will.

@vivien
Copy link
Owner

vivien commented Dec 15, 2022

I colorize my blocks with a script that doesn't add newlines because it may want to color multiple things on the same line.

My bad, but I hardly can understand your scenario. Could you provide more details/or an example maybe?

Why tell i3blocks to create a new line?

It just marks the end of the text you want to be displayed/updated. Nobody wants multiple lines.

I'm not printing anything else on a new line.
I don't think "print the text I give you" is a hack.

while :; do
  echo -n a
  echo -n b
  sleep 1
done

What should it print? ab, b, or ababababababababa...? Perhaps b, aba than babababa...? When do you say that "whew, I'm ready with my line, hey i3blocks, I want it to be displayed on the screen"?

@zsugabubus nailed it, fetching complex data and printing it as you receive it makes it impossible to know where it ends, and that's not i3blocks job. For example, I could've assumed that once the output buffer is flushed, then the data is considered ready. But 1) you have a race condition (you can have more data written while you're reading the output) 2) it can be complex for the user to deal with buffered I/O, since it requires this programming knowledge and all languages and libraries handle that differently (i.e. some provide buffered I/O, some don't, some flush right away, some don't). So I decided to go with the newline, which is the idiomatic way to tell a program that a line is ready to be processed (pretty much the same as pressing Enter on your keyboard with an interactive program actually).

(Note: with persistent blocks, a user still need to flush its output buffer in order to make it readable by i3blocks, but the line reading code will stop once it encounters a newline and won't consume the text that comes after.)

So in 1.5 I've factorized the code and decided to go entirely line-based, to simplify the processing of (INI-style) config files, json lines (clicks) or block outputs. All text processing now use the same code, which is less error prone. That said, I could've and should've made the code retro-compatible somehow and accept non-newline terminated output for non-persistent blocks. Sorry for the inconvenience.

Closing as it's a duplicate of #393

@vivien vivien closed this as completed Dec 15, 2022
dllud pushed a commit to dllud/i3blocks that referenced this issue Jan 12, 2024
taskw: Add several new config options and timewarrior integration
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

No branches or pull requests

4 participants