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:
parent
b2c3df7550
commit
a7fe9ad779
1 changed files with 38 additions and 20 deletions
|
@ -18,16 +18,9 @@ static void convert_to_renderer_coordinates(SDL_Renderer *renderer, int *x, int
|
||||||
*y = (int) (*y / scale_y) - viewport.y;
|
*y = (int) (*y / scale_y) - viewport.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct point get_mouse_point(struct screen *screen) {
|
static void get_mouse_point(struct screen *screen, int *x, int *y) {
|
||||||
int x;
|
SDL_GetMouseState(x, y);
|
||||||
int y;
|
convert_to_renderer_coordinates(screen->renderer, x, 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 const int ACTION_DOWN = 1;
|
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,
|
void input_manager_process_mouse_button(struct input_manager *input_manager,
|
||||||
const SDL_MouseButtonEvent *event) {
|
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->type == SDL_MOUSEBUTTONDOWN) {
|
||||||
if (event->button == SDL_BUTTON_RIGHT) {
|
if (event->button == SDL_BUTTON_RIGHT) {
|
||||||
press_back_or_turn_screen_on(input_manager->controller);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
// double-click on black borders resize to fit the device screen
|
// double-click on black borders resize to fit the device screen
|
||||||
if (event->button == SDL_BUTTON_LEFT && event->clicks == 2) {
|
if (event->button == SDL_BUTTON_LEFT && event->clicks == 2
|
||||||
SDL_bool outside_device_screen =
|
&& 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);
|
screen_resize_to_fit(input_manager->screen);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// otherwise, send the click event to the device
|
// otherwise, send the click event to the device
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (outside_device_screen) {
|
||||||
|
// ignore
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct control_event control_event;
|
struct control_event control_event;
|
||||||
if (mouse_button_from_sdl_to_android(event, input_manager->screen->frame_size, &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)) {
|
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,
|
void input_manager_process_mouse_wheel(struct input_manager *input_manager,
|
||||||
const SDL_MouseWheelEvent *event) {
|
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 = {
|
struct position position = {
|
||||||
.screen_size = input_manager->screen->frame_size,
|
.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;
|
struct control_event control_event;
|
||||||
if (mouse_wheel_from_sdl_to_android(event, position, &control_event)) {
|
if (mouse_wheel_from_sdl_to_android(event, position, &control_event)) {
|
||||||
|
|
Loading…
Reference in a new issue