From 98b42ca95884ff3edf5c631d64f6af5a381d50c0 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Sun, 12 Sep 2021 18:36:25 +0200 Subject: [PATCH] [HTML5] Fix input not working when buffered. After input buffering was reworked, input accumulation is now handled outside of OS, and the JavaScript plaform never implemented that. Additionally, the JavaScript platform is quite obnoxious about calling specific APIs outside specific user triggered events. This commit adds event flushing during the main iteration, and forces it during keydown/keyup/mousedown/mouseup/touchstart/touchend/touchcanel events (effectively only accumulating only "move" events). --- platform/javascript/os_javascript.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 2e0053338fd..8262d17e394 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -267,6 +267,10 @@ EM_BOOL OS_JavaScript::keydown_callback(int p_event_type, const EmscriptenKeyboa return false; } os->input->parse_input_event(ev); + + // Make sure to flush all events so we can call restricted APIs inside the event. + os->input->flush_buffered_events(); + // Resume audio context after input in case autoplay was denied. os->resume_audio(); return true; @@ -276,13 +280,22 @@ EM_BOOL OS_JavaScript::keypress_callback(int p_event_type, const EmscriptenKeybo OS_JavaScript *os = get_singleton(); os->deferred_key_event->set_unicode(p_event->charCode); os->input->parse_input_event(os->deferred_key_event); + + // Make sure to flush all events so we can call restricted APIs inside the event. + os->input->flush_buffered_events(); + return true; } EM_BOOL OS_JavaScript::keyup_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data) { + OS_JavaScript *os = get_singleton(); Ref ev = setup_key_event(p_event); ev->set_pressed(false); - get_singleton()->input->parse_input_event(ev); + os->input->parse_input_event(ev); + + // Make sure to flush all events so we can call restricted APIs inside the event. + os->input->flush_buffered_events(); + return ev->get_scancode() != KEY_UNKNOWN && ev->get_scancode() != 0; } @@ -363,8 +376,13 @@ EM_BOOL OS_JavaScript::mouse_button_callback(int p_event_type, const EmscriptenM ev->set_button_mask(mask); os->input->parse_input_event(ev); + + // Make sure to flush all events so we can call restricted APIs inside the event. + os->input->flush_buffered_events(); + // Resume audio context after input in case autoplay was denied. os->resume_audio(); + // Prevent multi-click text selection and wheel-click scrolling anchor. // Context menu is prevented through contextmenu event. return true; @@ -629,6 +647,10 @@ EM_BOOL OS_JavaScript::touch_press_callback(int p_event_type, const EmscriptenTo os->input->parse_input_event(ev); } + + // Make sure to flush all events so we can call restricted APIs inside the event. + os->input->flush_buffered_events(); + // Resume audio context after input in case autoplay was denied. os->resume_audio(); return true; @@ -954,6 +976,8 @@ bool OS_JavaScript::main_loop_iterate() { godot_js_os_fs_sync(&OS_JavaScript::fs_sync_callback); } + input->flush_buffered_events(); + if (godot_js_display_gamepad_sample() == OK) process_joypads();