Skip to content

Commit

Permalink
Ignore mouse events outside device screen
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rom1v committed Nov 18, 2018
1 parent b2c3df7 commit a7fe9ad
Showing 1 changed file with 38 additions and 20 deletions.
58 changes: 38 additions & 20 deletions app/src/input_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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)) {
Expand All @@ -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)) {
Expand Down

0 comments on commit a7fe9ad

Please sign in to comment.