From e3b0f24626b4438445560c76e5ec6607c3cc2264 Mon Sep 17 00:00:00 2001 From: paccer Date: Sat, 10 Feb 2024 03:03:16 +0100 Subject: [PATCH 1/3] Fix missed grab state changes in SDL demos Move grab handling out of `nk_sdl_handle_event` to `nk_sdl_handle_grab`, which is now called outside of the event loop. This change makes the logic similar to the GLFW demos and fixes issues with missed grab state changes and mouse cursor disappearing. --- demo/sdl_opengl2/main.c | 1 + demo/sdl_opengl2/nuklear_sdl_gl2.h | 20 ++++++++++++-------- demo/sdl_opengl3/main.c | 4 +++- demo/sdl_opengl3/nuklear_sdl_gl3.h | 20 ++++++++++++-------- demo/sdl_opengles2/main.c | 1 + demo/sdl_opengles2/nuklear_sdl_gles2.h | 20 ++++++++++++-------- demo/sdl_renderer/main.c | 1 + demo/sdl_renderer/nuklear_sdl_renderer.h | 20 ++++++++++++-------- 8 files changed, 54 insertions(+), 33 deletions(-) diff --git a/demo/sdl_opengl2/main.c b/demo/sdl_opengl2/main.c index 45c51d2ea..438f2d34b 100644 --- a/demo/sdl_opengl2/main.c +++ b/demo/sdl_opengl2/main.c @@ -139,6 +139,7 @@ main(int argc, char *argv[]) if (evt.type == SDL_QUIT) goto cleanup; nk_sdl_handle_event(&evt); } + nk_sdl_handle_grab(); /* optional grabbing behavior */ nk_input_end(ctx); /* GUI */ diff --git a/demo/sdl_opengl2/nuklear_sdl_gl2.h b/demo/sdl_opengl2/nuklear_sdl_gl2.h index 819723c83..067962bc1 100644 --- a/demo/sdl_opengl2/nuklear_sdl_gl2.h +++ b/demo/sdl_opengl2/nuklear_sdl_gl2.h @@ -233,21 +233,25 @@ nk_sdl_font_stash_end(void) nk_style_set_font(&sdl.ctx, &sdl.atlas.default_font->handle); } -NK_API int -nk_sdl_handle_event(SDL_Event *evt) +NK_API void +nk_sdl_handle_grab(void) { struct nk_context *ctx = &sdl.ctx; - - /* optional grabbing behavior */ if (ctx->input.mouse.grab) { SDL_SetRelativeMouseMode(SDL_TRUE); - ctx->input.mouse.grab = 0; } else if (ctx->input.mouse.ungrab) { - int x = (int)ctx->input.mouse.prev.x, y = (int)ctx->input.mouse.prev.y; + SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); SDL_SetRelativeMouseMode(SDL_FALSE); - SDL_WarpMouseInWindow(sdl.win, x, y); - ctx->input.mouse.ungrab = 0; + } else if (ctx->input.mouse.grabbed) { + ctx->input.mouse.pos.x = ctx->input.mouse.prev.x; + ctx->input.mouse.pos.y = ctx->input.mouse.prev.y; } +} + +NK_API int +nk_sdl_handle_event(SDL_Event *evt) +{ + struct nk_context *ctx = &sdl.ctx; switch(evt->type) { diff --git a/demo/sdl_opengl3/main.c b/demo/sdl_opengl3/main.c index e039a2f71..44c8c740a 100644 --- a/demo/sdl_opengl3/main.c +++ b/demo/sdl_opengl3/main.c @@ -149,7 +149,9 @@ int main(int argc, char *argv[]) while (SDL_PollEvent(&evt)) { if (evt.type == SDL_QUIT) goto cleanup; nk_sdl_handle_event(&evt); - } nk_input_end(ctx); + } + nk_sdl_handle_grab(); /* optional grabbing behavior */ + nk_input_end(ctx); /* GUI */ if (nk_begin(ctx, "Demo", nk_rect(50, 50, 230, 250), diff --git a/demo/sdl_opengl3/nuklear_sdl_gl3.h b/demo/sdl_opengl3/nuklear_sdl_gl3.h index 4e7df6bb4..4b0500388 100644 --- a/demo/sdl_opengl3/nuklear_sdl_gl3.h +++ b/demo/sdl_opengl3/nuklear_sdl_gl3.h @@ -342,21 +342,25 @@ nk_sdl_font_stash_end(void) } -NK_API int -nk_sdl_handle_event(SDL_Event *evt) +NK_API void +nk_sdl_handle_grab(void) { struct nk_context *ctx = &sdl.ctx; - - /* optional grabbing behavior */ if (ctx->input.mouse.grab) { SDL_SetRelativeMouseMode(SDL_TRUE); - ctx->input.mouse.grab = 0; } else if (ctx->input.mouse.ungrab) { - int x = (int)ctx->input.mouse.prev.x, y = (int)ctx->input.mouse.prev.y; + SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); SDL_SetRelativeMouseMode(SDL_FALSE); - SDL_WarpMouseInWindow(sdl.win, x, y); - ctx->input.mouse.ungrab = 0; + } else if (ctx->input.mouse.grabbed) { + ctx->input.mouse.pos.x = ctx->input.mouse.prev.x; + ctx->input.mouse.pos.y = ctx->input.mouse.prev.y; } +} + +NK_API int +nk_sdl_handle_event(SDL_Event *evt) +{ + struct nk_context *ctx = &sdl.ctx; switch(evt->type) { diff --git a/demo/sdl_opengles2/main.c b/demo/sdl_opengles2/main.c index b114159f3..9ef90a709 100644 --- a/demo/sdl_opengles2/main.c +++ b/demo/sdl_opengles2/main.c @@ -92,6 +92,7 @@ MainLoop(void* loopArg){ if (evt.type == SDL_QUIT) running = nk_false; nk_sdl_handle_event(&evt); } + nk_sdl_handle_grab(); /* optional grabbing behavior */ nk_input_end(ctx); diff --git a/demo/sdl_opengles2/nuklear_sdl_gles2.h b/demo/sdl_opengles2/nuklear_sdl_gles2.h index 39a444dbd..4e97fbaa7 100644 --- a/demo/sdl_opengles2/nuklear_sdl_gles2.h +++ b/demo/sdl_opengles2/nuklear_sdl_gles2.h @@ -342,21 +342,25 @@ nk_sdl_font_stash_end(void) } -NK_API int -nk_sdl_handle_event(SDL_Event *evt) +NK_API void +nk_sdl_handle_grab(void) { struct nk_context *ctx = &sdl.ctx; - - /* optional grabbing behavior */ if (ctx->input.mouse.grab) { SDL_SetRelativeMouseMode(SDL_TRUE); - ctx->input.mouse.grab = 0; } else if (ctx->input.mouse.ungrab) { - int x = (int)ctx->input.mouse.prev.x, y = (int)ctx->input.mouse.prev.y; + SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); SDL_SetRelativeMouseMode(SDL_FALSE); - SDL_WarpMouseInWindow(sdl.win, x, y); - ctx->input.mouse.ungrab = 0; + } else if (ctx->input.mouse.grabbed) { + ctx->input.mouse.pos.x = ctx->input.mouse.prev.x; + ctx->input.mouse.pos.y = ctx->input.mouse.prev.y; } +} + +NK_API int +nk_sdl_handle_event(SDL_Event *evt) +{ + struct nk_context *ctx = &sdl.ctx; switch(evt->type) { diff --git a/demo/sdl_renderer/main.c b/demo/sdl_renderer/main.c index 940ea84c9..a4a0f28f3 100644 --- a/demo/sdl_renderer/main.c +++ b/demo/sdl_renderer/main.c @@ -177,6 +177,7 @@ main(int argc, char *argv[]) if (evt.type == SDL_QUIT) goto cleanup; nk_sdl_handle_event(&evt); } + nk_sdl_handle_grab(); /* optional grabbing behavior */ nk_input_end(ctx); /* GUI */ diff --git a/demo/sdl_renderer/nuklear_sdl_renderer.h b/demo/sdl_renderer/nuklear_sdl_renderer.h index fbea3cf64..e6dc24b07 100644 --- a/demo/sdl_renderer/nuklear_sdl_renderer.h +++ b/demo/sdl_renderer/nuklear_sdl_renderer.h @@ -264,21 +264,25 @@ nk_sdl_font_stash_end(void) nk_style_set_font(&sdl.ctx, &sdl.atlas.default_font->handle); } -NK_API int -nk_sdl_handle_event(SDL_Event *evt) +NK_API void +nk_sdl_handle_grab(void) { struct nk_context *ctx = &sdl.ctx; - - /* optional grabbing behavior */ if (ctx->input.mouse.grab) { SDL_SetRelativeMouseMode(SDL_TRUE); - ctx->input.mouse.grab = 0; } else if (ctx->input.mouse.ungrab) { - int x = (int)ctx->input.mouse.prev.x, y = (int)ctx->input.mouse.prev.y; + SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); SDL_SetRelativeMouseMode(SDL_FALSE); - SDL_WarpMouseInWindow(sdl.win, x, y); - ctx->input.mouse.ungrab = 0; + } else if (ctx->input.mouse.grabbed) { + ctx->input.mouse.pos.x = ctx->input.mouse.prev.x; + ctx->input.mouse.pos.y = ctx->input.mouse.prev.y; } +} + +NK_API int +nk_sdl_handle_event(SDL_Event *evt) +{ + struct nk_context *ctx = &sdl.ctx; switch(evt->type) { From a10eb1351acfe23cf93cfbf5b021f93ca57a4eee Mon Sep 17 00:00:00 2001 From: paccer Date: Sat, 10 Feb 2024 17:21:32 +0100 Subject: [PATCH 2/3] Fix cursor warping to center on older SDL versions Reverted the order of the SDL_WarpMouseInWindow and SDL_GetMouseState to its original sequence. This avoids cursor warping to the center of screen on older SDL versions It causes an additional SDL_MOUSEMOTION event when ungrabbing, but does not cause any issues. --- demo/sdl_opengl2/nuklear_sdl_gl2.h | 2 +- demo/sdl_opengl3/nuklear_sdl_gl3.h | 2 +- demo/sdl_opengles2/nuklear_sdl_gles2.h | 2 +- demo/sdl_renderer/nuklear_sdl_renderer.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/demo/sdl_opengl2/nuklear_sdl_gl2.h b/demo/sdl_opengl2/nuklear_sdl_gl2.h index 067962bc1..2a885b57f 100644 --- a/demo/sdl_opengl2/nuklear_sdl_gl2.h +++ b/demo/sdl_opengl2/nuklear_sdl_gl2.h @@ -240,8 +240,8 @@ nk_sdl_handle_grab(void) if (ctx->input.mouse.grab) { SDL_SetRelativeMouseMode(SDL_TRUE); } else if (ctx->input.mouse.ungrab) { - SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); SDL_SetRelativeMouseMode(SDL_FALSE); + SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); } else if (ctx->input.mouse.grabbed) { ctx->input.mouse.pos.x = ctx->input.mouse.prev.x; ctx->input.mouse.pos.y = ctx->input.mouse.prev.y; diff --git a/demo/sdl_opengl3/nuklear_sdl_gl3.h b/demo/sdl_opengl3/nuklear_sdl_gl3.h index 4b0500388..7c847b1e0 100644 --- a/demo/sdl_opengl3/nuklear_sdl_gl3.h +++ b/demo/sdl_opengl3/nuklear_sdl_gl3.h @@ -349,8 +349,8 @@ nk_sdl_handle_grab(void) if (ctx->input.mouse.grab) { SDL_SetRelativeMouseMode(SDL_TRUE); } else if (ctx->input.mouse.ungrab) { - SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); SDL_SetRelativeMouseMode(SDL_FALSE); + SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); } else if (ctx->input.mouse.grabbed) { ctx->input.mouse.pos.x = ctx->input.mouse.prev.x; ctx->input.mouse.pos.y = ctx->input.mouse.prev.y; diff --git a/demo/sdl_opengles2/nuklear_sdl_gles2.h b/demo/sdl_opengles2/nuklear_sdl_gles2.h index 4e97fbaa7..e3f4afbdc 100644 --- a/demo/sdl_opengles2/nuklear_sdl_gles2.h +++ b/demo/sdl_opengles2/nuklear_sdl_gles2.h @@ -349,8 +349,8 @@ nk_sdl_handle_grab(void) if (ctx->input.mouse.grab) { SDL_SetRelativeMouseMode(SDL_TRUE); } else if (ctx->input.mouse.ungrab) { - SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); SDL_SetRelativeMouseMode(SDL_FALSE); + SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); } else if (ctx->input.mouse.grabbed) { ctx->input.mouse.pos.x = ctx->input.mouse.prev.x; ctx->input.mouse.pos.y = ctx->input.mouse.prev.y; diff --git a/demo/sdl_renderer/nuklear_sdl_renderer.h b/demo/sdl_renderer/nuklear_sdl_renderer.h index e6dc24b07..f2670bbf9 100644 --- a/demo/sdl_renderer/nuklear_sdl_renderer.h +++ b/demo/sdl_renderer/nuklear_sdl_renderer.h @@ -271,8 +271,8 @@ nk_sdl_handle_grab(void) if (ctx->input.mouse.grab) { SDL_SetRelativeMouseMode(SDL_TRUE); } else if (ctx->input.mouse.ungrab) { - SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); SDL_SetRelativeMouseMode(SDL_FALSE); + SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); } else if (ctx->input.mouse.grabbed) { ctx->input.mouse.pos.x = ctx->input.mouse.prev.x; ctx->input.mouse.pos.y = ctx->input.mouse.prev.y; From 56ab9d96eac8af467cfdd02523497ca6a15715d8 Mon Sep 17 00:00:00 2001 From: paccer Date: Fri, 23 Feb 2024 20:39:08 +0100 Subject: [PATCH 3/3] Added comment to nk_sdl_handle_grab in SDL demos Explains call order of SDL_SetRelativeMouseMode and SDL_SetWindowGrab --- demo/sdl_opengl2/nuklear_sdl_gl2.h | 1 + demo/sdl_opengl3/nuklear_sdl_gl3.h | 1 + demo/sdl_opengles2/nuklear_sdl_gles2.h | 1 + demo/sdl_renderer/nuklear_sdl_renderer.h | 1 + 4 files changed, 4 insertions(+) diff --git a/demo/sdl_opengl2/nuklear_sdl_gl2.h b/demo/sdl_opengl2/nuklear_sdl_gl2.h index 2a885b57f..fbc7ec736 100644 --- a/demo/sdl_opengl2/nuklear_sdl_gl2.h +++ b/demo/sdl_opengl2/nuklear_sdl_gl2.h @@ -240,6 +240,7 @@ nk_sdl_handle_grab(void) if (ctx->input.mouse.grab) { SDL_SetRelativeMouseMode(SDL_TRUE); } else if (ctx->input.mouse.ungrab) { + /* better support for older SDL by setting mode first; causes an extra mouse motion event */ SDL_SetRelativeMouseMode(SDL_FALSE); SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); } else if (ctx->input.mouse.grabbed) { diff --git a/demo/sdl_opengl3/nuklear_sdl_gl3.h b/demo/sdl_opengl3/nuklear_sdl_gl3.h index 7c847b1e0..6c9d4b174 100644 --- a/demo/sdl_opengl3/nuklear_sdl_gl3.h +++ b/demo/sdl_opengl3/nuklear_sdl_gl3.h @@ -349,6 +349,7 @@ nk_sdl_handle_grab(void) if (ctx->input.mouse.grab) { SDL_SetRelativeMouseMode(SDL_TRUE); } else if (ctx->input.mouse.ungrab) { + /* better support for older SDL by setting mode first; causes an extra mouse motion event */ SDL_SetRelativeMouseMode(SDL_FALSE); SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); } else if (ctx->input.mouse.grabbed) { diff --git a/demo/sdl_opengles2/nuklear_sdl_gles2.h b/demo/sdl_opengles2/nuklear_sdl_gles2.h index e3f4afbdc..6f46d5200 100644 --- a/demo/sdl_opengles2/nuklear_sdl_gles2.h +++ b/demo/sdl_opengles2/nuklear_sdl_gles2.h @@ -349,6 +349,7 @@ nk_sdl_handle_grab(void) if (ctx->input.mouse.grab) { SDL_SetRelativeMouseMode(SDL_TRUE); } else if (ctx->input.mouse.ungrab) { + /* better support for older SDL by setting mode first; causes an extra mouse motion event */ SDL_SetRelativeMouseMode(SDL_FALSE); SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); } else if (ctx->input.mouse.grabbed) { diff --git a/demo/sdl_renderer/nuklear_sdl_renderer.h b/demo/sdl_renderer/nuklear_sdl_renderer.h index f2670bbf9..fb8596f7a 100644 --- a/demo/sdl_renderer/nuklear_sdl_renderer.h +++ b/demo/sdl_renderer/nuklear_sdl_renderer.h @@ -271,6 +271,7 @@ nk_sdl_handle_grab(void) if (ctx->input.mouse.grab) { SDL_SetRelativeMouseMode(SDL_TRUE); } else if (ctx->input.mouse.ungrab) { + /* better support for older SDL by setting mode first; causes an extra mouse motion event */ SDL_SetRelativeMouseMode(SDL_FALSE); SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); } else if (ctx->input.mouse.grabbed) {