// Mouse Event Emulator for Qt WebEngineView // Qt WebEngineView may not forward all mouse events to JavaScript properly // This script uses polling with document.elementFromPoint() to detect hover changes // and manually dispatches mouseover/mouseenter/mouseleave events. // ALSO: Injects a CSS stylesheet that simulates :hover effects using classes (function() { try { if (window.__mouse_emulator_injected) return; window.__mouse_emulator_injected = true; console.log("[MouseEventEmulator] Initialized - polling for hover state changes"); // ======================================================== // PART 1: Inject CSS stylesheet for hover simulation // ======================================================== var style = document.createElement("style"); style.type = "text/css"; style.id = "__mouse_emulator_hover_styles"; style.innerHTML = ` /* Checkbox hover simulation */ input[type="checkbox"].__mouse_hover { cursor: pointer; } /* Link hover simulation */ a.__mouse_hover { text-decoration: underline; } `; if (document.head) { document.head.insertBefore(style, document.head.firstChild); } else { document.body.insertBefore(style, document.body.firstChild); } // ======================================================== // PART 2: Track hover state and apply hover class // ======================================================== var lastElement = null; var lastX = -1; var lastY = -1; // High-frequency polling to detect element changes at mouse position var pollIntervalId = setInterval(function() { if (!window.__lastMousePos) { window.__lastMousePos = { x: 0, y: 0 }; } var x = window.__lastMousePos.x; var y = window.__lastMousePos.y; lastX = x; lastY = y; var element = document.elementFromPoint(x, y); if (!element || element === document || element.tagName === "HTML") { if (lastElement && lastElement !== document) { try { lastElement.classList.remove("__mouse_hover"); var leaveEvent = new MouseEvent("mouseleave", { bubbles: true, cancelable: true, view: window, }); lastElement.dispatchEvent(leaveEvent); } catch (err) { console.warn("[MouseEventEmulator] Error in leave handler:", err); } lastElement = null; } return; } // Element changed if (element !== lastElement) { // Remove hover class from previous element if (lastElement && lastElement !== document && lastElement !== element) { try { lastElement.classList.remove("__mouse_hover"); var leaveEvent = new MouseEvent("mouseleave", { bubbles: true, cancelable: true, view: window, clientX: x, clientY: y, }); lastElement.dispatchEvent(leaveEvent); } catch (err) { console.warn("[MouseEventEmulator] Error dispatching mouseleave:", err); } } // Add hover class and dispatch events for new element if (element) { try { element.classList.add("__mouse_hover"); var overEvent = new MouseEvent("mouseover", { bubbles: true, cancelable: true, view: window, clientX: x, clientY: y, }); element.dispatchEvent(overEvent); var enterEvent = new MouseEvent("mouseenter", { bubbles: false, cancelable: true, view: window, clientX: x, clientY: y, }); element.dispatchEvent(enterEvent); var moveEvent = new MouseEvent("mousemove", { bubbles: true, cancelable: true, view: window, clientX: x, clientY: y, }); element.dispatchEvent(moveEvent); } catch (err) { console.warn("[MouseEventEmulator] Error dispatching mouse events:", err); } } lastElement = element; } }, 50); // Track mouse position from all available events document.addEventListener( "mousemove", function(e) { window.__lastMousePos = { x: e.clientX, y: e.clientY }; }, true ); document.addEventListener( "mousedown", function(e) { window.__lastMousePos = { x: e.clientX, y: e.clientY }; }, true ); document.addEventListener( "mouseup", function(e) { window.__lastMousePos = { x: e.clientX, y: e.clientY }; }, true ); document.addEventListener( "mouseover", function(e) { window.__lastMousePos = { x: e.clientX, y: e.clientY }; }, true ); document.addEventListener( "mouseenter", function(e) { window.__lastMousePos = { x: e.clientX, y: e.clientY }; }, true ); console.log("[MouseEventEmulator] Ready - polling enabled for hover state detection"); } catch (e) { console.error("[MouseEventEmulator] FATAL ERROR:", e); if (e.stack) { console.error("[MouseEventEmulator] Stack:", e.stack); } } })();