Name every silent input rejection with WebSurfaceInputOutcome
bool returns on the five record_* surface inputs collapsed nine real outcomes into one bit. The cascade we found in this round — silent click drop because viewport_bounds wasn't measured yet, then keyboard_focus stays None, then typing also "fails" — looked like three independent symptoms but was one root cause hiding inside that bit. Replace the bool with a #[must_use] WebSurfaceInputOutcome enum so each rejection names itself at the call site. Variants map 1:1 to real return points in web_surface.rs: Applied / NoChange / Buffered — three distinct success-ish states the controller already needed to disambiguate (only Applied notifies) DroppedInvalidBounds — geometry rejected zero/NaN viewport DroppedNoViewportBounds — input arrived before the viewport tracker DroppedOutOfBounds — window position outside the viewport rect DroppedZeroDelta — wheel rounded to zero device px DroppedEmptyText — empty record_typed_text DroppedNoKeyboardFocus — type without a prior click DroppedFocusMismatch — focus belongs to another tab/url Behavior preserved: Applied is the only notify trigger, matching the old `true` semantics. Three new negative-path tests (no_viewport_bounds, zero_delta, no_keyboard_focus) lock the named drops so a future regression surfaces as a wrong variant in tests instead of a missing repaint. cargo test ely_app --bin ely_app web_surface: 17 passed.
This commit is contained in:
@@ -50,6 +50,46 @@ pub(super) struct WebSurfacePendingInput {
|
||||
pub(super) typed_text: Option<String>,
|
||||
}
|
||||
|
||||
/// Outcome of a `WebSurfaceStore::record_*` call.
|
||||
///
|
||||
/// Replaces the previous `-> bool` return so silent rejections name
|
||||
/// themselves at the call site. Callers only branch on `Applied`
|
||||
/// (every other variant means "do nothing, don't notify"), but each
|
||||
/// `Dropped*` / non-`Applied` variant pins down *why* a coordinate
|
||||
/// or keystroke never reached the runtime — so the next regression
|
||||
/// shows up as a specific variant in tests instead of a missing
|
||||
/// repaint. `#[must_use]` keeps a future caller from dropping the
|
||||
/// outcome on the floor and reintroducing the silent-fail pattern.
|
||||
#[must_use]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub(super) enum WebSurfaceInputOutcome {
|
||||
/// State changed and the renderer should re-notify.
|
||||
Applied,
|
||||
/// Same value as currently recorded — nothing to flush downstream.
|
||||
NoChange,
|
||||
/// First sighting of a new value; held back until a second
|
||||
/// matching measurement confirms it (viewport-resize debounce).
|
||||
Buffered,
|
||||
/// Geometry constructor rejected the input (zero/NaN/negative
|
||||
/// bounds). The viewport never measured cleanly.
|
||||
DroppedInvalidBounds,
|
||||
/// Viewport bounds have not been recorded yet, so window-relative
|
||||
/// coordinates can't be translated into the page coordinate space.
|
||||
DroppedNoViewportBounds,
|
||||
/// Window position falls outside the viewport rect after scaling.
|
||||
DroppedOutOfBounds,
|
||||
/// Wheel delta rounded to zero device pixels in both axes.
|
||||
DroppedZeroDelta,
|
||||
/// Empty string passed to `record_typed_text` — nothing to buffer.
|
||||
DroppedEmptyText,
|
||||
/// `record_typed_text` ran before any click established
|
||||
/// keyboard focus on this surface.
|
||||
DroppedNoKeyboardFocus,
|
||||
/// Keyboard focus belongs to a different tab or the URL drifted
|
||||
/// (redirect / trailing-slash mismatch) since the focusing click.
|
||||
DroppedFocusMismatch,
|
||||
}
|
||||
|
||||
pub(super) enum WebSurfaceState {
|
||||
Loading { requested_url: String, previous_frame: Option<WebSurfaceFrame> },
|
||||
Ready(WebSurfaceFrame),
|
||||
|
||||
Reference in New Issue
Block a user