diff --git a/src/twn_engine_context_c.h b/src/twn_engine_context_c.h index 4ea240a..b91b9bd 100644 --- a/src/twn_engine_context_c.h +++ b/src/twn_engine_context_c.h @@ -82,6 +82,8 @@ typedef struct EngineContext { bool resync_flag; bool was_successful; bool render_double_buffered; + /* signals mouse focus, used to disable mouse capture */ + bool window_mouse_resident; } EngineContext; /* TODO: does it need to be marked with TWN_API? */ diff --git a/src/twn_input.c b/src/twn_input.c index cef4aa1..9eaf186 100644 --- a/src/twn_input.c +++ b/src/twn_input.c @@ -218,7 +218,7 @@ void input_state_deinit(InputState *input) { void input_state_update(InputState *input) { /* TODO: don't spam it if it happens */ - if (SDL_SetRelativeMouseMode(ctx.game_copy.mouse_capture) != 0) + if (SDL_SetRelativeMouseMode(ctx.game_copy.mouse_capture && ctx.window_mouse_resident) != 0) log_warn("(%s) Mouse capture isn't supported.", __func__); int x, y; @@ -231,7 +231,9 @@ void input_state_update(InputState *input) { input->mouse_relative_position = (Vec2){ (float)x, (float)y }; ctx.game.mouse_position = input->mouse_window_position; - ctx.game.mouse_movement = input->mouse_relative_position; + + if (ctx.window_mouse_resident) + ctx.game.mouse_movement = input->mouse_relative_position; for (size_t i = 0; i < shlenu(input->action_hash); ++i) { Action *action = &input->action_hash[i].value; diff --git a/src/twn_loop.c b/src/twn_loop.c index 7f93b07..fb7d224 100644 --- a/src/twn_loop.c +++ b/src/twn_loop.c @@ -42,6 +42,16 @@ static int event_callback(void *userdata, SDL_Event *event) { ctx.resync_flag = true; break; + case SDL_WINDOWEVENT_FOCUS_LOST: { + ctx.window_mouse_resident = false; + break; + } + + case SDL_WINDOWEVENT_FOCUS_GAINED: { + ctx.window_mouse_resident = true; + break; + } + default: break; } @@ -706,6 +716,7 @@ static bool initialize(void) { */ ctx.render_double_buffered = true; + ctx.window_mouse_resident = true; return true;