microsoft/Terminal

Spurious double clicks

オープン

#14,474 opened on 2022/12/01

 (1 件のコメント) (0 件のリアクション) (0 人の担当者)C++ (9,275 件のフォーク)batch import
Area-InputHelp WantedIssue-BugPriority-2Product-Conpty

Repository metrics

Stars
 (103,173 個のスター)
PR merge metrics
 (PR metrics pending)

説明

Windows Terminal version

Current main

Windows build number

10.0.19044.2251

Other Software

Any win32 console app with mouse support, e.g. Far Manager

Steps to reproduce

Single-clicking intensively in different places in any console application with mouse support running in the Windows Terminal.

Code for repro

#include <iostream>
#include "windows.h"

int main()
{
    auto reply = INPUT_RECORD{};
    auto count = DWORD{};
    auto input = ::GetStdHandle(STD_INPUT_HANDLE);
    ::SetConsoleMode(input, ENABLE_EXTENDED_FLAGS | ENABLE_MOUSE_INPUT);
    while (::ReadConsoleInputW(input, &reply, 1, &count) && count)
    {
        if (reply.EventType == MOUSE_EVENT
         && reply.Event.MouseEvent.dwEventFlags & DOUBLE_CLICK)
        {
            std::cout << "DOUBLE_CLICK\n";
        }
        else if (reply.EventType == KEY_EVENT
              && reply.Event.KeyEvent.wVirtualKeyCode == 27)
        {
            break;
        }
    }
}

Expected Behavior

No spurious double clicks.

Actual Behavior

Spurious double clicks are triggered randomly

https://user-images.githubusercontent.com/11535558/205082756-30e04223-fb40-407b-8766-fc74c8893674.mp4

Apparently this is due to the SGR mouse tracking protocol misinterpretation. Mouse drag is interpreted as a single click and its last position is remembered as with a normal click, and when the button is released, a false double click occurs:

https://github.com/microsoft/terminal/blob/52cc523ed292a916f28cbd75f6c165285942e21c/src/terminal/parser/InputStateMachineEngine.cpp#L843-L971

Everything works as expected If dragging is silently ignored (see possible fix below).

Possible fix: terminal\src\terminal\parser\InputStateMachineEngine.cpp:873:

const auto buttonID = (sgrEncoding & 0x3) | ((sgrEncoding & 0xC0) >> 4) | ((sgrEncoding & 0x20) >> 5) * 3;

コントリビューターガイド