microsoft/Terminal

Spurious double clicks

Open

#14,474 创建于 2022年12月1日

在 GitHub 查看
 (1 评论) (0 反应) (0 负责人)C++ (3,212 fork)batch import
Area-InputHelp WantedIssue-BugPriority-2Product-Conpty

仓库指标

Star
 (35,764 star)
PR 合并指标
 (平均合并 27天 19小时) (30 天内合并 24 个 PR)

描述

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;

贡献者指南