Git Product home page Git Product logo

winpty's Introduction

winpty

Build Status

winpty is a Windows software package providing an interface similar to a Unix pty-master for communicating with Windows console programs. The package consists of a library (libwinpty) and a tool for Cygwin and MSYS for running Windows console programs in a Cygwin/MSYS pty.

The software works by starting the winpty-agent.exe process with a new, hidden console window, which bridges between the console API and terminal input/output escape codes. It polls the hidden console's screen buffer for changes and generates a corresponding stream of output.

The Unix adapter allows running Windows console programs (e.g. CMD, PowerShell, IronPython, etc.) under mintty or Cygwin's sshd with properly-functioning input (e.g. arrow and function keys) and output (e.g. line buffering). The library could be also useful for writing a non-Cygwin SSH server.

Supported Windows versions

winpty runs on Windows XP through Windows 10, including server versions. It can be compiled into either 32-bit or 64-bit binaries.

Cygwin/MSYS adapter (winpty.exe)

Prerequisites

You need the following to build winpty:

  • A Cygwin or MSYS installation
  • GNU make
  • A MinGW g++ toolchain capable of compiling C++11 code to build winpty.dll and winpty-agent.exe
  • A g++ toolchain targeting Cygwin or MSYS to build winpty.exe

Winpty requires two g++ toolchains as it is split into two parts. The winpty.dll and winpty-agent.exe binaries interface with the native Windows command prompt window so they are compiled with the native MinGW toolchain. The winpty.exe binary interfaces with the MSYS/Cygwin terminal so it is compiled with the MSYS/Cygwin toolchain.

MinGW appears to be split into two distributions -- MinGW (creates 32-bit binaries) and MinGW-w64 (creates both 32-bit and 64-bit binaries). Either one is generally acceptable.

Cygwin packages

The default g++ compiler for Cygwin targets Cygwin itself, but Cygwin also packages MinGW-w64 compilers. As of this writing, the necessary packages are:

  • Either mingw64-i686-gcc-g++ or mingw64-x86_64-gcc-g++. Select the appropriate compiler for your CPU architecture.
  • gcc-g++
  • make

As of this writing (2016-01-23), only the MinGW-w64 compiler is acceptable. The MinGW compiler (e.g. from the mingw-gcc-g++ package) is no longer maintained and is too buggy.

MSYS packages

For the original MSYS, use the mingw-get tool (MinGW Installation Manager), and select at least these components:

  • mingw-developer-toolkit
  • mingw32-base
  • mingw32-gcc-g++
  • msys-base
  • msys-system-builder

When running ./configure, make sure that mingw32-g++ is in your PATH. It will be in the C:\MinGW\bin directory.

MSYS2 packages

For MSYS2, use pacman and install at least these packages:

  • msys/gcc
  • mingw32/mingw-w64-i686-gcc or mingw64/mingw-w64-x86_64-gcc. Select the appropriate compiler for your CPU architecture.
  • make

MSYS2 provides three start menu shortcuts for starting MSYS2:

  • MinGW-w64 Win32 Shell
  • MinGW-w64 Win64 Shell
  • MSYS2 Shell

To build winpty, use the MinGW-w64 {Win32,Win64} shortcut of the architecture matching MSYS2. These shortcuts will put the g++ compiler from the {mingw32,mingw64}/mingw-w64-{i686,x86_64}-gcc packages into the PATH.

Alternatively, instead of installing mingw32/mingw-w64-i686-gcc or mingw64/mingw-w64-x86_64-gcc, install the mingw-w64-cross-gcc and mingw-w64-cross-crt-git packages. These packages install cross-compilers into /opt/bin, and then any of the three shortcuts will work.

Building the Unix adapter

In the project directory, run ./configure, then make, then make install. By default, winpty is installed into /usr/local. Pass PREFIX=<path> to make install to override this default.

Using the Unix adapter

To run a Windows console program in mintty or Cygwin sshd, prepend winpty to the command-line:

$ winpty powershell
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

PS C:\rprichard\proj\winpty> 10 + 20
30
PS C:\rprichard\proj\winpty> exit

Embedding winpty / MSVC compilation

See src/include/winpty.h for the prototypes of functions exported by winpty.dll.

Only the winpty.exe binary uses Cygwin; all the other binaries work without it and can be compiled with either MinGW or MSVC. To compile using MSVC, download gyp and run gyp -I configurations.gypi in the src subdirectory. This will generate a winpty.sln and associated project files. See the src/winpty.gyp and src/configurations.gypi files for notes on dealing with MSVC versions and different architectures.

Compiling winpty with MSVC currently requires MSVC 2013 or newer.

Debugging winpty

winpty comes with a tool for collecting timestamped debugging output. To use it:

  1. Run winpty-debugserver.exe on the same computer as winpty.
  2. Set the WINPTY_DEBUG environment variable to trace for the winpty.exe process and/or the process using libwinpty.dll.

winpty also recognizes a WINPTY_SHOW_CONSOLE environment variable. Set it to 1 to prevent winpty from hiding the console window.

Copyright

This project is distributed under the MIT license (see the LICENSE file in the project root).

By submitting a pull request for this project, you agree to license your contribution under the MIT license to this project.

winpty's People

Contributors

cjfromthesea avatar dscho avatar haomingz avatar holtrop avatar jackyzy823 avatar jkells avatar rprichard avatar sschuberth avatar the-ress avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

winpty's Issues

Wrapped lines create extra linefeed

When sending a line which is as long as the console window width (a wrapped line) the following CR LF sequence to move the cursor to the next line is superfluous, because the terminal cursor position has implicitly moved to the next line already. This creates an extra empty line in the terminal client.

Improve startup behavior of CLS (clear screen) and full-screen programs

Currently, running console.exe cmd.exe /c cls appears to have no effect:

rprichard@vbwin7 ~
$ console cmd.exe /c cls

rprichard@vbwin7 ~
$

Similarly, if my cursor is in the middle of the screen, and I start winpty on cmd, then press F7, the F7 popup appears at the bottom of the terminal, but the popup always appears in the center of the console:

f7atbottom

This happens because winpty must translate between the console (which is initially entirely blank) and the terminal, which typically has content on startup. winpty could have avoided this issue by clearing the terminal on startup, but that would hurt user experience overall.

So far, I'd considered this issue a limitation, but now I think it might be solvable by initializing the console cursor position to the terminal's cursor position. winpty would need to determine the cursor position at startup, which is possible using the DSR (Device Status Report) escape sequence.

When scraping, winpty wouldn't output the blank lines prior to the initial line. It would only output those lines once they changed, or once the cursor moved into them. Ideally, it would make some effort to shift the lines into the terminal's scrollback -- which I think happens with either Erase Display or Scroll Up.

Things to consider:

  • Are things like Agent::resetConsoleTracking and Terminal::reset affected somehow?
  • The new Windows 10 rewrapping behavior can already result in blank lines at the top of a console window that are not output. Are these situations related somehow?

The idea of blocking startup until the terminal responds to queries also came up with color translation (#45).

Windows: Powershell error

console.exe powershell.exe

Windows PowerShell
Copyright (C) 2012 Microsoft Corporation. All rights reserved.

PS C:\Users\peters\Documents> Internal Windows PowerShell error. Loading manage
d Windows PowerShell failed with error 80090006.

Windows 7 SP1 and latest from HEAD.

console.exe cannot handle non-ascii characters in command line argument

console.exe aborts due to assertion failure when I put non-ASCII characters in command line argument.
As far as I can see, it is because mbstowcs() returns -1 since mbstowcs() is locale dependent by spec and requires proper setting of LC_CTYPE via a call to setlocale() for conversion of non-ASCII characters.
In my environment (Cygwin64), the following addition to main() is enough:

setlocale(LC_CTYPE, "");

As far as I can recall, locale related implementation was poor on Cygwin 1.5 era, so I don't know if it also works for old Cygwin or msys1 as expected.

Override the color translation heuristic by detecting terminal colors with OSC codes

winpty currently uses a color translation heuristic to translate console colors into terminal colors. It's described in detail here. Basically, the console always use LtGray-on-Black (overriding the default), even if the terminal is Black-on-White, Green-on-Black, etc.

So far, I haven't had any complaints about the heuristic, but even still, if it's possible to get the colors exactly right, it seems worth trying.

There are a few issues that make color translation difficult:

  1. (In theory) Some Windows programs might not behave properly with a non-default color scheme. I'm not sure whether this is an issue in practice, but if it were, a winpty user might appreciate the current translation strategy.
  2. winpty doesn't know what colors the terminal is using.
  3. Forcing the terminal text to have the same color as the console looks very ugly, even when the color schemes mostly match.

It turns out that there are OSC terminal codes that would let winpty query the color table, solving # 2:

  • ESC ] 10 ; ? ; ESC \ produces the foreground color (as an RGB color).
  • ESC ] 11 ; ? ; ESC \ produces the background color.
  • ESC ] 4 ; nn ; ESC \ produces palette color nn.

Here's how I think it would work. At startup, winpty would print 18 OSC codes--two for foreground and background, 16 for the palette. Once it received the replies, it would search for the two terminal palette colors closest to the terminal fore/back colors. It would configure the console to use those two colors as its fore/back colors, then it would map those two console colors to the terminal's default coloring (i.e. "no coloring"). The other 14 console colors would map to their corresponding terminal colors.

Some difficulties:

  • Many terminals don't reply to these OSC commands. I think I can work around this using the same DSR trick that I'm using to recognize ESC keypresses. (i.e. print ESC [ 6 n and wait for the row+col reply.)
  • Some terminal don't even reply to DSR. So far, I only know of the Cygwin Console (i.e. TERM=cygwin). I think I can work around that terminal by whitelisting TERM values.
  • Nonetheless, some terminal might exist that sets TERM=xterm and doesn't reply to anything. In that case, it's not clear how initialization works. I think I need to clear the screen, with the appropriate fore/back color, before starting the user's child process. I suppose winpty could wait a second or two, but that'd be awful.

Alternatively, there could be an interface to winpty for specifying the foreground and background colors. Perhaps a command-line argument to console.exe or an environment variable. (e.g. --color-scheme LtGray-on-Black)

cygwin ssh: Assertion failed: success, file winpty.cc, line 191

console works locally in mintty, but fails under cygwin ssh:

    $ console cmd.exe
    Assertion failed: success, file winpty.cc, line 191

    This application has requested the Runtime to terminate it in an unusual way.
    Please contact the application's support team for more information.

9a9c148

OS: Win7 pro SP1, domain user is local admin

APPCRASH in winpty-agent.exe

We are seeing infrequent crashes of winpty-agent.exe on Windows 7 64-bit. I assume it is due to a failing ASSERT, but could not reproduce the crash so far:

Problem signature:
Problem Event Name: APPCRASH
Application Name: winpty-agent.exe
Application Version: 0.0.0.0
Application Timestamp: 52a85668
Fault Module Name: winpty-agent.exe
Fault Module Version: 0.0.0.0
Fault Module Timestamp: 52a85668
Exception Code: 40000015
Exception Offset: 000091c0
OS Version: 6.1.7601.2.1.0.256.48
Locale ID: 1033
Additional Information 1: 7a18
Additional Information 2: 7a188dc7e1a37cade12485cc5ec071bb
Additional Information 3: cf42
Additional Information 4: cf42ba909ccdd17b26b5c1402a7571a9

Environment Variables are not inherited

Repro

cmd /c set

ALLUSERSPROFILE=C:\ProgramData
APPDATA=C:\Users\Administrator\AppData\Roaming
COMMONPROGRAMFILES=C:\Program Files (x86)\Common Files
COMPUTERNAME=VAGRANT-2008R2
COMSPEC=C:\Windows\system32\cmd.exe
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
FP_NO_HOST_CHECK=NO
HOME=C:\cygwin\home\Administrator
HOMEDRIVE=C:
HOMEPATH=\Users\Administrator
HOSTNAME=vagrant-2008R2
INFOPATH=/usr/local/info:/usr/share/info:/usr/info:
LANG=en_US.UTF-8
LOCALAPPDATA=C:\Users\Administrator\AppData\Local
LOGONSERVER=\\VAGRANT-2008R2
MANPATH=/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man
NUMBER_OF_PROCESSORS=1
OLDPWD=/etc/skel
OS=Windows_NT
PATH=C:\cygwin\usr\local\bin;C:\cygwin\bin;C:\ruby\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.RB;.RBW
PRINTER=Microsoft XPS Document Writer
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_ARCHITEW6432=AMD64
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 42 Stepping 7, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=2a07
PROGRAMFILES=C:\Program Files (x86)
PROMPT=$P$G
PS1=\[\e]0;\w\a\]\n\[\e[32m\]\u@\h \[\e[33m\]\w\[\e[0m\]\n\$
PSModulePath=C:\Windows\system32\WindowsPowerShell\v1.0\Modules\
PUBLIC=C:\Users\Public
PWD=/home/Administrator
ProgramData=C:\ProgramData
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
SESSIONNAME=Console
SHELL=/bin/bash
SHLVL=1
SYSTEMDRIVE=C:
SYSTEMROOT=C:\Windows
TEMP=C:\cygwin\tmp
TERM=xterm
TMP=C:\cygwin\tmp
TZ=America/Los_Angeles
USER=Administrator
USERDOMAIN=VAGRANT-2008R2
USERNAME=Administrator
USERPROFILE=C:\Users\Administrator
WINDIR=C:\Windows
_=/cygdrive/c/Windows/system32/cmd
temp=C:\Users\ADMINI~1\AppData\Local\Temp
tmp=C:\Users\ADMINI~1\AppData\Local\Temp
windows_tracing_flags=3
windows_tracing_logfile=C:\BVTBin\Tests\installpackage\csilogfile.log
console cmd /c set
COMSPEC=C:\Windows\SysWOW64\cmd.exe
PATH=C:\cygwin\usr\local\bin;C:\cygwin\bin;C:\ruby\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\Wi
ndowsPowerShell\v1.0
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC
PROMPT=$P$G
SYSTEMDRIVE=C:
SYSTEMROOT=C:\Windows
WINDIR=C:\Windows

I expected that I would have a shared environment. In looking at the code, all seems right in that the creation of desktop stations and processes seem to pass null if the environment is in fact empty. Not sure what is going on, but it seems to me that the processes should at the very least be able to share an environment. At the very least it should spawn a full windows environment with both system and user (default variables) set.

Escape/transform U+001B when it appears in the Windows console

Currently, if a console cell contains U+001B, winpty copies it through to the terminal. This behavior wasn't ever intentional, and now that I've noticed it, I think it should be changed, probably by replacing U+001B with another character like a space, a question mark, or perhaps U+FFFD (�). winpty generally tries to keep the terminal looking like the console, and the console does not interpret escape sequences.

This behavior is arguably a feature. For example, this currently works, assuming default colors and a wide enough mintty terminal:

$ WINPTY_SHOW_CONSOLE=1 console c:/Python27/python
Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print "\x1b[9mCROSSED\x1b[0m"
CROSSED
>>>

In mintty, the text is struck through, like CROSSED.

In the winpty's underlying console, this is what appears:

Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print "\x1b[9mCROSSED\x1b[0m"
�[9mCROSSED�[0m
>>>

The ability breaks easily, though. If the escape sequence wraps around a line, winpty will typically insert its own control sequences (or at least CR and LF) into the console's escape sequence. The ability also interferes with winpty's color handling and cursor positioning.

If a Windows console program's escape sequences are interpreted, they should be interpreted without writing them to the console screen buffer.

send SIGHUP to child process

I use the following command line to start bash on windows

 mintty.exe -e console.exe bash -l 

This way I can start console applications like python in the bash/mintty window.
But it seems that when I close the mintty window the SIGHUP does not reach bash and therefore the bash history is not stored.

I think it would be nice if console.exe and winpty-agent.exe would send the SIGHUP signal to their child process when they receive one.

When I use

mintty.exe -e bash -l

the bash history works fine.

http://mintty.googlecode.com/svn/trunk/docs/mintty.1.html#17

Consider clearing the TERM variable

See #23. Clearing the TERM and PAGER variables fixed that problem, but perhaps winpty's console.exe utility ought to clear TERM. This behavior probably doesn't belong in the agent or DLL.

I don't think winpty should be clearing PAGER, even though it was necessary to fix #23.

Error 0x2 starting <app>

I'm getting Error 0x2 starting <app> for some application. I've not figured out the pattern yet.

Tried on Windows 7 (32 bit), Windows 8.1 (32bit) and Windows 10 (64 bit).
Tried with both 32bit and 64bit winpty and app versions (for docker)
Using Babun Shell.

Examples (not working):

{ ~ }  » docker --version
Docker version 1.9.1, build a34a1d5
{ ~ }  » console --version
winpty version 0.2.1
commit 83b6e9281d04e64bd2e588a422b824f6ad617811
{ ~ }  » console docker --version
Error 0x2 starting docker --version
{ ~ }  » pact --version
pact version 1.1.0 (based on apt-cyg 0.57)
Tweaked and maintained by Tom Bujok (@tombujok)
Copyright (c) 2014-2015. Released under the MIT.
{ ~ }  » console pact --version
Error 0x2 starting pact --version

Examples (working):

{ ~ }  » console uname -a
CYGWIN_NT-10.0-WOW IE11WIN10 1.7.35(0.287/5/3) 2015-03-04 12:07 i686 Cygwin
{ ~ }  » console curl --version
curl 7.41.0 (i686-pc-cygwin) libcurl/7.41.0 OpenSSL/1.0.2a zlib/1.2.8 libidn/1.29 libssh2/1.5.0
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: Debug IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets Metalink

tmux won't start in winpty based terminal

I am using pty.js which is based on winpty to start a cygwin based tmux. Tmux is exiting with an error stating that the terminal is not a true terminal. It does the same thing when started from cmd.exe. However it works fine when started from mintty.

The strange thing is that when I run screen (cygwin) via winpty and then start tmux inside that screen session, everything works fine.

I asked on the tmux IRC channel and they suspect that this has to do with:

NicM: on cgywin tmux requires that opening the terminal device (ie open(ttyname(STDIN_FILENO))) works
NicM: find out what it is and more likely it needs to be added to winpty
NicM: i bet it isn't giving a pty filesystem node

Is there some incompatibility that could cause this? Do you have some pointers for me? Any help is much appreciated.

winpty hangs when launching docker

When attempting to run docker in debug mode on Cygwin with the following command, the console hangs when exiting :

console docker -D run -it busybox
/ # exit

On windows (command prompt), all is ok.

 docker -D run -it busybox
/ # exit
DEBU[0002] [hijack] End of stdout
DEBU[0002] [hijack] End of stdin
DEBU[0002] Couldn't send EOF: use of closed network connection
DEBU[0002] End of CmdRun(), Waiting for hijack to finish.

In cygwin, debug log doesn't appear and console hangs. It is not possible to interrupt (ctrl+c) the process.

I notice no issue in normal mode (without the flag -D).

Screen buffer switching broken on Windows 7 (ChangeScreenBuffer test program crashes)

On Windows 7, when I run the misc/ChangeScreenBuffer test program, the agent switches into direct mode briefly, then immediately switches back to scrolling mode. Apparently, one of its calls to GetConsoleScreenBufferInfo sees the new screen buffer, but later calls see the original buffer. The agent displays the contents of the original buffer, not the new buffer.

There is only a single console input queue (IIRC), so pressing ESC still successfully closes the ChangeScreenBuffer test program, at which point, the agent apparently has trouble reopening CONOUT$, and it crashes.

The test program works fine on Windows 8 and Windows 10.

Can't capture the output of help(0) in a python console

I saw this issue in an IronPython prompt of a cygwin session. The cygwin session ran in Mintty. The output of help(0) was empty. I could see a very short halt of the prompt but nothing showed. It should print the type information of the int 0. Other kinds of outputs seemed all right.

Do you have any idea about the causes to that? Thanks.

gyp generates inscrutable error message on winpty.gyp

When I run gyp on winpty.gyp, it outputs this nonsensical error message:

C:\rprichard\proj\winpty\winpty>..\gyp\gyp winpty.gyp
gyp: Could not automatically locate src directory.  This isa temporary Chromium
feature that will be removed.  Use--depth as a workaround.

I'm speculating, but I think the deal is:

  • Chromium's gyp files use a DEPTH variable.
  • Somehow, DEPTH needs to be set, and it can be set by hand with a --depth argument.
  • That's cumbersome, though, so in 2009, a hack went into gyp to autodetect a DEPTH value by looking for the first source file whose absolute path contains a src component. If it can't find an appropriate DEPTH setting, then gyp aborts, because there's something wrong with your Chromium checkout.

The immediate work-around for this error is to pass --depth with (I think?) any arbitrary value:

..\gyp\gyp winpty.gyp --depth .

It's dumb, but if I add a src directory, then gyp will Just Work. So, maybe I'll reorganize the source tree someday.

It might make sense to look for a gyp alternative, too, especially given that Chromium seems to be switching away from gyp toward gn. Alternatives to gyp include:

  • Check in VC project files
  • CMake (Could CMake replace the Makefiles? Need to consider MSYS, MSYS2, and Cygwin.)

Use STARTUPINFO flags to start winpty-agent.exe more efficiently

At startup, the agent currently:

  1. resizes the buffer
  2. clears the buffer (i.e. using the conventional LtGray-on-Black color required by the winpty color translation heuristic)
  3. sets the window title (to empty string, IIRC)

All of these could be done instead using STARTUPINFO fields:

  1. STARTF_USECOUNTCHARS (The Win32-OpenSSH project is also using STARTF_USESIZE, which seems odd to me.)
  2. STARTF_USEFILLATTRIBUTE
  3. lpTitle

It is probably more efficient to let Windows do this, because it's going to anyway, and because it's presumably fewer RPCs.

Improve console resizing behavior w.r.t. large terminals

Currently, if the user attempts to make the terminal too big, winpty simply issues a SetConsoleWindowInfo call with invalid size values, and the API call fails. The result is a wide buffer, and a window with whatever width it most recently had. It should probably try to do more.

At the absolute least, if the width is too large, it should still change the height.

It should probably cap the window size to the largest possible. Ordinarily, winpty tries to keep the window and buffer widths equal, but maybe it should allow the buffer width to be greater. If the buffer width is greater, winpty now scrapes the entire buffer width, but only in Scrolling Mode, not Direct Mode.

Dynamically adjusting the font sizes is also a possibility. It's probably necessary, but it can't fully solve the problem, and it creates an awkward situation where we can handle small terminals and big terminals, but not "tall and skinny" terminals.

See my analysis of IDEA-117552. The IDEA-136296 issue also has a screenshot demonstrating the cursor positioned beyond the line's visible characters.

I poked at the console size APIs a bit tonight. Tentatively, I think this is the behavior:

  • If a size requirement isn't satisfied, the API fails and nothing happens. (Out-of-bounds coordinates aren't modified to be in-bounds.)
  • SetConsoleWindowInfo sets the window position and size. The new window rectangle must be completely inside the buffer size, and the new size must be no greater than the current GetLargestConsoleWindowSize value. Each coordinate must be at least 1, but a 1x1 size is OK. Changing the console window position with this API does not move the graphical window. That is, the GUI window's (Left, Top) coordinate is unchanged. Rather, the (Right, Bottom) coordinate changes.
  • SetConsoleScreenBufferSize sets the buffer size. The new buffer size must be >= the current window size. It is OK to exclude cells that are currently visible--Windows will automatically move the window, but it won't shrink the window. The buffer width (in columns) must be at least large enough that a window of minimum pixel width (e.g. 130 pixels) would not have more columns than the buffer. The buffer height must be at least 1.
  • GetLargestConsoleWindowSize returns the largest allowed value for the console window size, in rows and columns. The console window is not allowed to be larger than the screen. Crucially, in a multi-monitor setup, the console window cannot be larger than some monitor, apparently whichever monitor is showing more of the console.

I am wondering precisely which monitor GetLargestConsoleWindowSize uses. Maybe it's the monitor containing the center-point of the window? I suspect it's possible to position a window so that the center-point is not on a monitor at all. Then what?

In a multi-monitor setup, it is possible to call SetConsoleWindowInfo to change the console size successfully, then call it again unsuccessfully using the exact same rectangle. The first call changes the monitor that the console associates with, such that the new console size is no longer valid. Given that terminal resizing is a multi-step affair in the agent, this has the potential for complicating things.

Part of the trouble here is that an IntelliJ window can span multiple monitors, but a console window generally can't. People with multiple monitors are therefore more likely to hit this issue.

I think it's possible to query monitor positions with EnumDisplayMonitors.

Aside: For an interesting example of Direct Mode, see the wmic.exe utility included with Windows. The utility resizes the buffer on startup--by making the buffer 1500 columns wide and 300 lines tall! Once in Direct Mode, if you type a line longer than the terminal width, it doesn't wrap--instead, the entire visible contents of the terminal scroll off the left side of the terminal. Pressing Home shows part of the contents again, but only part, because the cursor hasn't moved all the way to the left. Pressing Enter scrolls back left. Resizing the terminal resets the buffer width to the new terminal width, which restores ordinary wrapping behavior, but it does not end Direct Mode, because the buffer height is still 300. Exiting wmic.exe does restore Scrolling Mode, but not if the terminal has been resized in the interim.

Unicode output is not handled correctly

winpty shows non-ASCII characters using a question mark. e.g.:

test1.cc

#include <stdio.h>
#include <assert.h>
#include <windows.h>

int main() {
    wchar_t ch = 0x754C; // U+754C (CJK UNIFIED IDEOGRAPH-754C)
    DWORD actual = 0;
    BOOL ret = WriteConsoleW(
        GetStdHandle(STD_OUTPUT_HANDLE),
        &ch, 1, &actual, NULL);
    assert(ret && actual == 1);
    return 0;
}
$ ~/proj/winpty/winpty/build/console.exe ./test1.exe
?

I think I have it narrowed down to two things:

  • winpty uses ReadConsoleOutputA, when it should be using ReadConsoleOutputW. I have a patch that I'll probably push to master soon.
  • Amusingly enough, the console must not use a raster font. If it does, then apparently non-ASCII characters are converted to question marks, even when using the Unicode WriteConsoleW / ReadConsoleOutputW functions. winpty currently changes the console font (Agent.cc, setSmallFont), because the console window must fit on the screen, even though it is invisible, so a large font would quietly break things. The obvious fix is to pick a non-raster font, although the APIs for selecting the font are pretty dodgy, IIRC, so that might be unreliable. I'll keep looking at it.

One other issue: when winpty converts the UTF-16 console buffer to its Unix-pty output pipe, it always encodes its output as UTF-8. It wouldn't surprise me if that were incorrect behavior--maybe it ought to use a locale-specific encoding?

Here's a test program demonstrating the problem. Open a console with a raster font and observe the question mark. With a non-raster font, an unknown character box appears (for me, anyway), but the program outputs the correct UTF-16 value:

#include <windows.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
    system("cls");

    // Write character.
    wchar_t ch = 0x754C; // U+754C (CJK UNIFIED IDEOGRAPH-754C)
    DWORD actual = 0;
    BOOL ret = WriteConsoleW(
        GetStdHandle(STD_OUTPUT_HANDLE),
        &ch, 1, &actual, NULL);
    assert(ret && actual == 1);

    // Read it back.
    CHAR_INFO data;
    COORD bufSize = {1, 1};
    COORD bufCoord = {0, 0};
    SMALL_RECT topLeft = {0, 0, 0, 0};
    ret = ReadConsoleOutputW(
            GetStdHandle(STD_OUTPUT_HANDLE), &data, bufSize, bufCoord, &topLeft);
    assert(ret);

    printf("CHAR: 0x%04x\n", data.Char.UnicodeChar);
    return 0;
}

[Feature Request] A New Stable Release

The most recent release appears to be over three years old, whereas the most recent commit appears to be less than a year old. Maybe it's just me, but... There seems to be a discrepancy here.

Given that the 0.1.1 release is probably tragically broken in several painful ways (e.g., 64-bit support), it'd be great to get an 0.1.2 or (preferably) 0.2 release at some point. No rush, of course. I'm happy to just git clone up the live codebase. But an official release would probably simplify CLI life for others.

As well as demonstrate that this project is still alive and kicking! 👠

Windows XP - Absolute path is required

Do you have any idea why an absolute path to cmd.exe is required on Windows XP to start a new pty session? It's no biggie doing that, but it's odd though. Do you have any ideas on how we could get it working using a relative path?

DOS edit.com behaves poorly in winpty

There are two problems I hit trying to run DOS edit.com inside winpty:

  1. Massive font sizes with code page switches. When my console used Japanese code page 932, starting edit.com switched to code page 437. The code page switch sometimes changes the font to something huge. IIRC, each character was ~150 px tall or something. This seems to have forced the window to be very small, so only a small piece of the top-left of the screen buffer was visible.

  2. Resizing breaks. When edit.com starts, it resizes the console buffer and window to something like 80x50 or 80x25. winpty is now OK with this -- it switches to direct mode and only scrapes the intersection of the new console size and the old terminal size. As soon as the terminal is resized again, winpty resizes the console. So far, this is all by design.

    However, whenever the console is of a "non-standard" size, something goes wrong with edit.com. I can still type characters, and I'll see the cursor advance, but the text doesn't appear inside the editor.

    It seems that once edit.com has run inside a console, Windows does not allow changing the buffer size using the properties dialog until ntvdm.exe exits. The buffer can be resized using the APIs. This limitation doesn't apply to all DOS programs -- I can resize the buffer with command.com.

I've considered doing something about problem 1 by polling for code page switches and repeating the font size setting. It would also be necessary to examine the window rectangle and fix it.

Another approach might be to preemptively configure all code pages' fonts, if perhaps the console remembers each code page's font individually. winpty would switch to each code page and configure a font. I suspect that approach won't work.

For problem 2, I don't know why edit.com is special, or how the console knows to restrict the terminal sizes.

Using winpty with neovim

Hi, let me start with a bit of background:

libvterm is an abstract terminal emulator library without any system dependencies(implemented in pure C99 API). It exposes a structure that keeps track of terminal state and updates the screen when it receives terminal output(fed by the user).

One program that uses this library to implement an embedded terminal emulator is neovim. ATM neovim is only officially supported on UNIX, but some community members are porting it to windows.

When running under windows, neovim spawns a program with libuv, which in turns calls windows CreateProcess API to spawn and communicate with children, transfering bytes from/to their stdio into the abstract terminal emulator. While this doesn't work with native windows console programs, I wanted to try using winpty unix adapter to make neovim fully capable of running its terminal emulator on windows.

I have some questions about winpty:

  • Do we need anything other than winpty unix adapter(console.exe) in order to "convert" windows console programs into the "unix format"? In other words, just spawning console.exe using CreateProcess(and proper stdio redirection) is enough to make it create a hidden console window and forward esc codes to the parent process?
  • How do we notify programs running under console.exe that window dimensions have changed?

Upgrade line counters to 64 bits

There are a handful of counters that are 32 bits and could overflow given enough scrolling. e.g.:

  • Agent::m_scrolledCount
  • Agent::m_scrapedLineCount
  • Terminal::m_remoteLine

If the console scrolled 1000 lines a second, these counters would overflow in 25 days.

Invalid repository name (sequenceiq\hadoop-docker), only [a-z0-9-_.] are allowed

winpty seems great but I have run to a problem when using it with Docker. It seems like winpty is not passing the image names with slashes to Docker. I tried different combinations of quotes and slashes.

The docker command runs correctly on my Ubuntu laptop.

Any suggestions?

$ winpty docker run -it sequenceiq/hadoop-docker:2.7.0 /etc/bootstrap.sh -bash
Unable to find image 'sequenceiq\hadoop-docker:2.7.0' locally
FATA[0000] Invalid repository name (sequenceiq\hadoop-docker), only [a-z0-9-_.] are allowed

SetProcessWindowStation call in winpty.dll is not thread-safe and breaks clipboard

winpty.dll uses SetProcessWindowStation to help put a console into the background. This call could conflict with what other threads are doing, including those starting other winpty instances.

I'm not sure what can be done about this, if anything. It might be the winpty.dll client's responsibility to deal with the consequences.

winpty-agent.exe hangs on Windows 10 upon terminal resize

E.g. within mintty, execute

console.exe cmd

then resize the terminal window -> winpty-agent.exe hangs in

(gdb) bt
#0 0x77c28c3c in ntdll!ZwDeviceIoControlFile () from C:\Windows\SYSTEM32\ntdll.dll
#1 0x76e8c8e9 in KERNELBASE!GetConsoleMode () from C:\Windows\SYSTEM32\KernelBase.dll
#2 0x76e8c7fa in KERNELBASE!GetConsoleMode () from C:\Windows\SYSTEM32\KernelBase.dll
#3 0x76f03230 in SetConsoleScreenBufferSize () from C:\Windows\SYSTEM32\KernelBase.dll
#4 0x0040485c in Win32Console::resizeBuffer(Coord const&) ()
#5 0x00404a97 in Win32Console::reposition(Coord const&, SmallRect const&) ()
#6 0x004033b1 in Agent::resizeWindow(int, int) ()
#7 0x00402dff in Agent::handleSetSizePacket(ReadBuffer&) ()
#8 0x0040295d in Agent::handlePacket(ReadBuffer&) ()
#9 0x004028d1 in Agent::pollControlSocket() ()
#10 0x0040275c in Agent::onPipeIo(NamedPipe*) ()
#11 0x0040154a in EventLoop::run() ()
#12 0x004064e6 in main () 

Workaround: Enable legacy console in cmd > Properties.

The following patch seems to prevent the hang:

diff --git a/agent/Agent.cc b/agent/Agent.cc
index 5983ab9..52c5c4b 100644
--- a/agent/Agent.cc
+++ b/agent/Agent.cc
@@ -392,8 +392,8 @@ void Agent::resizeWindow(int cols, int rows)
         markEntireWindowDirty();
     m_dirtyWindowTop = newWindowRect.top();

-    m_console->reposition(newBufferSize, newWindowRect);
     unfreezeConsole();
+    m_console->reposition(newBufferSize, newWindowRect);
 }

 void Agent::scrapeOutput()

Can't get winpty working

Hi!

Thank you all for this great tool!

Unfortunately I can't get winpty working:

My OS: Win7 32bit
Latest winpty version: https://github.com/rprichard/winpty/archive/master.zip

via Cygwin

packages:
mingw-gcc-g++
gcc-g++ (gcc4-g++ is obsolete)
make

 ~/winpty-master
$ ./configure
uname -s identifies a Cygwin environment.
uname -m identifies a i686 environment.
Found Cygwin/MSYS G++ compiler: i686-pc-cygwin-g++
Found 32-bit MinGW G++ compiler: i686-pc-mingw32-g++
Writing config-unix.mk
Writing config-mingw.mk

 ~/winpty-master
$ make
cd agent && make
make[1]: Entering directory '/home/User/winpty-master/agent'
Compiling EventLoop.cc
Compiling NamedPipe.cc
Compiling Agent.cc
Compiling AgentAssert.cc
Compiling Terminal.cc
Compiling Win32Console.cc
Compiling ConsoleInput.cc
Compiling ../shared/DebugClient.cc
Compiling Coord.cc
Compiling SmallRect.cc
Compiling main.cc
Linking ../build/winpty-agent.exe
make[1]: Leaving directory '/home/User/winpty-master/agent'
cd libwinpty && make
make[1]: Entering directory '/home/User/winpty-master/libwinpty'
Compiling winpty.cc
winpty.cc: In function ‘void* createNamedPipe(const wstring&, bool)’:
winpty.cc:142:28: error: ‘FILE_FLAG_FIRST_PIPE_INSTANCE’ was not declared in this scope
winpty.cc:150:1: warning: control reaches end of non-void function [-Wreturn-type]
../config.mk:31: recipe for target 'winpty.o' failed
make[1]: *** [winpty.o] Error 1
make[1]: Leaving directory '/home/User/winpty-master/libwinpty'
Makefile:24: recipe for target 'all' failed
make: *** [all] Error 2

I don't know what to do at this point in Cygwin.

via MinGW

packages:
mingw32-make
g++
msys-dvlpr
and the zlib1.dll in C:\MinGW\bin (source: http://zlib.net/zlib128-dll.zip)

 ~/winpty-master
$ ./configure
uname -s identifies a MSYS environment.
Found Cygwin/MSYS G++ compiler: i686-pc-msys-g++
Found 32-bit MinGW G++ compiler: mingw32-g++
Writing config-unix.mk
Writing config-mingw.mk

 ~/winpty-master
$ make
cd agent && make
make[1]: Entering directory `/home/User/winpty-master/agent'
Compiling EventLoop.cc
Compiling NamedPipe.cc
Compiling Agent.cc
Compiling AgentAssert.cc
Compiling Terminal.cc
Compiling Win32Console.cc
Compiling ConsoleInput.cc
Compiling ../shared/DebugClient.cc
Compiling Coord.cc
Compiling SmallRect.cc
Compiling main.cc
Linking ../build/winpty-agent.exe
make[1]: Leaving directory `/home/User/winpty-master/agent'
cd libwinpty && make
make[1]: Entering directory `/home/User/winpty-master/libwinpty'
Compiling winpty.cc
Compiling ../shared/DebugClient.cc
Linking ../build/winpty.dll
make[1]: Leaving directory `/home/User/winpty-master/libwinpty'
cd unix-adapter && make
make[1]: Entering directory `/home/User/winpty-master/unix-adapter'
Compiling main.cc
Compiling Shared.cc
Linking ../build/console.exe
make[1]: Leaving directory `/home/User/winpty-master/unix-adapter'

Everything fine at this point. But the console.exe doesn't work.
I tried your testcase via mintty and put everything into

$ ls /usr/local/bin
console.exe  msys-1.0.dll  winpty.dll  winpty-agent.exe

With the msys-1.0.dllbecause of:

$ console
/usr/local/bin/console.exe: error while loading shared libraries: msys-1.0.dll: cannot open shared object file: No such file or directory

If I try

$ console /cygdrive/c/Python27/python.exe

it just hangs and I have to kill it.

(Python source: https://www.python.org/ftp/python/2.7.8/python-2.7.8.msi)

Combine ReadConsoleOutputW calls to potentially reduce scraping CPU usage

Currently, when scraping the console in scrolling mode, winpty-agent.exe reads each line of the console using a separate ReadConsoleOutputW call. I think each call requires a context switch to conhost.exe / csrss.exe, so consolidating some of the calls might reduce CPU usage.

The OS version matters a lot here. While Windows 8 and up allow arbitrarily large reads, earlier versions of Windows do not. (In fact, with Windows 7, issuing a read of precisely the wrong size can apparently crash conhost.exe. See here for details.)

With Windows 7 and earlier, it is still possible to combine calls, but AFAIK, the console I/O is implemented using a 64KiB heap, and presumably the heap could become fragmented. Because Windows 7 can crash, I'm a little worried about reducing winpty's reliability. That said, winpty already uses a 3000-character read to find the sync marker, so perhaps reads up to that size are OK.

Doing feature detection for this issue seems hard, so maybe winpty will use GetVersionEx. MSDN lists that function as deprecated, because it's been replaced by "version helpers", but I don't think MinGW has the new APIs (even mingw-w64). I think GetVersionEx works up to Windows 8.1, though, so maybe it'll work.

npm install failed because missing some files

Although I do not think this problem is because of this reason...

deps\winpty\agent\AgentAssert.cc
deps\winpty\agent\winpty_wcsnlen.cc
deps\winpty\agent\winpty_wcsnlen.h
deps\winpty\agent\AgentAssert.h

When installing I use npm install --msvs_version=2015.

Some Windows 10 PowerShell text is invisible

Open Windows 10 PowerShell under winpty with WINPTY_SHOW_CONSOLE=1, and type the text dir -r. The -r is visible in the Windows console window, but it is invisible in the terminal. It looks like the color translation is turning the -r into black-on-black or something.

Reduce polling to reduce CPU/power consumption

Currently, winpty scans the console for changes about once every 25ms or so. It does this scanning even when no output is appearing (e.g. the default situation, most of the time). This seems wasteful of CPU time, and AIUI, regular polling is especially bad on laptops, where it could prevent a computer from entering some low-power state.

There are a couple ways to fix this:

  • Determine a maximum acceptable interval and increase the polling interval to the maximum after a period of no activity. If the interval is too long, a program could fill the entire console buffer resulting in lost output.
  • Use the Console WinEvents API to wake the agent up when a change happens.

To use the Console WinEvents API, the agent would register an event handler to receive console events on the system. The handler receives events from all consoles by default, which is suboptimal. It can be targeted at a specific PID. IIRC, on Windows 7, that PID is the conhost PID. There is no documented API to retrieve the conhost PID, but it can be determined by briefly collecting all console events and looking for a EVENT_CONSOLE_START_APPLICATION event. On earlier Windows versions, I think(?) the PID is that of the csrss.exe process.

The WinEvents API doesn't appear rich enough to supplant much of winpty's scraping, but I do wonder if winpty's latency could be improved somehow with, say, a fast path based on EVENT_CONSOLE_UPDATE_SIMPLE events.

Cygwin Package

Can this be a Cygwin Package so it can be installed from Cygwin package installer?

High CPU usage on Windows 10 non-legacy mode, related to Select All freeze method

I notice about a 10-12% idle CPU consumption in my Windows 10 VM, non-legacy mode, once the 3000-line screen buffer has filled up. It appears to result from winpty's use of "Select All" to freeze console output.

I suspect it can be fixed by using "Mark" instead of "Select All". winpty used to use Mark, but it had the side-effect of temporarily moving the cursor to the top-left, which IIRC broke some Cygwin programs. (The program was probably reading the cursor position.) The new Mark behavior doesn't appear to do this, though, so maybe it will be OK.

If not, the WinEvents API should help. (#46)

Can't compile in cygwin (Babun)

This is the message I get when I try to compile:

$ ./configure
uname -s identifies a Cygwin environment.
uname -m identifies a i686 environment.
Found Cygwin/MSYS G++ compiler: i686-pc-cygwin-g++
Found 32-bit MinGW G++ compiler: i686-w64-mingw32-g++
Writing config-unix.mk
Writing config-mingw.mk

$ make
cd agent && make
make[1]: Entering directory '/home/m0ngr31/winpty/agent'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/m0ngr31/winpty/agent'
cd libwinpty && make
make[1]: Entering directory '/home/m0ngr31/winpty/libwinpty'
make[1]: '../build/winpty.dll' is up to date.
make[1]: Leaving directory '/home/m0ngr31/winpty/libwinpty'
cd unix-adapter && make
make[1]: Entering directory '/home/m0ngr31/winpty/unix-adapter'
Compiling main.cc
In file included from /usr/include/w32api/_mingw.h:17:0,
                 from /usr/include/w32api/windows.h:9,
                 from main.cc:23:
/usr/include/w32api/_cygwin.h:14:20: fatal error: stddef.h: No such file or directory
 #include <stddef.h>
                    ^
compilation terminated.
../config.mk:31: recipe for target 'main.o' failed
make[1]: *** [main.o] Error 1
make[1]: Leaving directory '/home/m0ngr31/winpty/unix-adapter'
Makefile:24: recipe for target 'all' failed
make: *** [all] Error 2

I have the packages it said I needed, but no luck so far. I've tried both master and win10 branches.

Long environment strings are being truncated.

@rprichard If you try to start a new tty with a long environment string, it get's truncated.

Reading up on http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx no mention of a size limitation in the unicode version, only the ansi one.

If you put a trace in https://github.com/rprichard/winpty/blob/master/agent/Agent.cc#L193 you can clearly see a truncated string in the env variable. Only 35% of the content is transmitted via the IPC channel.

Also there's a bug in winpty.cc: https://github.com/rprichard/winpty/blob/master/libwinpty/winpty.cc#L373

Example:

Test=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA123

Add mouse support

IntelliJ's winpty fork (jediterm -> pty4j -> winpty) has mouse support; upstream winpty should also have it.

Terminals can report mouse movement, button press/release events, and scroll-wheel ticks.

By default, they don't report any of these events, but they can be put into a mode where they do. Once this mode is entered, the default text selection / history navigation is disabled in most terminals, so winpty shouldn't activate mouse mode unless we know it's desired. AFAICT, there's no good way to automatically make this determination -- I thought we could look for the ENABLE_MOUSE_INPUT console mode flag, but that flag is frequently set by programs that don't really care about mouse input, such as native Python 2.7 and Cygwin command-line programs. Therefore, winpty users will need to explicitly opt-in to mouse support.

I have a document I'm working on that will describe how mouse support varies across terminals. My intention is to have a --mouse option in the UNIX adapter whose only role is to enable and disable mouse input. The agent will always recognize mouse escapes, regardless of whether --mouse was passed.

The --mouse option will prefer modes 1003 and 1006, with fallbacks to 1002, 1000, and 1015. The agent will handle any of these modes. It won't support modes 9 (which lacks mouse-release events) or mode 1005 (UTF-8 coordinates create decoding ambiguity).

It might make sense to have more options for --mouse for users who want to avoid the unnecessary traffic, but since no one has even asked me for --mouse, I'm guessing I don't need to bother with it. In any event, --mouse is just a convenience option; users can enable the other modes if they want, e.g.:

printf '\e[?1002h\e[?1006h' && console cmd

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.