diff --git a/core/hostevents_sdl.cpp b/core/hostevents_sdl.cpp index 27daa94..6c92b35 100644 --- a/core/hostevents_sdl.cpp +++ b/core/hostevents_sdl.cpp @@ -29,6 +29,7 @@ along with this program. If not, see . EventManager* EventManager::event_manager; static int get_sdl_event_key_code(const SDL_KeyboardEvent &event); +static void toggle_mouse_grab(const SDL_KeyboardEvent &event); void EventManager::poll_events() { @@ -53,6 +54,14 @@ void EventManager::poll_events() case SDL_KEYDOWN: case SDL_KEYUP: { + // Internal shortcuts to trigger mouse grab, intentionally not + // sent to the host. + if (event.key.keysym.sym == SDLK_g && SDL_GetModState() == KMOD_LCTRL) { + if (event.type == SDL_KEYUP) { + toggle_mouse_grab(event.key); + } + return; + } int key_code = get_sdl_event_key_code(event.key); if (key_code != -1) { KeyboardEvent ke; @@ -278,3 +287,25 @@ static int get_sdl_event_key_code(const SDL_KeyboardEvent &event) } return -1; } + +static void toggle_mouse_grab(const SDL_KeyboardEvent &event) { + SDL_Window *window = SDL_GetWindowFromID(event.windowID); + if (SDL_GetRelativeMouseMode()) { + SDL_SetRelativeMouseMode(SDL_FALSE); + SDL_SetWindowTitle(window, "DingusPPC Display"); + } else { + // If the mouse is initially outside the window, move it to the middle, + // so that clicks are handled by the window (instead making it lose + // focus, at least with macOS hosts). + int mouse_x, mouse_y, window_x, window_y, window_width, window_height; + SDL_GetGlobalMouseState(&mouse_x, &mouse_y); + SDL_GetWindowPosition(window, &window_x, &window_y); + SDL_GetWindowSize(window, &window_width, &window_height); + if (mouse_x < window_x || mouse_x >= window_x + window_width || + mouse_y < window_y || mouse_y >= window_y + window_height) { + SDL_WarpMouseInWindow(window, window_width / 2, window_height / 2); + } + SDL_SetRelativeMouseMode(SDL_TRUE); + SDL_SetWindowTitle(window, "DingusPPC Display (Mouse Grabbed)"); + } +}