Giter VIP home page Giter VIP logo

Comments (6)

AnneKitsune avatar AnneKitsune commented on July 24, 2024

Does println flush its content as soon as it is called? If not, that could be the cause of your error. You can try by using the write macro.

from crossterm.

TimonPost avatar TimonPost commented on July 24, 2024

Thanks for looking into it!. println! does flush the buffer. But it is not the problem here, in the example above I use println! but in the actual code of the crate, this code will be used to write the ANSI escape code to the screen.

  fn write_str(&self, string: &str) -> io::Result<usize> {
        let out = &self.handle;
        let mut handle = out.lock();
        let amt = handle.write(string.as_bytes())?;
        handle.flush()?;
        Ok(amt)
}

I have to add something to this issue: When using ioctl to set and get terminal size, the information I get back from get_size() will be up to data. But I am not sure if I may use that function because I saw this issue.

I accidentally created this issue here at term_size crate and the fun thing was that he had the same problem. Check that out for more info.

from crossterm.

Screwtapello avatar Screwtapello commented on July 24, 2024

Here's what's going on:

  • your application prints an escape code to stdout
  • your application's stdout gets flushed to the kernel
  • the kernel wakes up the terminal emulator and tells it there's data to read
  • the terminal emulator reads the escape code, along with anything else that happened to be output around the same time
  • the terminal emulator probably waits a little while to see if any more data is going to arrive before parsing anything
  • the terminal emulator parses the escape code, resizes the GUI window and tells the kernel (via ioctl(TIOCSWINSZ), note the S instead of G) that the terminal has a new size
  • the kernel sends your application SIGWINCH to notify it that the terminal has resized

All of those steps take time, and if your application checks the terminal size at any point before SIGWINCH arrives, it'll read the "old" values.

In general, it's not possible for an application to resize the terminal it's running in; you can ask for a resize but there's no guarantee you'll get the dimensions you asked for (maybe the screen can't fit a window that large, or the windowing system won't resize a window that small), and even if the terminal does resize the user can just resize it right back afterward.

from crossterm.

TimonPost avatar TimonPost commented on July 24, 2024

Realy thanks for that detailes explanation! Explains alot.

However when I used 'ioctl' to set the terminal size instead of Ansi escape codes it seems liked it worked just fine. I'll see if I can reproduce that again to validate that statement. Because then the question, why does it works when doing it like that. Not sure but could the signal() function has something to do with this?

from crossterm.

AnneKitsune avatar AnneKitsune commented on July 24, 2024

Probably because there's no step where the kernel has to wait for stdin and parse the content, since you are directly modifying the kernel values and retrieving them right after?

from crossterm.

Screwtapello avatar Screwtapello commented on July 24, 2024

However when I used 'ioctl' to set the terminal size instead of Ansi escape codes it seems liked it worked just fine.

I assume you mean setting the "terminal size" with TIOCSWINSZ, and by "worked just fine" you mean that TIOCGWINSZ retrieved the expected value.

Those ioctls set and get the dimensions stored in the kernel, so they're naturally up-to-date with each other. But setting the terminal size with TIOCSWINSZ doesn't notify the terminal emulator about the change, nor resize the GUI window on-screen, so your application is going to have the wrong idea about terminal size.

I'm a little surprised that the kernel allows TIOCSWINSZ to be called on the application-end of a psuedo-terminal at all.

from crossterm.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.