ViewerTest_EventManager - added tracking of EMSCRIPTEN_EVENT_FOCUSOUT event.
onWasmMouseCallback() has been adjusted to return FALSE for EMSCRIPTEN_EVENT_TARGET_WINDOW
target to avoid misbehavior of other HTML controls.
WNT_Window::ProcessMessage() now handles WM_SETFOCUS/WM_KILLFOCUS instead of WM_ACTIVATE to track focus changes.
AIS_ViewController::ProcessFocus() now redirects to AIS_ViewController::ResetViewInput() on focus loss.
This fixes issues when key action (like WASD navigation) keep working even after releasing key if window has been switched.
emscripten_set_touchmove_callback (aTargetId, this, toUseCapture, onTouchCallback);
emscripten_set_touchcancel_callback(aTargetId, this, toUseCapture, onTouchCallback);
- //emscripten_set_keypress_callback (EMSCRIPTEN_EVENT_TARGET_WINDOW, this, toUseCapture, onKeyCallback);
- emscripten_set_keydown_callback (EMSCRIPTEN_EVENT_TARGET_WINDOW, this, toUseCapture, onKeyDownCallback);
- emscripten_set_keyup_callback (EMSCRIPTEN_EVENT_TARGET_WINDOW, this, toUseCapture, onKeyUpCallback);
+ //emscripten_set_keypress_callback (aTargetId, this, toUseCapture, onKeyCallback);
+ emscripten_set_keydown_callback (aTargetId, this, toUseCapture, onKeyDownCallback);
+ emscripten_set_keyup_callback (aTargetId, this, toUseCapture, onKeyUpCallback);
+ //emscripten_set_focus_callback (aTargetId, this, toUseCapture, onFocusCallback);
+ //emscripten_set_focusin_callback (aTargetId, this, toUseCapture, onFocusCallback);
+ emscripten_set_focusout_callback (aTargetId, this, toUseCapture, onFocusCallback);
}
// ================================================================
EmscriptenMouseEvent anEvent = *theEvent;
anEvent.targetX -= jsGetBoundingClientLeft();
anEvent.targetY -= jsGetBoundingClientTop();
- return aWindow->ProcessMouseEvent (*this, theEventType, &anEvent) ? EM_TRUE : EM_FALSE;
+ aWindow->ProcessMouseEvent (*this, theEventType, &anEvent);
+ return EM_FALSE;
}
return aWindow->ProcessMouseEvent (*this, theEventType, theEvent) ? EM_TRUE : EM_FALSE;
return hasActions;
}
+// ================================================================
+// Function : onFocusEvent
+// Purpose :
+// ================================================================
+EM_BOOL WasmOcctView::onFocusEvent (int theEventType, const EmscriptenFocusEvent* theEvent)
+{
+ if (myView.IsNull()
+ || (theEventType != EMSCRIPTEN_EVENT_FOCUS
+ && theEventType != EMSCRIPTEN_EVENT_FOCUSIN // about to receive focus
+ && theEventType != EMSCRIPTEN_EVENT_FOCUSOUT))
+ {
+ return EM_FALSE;
+ }
+
+ Handle(Wasm_Window) aWindow = Handle(Wasm_Window)::DownCast (myView->Window());
+ return aWindow->ProcessFocusEvent (*this, theEventType, theEvent) ? EM_TRUE : EM_FALSE;
+}
+
// ================================================================
// Function : onKeyDownEvent
// Purpose :
//! Key up event.
EM_BOOL onKeyUpEvent (int theEventType, const EmscriptenKeyboardEvent* theEvent);
+ //! Focus change event.
+ EM_BOOL onFocusEvent (int theEventType, const EmscriptenFocusEvent* theEvent);
+
//! @name Emscripten callbacks (static functions)
private:
static EM_BOOL onKeyUpCallback (int theEventType, const EmscriptenKeyboardEvent* theEvent, void* theView)
{ return ((WasmOcctView* )theView)->onKeyUpEvent (theEventType, theEvent); }
+ static EM_BOOL onFocusCallback (int theEventType, const EmscriptenFocusEvent* theEvent, void* theView)
+ { return ((WasmOcctView* )theView)->onFocusEvent (theEventType, theEvent); }
+
private:
//! Register hot-keys for specified Action.
window.onresize = updateCanvasSize;
updateCanvasSize();
+// capture keyboard input on mouse click
+occViewerCanvas.tabIndex = -1;
+occViewerCanvas.onclick = (theEvent) => { occViewerCanvas.focus() };
+occViewerCanvas.focus();
+
//! Check browser support.
function isWasmSupported()
{
OccViewerModule.openFromMemory (aFile.name, aDataBuffer, aDataArray.length, true);
//OccViewerModule._free (aDataBuffer); will be freed by called method
OccViewerModule.displayGround (true);
+ occViewerCanvas.focus();
};
aReader.readAsArrayBuffer(aFile);
};
virtual void ProcessInput() Standard_OVERRIDE {}
//! Handle focus event.
- //! Default implementation does nothing.
+ //! Default implementation resets cached input state (pressed keys).
virtual void ProcessFocus (bool theIsActivated) Standard_OVERRIDE
{
- (void )theIsActivated;
+ if (!theIsActivated)
+ {
+ ResetViewInput();
+ }
}
//! Handle window close event.
EmscriptenMouseEvent anEvent = *theEvent;
anEvent.targetX -= occJSGetBoundingClientLeft();
anEvent.targetY -= occJSGetBoundingClientTop();
- return aWindow->ProcessMouseEvent (*aViewCtrl, theEventType, &anEvent) ? EM_TRUE : EM_FALSE;
+ aWindow->ProcessMouseEvent (*aViewCtrl, theEventType, &anEvent);
+ return EM_FALSE;
}
return aWindow->ProcessMouseEvent (*aViewCtrl, theEventType, theEvent) ? EM_TRUE : EM_FALSE;
}
return EM_FALSE;
}
+
+//! Handle focus change event.
+static EM_BOOL onWasmFocusCallback (int theEventType, const EmscriptenFocusEvent* theEvent, void*)
+{
+ Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager();
+ if (!aViewCtrl.IsNull()
+ && !ViewerTest::CurrentView().IsNull())
+ {
+ Handle(Wasm_Window) aWindow = Handle(Wasm_Window)::DownCast (ViewerTest::CurrentView()->Window());
+ return aWindow->ProcessFocusEvent (*aViewCtrl, theEventType, theEvent) ? EM_TRUE : EM_FALSE;
+ }
+ return EM_FALSE;
+}
#endif
// ==============================================================================
// keyboard input requires a focusable element or EMSCRIPTEN_EVENT_TARGET_WINDOW
emscripten_set_keydown_callback (aTargetId, anOpaque, toUseCapture, onWasmKeyCallback);
emscripten_set_keyup_callback (aTargetId, anOpaque, toUseCapture, onWasmKeyCallback);
+ //emscripten_set_focus_callback (aTargetId, anOpaque, toUseCapture, onWasmFocusCallback);
+ //emscripten_set_focusin_callback (aTargetId, anOpaque, toUseCapture, onWasmFocusCallback);
+ emscripten_set_focusout_callback (aTargetId, anOpaque, toUseCapture, onWasmFocusCallback);
#else
(void )theWin;
#endif
}
return false;
}
- case WM_ACTIVATE:
+ case WM_SETFOCUS:
+ case WM_KILLFOCUS:
{
if (theMsg.hwnd == (HWND )myHWindow)
{
- theListener.ProcessFocus (LOWORD(theMsg.wParam) == WA_CLICKACTIVE
- || LOWORD(theMsg.wParam) == WA_ACTIVE);
+ theListener.ProcessFocus (theMsg.message == WM_SETFOCUS);
return true;
}
return false;
{
return ProcessUiEvent (theListener, theEventType, (const EmscriptenUiEvent* )theEvent);
}
+ case EMSCRIPTEN_EVENT_FOCUS:
+ case EMSCRIPTEN_EVENT_FOCUSIN:
+ case EMSCRIPTEN_EVENT_FOCUSOUT:
+ {
+ return ProcessFocusEvent (theListener, theEventType, (const EmscriptenFocusEvent* )theEvent);
+ }
}
return false;
#else
return true;
}
+// =======================================================================
+// function : ProcessFocusEvent
+// purpose :
+// =======================================================================
+bool Wasm_Window::ProcessFocusEvent (Aspect_WindowInputListener& theListener,
+ int theEventType, const EmscriptenFocusEvent* )
+{
+ bool isActivated = false;
+#if defined(__EMSCRIPTEN__)
+ if (theEventType != EMSCRIPTEN_EVENT_FOCUS
+ && theEventType != EMSCRIPTEN_EVENT_FOCUSIN // about to receive focus
+ && theEventType != EMSCRIPTEN_EVENT_FOCUSOUT)
+ {
+ return false;
+ }
+ isActivated = theEventType == EMSCRIPTEN_EVENT_FOCUS;
+#else
+ (void )theEventType;
+#endif
+ theListener.ProcessFocus (isActivated);
+ return true;
+}
+
// =======================================================================
// function : MouseButtonsFromNative
// purpose :
struct EmscriptenTouchEvent;
struct EmscriptenKeyboardEvent;
struct EmscriptenUiEvent;
+struct EmscriptenFocusEvent;
//! This class defines WebAssembly window (HTML5 canvas) intended for creation of OpenGL (WebGL) context.
//!
Standard_EXPORT virtual bool ProcessUiEvent (Aspect_WindowInputListener& theListener,
int theEventType, const EmscriptenUiEvent* theEvent);
+ //! Process a focus input change message.
+ //! @param[in,out] theListener listener to redirect message
+ //! @param[in] theEventType message type to process
+ //! @param[in] theEvent message to process
+ //! @return TRUE if message has been processed
+ Standard_EXPORT virtual bool ProcessFocusEvent (Aspect_WindowInputListener& theListener,
+ int theEventType, const EmscriptenFocusEvent* theEvent);
+
protected:
TCollection_AsciiString myCanvasId;