Skip to content

Commit 6e5994e

Browse files
committed
[Web] Fix Web MouseWheel scrolling
1 parent f92f1ce commit 6e5994e

File tree

4 files changed

+34
-11
lines changed

4 files changed

+34
-11
lines changed

platform/web/display_server_web.cpp

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -634,18 +634,18 @@ Point2i DisplayServerWeb::mouse_get_position() const {
634634
}
635635

636636
// Wheel
637-
int DisplayServerWeb::mouse_wheel_callback(double p_delta_x, double p_delta_y) {
637+
int DisplayServerWeb::mouse_wheel_callback(int p_delta_mode, double p_delta_x, double p_delta_y) {
638638
#ifdef PROXY_TO_PTHREAD_ENABLED
639639
if (!Thread::is_main_thread()) {
640-
callable_mp_static(DisplayServerWeb::_mouse_wheel_callback).call_deferred(p_delta_x, p_delta_y);
640+
callable_mp_static(DisplayServerWeb::_mouse_wheel_callback).call_deferred(p_delta_mode, p_delta_x, p_delta_y);
641641
return true;
642642
}
643643
#endif
644644

645-
return _mouse_wheel_callback(p_delta_x, p_delta_y);
645+
return _mouse_wheel_callback(p_delta_mode, p_delta_x, p_delta_y);
646646
}
647647

648-
int DisplayServerWeb::_mouse_wheel_callback(double p_delta_x, double p_delta_y) {
648+
int DisplayServerWeb::_mouse_wheel_callback(int p_delta_mode, double p_delta_x, double p_delta_y) {
649649
if (!godot_js_display_canvas_is_focused() && !godot_js_is_ime_focused()) {
650650
if (get_singleton()->cursor_inside_canvas) {
651651
godot_js_display_canvas_focus();
@@ -665,21 +665,44 @@ int DisplayServerWeb::_mouse_wheel_callback(double p_delta_x, double p_delta_y)
665665
ev->set_ctrl_pressed(input->is_key_pressed(Key::CTRL));
666666
ev->set_meta_pressed(input->is_key_pressed(Key::META));
667667

668+
enum DeltaMode {
669+
DELTA_MODE_PIXEL = 0,
670+
DELTA_MODE_LINE = 1,
671+
DELTA_MODE_PAGE = 2,
672+
};
673+
const float MOUSE_WHEEL_PIXEL_FACTOR = 0.03f;
674+
const float MOUSE_WHEEL_LINE_FACTOR = 0.3f;
675+
const float MOUSE_WHEEL_PAGE_FACTOR = 1.0f;
676+
float mouse_wheel_factor;
677+
678+
switch (p_delta_mode) {
679+
case DELTA_MODE_PIXEL: {
680+
mouse_wheel_factor = MOUSE_WHEEL_PIXEL_FACTOR;
681+
} break;
682+
case DELTA_MODE_LINE: {
683+
mouse_wheel_factor = MOUSE_WHEEL_LINE_FACTOR;
684+
} break;
685+
case DELTA_MODE_PAGE: {
686+
mouse_wheel_factor = MOUSE_WHEEL_PAGE_FACTOR;
687+
} break;
688+
}
689+
668690
if (p_delta_y < 0) {
669691
ev->set_button_index(MouseButton::WHEEL_UP);
692+
ev->set_factor(-p_delta_y * mouse_wheel_factor);
670693
} else if (p_delta_y > 0) {
671694
ev->set_button_index(MouseButton::WHEEL_DOWN);
695+
ev->set_factor(p_delta_y * mouse_wheel_factor);
672696
} else if (p_delta_x > 0) {
673697
ev->set_button_index(MouseButton::WHEEL_LEFT);
698+
ev->set_factor(p_delta_x * mouse_wheel_factor);
674699
} else if (p_delta_x < 0) {
675700
ev->set_button_index(MouseButton::WHEEL_RIGHT);
701+
ev->set_factor(-p_delta_x * mouse_wheel_factor);
676702
} else {
677703
return false;
678704
}
679705

680-
// Different browsers give wildly different delta values, and we can't
681-
// interpret deltaMode, so use default value for wheel events' factor.
682-
683706
MouseButtonMask button_flag = mouse_button_to_mask(ev->get_button_index());
684707
BitField<MouseButtonMask> button_mask = input->get_mouse_button_mask();
685708
button_mask.set_flag(button_flag);

platform/web/display_server_web.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ class DisplayServerWeb : public DisplayServer {
122122
static int _mouse_button_callback(int p_pressed, int p_button, double p_x, double p_y, int p_modifiers);
123123
WASM_EXPORT static void mouse_move_callback(double p_x, double p_y, double p_rel_x, double p_rel_y, int p_modifiers, double p_pressure);
124124
static void _mouse_move_callback(double p_x, double p_y, double p_rel_x, double p_rel_y, int p_modifiers, double p_pressure);
125-
WASM_EXPORT static int mouse_wheel_callback(double p_delta_x, double p_delta_y);
126-
static int _mouse_wheel_callback(double p_delta_x, double p_delta_y);
125+
WASM_EXPORT static int mouse_wheel_callback(int p_delta_mode, double p_delta_x, double p_delta_y);
126+
static int _mouse_wheel_callback(int p_delta_mode, double p_delta_x, double p_delta_y);
127127
WASM_EXPORT static void touch_callback(int p_type, int p_count);
128128
static void _touch_callback(int p_type, int p_count);
129129
WASM_EXPORT static void key_callback(int p_pressed, int p_repeat, int p_modifiers);

platform/web/godot_js.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ extern int godot_js_pwa_update();
6161
// Input
6262
extern void godot_js_input_mouse_button_cb(int (*p_callback)(int p_pressed, int p_button, double p_x, double p_y, int p_modifiers));
6363
extern void godot_js_input_mouse_move_cb(void (*p_callback)(double p_x, double p_y, double p_rel_x, double p_rel_y, int p_modifiers, double p_pressure));
64-
extern void godot_js_input_mouse_wheel_cb(int (*p_callback)(double p_delta_x, double p_delta_y));
64+
extern void godot_js_input_mouse_wheel_cb(int (*p_callback)(int p_delta_mode, double p_delta_x, double p_delta_y));
6565
extern void godot_js_input_touch_cb(void (*p_callback)(int p_type, int p_count), uint32_t *r_identifiers, double *r_coords);
6666
extern void godot_js_input_key_cb(void (*p_callback)(int p_type, int p_repeat, int p_modifiers), char r_code[32], char r_key[32]);
6767
extern void godot_js_input_vibrate_handheld(int p_duration_ms);

platform/web/js/libs/library_godot_input.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ const GodotInput = {
526526
godot_js_input_mouse_wheel_cb: function (callback) {
527527
const func = GodotRuntime.get_func(callback);
528528
function wheel_cb(evt) {
529-
if (func(evt['deltaX'] || 0, evt['deltaY'] || 0)) {
529+
if (func(evt.deltaMode, evt.deltaX ?? 0, evt.deltaY ?? 0)) {
530530
evt.preventDefault();
531531
}
532532
}

0 commit comments

Comments
 (0)