Skip to content

Adjust click event threshold for XR Device ray interaction from 1px to 5px #100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions docs/manual/references/runtime-configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,32 @@ Then you can view the graphics debugging logs in `TR_GLES` channel as well:
```

> This option is only available in the OpenGLES backend and requires the support of the `KHR_debug` extension in the device.

### Configure click distance threshold

## Click Distance Threshold

The click distance threshold determines the maximum distance between `mousedown` and `mouseup` hit points for triggering click events, as defined in the [Web UI Events specification](https://www.w3.org/TR/uievents/). This threshold helps distinguish between click and drag gestures by measuring the spatial proximity of pointer events.

When a user interaction begins with a `selectStart` event and ends with a `selectEnd` event, a `click` event is only generated if:
1. Both events target the same element
2. The distance between hit points is less than the configured threshold

### Configuration

To configure the click distance threshold:

```sh
adb shell setprop jsar.events.click_distance_threshold 5
```

The default value is 5 pixels, which provides good tolerance for pointer device jitter while maintaining distinction between click and drag gestures.

- **Smaller values** (1-3): More precise click detection, may be harder to trigger clicks with pointing devices
- **Larger values** (5-10): More tolerant of device jitter, easier to trigger clicks but may register drags as clicks

You can also set this via environment variable:

```sh
export JSAR_CLICK_DISTANCE_THRESHOLD=5
```
42 changes: 41 additions & 1 deletion src/client/dom/document_event_dispatcher.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <cstdlib>
#include <cstring>
#include <client/builtin_scene/ecs-inl.hpp>
#include <client/dom/element.hpp>
#include <client/html/html_element.hpp>
Expand All @@ -6,11 +8,49 @@

#include "./document_event_dispatcher.hpp"

#if defined(__ANDROID__) && (__ANDROID_API__ >= 26)
#include <sys/system_properties.h>
#endif

namespace dom
{
using namespace std;
using namespace std::placeholders;

float DocumentEventDispatcher::GetClickDistanceThreshold()
{
// Default threshold: 5 pixels
float defaultThresholdPixels = 5.0f;

#if defined(__ANDROID__) && (__ANDROID_API__ >= 26)
char thresholdStr[PROP_VALUE_MAX];
if (__system_property_get("jsar.events.click_distance_threshold", thresholdStr) >= 0)
{
char *endptr;
float threshold = strtof(thresholdStr, &endptr);
if (endptr != thresholdStr && threshold > 0)
{
return client_cssom::pixelToMeter(threshold);
}
}
#endif

// Check environment variable
const char *envThreshold = std::getenv("JSAR_CLICK_DISTANCE_THRESHOLD");
if (envThreshold != nullptr)
{
char *endptr;
float threshold = strtof(envThreshold, &endptr);
if (endptr != envThreshold && threshold > 0)
{
return client_cssom::pixelToMeter(threshold);
}
}

// Return default threshold
return client_cssom::pixelToMeter(defaultThresholdPixels);
}

DocumentEventDispatcher::DocumentEventDispatcher(HTMLDocument *document)
: document_(document)
{
Expand Down Expand Up @@ -63,7 +103,7 @@ namespace dom
// Criteria 1: same target
current_mousedown_target_.lock() == target &&
// Criteria 2: distance < threshold
glm::distance(current_mousedown_hit_point_, hitPoint) < click_distance_threshold_
glm::distance(current_mousedown_hit_point_, hitPoint) < Click_distance_threshold_
// TODO(yorkie): add criteria: time < 500ms?
)
target->simulateClick(hitPoint);
Expand Down
3 changes: 2 additions & 1 deletion src/client/dom/document_event_dispatcher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ namespace dom
glm::vec3 current_scroll_end_point_;
bool is_scroll_in_progress_ = false;

static inline float click_distance_threshold_ = client_cssom::pixelToMeter(1);
static float GetClickDistanceThreshold();
static inline float Click_distance_threshold_ = GetClickDistanceThreshold();
};
}