Skip to content

Commit e8a565f

Browse files
committed
Fix touch events HiDPI-scaling
Touch events were HiDPI-scaled twice: - once because the position (provided as floats between 0 and 1) were converted in pixels using the drawable size (not the window size) - once due to screen_convert_to_frame_coords() One possible fix could be to compute the position in pixels from the window size instead, but this would unnecessarily round the event position to the nearest window coordinates (instead of drawable coordinates). Instead, expose two separate functions to convert to frame coordinates from either window or drawable coordinates. Fixes #1536 <#1536> Refs #15 <#15> Refs e40532a
1 parent 3c1ed5d commit e8a565f

File tree

3 files changed

+27
-12
lines changed

3 files changed

+27
-12
lines changed

app/src/input_manager.c

+10-9
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ convert_mouse_motion(const SDL_MouseMotionEvent *from, struct screen *screen,
434434
to->inject_touch_event.pointer_id = POINTER_ID_MOUSE;
435435
to->inject_touch_event.position.screen_size = screen->frame_size;
436436
to->inject_touch_event.position.point =
437-
screen_convert_to_frame_coords(screen, from->x, from->y);
437+
screen_convert_window_to_frame_coords(screen, from->x, from->y);
438438
to->inject_touch_event.pressure = 1.f;
439439
to->inject_touch_event.buttons = convert_mouse_buttons(from->state);
440440

@@ -472,15 +472,15 @@ convert_touch(const SDL_TouchFingerEvent *from, struct screen *screen,
472472
to->inject_touch_event.pointer_id = from->fingerId;
473473
to->inject_touch_event.position.screen_size = screen->frame_size;
474474

475-
int ww;
476-
int wh;
477-
SDL_GL_GetDrawableSize(screen->window, &ww, &wh);
475+
int dw;
476+
int dh;
477+
SDL_GL_GetDrawableSize(screen->window, &dw, &dh);
478478

479479
// SDL touch event coordinates are normalized in the range [0; 1]
480-
int32_t x = from->x * ww;
481-
int32_t y = from->y * wh;
480+
int32_t x = from->x * dw;
481+
int32_t y = from->y * dh;
482482
to->inject_touch_event.position.point =
483-
screen_convert_to_frame_coords(screen, x, y);
483+
screen_convert_drawable_to_frame_coords(screen, x, y);
484484

485485
to->inject_touch_event.pressure = from->pressure;
486486
to->inject_touch_event.buttons = 0;
@@ -510,7 +510,7 @@ convert_mouse_button(const SDL_MouseButtonEvent *from, struct screen *screen,
510510
to->inject_touch_event.pointer_id = POINTER_ID_MOUSE;
511511
to->inject_touch_event.position.screen_size = screen->frame_size;
512512
to->inject_touch_event.position.point =
513-
screen_convert_to_frame_coords(screen, from->x, from->y);
513+
screen_convert_window_to_frame_coords(screen, from->x, from->y);
514514
to->inject_touch_event.pressure = 1.f;
515515
to->inject_touch_event.buttons =
516516
convert_mouse_buttons(SDL_BUTTON(from->button));
@@ -575,7 +575,8 @@ convert_mouse_wheel(const SDL_MouseWheelEvent *from, struct screen *screen,
575575

576576
struct position position = {
577577
.screen_size = screen->frame_size,
578-
.point = screen_convert_to_frame_coords(screen, mouse_x, mouse_y),
578+
.point = screen_convert_window_to_frame_coords(screen,
579+
mouse_x, mouse_y),
579580
};
580581

581582
to->type = CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT;

app/src/screen.c

+9-2
Original file line numberDiff line numberDiff line change
@@ -580,14 +580,14 @@ screen_handle_window_event(struct screen *screen,
580580
}
581581

582582
struct point
583-
screen_convert_to_frame_coords(struct screen *screen, int32_t x, int32_t y) {
583+
screen_convert_drawable_to_frame_coords(struct screen *screen,
584+
int32_t x, int32_t y) {
584585
unsigned rotation = screen->rotation;
585586
assert(rotation < 4);
586587

587588
int32_t w = screen->content_size.width;
588589
int32_t h = screen->content_size.height;
589590

590-
screen_hidpi_scale_coords(screen, &x, &y);
591591

592592
x = (int64_t) (x - screen->rect.x) * w / screen->rect.w;
593593
y = (int64_t) (y - screen->rect.y) * h / screen->rect.h;
@@ -616,6 +616,13 @@ screen_convert_to_frame_coords(struct screen *screen, int32_t x, int32_t y) {
616616
return result;
617617
}
618618

619+
struct point
620+
screen_convert_window_to_frame_coords(struct screen *screen,
621+
int32_t x, int32_t y) {
622+
screen_hidpi_scale_coords(screen, &x, &y);
623+
return screen_convert_drawable_to_frame_coords(screen, x, y);
624+
}
625+
619626
void
620627
screen_hidpi_scale_coords(struct screen *screen, int32_t *x, int32_t *y) {
621628
// take the HiDPI scaling (dw/ww and dh/wh) into account

app/src/screen.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,14 @@ screen_handle_window_event(struct screen *screen, const SDL_WindowEvent *event);
124124
// convert point from window coordinates to frame coordinates
125125
// x and y are expressed in pixels
126126
struct point
127-
screen_convert_to_frame_coords(struct screen *screen, int32_t x, int32_t y);
127+
screen_convert_window_to_frame_coords(struct screen *screen,
128+
int32_t x, int32_t y);
129+
130+
// convert point from drawable coordinates to frame coordinates
131+
// x and y are expressed in pixels
132+
struct point
133+
screen_convert_drawable_to_frame_coords(struct screen *screen,
134+
int32_t x, int32_t y);
128135

129136
// Convert coordinates from window to drawable.
130137
// Events are expressed in window coordinates, but content is expressed in

0 commit comments

Comments
 (0)