Skip to content

Commit

Permalink
Get window size on more Windows terminals.
Browse files Browse the repository at this point in the history
This is an alternate approach to determining the window size that works on more Windows terminals.

Terminals with accurate width detection: Normal Windows console, cmder, ConEmu, VS Code, Hyper, etc.

mintty-based terminals will always be 60 characters wide. Cygwin in a command console is ok, but
running under x-windows will also always be 60.

Tested on Windows 8 and Windows 10.

Closes rust-lang#5124.
  • Loading branch information
ehuss committed Sep 12, 2018
1 parent b0679d5 commit 5b139d1
Showing 1 changed file with 35 additions and 2 deletions.
37 changes: 35 additions & 2 deletions src/cargo/core/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,18 +359,51 @@ mod imp {
extern crate winapi;

use std::mem;
use std::ptr;
use self::winapi::um::fileapi::*;
use self::winapi::um::handleapi::*;
use self::winapi::um::processenv::*;
use self::winapi::um::winbase::*;
use self::winapi::um::wincon::*;
use self::winapi::um::winnt::*;

pub fn stderr_width() -> Option<usize> {
unsafe {
let stdout = GetStdHandle(STD_ERROR_HANDLE);
let mut csbi: CONSOLE_SCREEN_BUFFER_INFO = mem::zeroed();
if GetConsoleScreenBufferInfo(stdout, &mut csbi) == 0 {
if GetConsoleScreenBufferInfo(stdout, &mut csbi) != 0 {
return Some((csbi.srWindow.Right - csbi.srWindow.Left) as usize)
}

// On mintty/msys/cygwin based terminals, the above fails with
// INVALID_HANDLE_VALUE. Use an alternate method which works
// in that case as well.
let h = CreateFileA("CONOUT$\0".as_ptr() as *const CHAR,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
ptr::null_mut(),
OPEN_EXISTING,
0,
ptr::null_mut()
);
if h == INVALID_HANDLE_VALUE {
return None;
}
Some((csbi.srWindow.Right - csbi.srWindow.Left) as usize)

let mut csbi: CONSOLE_SCREEN_BUFFER_INFO = mem::zeroed();
let rc = GetConsoleScreenBufferInfo(h, &mut csbi);
CloseHandle(h);
if rc != 0 {
let width = (csbi.srWindow.Right - csbi.srWindow.Left) as usize;
// Some terminals, such as mintty, always return 79 instead of
// the actual width. In that case, use a conservative value.
if width == 79 {
return Some(60);
} else {
return Some(width);
}
}
return None;
}
}
}

0 comments on commit 5b139d1

Please sign in to comment.