How does Unity GUI's Event.Repaint works?

I am trying to do a practice with a unity’s blog. It creates a custom GUI button which will flash red if I holding it down for longger than 2 seconds. But when I trying to follow the code in the article, I find when I hold the button down, the event.repaint would not be called, and the button would not flash red. Only when I move the mouse in and out the button area, the event.repaint will be called few times. Here is part of main code:

private void OnGUI()
    {
        bool clicked = FlashingButton(buttonRect, new GUIContent("FlashingButton"), EditorStyles.miniButton);
    }

    public bool FlashingButton(Rect rc, GUIContent content, GUIStyle style)
    {
        int controlID = GUIUtility.GetControlID(FocusType.Passive);

        var state = (FlashingButtonInfo)GUIUtility.GetStateObject(typeof(FlashingButtonInfo), controlID);
        switch (Event.current.GetTypeForControl(controlID))
        {
            case EventType.Repaint:
                Debug.Log("repaint");
                GUI.color = state.IsFlashing(controlID) ? Color.red : Color.white;
                style.Draw(rc, content, controlID);
                break;
            case EventType.MouseDown:
                Debug.Log("mouse down");
                if(rc.Contains(Event.current.mousePosition)
                    && Event.current.button == 0
                    && GUIUtility.hotControl == 0)
                {
                    GUIUtility.hotControl = controlID;
                    state.MouseDownNow();
                }
                break;
            case EventType.MouseUp:
                if(GUIUtility.hotControl == controlID)
                {
                    GUIUtility.hotControl = 0;
                }
                break;
        }
        return GUIUtility.hotControl == controlID;
    }

And the FlashingButtonInfo Class:

public class FlashingButtonInfo
{
    private double mouseDownAt;

    public void MouseDownNow()
    {
        mouseDownAt = EditorApplication.timeSinceStartup;
    }

    public bool IsFlashing(int controlID)
    {
        if (GUIUtility.hotControl != controlID)
            return false;

        double elapsedTime = EditorApplication.timeSinceStartup - mouseDownAt;
        if (elapsedTime < 2.0f)
            return false;

        return (int)((elapsedTime - 2f) / 0.1f) % 2 == 0;
    }
}

This article is six years old, and is using an UI toolkit that is currently only used within unity editor extensions.

Try using uGUI button instead.
https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/script-Button.html

Yes, do not use OnGUI and all that mess unless you are working on editor code. It’s confusing as hell and almost impossible to understand the deeper workings.