From d4cf2f3ef431a4046d6578c2743c9a134cea9a4e Mon Sep 17 00:00:00 2001 From: Matt Godbolt Date: Sat, 14 Sep 2024 16:33:48 -0500 Subject: [PATCH] Mitigations for OS X caps lock Caps lock is treated like a "sticky" key in OS X. So...treat it like a "tap". Fixes #297 and at least warns about #29 --- main.js | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/main.js b/main.js index 8df1fbe0..d4942925 100644 --- a/main.js +++ b/main.js @@ -65,6 +65,7 @@ let audioFilterFreq = 7000; let audioFilterQ = 5; let stationId = 101; let econet = null; +const isMac = window.navigator.platform.indexOf("Mac") === 0; if (queryString) { if (queryString[queryString.length - 1] === "/") @@ -444,11 +445,14 @@ function keyDown(evt) { } else if (code === utils.keyCodes.B && evt.ctrlKey) { // Ctrl-B turns on the printer, so we open a printer output // window in addition to passing the keypress along to the beeb. - processor.sysvia.keyDown(keyCode(evt), evt.shiftKey); + processor.sysvia.keyDown(code, evt.shiftKey); evt.preventDefault(); checkPrinterWindow(); + } else if (isMac && code === utils.keyCodes.CAPSLOCK) { + handleMacCapsLock(); + evt.preventDefault(); } else { - processor.sysvia.keyDown(keyCode(evt), evt.shiftKey); + processor.sysvia.keyDown(code, evt.shiftKey); evt.preventDefault(); } } @@ -461,16 +465,33 @@ function keyUp(evt) { if (!running) return; if (evt.altKey) { const handler = emuKeyHandlers[code]; - if (handler) { - handler(false, code); - evt.preventDefault(); - } + if (handler) handler(false, code); } else if (code === utils.keyCodes.F12 || code === utils.keyCodes.BREAK) { processor.setReset(false); + } else if (isMac && code === utils.keyCodes.CAPSLOCK) { + handleMacCapsLock(); } evt.preventDefault(); } +function handleMacCapsLock() { + // Mac browsers seem to model caps lock as a physical key that's down when capslock is on, and up when it's off. + // No event is generated when it is physically released on the keyboard. So, we simulate a "tap" here. + processor.sysvia.keyDown(utils.keyCodes.CAPSLOCK); + setTimeout(() => processor.sysvia.keyUp(utils.keyCodes.CAPSLOCK), 100); + if (!window.localStorage.getItem("warnedAboutRubbishMacs")) { + showError( + "handling caps lock on Mac OS X", + "Mac OS X does not generate key up events for caps lock presses. " + + "jsbeeb can only simulate a 'tap' of the caps lock key. This means it doesn't work well for games " + + " that use caps lock for left or fire, as we can't tell if it's being held down. If you need to play " + + "such a game, please see the documentation about remapping keys." + + "Close this window to continue (you won't see this error again)", + ); + window.localStorage.setItem("warnedAboutRubbishMacs", true); + } +} + const $discsModal = new bootstrap.Modal(document.getElementById("discs")); const $fsModal = new bootstrap.Modal(document.getElementById("econetfs"));