Repository: microsoft/terminal
File: src/terminal/parser/InputStateMachineEngine.cpp (C++)

Code before:
    //   MMM - Control, Alt, Shift state (respectively)
    //   D - flag signifying a drag event

    // This retrieves the 2 MSBs and concatenates them to the 2 LSBs to create BBBB in binary
    // This represents which button had a change in state
    const auto buttonID = (sgrEncoding & 0x3) | ((sgrEncoding & 0xC0) >> 4);
    const auto currentTime = std::chrono::steady_clock::now();
    // Step 1: Translate which button was affected
    // NOTE: if scrolled, having buttonFlag = 0 means
    //       we don't actually update the buttonState
    DWORD buttonFlag = 0;
    switch (buttonID)
    {
    case CsiMouseButtonCodes::Left:
        buttonFlag = FROM_LEFT_1ST_BUTTON_PRESSED;
        // If this is a mouse down, check if it's a double click
        // and also update our last clicked position and time
        if (id == CsiActionCodes::MouseDown)
        {
            if (_lastMouseClickPos && _lastMouseClickTime &&
                til::point(uiPos) == _lastMouseClickPos &&
                (std::chrono::steady_clock::time_point() - _lastMouseClickTime.value()) < _doubleClickTime)
            {
                eventFlags |= DOUBLE_CLICK;
            }
            _lastMouseClickPos = uiPos;
            _lastMouseClickTime = currentTime;
        }
        break;
    case CsiMouseButtonCodes::Right:
        buttonFlag = RIGHTMOST_BUTTON_PRESSED;
        break;
    case CsiMouseButtonCodes::Middle:
        buttonFlag = FROM_LEFT_2ND_BUTTON_PRESSED;
        break;
    case CsiMouseButtonCodes::ScrollBack:
    {
        // set high word to proper scroll direction
        // scroll intensity is assumed to be constant value
        buttonState |= SCROLL_DELTA_BACKWARD;
        eventFlags |= MOUSE_WHEELED;
        break;
    }
    case CsiMouseButtonCodes::ScrollForward:
    {
        // set high word to proper scroll direction
        // scroll intensity is assumed to be constant value
        buttonState |= SCROLL_DELTA_FORWARD;
        eventFlags |= MOUSE_WHEELED;
        break;
    }

Review comment (suggestion):
I think that if there’s a double click, we should reset the time to blank. This way, three clicks doesn’t turn into “single double double”.

Code after:
    //   MMM - Control, Alt, Shift state (respectively)
    //   D - flag signifying a drag event

    // This retrieves the 2 MSBs and concatenates them to the 2 LSBs to create BBBB in binary
    // This represents which button had a change in state
    const auto buttonID = (sgrEncoding & 0x3) | ((sgrEncoding & 0xC0) >> 4);
    const auto currentTime = std::chrono::steady_clock::now();
    // Step 1: Translate which button was affected
    // NOTE: if scrolled, having buttonFlag = 0 means
    //       we don't actually update the buttonState
    DWORD buttonFlag = 0;
    switch (buttonID)
    {
    case CsiMouseButtonCodes::Left:
        buttonFlag = FROM_LEFT_1ST_BUTTON_PRESSED;
        break;
    case CsiMouseButtonCodes::Right:
        buttonFlag = RIGHTMOST_BUTTON_PRESSED;
        break;
    case CsiMouseButtonCodes::Middle:
        buttonFlag = FROM_LEFT_2ND_BUTTON_PRESSED;
        break;
    case CsiMouseButtonCodes::ScrollBack:
    {
        // set high word to proper scroll direction
        // scroll intensity is assumed to be constant value
        buttonState |= SCROLL_DELTA_BACKWARD;
        eventFlags |= MOUSE_WHEELED;
        break;
    }
    case CsiMouseButtonCodes::ScrollForward:
    {
        // set high word to proper scroll direction
        // scroll intensity is assumed to be constant value
        buttonState |= SCROLL_DELTA_FORWARD;
        eventFlags |= MOUSE_WHEELED;
        break;
    }
    case CsiMouseButtonCodes::Released:
        // hover event, we still want to send these but we don't
        // need to do anything special here, so just break
        break;
    default:
        // no detectable buttonID, so we can't update the state
        return false;
    }

    // Step 2: Decide whether to set or clear that button's bit
    // NOTE: WI_SetFlag/WI_ClearFlag can't be used here because buttonFlag would have to be a compile-time constant
    switch (id)
    {