Skip to content

Conversation

spongeBor
Copy link

@spongeBor spongeBor commented Jun 6, 2025

问题背景:

  • 在 macOS 系统中,CapsLock 键有一个特殊的行为特点:
  • 当 CapsLock 灯常亮(激活状态)时,按下 CapsLock 键不会正常触发 keyup 事件
  • 这导致当 CapsLock 常亮时,其他的快捷键监听器无法正常工作
    修复方案:
  • 状态检测:使用 getModifierState('CapsLock') API 检测 CapsLock 的实际状态
  • 定时器备用机制:设置 100ms 定时器,防止真实 keyup 事件丢失
  • 模拟事件:当检测到状态变化或定时器触发时,创建模拟的 keyup 事件
  • 状态同步:确保内部状态与系统实际状态保持一致
    这个修复确保了即使在 CapsLock 灯常亮的情况下,相关的快捷键监听器也能正常工作。

Problem Background:

  • On macOS systems, the CapsLock key has a special behavioral characteristic:
  • When the CapsLock light is constantly on (activated state), pressing the CapsLock key does not properly trigger the keyup event
  • This causes other shortcut key listeners to not work properly when CapsLock is constantly lit
    Fix Solution:
  • State Detection: Use the getModifierState('CapsLock') API to detect the actual state of CapsLock
  • Timer Backup Mechanism: Set a 100ms timer to prevent real keyup events from being lost
  • Simulated Events: When state changes are detected or the timer triggers, create simulated keyup events
  • State Synchronization: Ensure internal state stays synchronized with the actual system state
    This fix ensures that even when the CapsLock light is constantly on, related shortcut key listeners can still work properly.

… CapsLock light is constantly on in macOS systems.
@jaywcjlove
Copy link
Owner

@spongeBor Based on my testing, when the Caps Lock key is active (indicator light is on), deactivating it causes the hotkey listener to stop responding to any key events.

@spongeBor
Copy link
Author

This bug is causing keyboard shortcuts to malfunction when using our company's tools. So far, we've only identified this particular scenario. Based on previous reports, the shortcut failure issue has also been encountered on Windows systems.

@jaywcjlove
Copy link
Owner

Based on my testing, when the Caps Lock key is active (indicator light is on), deactivating it causes the hotkey listener to stop responding to any key events.

@spongeBor Yes, I tested your code on my device, but unfortunately, it still doesn't resolve the issue where the hotkey listener stops working after toggling Caps Lock.

@spongeBor
Copy link
Author

I will check the code behavior later and get back to you.

@spongeBor
Copy link
Author

spongeBor commented Jun 7, 2025

截屏2025-06-07 22 29 38 你可以用图中的测试代码来验证当前bugfix 是有效的:
  • fix/mac_capslock分支没有执行build操作,所以在这个分支下可以直接验证这个bug的存在;
  • 当你在website页面按e可以在控制台有两个输出,按backspace在控制台也有两个输出,按其它按键只会有1个输出;当你长按caps Lock按键使绿灯长亮时,重复之前的操作,你会发现只有any的1个输出了,此时单纯按灭caps Lock的灯仍然无效,需要你再按一次capsLock才能恢复正常。
  • 执行npm run build 生成基于当前分支的的最新dist代码,重启website,再次执行上面的操作,你会发现,无论如何操作,e 和 backspace 的按键都会有两个输出。

You can use the test code in the image to verify that the current bugfix is effective:

  • The fix/mac_capslock branch has not executed the build operation, so you can directly verify the existence of this bug under this branch;
  • When you press 'e' on the website page, you can see two outputs in the console, and pressing backspace also produces two outputs in the console, while pressing other keys only produces 1 output; When you long-press the caps Lock key to make the green light stay on, repeat the previous operations, and you will find that there is only 1 output from 'any'. At this point, simply pressing to turn off the caps Lock light is still ineffective, and you need to press capsLock once more to restore normal operation.
  • Execute npm run build to generate the latest dist code based on the current branch, restart the website, and perform the above operations again. You will find that no matter how you operate, both 'e' and backspace keys will have two outputs.

@spongeBor
Copy link
Author

I've made some optimizations. If you encounter any other edge cases or unhandled scenarios, please inform me and I'll investigate this issue further.

@jaywcjlove
Copy link
Owner

@spongeBor I've pulled your branch and tested it, but the issue still persists. After holding down Caps Lock and then releasing it to deactivate, the key press events stop responding correctly.

image

@spongeBor
Copy link
Author

spongeBor commented Jun 9, 2025

I added a test commit. Please help verify whether it behaves consistently with what's described in this comment. From the test results, it appears the issue has been completely resolved.Looking forward to your reply.

@jaywcjlove
Copy link
Owner

@spongeBor You didn’t commit the test file—only the compiled files were included. I’ve compiled it locally, and unfortunately, the issue still persists. It hasn’t been resolved.

@spongeBor
Copy link
Author

spongeBor commented Jun 9, 2025

我用我的提到的测试方法一定是可行的,能否告知你是如何测试的,我来试下

@jaywcjlove
Copy link
Owner

@spongeBor 我的测试方法

  1. 克隆代码
  2. 编译代码
  3. 运行文档网站
  4. 长摁 CapsLock 灯常亮(激活状态)
  5. 再摁 CapsLock 灯不亮
  6. 再摁 CapsLock 就不触发事件了

我在 Chrome Version 137.0.7151.69 (Official Build) (arm64) 上测试的

@spongeBor
Copy link
Author

spongeBor commented Jun 10, 2025

经过我多次的测试,确实复现了您说的这个现象;

  • 这个现象无论是之前的代码还是当前的bugfix的代码都有存在;
  • 通过溯源,我发现该现象来源于在取消CapsLock激活状态后,再次点击CapsLock是不触发keyup和keydown事件的,这看起来更像是mac系统上浏览器事件监听器本身的bug所致,暂没有找到好的解决办法;
  • 这个bugfix 解决的问题是:在激活CapsLock 或者CapsLock被关闭后,单独监听的key无法响应的问题;如fix:Fix the issue where hotkey listeners cannot be triggered when the… #514 (comment) 所描述的那样。
  • 总结一下:之前的代码会在你激活capsLock或CapsLock被关闭后,单独监听的key值无法响应;bugfix解决了这个问题,唯独对capsLock无法在capsLock关闭后立即触发,但就算没有bugfix这个现象也存在;另外该bugfix可以让其他值触发后,恢复对capsLock的响应,这一点之前也是做不到的。
  • 从应用场景上来看,该bugfix虽然没有解决全部的问题(capsLock在关闭后的立即响应触发问题没有解决),但对于上面所提到场景的解决十分有力的,可以很好的解决我们的应用在使用中的困扰。

@spongeBor
Copy link
Author

我已经移除了站点的console.log代码,而且更新了dist部分代码,悉知

jaywcjlove added a commit that referenced this pull request Jun 10, 2025
github-actions bot pushed a commit that referenced this pull request Jun 10, 2025
@jaywcjlove
Copy link
Owner

jaywcjlove commented Jun 10, 2025

这个bugfix 解决的问题是:在激活CapsLock 或者CapsLock被关闭后,单独监听的key无法响应的问题;

我终于明白了问题出现在哪里,我测试的时候顺手修复了这个问题,我的方法是直接排除 CapsLock 键 @spongeBor

@jaywcjlove
Copy link
Owner

@spongeBor 噢,我又想了想,CapsLock 在 macOS 下面是问题键,在windows和 Linux 上可能不是,是不是这个bug 修复得有点大意了,是否需要在 加个判断是否只是在 macOS/iOS 下才排除 CapsLock

@jaywcjlove
Copy link
Owner

hotkeys-js/src/index.js

Lines 103 to 109 in 194b93c

if (event.key) {
// Ensure that when capturing keystrokes in modern browsers,
// uppercase and lowercase letters (such as R and r) return the same key value.
// https://github.com/jaywcjlove/hotkeys-js/pull/514
// https://developer.mozilla.org/zh-CN/docs/Web/API/KeyboardEvent/key
key = code(event.key);
}

在 macOS 下面摁下大写之后 key code 不一样 @spongeBor

@spongeBor
Copy link
Author

排除capsLock确实是一个简单的修复方式;

  • 我之前的考量也是尽量不影响其他端的用户
  • 但从业务角度来看需要监听capslock的情况非常少,至少在我们的工具类应用中没有见过这种用法;
  • 从使用习惯来讲这个键也是有固定功能键,除非故意而为之,一般也不太可能出现在正常的应用中;
  • 直接排除掉这个键或许也能避免很多奇怪的使用场景

@jaywcjlove
Copy link
Owner

@spongeBor 感谢🙏,我关闭掉 PR,根据你的分析,我觉得没有必要去考虑其它平台是否需要排除 capslock,这样可以保持一致,避免奇怪的兼容问题

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants