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.
This commit is contained in:
Romain Vimont 2018-11-18 21:20:21 +01:00
parent b2c3df7550
commit a7fe9ad779

View file

@ -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)) {