Immediate-Mode-UI / Immediate-Mode-UI/Nuklear

Inconsistent grabbing behavior in demos (click and drag property)

Open
#608 8 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
11.4k
Forks
686
Avg merge
4d 1h
Merged PRs (30d)
3

Description

There seems to be an issue with the implementation of grabbing behavior across several demos, particularly when this behavior is combined with relative movement (dragging an input value).

The problem primarily arises due to how the grab state (`nk_context` `input.mouse.grab/ungrab`) is always reset, even if no event happens, leading to grab/ungrab potentially being missed in event handling, especially noticeable with frameworks like SDL.

#### Issue Details

The issue occurs with the following sequence of events:
1. **Main Loop, Cycle 1:** A mouse down event is registered, invoking `nk_input_button` which in turn causes `nk_property_*` to set the grab state to `1` (`nk_true`) later in main loop.
2. **Main Loop, Cycle 2:** No new event is registered (mouse remains pressed), causing the event loop to be skipped, then `nk_input_end` is called, which resets the grab state to `0` without being handled.

Similarly, The same problem happens with the ungrab state

#### Impact Details
- This is a problem for frameworks that do not automatically generate an event following a mouse down/up action. For instance, the SDL implementation requires two consecutive events for proper grabbing behavior. A scenario where the mouse is pressed down and then moved with more than 1 cycle in-between fails to maintain the grab/ungrab state, unlike when multiple events happen, such as a mouse move together with mouse down event.

- Its an even bigger problem when a grab event gets handled, but the ungrab event doesn't, causing the mouse cursor to disappear permanently and staying in relative mode with the SDL demos

#### Solution
I wouldn't mind providing a pull request, but i'm not sure about the ideal way to implement the solution,
maybe someone more familiar with the framework might be able to suggest a more integrated solution than mine?

**EDIT:**
see better solution in https://github.com/Immediate-Mode-UI/Nuklear/issues/608#issuecomment-1933193129

Old solution

A simple way of solving it would be something like the following:
```
bool grab_handled = false;
while (running) {
/* Input */
SDL_Event evt;
nk_input_begin(ctx);
while (SDL_PollEvent(&evt)) {
if (evt.type == SDL_QUIT)
goto cleanup;
nk_sdl_handle_event(&evt);
grab_handled = true;
}

if (grab_handled) {
nk_input_end(ctx);
grab_handled = false;
}
...
```
This approach only resets grab / ungrab when its been handled.

I believe the following issues are related:
These two has @vurtun mentioning that here is a problem:
https://github.com/vurtun/nuklear/issues/203
https://github.com/vurtun/nuklear/issues/631

https://github.com/Immediate-Mode-UI/Nuklear/issues/556
https://github.com/Immediate-Mode-UI/Nuklear/issues/512

Contributor guide

Open the contributing guide

Research direction

Start by tracing nk_input_button, nk_property_* and nk_input_end through the SDL demos, focusing on how grab and ungrab state is reset when no event is received. Reproduce the mouse-down, idle-cycle, move, and mouse-up sequence described in the issue. Done means grab and ungrab transitions are not lost and SDL demos leave relative mouse mode reliably.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.