Donner 0.8.0-pre
Embeddable browser-grade SVG2 engine
Loading...
Searching...
No Matches
DragCoalesce.h File Reference

Drag coalesce policy: decides whether the editor should forward the current mouse position to the backend as a kMove pointer event, or drop it and wait for the in-flight response. More...

#include <optional>
#include <type_traits>
Include dependency graph for DragCoalesce.h:

Namespaces

namespace  donner
 Top-level Donner namespace, which is split into different sub-namespaces such as donner::svg and donner::css.

Functions

template<typename Vec>
bool donner::editor::ShouldPostDragMove (const Vec &screenPoint, const std::optional< Vec > &lastPostedScreenPoint, bool pendingFrameInFlight)
 Coalesce decision. Templated on the cursor type so the same helper works against donner::Vector2d, ImVec2, or any other 2D vector that exposes x / y and supports (a - b).lengthSquared() — either as a member or via a free function.

Variables

constexpr double donner::editor::kDragMoveScreenEpsilonPx = 0.25
 Cursor must move by more than this many CSS pixels (in screen space) before another kMove is posted. Picked to be smaller than 1 px so retina-display sub-pixel deltas still propagate, but big enough that OS jitter while the user holds the mouse still is filtered.

Detailed Description

Drag coalesce policy: decides whether the editor should forward the current mouse position to the backend as a kMove pointer event, or drop it and wait for the in-flight response.

Two filters compose:

  1. Backend cadence gate — if a previous kMove future is still in flight, suppress new posts. Otherwise the host overwrites pendingFrame every ImGui frame and discards every promise's future except the latest, so the user sees no preview updates until the backend's FIFO drains. Symptom: drag freezes mid- stroke and snaps to the release position. Reproduces under the session-backed client when a single round-trip is slower than one ImGui frame (e.g. Geode + IPC, ~30–60 ms on macOS).
  2. Sub-pixel jitter gate — if the cursor hasn't moved by more than kDragMoveScreenEpsilonPx, skip the post. Saves a backend round-trip on no-op moves the OS reports while the user holds the mouse still.

Both gates must pass for ShouldPostDragMove to return true.

Do not use async-renderer busy state as pendingFrameInFlight for local editor drags. Local drag previews are UI-thread state and must keep updating while the renderer is busy; queued DOM writes coalesce separately.