Skip to content

surface_input loses the PointerUp when a press that never became a drag is released outside the surface #3

Closed

Description

@Vanuan

Crate: gpui_interop 0.1.3 and 0.2.0 (src/input.rs).

The gateway reports an up outside the surface only when its own engine drag is in flight:

element = element.on_mouse_up_out(released_button, move |event, window, cx| {
    if drag(cx).is_none_or(|drag| drag.origin != own) {
        return;
    }
    // ...
});

(src/input.rs:322-325)

But the engine founds a drag only for a left press that moves past the threshold (bite-gp-authoring/src/elements/div.rs:2978-2980; DRAG_THRESHOLD = 2. at :52). Consequences:

  • right or middle press released off the surface → no PointerUp at all;
  • left press moved less than 2 px and released off the surface → no PointerUp either.

The producer's pressed state then never clears. The reference example and our viewport both keep a grab flag set on PointerDown and cleared on PointerUp (examples/interop_cube_drag.rs:280-298), so the next hover move is treated as a continuation of the drag — a stuck orbit in a 3D viewport.

Suggested fix: remember which surface owns the current press on the App (where SurfaceDrag already lives, because element-side state lives for one paint), and report the up when either "my drag is in flight" or "I own the press":

#[derive(Default)]
struct PressedSurface(Option<ElementId>);
impl Global for PressedSurface {}

set in on_any_mouse_down, cleared in capture_any_mouse_up and in the on_mouse_up_out handlers, and gate the latter on drag(cx).is_some_and(..) || pressed_origin(cx) == Some(&own).

(The separate engine limitation — on_drag only starting for the left button — is filed against bite-gpui; this one can be fixed inside the gateway.)

We carry this in a vendored copy; a right-drag released off-canvas no longer wedges the camera.

Status (0.2.0, 2026-11-03): unchanged — src/input.rs is byte-identical
between 0.1.3 and 0.2.0, and the patch described here still applies
unchanged.

Activity

  1. Vanuan commented on Nov 3, 2026

    @Vanuan
    ContributorAuthor

    Fixed in af0b93c (PR #6). The gateway records which surface owns the press and reports the up when either the engine drag or the press is its own, so right/middle presses and sub-threshold left presses released outside now deliver PointerUp. Covered by two new tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions