
Like many other canvas applications, tldraw uses modifiers to control the way that dragging interactions work. Shift will constrain the drag along the horizontal or vertical axis. Alt/option will create duplicates of the selected shapes. Ctrl/command will snap the shapes to other shapes on the canvas. And a point of pride for us: the modifier effect can be added or removed at any time during the interaction by pressing or releasing the modifier.
When we first implemented this feature, we noticed a problem: sometimes, when completing a modifier + drag interaction, the modifier's effect would be cancelled at the last moment.
We finally tracked it down to a common programming problem, a race condition, but not the type that we were used to. Rather than two software operations that might occur out of order, this was a physical race condition based on the imprecision of our bodies.
What was happening is this: at the end of the interaction, the user would release both the modifier key and the click at the "same time", but because the events were necessarily ordered, the keyup for the modifier would sometimes arrive first and cancel the effect before the mouseup ended the interaction.
In order to safely complete the interaction, a user would have to carefully release the click before releasing the modifier.
Release timeout
To prevent this, we add a delay for each modifier so that it is marked as released only after a delay:
The delay needed to be long enough to catch the gap between key-up and mouse-up, but short enough that it wouldn't feel sticky or slow. We went with 150ms. For the physical race condition, this delay was generous window for both events, the keyup and the mouseup, to occur in the user's experience of simultaneity. And if a finger had slipped off of a modifier key, it gave plenty of time to re-press that key without losing the effect.
After 150ms, we clear the effect and dispatch the key_up event synthetically:
Beyond modifiers
We use deferred commitment patterns in other parts of the codebase too. tldraw's click state machine uses timeouts to detect double and triple clicks, waiting to see if another click arrives before committing to a "single click"—and on mobile devices, pinch gesture detection waits before deciding whether a two-finger touch is a pinch or a multi-select.
If you've never noticed this delay before, good! It's one more little detail in tldraw that cheats reality to make the application feel better than in should. If you want to try the experience for yourself, give it a go on tldraw.com.