crossterm icon indicating copy to clipboard operation
crossterm copied to clipboard

`Display` on `StyledObject` is not working well with WinApi

Open MaulingMonkey opened this issue 4 years ago • 5 comments

This works fine on windows 10, but appears completely unstyled on windows 7:

use crossterm::*;

fn main() {
    println!("{} {} {}", "fore".black(),        "back".on_black(),      "Black");
    println!("{} {} {}", "fore".dark_grey(),    "back".on_dark_grey(),  "Dark Grey");
    println!("{} {} {}", "fore".grey(),         "back".on_grey(),       "Grey");
    println!("{} {} {}", "fore".white(),        "back".on_white(),      "White");
}

With enough flushing, you can kinda get it to work:

use crossterm_style::*;
use std::io::{stdout, Write};

fn main() {
    for color in &[Color::Black, Color::DarkGrey, Color::Grey, Color::White] {
        let color = *color;
        print!("{}", Colored::Fg(color));
        stdout().flush().unwrap();
        print!("fore");
        stdout().flush().unwrap();
        print!("{}", Colored::Fg(Color::Reset));
        stdout().flush().unwrap();
        print!(" ");
        stdout().flush().unwrap();
        print!("{}", Colored::Bg(color));
        stdout().flush().unwrap();
        print!("back");
        stdout().flush().unwrap();
        print!("{}", Colored::Bg(Color::Reset));
        stdout().flush().unwrap();
        print!(" {:?}", color);
        stdout().flush().unwrap();
        println!();
    }
}

MaulingMonkey avatar Sep 28 '19 23:09 MaulingMonkey

Might be worth introducing an env var or feature or something to force legacy winapi mode for testing purpouses on win10 systems.

MaulingMonkey avatar Sep 29 '19 05:09 MaulingMonkey

Related to old issue: https://github.com/crossterm-rs/crossterm/issues/38 it is very strange behavior and probably has to with the order in which rust invokes the Display implemented for tose types and then how WinApi set's those collars. It is unclear to me why this happens. It was partaly solved in earlier releases. But there are still some problems with it. I will not this issue as a bug

TimonPost avatar Sep 29 '19 12:09 TimonPost

It seems like this could be fixed by flushing before (or after) every winapi call?

andrewhickman avatar Feb 21 '20 19:02 andrewhickman

The problem arises when you print at the same line. If you set style, print a string without line break and then set the style back, and then flush you won't have styled text.

Maybe this can be solved by using winapi for writing as well.

TimonPost avatar Feb 22 '20 06:02 TimonPost

To summarize the issue:

let x = format!("{}", hello".red());

This can easily work with ansi since the ansi sequence is written to x with the original str. In winapi case, the corresponding api is called and we never modify the original str, so the color information is lost (which is the expected behavior) so when we print later it will only color in ansi's case. I think formatting and winapi simply can't coexist together, we should just mention it in the docs and that should be enough.

sigmaSd avatar Sep 17 '20 12:09 sigmaSd