greshake / i3status-rust

Very resourcefriendly and feature-rich replacement for i3status, written in pure Rust
GNU General Public License v3.0
2.88k stars 475 forks source link

Running into multiple errors about JSON while trying to implement a new block #801

Closed AkechiShiro closed 4 years ago

AkechiShiro commented 4 years ago

I was writing a block to use redshift or sct directly from a block (and adjusting the temperature using the mouse scrolling, had a look into the Xrandr block to see how to properly do this) basically an equivalent to the hueshift block from py3status, after a lot of fixes and a successful compilation of i3status-rs I got this error on the i3bar when I explicitly add the new block (when I remove it the error goes away so it must be the block that's is the problem I suppose) I created : Error: Could not parse JSON (lexical error: probable comment found in input text Looking into .xsession-errors I see this error precisely: [i3bar] Could not parse JSON input (code = 2, message = lexical error: probable comment found in input text, comments are not enabled.): Is that having any link with Rust comments (I think that's not the case here) I left in the new code block ? This error comes from i3bar I suppose the best course of action from here should perhaps be to create a PR with the block and figure out what's going on from there ?

ammgws commented 4 years ago

Feel free to share the code via PR

AkechiShiro commented 4 years ago

I've shared the code via PR, I'd like a bit of feedback or guidance on the issue I'm facing as I don't really understand what's going on and why I'm getting an error related to JSON. Since my code doesn't really do anything with JSON, I suppose something in i3status-rust codebase organizes the data using the JSON format and somewhere an error is raised.

ammgws commented 4 years ago

Does the error in i3bar occur straight away, or does it happen randomly after the i3status-rs is already up and showing in the bar?

Can you run i3status-rs (with a minimal config) in a terminal and copy the output here? (I am running sway so don't have a X11 environment to test with myself)

AkechiShiro commented 4 years ago

The error occurs straight away when the block hueshift is present in the toml config file, the bar is never shown without the error. I'm using i3wm as my windows manager currently.

Using a minimal config with only the block hueshift and using the compiled version this is what I get it seems the error is not happening.

fork/i3status-rust/target/release/i3status-rs ~/.config/i3/minimal.toml    
{"version": 1, "click_events": true}
/bin/sct 
/bin/redshift
[[{"background":"#000000","color":"#a9a9a9","full_text":"| ","markup":"pango","separator":false,"separator_block_width":0},{"background":"#000000","color":"#93a1a1","full_text":" 6500 ","separator":false,"separator_block_width":0}],
[{"background":"#000000","color":"#a9a9a9","full_text":"| ","markup":"pango","separator":false,"separator_block_width":0},{"background":"#000000","color":"#93a1a1","full_text":" 6500 ","separator":false,"separator_block_width":0}],

The two /bin/ lines comes from a function what_is_supported() in my hueshift block that runs the which shell command to check if redshift or sct is installed. The full text seems to be the screen color temperature which by default is set at 6500, it is correct according to line 114 of the hueshift.rs block.

text: TextWidget::new(config.clone()).with_text(&current_temp.to_string()),

I've tried running the minimal config with my compiled i3status-rs in my i3 config (using absolute paths to avoid using the installed one) but the error about the JSON is still here even if I only have the "hueshift" block, I'm curious as to why the error only happens when I'm using i3status-rs in my i3 config and is not triggered when it is launched via the terminal.

I hope this will help further narrow down the issue, if you need any further information or testing, I'll be happy to keep providing more information.

ammgws commented 4 years ago

Ah that makes it easy then. The output of the which command is being printed to stdout in the middle of the JSON stream which is why your getting that error.

Check out the has_command function in util.rs. You should be and to use that instead.

AkechiShiro commented 4 years ago

Alright, I've taken a look at util.rs and the has_command and it was exactly what I needed. I've also modified the line that runs the redshift command to redirects its output to /dev/null the same way the has_command function does to not run into this error when scrolling/updating the block.

The error is fixed, the bar shows up and with the correct default text, I've replaced the TextWidget by a ButtonWidget (since scrolling would work only with a button I suppose).

Now, when I scroll on the block another error about JSON happens but this time it is different. This is the exact error [i3bar] Could not parse JSON input (code = 2, message = lexical error: invalid char in json text.) (running into a terminal I cannot really trigger the update to see what the output of i3status-rs is when the JSON error happens, would there be another way to see the output ?)

Here is the exact code inside the update function:

fn update(&mut self) -> Result<Option<Update>> {
    self.text.set_text(&self.current_temp.to_string());
    Ok(Some(self.update_interval.into()))
}

Setting the new value for the current_temp variable happens in the click function (see code block below) which calls another function called update_hue(new_temp), and I do set self.current_temp to the new_temp.

match self.config.scrolling.to_logical_direction(mb) {
    Some(Up) => {
        let new_temp: u16 = self.current_temp + self.step;
        if new_temp < self.max_temp {
            update_hue(new_temp);
            self.current_temp = new_temp;
        }
    }
    Some(Down) => {
        let new_temp: u16 = self.current_temp - self.step;
        if new_temp > self.min_temp {
            update_hue(new_temp);
            self.current_temp = new_temp;
        }
    }

Now what happens when I scroll, the redshift command is called and the screen color does change (according to the scrolling direction) even if there is still a JSON error on the bar.

I've also noticed something maybe peculiar, if I use redshift on the command line and set a manual temperature, when the bar updates (an update shouldn't trigger the click function but I'm not sure how to explain this), the temperature is set back to the default value in the config block. It's as if my current_temp variable doesn't get updated correctly, there is probably an issue with my code.

ammgws commented 4 years ago

Maybe you could try setting your bar command to i3status-rs 2>&1 | tee /tmp/debugi3rs and then run tail -f /tmp/debugi3rs to see what is happening when you scroll on the block.

AkechiShiro commented 4 years ago

Thanks for the help, I've tried that and it seems some numbers appears right after the whole JSON output of my config. It looks like that :

{"version": 1, "click_events": true}
[[{"background":"#000000","color":"#a9a9a9","full_text":"| ","markup":"pango","separator":false,"separator_block_width":0},{"background":"#000000","color":"#93a1a1","full_text":" 6500 ","markup":"pango","name":"8e354b15488f46a9bbbf97e89ccd7574","separator":false,"separator_block_width":0}],
[{"background":"#000000","color":"#a9a9a9","full_text":"| ","markup":"pango","separator":false,"separator_block_width":0},{"background":"#000000","color":"#93a1a1","full_text":" 6500 ","markup":"pango","name":"8e354b15488f46a9bbbf97e89ccd7574","separator":false,"separator_block_width":0}],
5
[{"background":"#000000","color":"#a9a9a9","full_text":"| ","markup":"pango","separator":false,"separator_block_width":0},{"background":"#000000","color":"#93a1a1","full_text":" 6500 ","markup":"pango","name":"8e354b15488f46a9bbbf97e89ccd7574","separator":false,"separator_block_width":0}],
5
[{"background":"#000000","color":"#a9a9a9","full_text":"| ","markup":"pango","separator":false,"separator_block_width":0},{"background":"#000000","color":"#93a1a1","full_text":" 6500 ","markup":"pango","name":"8e354b15488f46a9bbbf97e89ccd7574","separator":false,"separator_block_width":0}],
5
[{"background":"#000000","color":"#a9a9a9","full_text":"| ","markup":"pango","separator":false,"separator_block_width":0},{"background":"#000000","color":"#93a1a1","full_text":" 6500 ","markup":"pango","name":"8e354b15488f46a9bbbf97e89ccd7574","separator":false,"separator_block_width":0}],
5
[{"background":"#000000","color":"#a9a9a9","full_text":"| ","markup":"pango","separator":false,"separator_block_width":0},{"background":"#000000","color":"#93a1a1","full_text":" 6500 ","markup":"pango","name":"8e354b15488f46a9bbbf97e89ccd7574","separator":false,"separator_block_width":0}],
[{"background":"#000000","color":"#a9a9a9","full_text":"| ","markup":"pango","separator":false,"separator_block_width":0},{"background":"#000000","color":"#93a1a1","full_text":" 6100 ","markup":"pango","name":"8e354b15488f46a9bbbf97e89ccd7574","separator":false,"separator_block_width":0}],

I've also changed the code a bit and the error is slightly different but still about JSON parsing. It's now (parse error : after array element, I expect ',' or ']'). I'm a kinda of at a loss here since the way I execute my command is redirecting all the output to '/dev/null' I believe it's the right way. Here are my commands that gets executed when :

        Some(_redshift) => {
            Command::new("sh")
                .args(&[
                    "-c",
                    format!("redshift -O {} >/dev/null 2>&1", new_temp).as_str(),
                ])
                .spawn()
                .expect("Failed to set new color temperature using redshift.");
        }
        Some(_sct) => {
            Command::new("sh")
                .args(&["-c", format!("sct {} >/dev/null 2>&1", new_temp).as_str()])
                .spawn()
                .expect("Failed to set new color temperature using sct.");
        }

Also it appears that the variable current_temp gets updated correctly but the temperature shifts back to like 6500K when the i3bar updates but the value in the JSON shows up at 5400K, I don't know why this happens, I may need to have a look at whether after each update a redshift command is executed or not, I believe there isn't one that is executed but there is one by looking in the update function I might found something.

ammgws commented 4 years ago

Let's move discussion to the PR since the rogue output is coming from there.