BUGFIX: AltGr-key does not work, when connecting from Windows browser to Linux agent. (#5614)

Windows doesnt have a proper AltGr, but handles it using fake Ctrl+Alt. However the remote end might not be Windows, so we need to merge those into a single AltGr event. We detect this case by seeing the two key events directly after each other with a very short time between them.

wdlut committed Dec 7, 2023 at 04:48 UTC 6e4c8b0d164dd997b48fdbd32ad1be9532e4c360
1 file changed +56 -2
public/scripts/agent-desktop-0.0.2.js
+56 -2
@@ -7,6 +7,10 @@
7 // Polyfill Uint8Array.slice() for IE
8 if (!Uint8Array.prototype.slice) { Object.defineProperty(Uint8Array.prototype, 'slice', { value: function (begin, end) { return new Uint8Array(Array.prototype.slice.call(this, begin, end)); } }); }
9
10 +function isWindowsBrowser() {
11 + return navigator && !!(/win/i).exec(navigator.platform);
12 +}
13 +
14 // Construct a MeshServer object
15 var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
16 var obj = {}
@@ -37,6 +41,9 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
41 obj.localKeyMap = true;
42 obj.remoteKeyMap = false; // If false, the remote keyboard mapping is not used.
43 obj.pressedKeys = [];
44 + obj._altGrArmed = false; // Windows AltGr detection
45 + obj._altGrTimeout = 0;
46 + obj.isWindowsBrowser = isWindowsBrowser();
47
48 obj.sessionid = 0;
49 obj.username;
@@ -403,7 +410,16 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
410 if (!event) { event = window.event; }
411
412 var extendedKey = false; // Test feature, add ?extkeys=1 to url to use.
406 - if ((obj.UseExtendedKeyFlag || (urlargs.extkeys == 1)) && (typeof event.code == 'string') && (event.code.startsWith('Arrow') || (extendedKeyTable.indexOf(event.code) >= 0))) { extendedKey = true; }
413 +
414 + if ((obj.UseExtendedKeyFlag || (urlargs.extkeys == 1)) && (typeof event.code == 'string') && (event.code.startsWith('Arrow') || (extendedKeyTable.indexOf(event.code) >= 0))) {
415 + extendedKey = true;
416 + }
417 +
418 + if (obj.isWindowsBrowser) {
419 + if( obj.checkAltGr(obj, event, action) ) {
420 + return;
421 + };
422 + }
423
424 if ((extendedKey == false) && event.code && (event.code.startsWith('NumPad') == false) && (obj.localKeyMap == false)) {
425 // Convert "event.code" into a scancode. This works the same regardless of the keyboard language.
@@ -421,6 +437,44 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
437 }
438 }
439
440 + const ControlLeftKc = 17;
441 + const AltGrKc = 225;
442 + //return true: Key is alredy handled.
443 + obj.checkAltGr = function (obj, event, action) {
444 + // Windows doesn't have a proper AltGr, but handles it using
445 + // fake Ctrl+Alt. However the remote end might not be Windows,
446 + // so we need to merge those into a single AltGr event. We
447 + // detect this case by seeing the two key events directly after
448 + // each other with a very short time between them (<50ms).
449 + if (obj._altGrArmed) {
450 + obj._altGrArmed = false;
451 + clearTimeout(obj._altGrTimeout);
452 +
453 + if ((event.code === "AltRight") && ((event.timeStamp - obj._altGrCtrlTime) < 50)) {
454 + //AltGr detected.
455 + obj.SendKeyMsgKC( action, AltGrKc, false);
456 + return true;
457 + }
458 + }
459 +
460 + // Possible start of AltGr sequence?
461 + if ((event.code === "ControlLeft") && !(ControlLeftKc in obj.pressedKeys)) {
462 + obj._altGrArmed = true;
463 + obj._altGrCtrlTime = event.timeStamp;
464 + if( action == 1 ) {
465 + obj._altGrTimeout = setTimeout(obj._handleAltGrTimeout.bind(obj), 100);
466 + return true;
467 + }
468 + }
469 + return false;
470 + }
471 +
472 + obj._handleAltGrTimeout = function () { //Windows and no Ctrl+Alt -> send only Ctrl.
473 + obj._altGrArmed = false;
474 + clearTimeout(obj._altGrTimeout);
475 + obj.SendKeyMsgKC( 1, ControlLeftKc, false); // (KeyDown, "ControlLeft", false)
476 + }
477 +
478 // Send remote input lock. 0 = Unlock, 1 = Lock, 2 = Query
479 obj.SendRemoteInputLock = function (code) { obj.send(String.fromCharCode(0x00, 87, 0x00, 0x05, code)); }
480
@@ -456,7 +510,7 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
510
511 obj.SendKeyUnicode = function (action, val) {
512 if (obj.State != 3) return;
459 - if (obj.debugmode > 0) { console.log('Sending UnicodeKey ' + val); }
513 + if (obj.debugmode > 0) { console.log('Sending UnicodeKey ' + val + ', action ' + action); }
514 obj.send(String.fromCharCode(0x00, obj.InputType.KEYUNICODE, 0x00, 0x07, (action - 1)) + ShortToStr(val));
515 }
516