From 4bd6c58aea6ee93ff6496ed7598c2163fee32b13 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sat, 1 Jan 2022 12:10:55 +0100 Subject: [PATCH] uncapture --- app/src/screen.c | 39 +++++++++++++++++++++++++++++++++++++++ app/src/screen.h | 3 +++ 2 files changed, 42 insertions(+) diff --git a/app/src/screen.c b/app/src/screen.c index 87c9830e..f615e545 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -366,6 +366,7 @@ screen_init(struct screen *screen, const struct screen_params *params) { screen->maximized = false; screen->event_failed = false; screen->mouse_captured = false; + screen->uncapture_key_pressed = 0; static const struct sc_video_buffer_callbacks cbs = { .on_new_frame = sc_video_buffer_on_new_frame, @@ -753,6 +754,11 @@ screen_resize_to_pixel_perfect(struct screen *screen) { content_size.height); } +static inline bool +screen_is_uncapture_key(SDL_Keycode key) { + return key == SDLK_LALT || key == SDLK_LGUI || key == SDLK_RGUI; +} + bool screen_handle_event(struct screen *screen, SDL_Event *event) { switch (event->type) { @@ -802,6 +808,39 @@ screen_handle_event(struct screen *screen, SDL_Event *event) { break; } return true; + case SDL_KEYDOWN: + if (screen->im.mp->relative_mode && screen->mouse_captured) { + SDL_Keycode key = event->key.keysym.sym; + if (screen_is_uncapture_key(key)) { + if (!screen->uncapture_key_pressed) { + screen->uncapture_key_pressed = key; + return true; + } else { + // Another uncapture key has been pressed, cancel mouse + // uncapture + screen->uncapture_key_pressed = 0; + // Do not return, the event must be forwarded to the + // input manager + } + } + } + break; + case SDL_KEYUP: + if (screen->im.mp->relative_mode && screen->mouse_captured) { + SDL_Keycode key = event->key.keysym.sym; + SDL_Keycode uncapture_key_pressed = + screen->uncapture_key_pressed; + screen->uncapture_key_pressed = 0; + if (key == uncapture_key_pressed) { + // An uncapture key has been pressed then released: + // uncapture the mouse + screen_capture_mouse(screen, false); + return true; + } + // Do not return, the event must be forwarded to the input + // manager + } + break; case SDL_MOUSEWHEEL: case SDL_MOUSEMOTION: case SDL_MOUSEBUTTONDOWN: diff --git a/app/src/screen.h b/app/src/screen.h index 9eb78fb7..ca32496f 100644 --- a/app/src/screen.h +++ b/app/src/screen.h @@ -52,6 +52,9 @@ struct screen { bool event_failed; // in case SDL_PushEvent() returned an error bool mouse_captured; // only relevant in relative mouse mode + // To disable mouse capture, an uncapture key (LALT, LGUI or RGUI) must be + // pressed. This variable tracks the pressed mod key. + SDL_Keycode uncapture_key_pressed; AVFrame *frame; };