From a7fe9ad779057f7a2698fc1769dce3c3786993ee Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sun, 18 Nov 2018 21:20:21 +0100 Subject: [PATCH] Ignore mouse events outside device screen Never create a "struct point" with a position possibly outside the device screen (i.e. in the black borders area), and do not transmit such events. This fixes an assertion failure on mouse wheel events outside the device screen area. --- app/src/input_manager.c | 58 +++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/app/src/input_manager.c b/app/src/input_manager.c index 21b7c407..7a3a4ad1 100644 --- a/app/src/input_manager.c +++ b/app/src/input_manager.c @@ -18,16 +18,9 @@ static void convert_to_renderer_coordinates(SDL_Renderer *renderer, int *x, int *y = (int) (*y / scale_y) - viewport.y; } -static struct point get_mouse_point(struct screen *screen) { - int x; - int y; - SDL_GetMouseState(&x, &y); - convert_to_renderer_coordinates(screen->renderer, &x, &y); - SDL_assert_release(x >= 0 && x < 0x10000 && y >= 0 && y < 0x10000); - return (struct point) { - .x = (Uint16) x, - .y = (Uint16) y, - }; +static void get_mouse_point(struct screen *screen, int *x, int *y) { + SDL_GetMouseState(x, y); + convert_to_renderer_coordinates(screen->renderer, x, y); } static const int ACTION_DOWN = 1; @@ -271,8 +264,18 @@ void input_manager_process_mouse_motion(struct input_manager *input_manager, } } +static SDL_bool is_outside_device_screen(struct input_manager *input_manager, + int x, int y) +{ + return x < 0 || x >= input_manager->screen->frame_size.width || + y < 0 || y >= input_manager->screen->frame_size.height; +} + void input_manager_process_mouse_button(struct input_manager *input_manager, const SDL_MouseButtonEvent *event) { + SDL_bool outside_device_screen = is_outside_device_screen(input_manager, + event->x, + event->y); if (event->type == SDL_MOUSEBUTTONDOWN) { if (event->button == SDL_BUTTON_RIGHT) { press_back_or_turn_screen_on(input_manager->controller); @@ -283,17 +286,19 @@ void input_manager_process_mouse_button(struct input_manager *input_manager, return; } // double-click on black borders resize to fit the device screen - if (event->button == SDL_BUTTON_LEFT && event->clicks == 2) { - SDL_bool outside_device_screen = - event->x < 0 || event->x >= input_manager->screen->frame_size.width || - event->y < 0 || event->y >= input_manager->screen->frame_size.height; - if (outside_device_screen) { - screen_resize_to_fit(input_manager->screen); - return; - } - // otherwise, send the click event to the device + if (event->button == SDL_BUTTON_LEFT && event->clicks == 2 + && outside_device_screen) { + screen_resize_to_fit(input_manager->screen); + return; } + // otherwise, send the click event to the device } + + if (outside_device_screen) { + // ignore + return; + } + struct control_event control_event; if (mouse_button_from_sdl_to_android(event, input_manager->screen->frame_size, &control_event)) { if (!controller_push_event(input_manager->controller, &control_event)) { @@ -304,9 +309,22 @@ void input_manager_process_mouse_button(struct input_manager *input_manager, void input_manager_process_mouse_wheel(struct input_manager *input_manager, const SDL_MouseWheelEvent *event) { + int x; + int y; + get_mouse_point(input_manager->screen, &x, &y); + if (is_outside_device_screen(input_manager, x, y)) { + // ignore + return; + } + + SDL_assert_release(x >= 0 && x < 0x10000 && y >= 0 && y < 0x10000); + struct position position = { .screen_size = input_manager->screen->frame_size, - .point = get_mouse_point(input_manager->screen), + .point = { + .x = (Uint16) x, + .y = (Uint16) y, + }, }; struct control_event control_event; if (mouse_wheel_from_sdl_to_android(event, position, &control_event)) {