web: Fix touch input
This commit is contained in:
parent
cfbc6e085a
commit
1d99f8534d
73
dist/web/source/wasm-config.js
vendored
73
dist/web/source/wasm-config.js
vendored
@ -100,7 +100,77 @@ var notWorkingTimer = setTimeout(() => {
|
|||||||
|
|
||||||
var Module = {
|
var Module = {
|
||||||
preRun: [],
|
preRun: [],
|
||||||
postRun: [],
|
postRun: function() {
|
||||||
|
// Patch the emscripten GLFW module to send mouse and touch events in the right order
|
||||||
|
// For ImGui interactions to correctly work with touch input, MousePos events need
|
||||||
|
// to be processed first and then MouseButton events in the next frame. By default,
|
||||||
|
// GLFW does the exact opposite, which causes buttons to require two taps to register
|
||||||
|
// and windows get "stuck" to the cursor when dragged or resized
|
||||||
|
GLFW.onMousemove = event => {
|
||||||
|
if (event.type === "touchmove") {
|
||||||
|
event.preventDefault();
|
||||||
|
let primaryChanged = false;
|
||||||
|
for (let i of event.changedTouches) {
|
||||||
|
if (GLFW.primaryTouchId === i.identifier) {
|
||||||
|
Browser.setMouseCoords(i.pageX, i.pageY);
|
||||||
|
primaryChanged = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!primaryChanged) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Browser.calculateMouseEvent(event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GLFW.onMouseButtonChanged = (event, status) => {
|
||||||
|
if (!GLFW.active) return;
|
||||||
|
if (event.target != Module["canvas"]) return;
|
||||||
|
const isTouchType = event.type === "touchstart" || event.type === "touchend" || event.type === "touchcancel";
|
||||||
|
let eventButton = 0;
|
||||||
|
if (isTouchType) {
|
||||||
|
event.preventDefault();
|
||||||
|
let primaryChanged = false;
|
||||||
|
if (GLFW.primaryTouchId === null && event.type === "touchstart" && event.targetTouches.length > 0) {
|
||||||
|
const chosenTouch = event.targetTouches[0];
|
||||||
|
GLFW.primaryTouchId = chosenTouch.identifier;
|
||||||
|
Browser.setMouseCoords(chosenTouch.pageX, chosenTouch.pageY);
|
||||||
|
primaryChanged = true;
|
||||||
|
} else if (event.type === "touchend" || event.type === "touchcancel") {
|
||||||
|
for (let i of event.changedTouches) {
|
||||||
|
if (GLFW.primaryTouchId === i.identifier) {
|
||||||
|
GLFW.primaryTouchId = null;
|
||||||
|
primaryChanged = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!primaryChanged) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Browser.calculateMouseEvent(event);
|
||||||
|
eventButton = GLFW.DOMToGLFWMouseButton(event);
|
||||||
|
}
|
||||||
|
if (status == 1) {
|
||||||
|
GLFW.active.buttons |= (1 << eventButton);
|
||||||
|
try {
|
||||||
|
event.target.setCapture();
|
||||||
|
} catch (e) {}
|
||||||
|
} else {
|
||||||
|
GLFW.active.buttons &= ~(1 << eventButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GLFW.active.cursorPosFunc) {
|
||||||
|
getWasmTableEntry(GLFW.active.cursorPosFunc)(GLFW.active.id, Browser.mouseX, Browser.mouseY);
|
||||||
|
}
|
||||||
|
if (GLFW.active.mouseButtonFunc) {
|
||||||
|
getWasmTableEntry(GLFW.active.mouseButtonFunc)(GLFW.active.id, eventButton, status, GLFW.getModBits(GLFW.active));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
onRuntimeInitialized: function() {
|
onRuntimeInitialized: function() {
|
||||||
// Triggered when the wasm module is loaded and ready to use.
|
// Triggered when the wasm module is loaded and ready to use.
|
||||||
document.getElementById("loading").style.display = "none"
|
document.getElementById("loading").style.display = "none"
|
||||||
@ -157,7 +227,6 @@ window.addEventListener('resize', js_resizeCanvas, false);
|
|||||||
function js_resizeCanvas() {
|
function js_resizeCanvas() {
|
||||||
let canvas = document.getElementById('canvas');
|
let canvas = document.getElementById('canvas');
|
||||||
|
|
||||||
|
|
||||||
canvas.top = document.documentElement.clientTop;
|
canvas.top = document.documentElement.clientTop;
|
||||||
canvas.left = document.documentElement.clientLeft;
|
canvas.left = document.documentElement.clientLeft;
|
||||||
canvas.width = Math.min(document.documentElement.clientWidth, window.innerWidth || 0);
|
canvas.width = Math.min(document.documentElement.clientWidth, window.innerWidth || 0);
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
|
|
||||||
#include <hex/api/event_manager.hpp>
|
#include <hex/api/event_manager.hpp>
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <imgui_internal.h>
|
||||||
|
|
||||||
// Function used by c++ to get the size of the html canvas
|
// Function used by c++ to get the size of the html canvas
|
||||||
EM_JS(int, canvas_get_width, (), {
|
EM_JS(int, canvas_get_width, (), {
|
||||||
return Module.canvas.width;
|
return Module.canvas.width;
|
||||||
@ -37,6 +40,27 @@ extern "C" void handleThemeChange() {
|
|||||||
hex::EventOSThemeChanged::post();
|
hex::EventOSThemeChanged::post();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EM_JS(void, setupInputModeListener, (), {
|
||||||
|
Module.canvas.addEventListener('mousedown', function() {
|
||||||
|
Module._enterMouseMode();
|
||||||
|
});
|
||||||
|
|
||||||
|
Module.canvas.addEventListener('touchstart', function() {
|
||||||
|
Module._enterTouchMode();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE
|
||||||
|
extern "C" void enterMouseMode() {
|
||||||
|
ImGui::GetIO().AddMouseSourceEvent(ImGuiMouseSource_Mouse);
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE
|
||||||
|
extern "C" void enterTouchMode() {
|
||||||
|
ImGui::GetIO().AddMouseSourceEvent(ImGuiMouseSource_TouchScreen);
|
||||||
|
}
|
||||||
|
|
||||||
namespace hex {
|
namespace hex {
|
||||||
|
|
||||||
void nativeErrorMessage(const std::string &message) {
|
void nativeErrorMessage(const std::string &message) {
|
||||||
@ -70,6 +94,7 @@ namespace hex {
|
|||||||
void Window::setupNativeWindow() {
|
void Window::setupNativeWindow() {
|
||||||
resizeCanvas();
|
resizeCanvas();
|
||||||
setupThemeListener();
|
setupThemeListener();
|
||||||
|
setupInputModeListener();
|
||||||
|
|
||||||
bool themeFollowSystem = ImHexApi::System::usesSystemThemeDetection();
|
bool themeFollowSystem = ImHexApi::System::usesSystemThemeDetection();
|
||||||
EventOSThemeChanged::subscribe(this, [themeFollowSystem] {
|
EventOSThemeChanged::subscribe(this, [themeFollowSystem] {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user