Mouse input differences when using ENABLE_VIRTUAL_TERMINAL_INPUT #19818

Open
opened 2026-01-31 06:54:25 +00:00 by claunia · 5 comments
Owner

Originally created by @clinton-r on GitHub (May 5, 2023).

Windows Terminal version

1.16.10261.0

Windows build number

Microsoft Windows [Version 10.0.19045.2846]

Other Software

No response

Steps to reproduce

Compile this C code as a console application, and try it in both conhost and Windows Terminal. (Move the mouse over the window.)

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

int main(void)
{
    /* Get handles for stdin and stdout */
    HANDLE stdinH = GetStdHandle( STD_INPUT_HANDLE );
    HANDLE stdoutH = GetStdHandle( STD_OUTPUT_HANDLE );
    if (!stdinH || !stdoutH
     || (stdinH == INVALID_HANDLE_VALUE )
     || (stdoutH == INVALID_HANDLE_VALUE ))
    {
        return 1;
    }
    
    /* Set console output mode */
    DWORD outMode;
    if (!GetConsoleMode(stdoutH, &outMode))
    {
        return 2;
    }
    DWORD newMode = outMode;
    newMode |= ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
    newMode &= ~ENABLE_WRAP_AT_EOL_OUTPUT;
    newMode &= ~DISABLE_NEWLINE_AUTO_RETURN;
    newMode &= ~ENABLE_LVB_GRID_WORLDWIDE;
    if (!SetConsoleMode(stdoutH, newMode))
    {
        return 3;
    }
    
    /* Set console input mode */
    DWORD inMode;
    if (!GetConsoleMode(stdinH, &inMode))
    {
        SetConsoleMode(stdoutH, outMode);
        return 4;
    }
    newMode = inMode;
    newMode &= ~ENABLE_ECHO_INPUT;
    newMode &= ~ENABLE_INSERT_MODE;
    newMode &= ~ENABLE_LINE_INPUT;
    newMode |= ENABLE_MOUSE_INPUT;
    newMode &= ~ENABLE_PROCESSED_INPUT;
    newMode &= ~ENABLE_QUICK_EDIT_MODE;
    newMode |= ENABLE_EXTENDED_FLAGS;  /* Needed when changing _QUICK_EDIT_MODE */
    newMode |= ENABLE_WINDOW_INPUT;
    newMode |= ENABLE_VIRTUAL_TERMINAL_INPUT;
    //newMode &= ~ENABLE_VIRTUAL_TERMINAL_INPUT;
    if (!SetConsoleMode(stdinH, newMode))
    {
        SetConsoleMode(stdoutH, outMode);
        return 5;
    }
    
    /* Enable keypad application mode */
    printf("\x1b=");
    
    while (1)
    {
        DWORD numRead;
        INPUT_RECORD rec;
        BOOL successB = ReadConsoleInput( stdinH, &rec, 1, &numRead );
        if ( !successB || (numRead != 1) )
        {
            break;
        }
        
        if (rec.EventType == KEY_EVENT)
        {
            char c = rec.Event.KeyEvent.uChar.AsciiChar;
            printf(" KEY %s ", rec.Event.KeyEvent.bKeyDown ? "down" : "up  ");
            if (isprint(c))
            {
                printf("'%c'\n", c);
            }
            else
            {
                printf("\\x%02x'\n", (int)c);
            }
            
            /* Exit when X pressed */
            if ((c == 'x') || (c == 'X'))
            {
                break;
            }
        }
        else if (rec.EventType == MOUSE_EVENT)
        {
            printf(" MOUSE dwMousePosition=%d,%d  dwButtonState=0x%08x  dwControlKeyState=0x%08x  dwEventFlags=0x%08x\n",
                    (int)rec.Event.MouseEvent.dwMousePosition.X, 
                    (int)rec.Event.MouseEvent.dwMousePosition.Y,
                    (int)rec.Event.MouseEvent.dwButtonState,
                    (int)rec.Event.MouseEvent.dwControlKeyState,
                    (int)rec.Event.MouseEvent.dwEventFlags );
        }
    }
    
    /* Clean up */
    SetConsoleMode(stdoutH, outMode);
    SetConsoleMode(stdinH, inMode);

    return 0;
}

Expected Behavior

The same behaviour in both conhost and Windows Terminal.

Actual Behavior

In Windows Terminal, I receive mouse input only as virtual terminal input sequences. In conhost, I receive mouse input only as MOUSE_EVENT INPUT_RECORDs.

My guess is this is an intentional difference rather than a bug, but I wanted to ask some questions. I would like my program to work the same whether run in Windows Terminal or conhost. I would like to enable ENABLE_VIRTUAL_TERMINAL_INPUT to get VT sequences for key presses at least. Here are my questions:

  1. Is it possible to get the same mouse input behaviour (either VT sequences or input records) in both conhost and Windows Terminal, with ENABLE_VIRTUAL_TERMINAL_INPUT enabled? If so how? (Maybe a setting for Windows Terminal that I couldn't find?)
  2. Where can I find documentation of the mouse input VT sequences?

Thanks

Originally created by @clinton-r on GitHub (May 5, 2023). ### Windows Terminal version 1.16.10261.0 ### Windows build number Microsoft Windows [Version 10.0.19045.2846] ### Other Software _No response_ ### Steps to reproduce Compile this C code as a console application, and try it in both conhost and Windows Terminal. (Move the mouse over the window.) ``` #include <stdio.h> #include <windows.h> #include <ctype.h> int main(void) { /* Get handles for stdin and stdout */ HANDLE stdinH = GetStdHandle( STD_INPUT_HANDLE ); HANDLE stdoutH = GetStdHandle( STD_OUTPUT_HANDLE ); if (!stdinH || !stdoutH || (stdinH == INVALID_HANDLE_VALUE ) || (stdoutH == INVALID_HANDLE_VALUE )) { return 1; } /* Set console output mode */ DWORD outMode; if (!GetConsoleMode(stdoutH, &outMode)) { return 2; } DWORD newMode = outMode; newMode |= ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING; newMode &= ~ENABLE_WRAP_AT_EOL_OUTPUT; newMode &= ~DISABLE_NEWLINE_AUTO_RETURN; newMode &= ~ENABLE_LVB_GRID_WORLDWIDE; if (!SetConsoleMode(stdoutH, newMode)) { return 3; } /* Set console input mode */ DWORD inMode; if (!GetConsoleMode(stdinH, &inMode)) { SetConsoleMode(stdoutH, outMode); return 4; } newMode = inMode; newMode &= ~ENABLE_ECHO_INPUT; newMode &= ~ENABLE_INSERT_MODE; newMode &= ~ENABLE_LINE_INPUT; newMode |= ENABLE_MOUSE_INPUT; newMode &= ~ENABLE_PROCESSED_INPUT; newMode &= ~ENABLE_QUICK_EDIT_MODE; newMode |= ENABLE_EXTENDED_FLAGS; /* Needed when changing _QUICK_EDIT_MODE */ newMode |= ENABLE_WINDOW_INPUT; newMode |= ENABLE_VIRTUAL_TERMINAL_INPUT; //newMode &= ~ENABLE_VIRTUAL_TERMINAL_INPUT; if (!SetConsoleMode(stdinH, newMode)) { SetConsoleMode(stdoutH, outMode); return 5; } /* Enable keypad application mode */ printf("\x1b="); while (1) { DWORD numRead; INPUT_RECORD rec; BOOL successB = ReadConsoleInput( stdinH, &rec, 1, &numRead ); if ( !successB || (numRead != 1) ) { break; } if (rec.EventType == KEY_EVENT) { char c = rec.Event.KeyEvent.uChar.AsciiChar; printf(" KEY %s ", rec.Event.KeyEvent.bKeyDown ? "down" : "up "); if (isprint(c)) { printf("'%c'\n", c); } else { printf("\\x%02x'\n", (int)c); } /* Exit when X pressed */ if ((c == 'x') || (c == 'X')) { break; } } else if (rec.EventType == MOUSE_EVENT) { printf(" MOUSE dwMousePosition=%d,%d dwButtonState=0x%08x dwControlKeyState=0x%08x dwEventFlags=0x%08x\n", (int)rec.Event.MouseEvent.dwMousePosition.X, (int)rec.Event.MouseEvent.dwMousePosition.Y, (int)rec.Event.MouseEvent.dwButtonState, (int)rec.Event.MouseEvent.dwControlKeyState, (int)rec.Event.MouseEvent.dwEventFlags ); } } /* Clean up */ SetConsoleMode(stdoutH, outMode); SetConsoleMode(stdinH, inMode); return 0; } ``` ### Expected Behavior The same behaviour in both conhost and Windows Terminal. ### Actual Behavior In Windows Terminal, I receive mouse input only as virtual terminal input sequences. In conhost, I receive mouse input only as MOUSE_EVENT INPUT_RECORDs. My guess is this is an intentional difference rather than a bug, but I wanted to ask some questions. I would like my program to work the same whether run in Windows Terminal or conhost. I would like to enable ENABLE_VIRTUAL_TERMINAL_INPUT to get VT sequences for key presses at least. Here are my questions: 1. Is it possible to get the same mouse input behaviour (either VT sequences or input records) in both conhost and Windows Terminal, with ENABLE_VIRTUAL_TERMINAL_INPUT enabled? If so how? (Maybe a setting for Windows Terminal that I couldn't find?) 2. Where can I find documentation of the mouse input VT sequences? Thanks
claunia added the Issue-BugArea-InputProduct-Conpty labels 2026-01-31 06:54:26 +00:00
Author
Owner

@237dmitry commented on GitHub (May 5, 2023):

In conhost, I receive mouse input only as MOUSE_EVENT INPUT_RECORDs.

Is VT support enabled in conhost?

Set-ItemProperty -Path HKCU:\Console -Name VirtualTerminalLevel -Type dword -Value 1
@237dmitry commented on GitHub (May 5, 2023): > In conhost, I receive mouse input only as MOUSE_EVENT INPUT_RECORDs. Is VT support enabled in conhost? ``` Set-ItemProperty -Path HKCU:\Console -Name VirtualTerminalLevel -Type dword -Value 1 ```
Author
Owner

@o-sdn-o commented on GitHub (May 5, 2023):

I would like my program to work the same whether run in Windows Terminal or conhost.

I am also concerned about this issue. Possibly due to backwards compatibility limitations, the only option on Windows is to rely solely on the Win32 Console API (ReadConsoleInput) to handle input events, excluding VT processing on input. This is the only way to get uniform behavior. This also applies to window/buffer size reports. I would be happy to be wrong.

@o-sdn-o commented on GitHub (May 5, 2023): > I would like my program to work the same whether run in Windows Terminal or conhost. I am also concerned about this issue. Possibly due to backwards compatibility limitations, the only option on Windows is to rely solely on the Win32 Console API (ReadConsoleInput) to handle input events, excluding VT processing on input. This is the only way to get uniform behavior. This also applies to window/buffer size reports. I would be happy to be wrong.
Author
Owner

@clinton-r commented on GitHub (May 5, 2023):

In conhost, I receive mouse input only as MOUSE_EVENT INPUT_RECORDs.

Is VT support enabled in conhost?

Set-ItemProperty -Path HKCU:\Console -Name VirtualTerminalLevel -Type dword -Value 1

It wasn't set, so I just tried it - unfortunately it made no difference. (I think SetConsoleMode() is supposed to override that setting anyway.) Thanks.

@clinton-r commented on GitHub (May 5, 2023): > > In conhost, I receive mouse input only as MOUSE_EVENT INPUT_RECORDs. > > Is VT support enabled in conhost? > > ``` > Set-ItemProperty -Path HKCU:\Console -Name VirtualTerminalLevel -Type dword -Value 1 > ``` It wasn't set, so I just tried it - unfortunately it made no difference. (I think SetConsoleMode() is supposed to override that setting anyway.) Thanks.
Author
Owner

@PankajBhojwani commented on GitHub (May 10, 2023):

Thank you for filing this! Yep, this is a bug on our end (specifically with conpty), introduced in #9970 (though the issue is because of a combination of that and #4856).

@PankajBhojwani commented on GitHub (May 10, 2023): Thank you for filing this! Yep, this is a bug on our end (specifically with conpty), introduced in #9970 (though the issue is because of a combination of that and #4856).
Author
Owner

@yg-i commented on GitHub (May 26, 2024):

I'm not sure if this is related, but I have a transparent Webview2 window overlaid on top of all other windows. When I click in the transparent areas, my mouse clicks fall through to the window beneath (desired, expected behavior) in every single app (including conhost) except Windows Terminal. When Windows Terminal is beneath this transparent overlay, mouse clicking or dragging to select text etc doesn't work at all.

Clicking in the tab bar doesn't work either, but right click for some reason works for bringing up the context menu. Notably, hovering over the '+' button (for opening a new tab) does not produce the default visual feedback.

I've attached a .mp4 screen recording to demonstrate the issue:
https://github.com/microsoft/terminal/assets/148152939/18476dec-6e5d-4606-9536-1351c41d66c1

When I close or move away that transparent overlay, Windows Terminal once again responds to mouse.

Windows Terminal version: 1.19.10821.0

@yg-i commented on GitHub (May 26, 2024): I'm not sure if this is related, but I have a transparent Webview2 window overlaid on top of all other windows. When I click in the transparent areas, my mouse clicks fall through to the window beneath (desired, expected behavior) **in every single app (including conhost) except Windows Terminal**. When Windows Terminal is beneath this transparent overlay, mouse clicking or dragging to select text etc doesn't work at all. Clicking in the tab bar doesn't work either, but right click for some reason works for bringing up the context menu. Notably, hovering over the '+' button (for opening a new tab) does not produce the default visual feedback. I've attached a .mp4 screen recording to demonstrate the issue: https://github.com/microsoft/terminal/assets/148152939/18476dec-6e5d-4606-9536-1351c41d66c1 When I close or move away that transparent overlay, Windows Terminal once again responds to mouse. Windows Terminal version: 1.19.10821.0
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#19818