diff --git a/web/source/kmwosk.ts b/web/source/kmwosk.ts index f43ebc0594..bc1fe34cf3 100644 --- a/web/source/kmwosk.ts +++ b/web/source/kmwosk.ts @@ -3094,26 +3094,53 @@ if(!window['keyman']['initialized']) { * @return {boolean} */ osk.emulatesAltGr = function(keyLabels) { - var activeKeyboard = keymanweb.keyboardManager.activeKeyboard; - if(activeKeyboard == null || activeKeyboard['KV'] == null) { + var layers; + + // If we're not chiral, we're not emulating. + if(!keymanweb.keyboardManager.isChiral()) { return false; } - var layers = keyLabels ? keyLabels : activeKeyboard['KV']['KLS']; + if(!keyLabels) { + var activeKeyboard = keymanweb.keyboardManager.activeKeyboard; + if(activeKeyboard == null || activeKeyboard['KV'] == null) { + return false; + } + + layers = activeKeyboard['KV']['KLS']; + } else { + layers = keyLabels; + } - var unshiftedEmulationLayer = layers[osk.getLayerId(osk.modifierCodes['LCTRL'] | osk.modifierCodes['LALT'])]; - var shiftedEmulationLayer = layers[osk.getLayerId(osk.modifierCodes['SHIFT'] | osk.modifierCodes['LCTRL'] | osk.modifierCodes['LALT'])]; + var emulationMask = osk.modifierCodes['LCTRL'] | osk.modifierCodes['LALT']; + + var unshiftedEmulationLayer = layers[osk.getLayerId(emulationMask)]; + var shiftedEmulationLayer = layers[osk.getLayerId(osk.modifierCodes['SHIFT'] | emulationMask)]; // buildDefaultLayout ensures that these are aliased to the original modifier set being emulated. // As a result, we can directly test for reference equality. - if(unshiftedEmulationLayer != layers[osk.getLayerId(osk.modifierCodes['RALT'])]) { + if(unshiftedEmulationLayer != null && + unshiftedEmulationLayer != layers[osk.getLayerId(osk.modifierCodes['RALT'])]) { return false; } - if(shiftedEmulationLayer != layers[osk.getLayerId(osk.modifierCodes['RALT'] | osk.modifierCodes('SHIFT'))]) { + if(shiftedEmulationLayer != null && + shiftedEmulationLayer != layers[osk.getLayerId(osk.modifierCodes['RALT'] | osk.modifierCodes['SHIFT'])]) { return false; } + // It's technically possible for the OSK to not specify anything while allowing chiral input. A last-ditch catch: + + var bitmask = keymanweb.keyboardManager.getKeyboardModifierBitmask(); + if((bitmask & emulationMask) != emulationMask) { + // At least one of the emulation modifiers is never used by the keyboard! We can confirm everything's safe. + return true; + } + + if(unshiftedEmulationLayer == null && shiftedEmulationLayer == null) { + // We've run out of things to go on; we can't detect if chiral AltGr emulation is intended or not. + console.warn("Could not detect if AltGr emulation is safe, but defaulting to active emulation!") + } return true; } @@ -3160,11 +3187,17 @@ if(!window['keyman']['initialized']) { validIdList = [ 'default' ].concat(validIdList); // Automatic AltGr emulation if the 'leftctrl-leftalt' layer is otherwise undefined. - if(osk.emulatesAltGr(keyLabels) && validIdList.indexOf('rightalt') != -1) { - validIdList.push('leftctrl-leftalt'); - validIdList.push('leftctrl-leftalt-shift'); - keyLabels['leftctrl-leftalt'] = keyLabels['rightalt']; - keyLabels['leftctrl-leftalt-shift'] = keyLabels['rightalt-shift']; + if(osk.emulatesAltGr(keyLabels)) { + // We insert only the layers that need to be emulated. + if((validIdList.indexOf('leftctrl-leftalt') == -1) && validIdList.indexOf('rightalt') != -1) { + validIdList.push('leftctrl-leftalt'); + keyLabels['leftctrl-leftalt'] = keyLabels['rightalt']; + } + + if((validIdList.indexOf('leftctrl-leftalt-shift') == -1) && validIdList.indexOf('rightalt-shift') != -1) { + validIdList.push('leftctrl-leftalt-shift'); + keyLabels['leftctrl-leftalt-shift'] = keyLabels['rightalt-shift']; + } } // For desktop devices, we must create all layers, even if invalid. diff --git a/web/unit_tests/resources/keyboards/test_chirality.js b/web/unit_tests/resources/keyboards/test_chirality.js index da50da1312..1011b551b3 100644 --- a/web/unit_tests/resources/keyboards/test_chirality.js +++ b/web/unit_tests/resources/keyboards/test_chirality.js @@ -1 +1 @@ -if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_test_chirality());}function Keyboard_test_chirality(){this.KI="Keyboard_test_chirality";this.KN="KeymanWeb Chirality Tester";this.KMINVER="10.0";this.KV={F:' 1em "Arial"',K102:0};this.KDU=1;this.KLS={};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KLS);this.KH='';this.KM=0;this.KBVER="1.0";this.KMBM=0x031F;this.KVER="10.0.1014.0";this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16658,65)) {r=m=1;k.KO(0,t,"CAPSLOCK_RC_CAP_a");}else if(k.KKM(e,16666,65)) {r=m=1;k.KO(0,t,"CAPSLOCK_RCA_CAP_a");}else if(k.KKM(e,16664,65)) {r=m=1;k.KO(0,t,"CAPSLOCK_RA_CAP_a");}else if(k.KKM(e,16657,65)) {r=m=1;k.KO(0,t,"CAPSLOCK_LC_CAP_a");}else if(k.KKM(e,16660,65)) {r=m=1;k.KO(0,t,"CAPSLOCK_LA_CAP_a");}else if(k.KKM(e,16642,65)) {r=m=1;k.KO(0,t,"CAPSLOCK_RC_a");}else if(k.KKM(e,16650,65)) {r=m=1;k.KO(0,t,"CAPSLOCK_RCA_a");}else if(k.KKM(e,16648,65)) {r=m=1;k.KO(0,t,"CAPSLOCK_RA_a");}else if(k.KKM(e,16644,65)) {r=m=1;k.KO(0,t,"CAPSLOCK_LA_a");}else if(k.KKM(e,16641,65)) {r=m=1;k.KO(0,t,"CAPSLOCK_LC_a");}else if(k.KKM(e,16645,65)) {r=m=1;k.KO(0,t,"CAPSLOCK_LCA_a");}else if(k.KKM(e,16644,65)) {r=m=1;k.KO(0,t,"CAPSLOCK_LA_a");}else if(k.KKM(e,16641,65)) {r=m=1;k.KO(0,t,"CAPSLOCK_LC_a");}else if(k.KKM(e,16914,65)) {r=m=1;k.KO(0,t,"RC_CAP_a");}else if(k.KKM(e,16922,65)) {r=m=1;k.KO(0,t,"RCA_CAP_a");}else if(k.KKM(e,16920,65)) {r=m=1;k.KO(0,t,"RA_CAP_a");}else if(k.KKM(e,16913,65)) {r=m=1;k.KO(0,t,"LC_CAP_a");}else if(k.KKM(e,16916,65)) {r=m=1;k.KO(0,t,"LA_CAP_a");}else if(k.KKM(e,16898,65)) {r=m=1;k.KO(0,t,"RC_a");}else if(k.KKM(e,16906,65)) {r=m=1;k.KO(0,t,"RCA_a");}else if(k.KKM(e,16904,65)) {r=m=1;k.KO(0,t,"RA_a");}else if(k.KKM(e,16900,65)) {r=m=1;k.KO(0,t,"LA_a");}else if(k.KKM(e,16897,65)) {r=m=1;k.KO(0,t,"LC_a");}else if(k.KKM(e,16901,65)) {r=m=1;k.KO(0,t,"LCA_a");}else if(k.KKM(e,16900,65)) {r=m=1;k.KO(0,t,"LA_a");}else if(k.KKM(e,16897,65)) {r=m=1;k.KO(0,t,"LC_a");}else if(k.KKM(e,16640,65)) {r=m=1;k.KO(0,t,"CAPSLOCK_DF_a");}else if(k.KKM(e,16912,65)) {r=m=1;k.KO(0,t,"DF_CAP_a");}else if(k.KKM(e,16656,65)) {r=m=1;k.KO(0,t,"CAPSLOCK_DF_CAP_a");}else if(k.KKM(e,16896,65)) {r=m=1;k.KO(0,t,"DF_a");}else if(k.KKM(e,16384,66)) {r=m=1;k.KO(0,t,"b");}return r;};} \ No newline at end of file +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_test_chirality());}function Keyboard_test_chirality(){this.KI="Keyboard_test_chirality";this.KN="KeymanWeb Chirality Tester";this.KMINVER="10.0";this.KV={F:' 1em "Arial"',K102:0};this.KDU=1;this.KV.KLS={};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KV.KLS);this.KH='';this.KM=0;this.KBVER="1.0";this.KMBM=0x031F;this.KVER="10.0.1057.0";this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16658,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"CAPSLOCK_RC_CAP_a");}else if(k.KKM(e,16666,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"CAPSLOCK_RCA_CAP_a");}else if(k.KKM(e,16664,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"CAPSLOCK_RA_CAP_a");}else if(k.KKM(e,16657,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"CAPSLOCK_LC_CAP_a");}else if(k.KKM(e,16660,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"CAPSLOCK_LA_CAP_a");}else if(k.KKM(e,16642,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"CAPSLOCK_RC_a");}else if(k.KKM(e,16650,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"CAPSLOCK_RCA_a");}else if(k.KKM(e,16648,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"CAPSLOCK_RA_a");}else if(k.KKM(e,16644,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"CAPSLOCK_LA_a");}else if(k.KKM(e,16641,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"CAPSLOCK_LC_a");}else if(k.KKM(e,16645,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"CAPSLOCK_LCA_a");}else if(k.KKM(e,16644,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"CAPSLOCK_LA_a");}else if(k.KKM(e,16641,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"CAPSLOCK_LC_a");}else if(k.KKM(e,16914,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"RC_CAP_a");}else if(k.KKM(e,16922,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"RCA_CAP_a");}else if(k.KKM(e,16920,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"RA_CAP_a");}else if(k.KKM(e,16913,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"LC_CAP_a");}else if(k.KKM(e,16916,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"LA_CAP_a");}else if(k.KKM(e,16898,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"RC_a");}else if(k.KKM(e,16906,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"RCA_a");}else if(k.KKM(e,16904,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"RA_a");}else if(k.KKM(e,16900,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"LA_a");}else if(k.KKM(e,16897,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"LC_a");}else if(k.KKM(e,16901,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"LCA_a");}else if(k.KKM(e,16900,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"LA_a");}else if(k.KKM(e,16897,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"LC_a");}else if(k.KKM(e,16640,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"CAPSLOCK_DF_a");}else if(k.KKM(e,16912,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"DF_CAP_a");}else if(k.KKM(e,16656,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"CAPSLOCK_DF_CAP_a");}else if(k.KKM(e,16896,65)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"DF_a");}else if(k.KKM(e,16384,66)) {r=m=1;k.KDC(0,t);k.KO(-1,t,"b");}return r;};} \ No newline at end of file diff --git a/web/unit_tests/resources/keyboards/test_chirality.kmn b/web/unit_tests/resources/keyboards/test_chirality.kmn index eb870422e4..e0d4ecbe90 100644 --- a/web/unit_tests/resources/keyboards/test_chirality.kmn +++ b/web/unit_tests/resources/keyboards/test_chirality.kmn @@ -1,8 +1,6 @@ store(&TARGETS) 'any web desktop' store(©RIGHT) '© 2018 SIL International' store(&VISUALKEYBOARD) 'test_chirality.kvks' -store(&LANGUAGE) 'x0409' -store(&WINDOWSLANGUAGES) 'x0409' store(&NAME) 'KeymanWeb Chirality Tester' begin Unicode > use(main) diff --git a/web/unit_tests/resources/keyboards/test_chirality.kmx b/web/unit_tests/resources/keyboards/test_chirality.kmx index 8e276f650a..9eed989545 100644 Binary files a/web/unit_tests/resources/keyboards/test_chirality.kmx and b/web/unit_tests/resources/keyboards/test_chirality.kmx differ