I'm working on a project that aims to render a RDP connection in a browser (mobile and desktop) using Apache Guacamole. For the UI, I'm using ReactJS and guacamole-common-js. Everything works as expected on both platforms, other than the keyboard not being triggered on mobile browser.
const GuacdPage = (props) => {
const {connectionParam, onError, onStateChange, onSync} = props;
const [guacd, setGuacd] = useState({});
useEffect(() => {
console.log('initial effect starting')
renderDisplay();
}, []);
const renderDisplay = () => {
const tunnel = new Guacamole.WebSocketTunnel("/api/ws");
const client = new Guacamole.Client(tunnel);
client.onerror = onError;
client.onsync = onSync;
client.onstatechange = onStateChange
// Get display div from document
const displayEle = document.getElementById("display");
// Add client to display div
const element = client.getDisplay().getElement();
displayEle.appendChild(element);
client.connect("connection=" + connectionParam);
const display = client.getDisplay();
const sink = new Guacamole.InputSink();
displayEle.appendChild(sink.getElement());
sink.focus();
const keyboard = new Guacamole.Keyboard(sink.getElement());
keyboard.onkeydown = (keysym) => {
client.sendKeyEvent(1, keysym);
};
keyboard.onkeyup = (keysym) => {
client.sendKeyEvent(0, keysym);
};
const mouse = new Guacamole.Mouse(element);
mouse.onmousedown = mouse.onmouseup = function(mouseState) {
sink.focus();
client.sendMouseState(mouseState);
};
mouse.onmousemove = function(mouseState) {
sink.focus();
client.getDisplay().showCursor(false);
mouseState.x = mouseState.x / display.getScale();
mouseState.y = mouseState.y / display.getScale();
client.sendMouseState(mouseState);
};
const touch = new Guacamole.Mouse.Touchscreen(element);
touch.onmousedown = touch.onmousemove = touch.onmouseup = function(state) {
client.sendMouseState(state);
};
window.addEventListener("resize", handleResize);
return () => {
client.disconnect()
window.removeEventListener("resize", handleResize)
}
};
const handleResize = () => {
const width = document.body.offsetWidth
const height = document.body.offsetHeight
guacd.client.sendSize(width, height);
}
return (
<div>
<div className="container">
<div id="display" />
</div>
</div>
);
};
export default GuacdPage;
I have tried two solutions:
- Using an InputSink
- Using an OnScreenKeyboard
The 2nd method renders a "list of keys" on screen with no effect, and the 1st does nothing - I think the issue has to do how the focus is being handled. I'm not sure if I need to be creating a dedicated input field for the input sink.
Any input would be greatly appreciated. Thanks