squirrel icon indicating copy to clipboard operation
squirrel copied to clipboard

shift切换中英文经常出现不希望的切换

Open netjune opened this issue 5 years ago • 29 comments

单独按shift切换是正常的, 但是经常遇到shift+其他按键组合也会切换中英文, 比如用shift加字母来输入大写, 也会切换中英文, 出现频率非常高, 非常不方便, 请问有什么解决办法吗?

netjune avatar Nov 13 '19 02:11 netjune

按照程序逻辑,Shift键按下到放开的过程中按下了其他字符按键,如字母键,是不会发生切换的。只有快速单击Shift键才会切换。 题中所述的问题在这种情况下未能重现。 需要您提供进一步的线索,例如是否只在某个特定应用里发生该问题? 这可能是个别应用处理键盘事件导致冲突,也可能是键盘硬件故障Shift键产生了快速重复按键的信号。 另外请仔细观察记录发生故障时的按键动作。是否有未觉察到的短暂单击Shift键的动作。 如果Shift做切换键不合适,可以考虑在配置里禁用,改成Control键或者使用组合键。 新的配置里有一组备选的快捷键,其中中西文切换使用 Shift+space: https://github.com/rime/rime-prelude/blob/master/key_bindings.yaml#L59

lotem avatar Nov 13 '19 02:11 lotem

进一步测试了一下, 发现有以下规律:

  1. shift与非字母键组合输入时容易出现, 比如shift+回车组合, 如果按键之后, 先松开回车, 则不会切换, 如果两者同时松开, 基本都会出现.
  2. shift与字母键组合确实不太容易出现, 之前反馈不准确.

netjune avatar Nov 13 '19 02:11 netjune

之前测试是在emacs里会出现, 现在又试了几个其他程序, 浏览器文本框, 系统备忘录, vscode, 都不会出现.

现在确定的是在emacs里会出现, 比如shift+回车组合, shift+backspace, 都会出现. 用的是emacs-26.3修改版. 正在测试master版本看会不会出现.

netjune avatar Nov 13 '19 15:11 netjune

测试了emacs的master版本, 也会出现此问题.

netjune avatar Nov 13 '19 15:11 netjune

这种问题该怎么调试啊? 什么情况下应用程序会影响系统输入法状态? 难道它给把一个按键事件发送给了系统? 比如发送了shift按键事件给系统? 然后系统再传给输入法?

我的理解是按键事件首先被输入法截获, 然后转换后才传给应用程序.

netjune avatar Nov 14 '19 02:11 netjune

这种问题该怎么调试啊? 什么情况下应用程序会影响系统输入法状态? 难道它给把一个按键事件发送给了系统? 比如发送了shift按键事件给系统? 然后系统再传给输入法?

我的理解是按键事件首先被输入法截获, 然后转换后才传给应用程序.

macOS 上輸入法可能不是首先處理鍵盤事件的。 Shift鍵的要點在於,切換發生在keyup事件,在此之前應用有可能響應了Shift keydown,以及key up之前的字符按鍵。

順便提一下,我用 emacs 26.2 測試未能重現。 或許是某些配置包導致的問題。請務必用 emacs -Q 在無配置狀態下測試。

lotem avatar Nov 14 '19 03:11 lotem

順便提一下,我用 emacs 26.2 測試未能重現。 或許是某些配置包導致的問題。請務必用 emacs -Q 在無配置狀態下測試。

我测试了一下emacs 26.2, 也能重现, 是用的emacs -Q. 重现使用shift+回车, 操作要点: 按键后, 两键要同时松开, 必然重现. 如果回车键先松开, shift延后几百毫秒松开, 那么不会出现.

可能是我按键比较快, 但是同样的操作速度, 在其他程序里不会重现, 目前只有emacs会出现此问题.

netjune avatar Nov 15 '19 05:11 netjune

macOS 上輸入法可能不是首先處理鍵盤事件的。 Shift鍵的要點在於,切換發生在keyup事件,在此之前應用有可能響應了Shift keydown,以及key up之前的字符按鍵。

这一段不是很理解, 你是说键盘事件先到应用程序, 然后再到输入法? 是不是有部分事件被应用处理了之后, 到不了输入法? 另外, 这些事件被应用处理过程中, 应用能修改事件或者插入一些新的按键事件吗?

Shift鍵的要點在於,切換發生在keyup事件,在此之前應用有可能響應了Shift keydown,以及key up之前的字符按鍵。

shift的keyup事件最终是传给了输入法, 才导致中英文切换的吧? 这样的话, 跟应用之前响应的shift keydown等事件有什么关系吗?

我们现在只针对shift加回车组合键来分析一下.

比如, 我在macvim里也用同样的速度按shift+回车, 输入法中英为没有切换, 但是在emacs里, 就会导致输入法中英文切换, 几乎百分百出现.

  1. 在macvim中, shift加回车组合键的keydown和keyup事件全部被macvim处理了, 输入法什么也没收到, 所以不切换中英文?
  2. 在emacs中, 输入法是收到了一个(仅)shift短暂按下并松开的事件, 所以切换了中英文? 即emacs把shift加回车组合键的keydown事件处理了, 然后把keyup事件留给了输入法? 这个keyup可能不止一个, 先是一个回车键的keyup, 然后是shift键的keyup.

请问怎么打开输入法的日志, 让它记录一下收到了哪些键盘事件?

netjune avatar Nov 18 '19 17:11 netjune

https://github.com/rime/librime/blob/master/src/rime/engine.cc#L99 Debug build會輸出這項日誌。Release build沒有。

我猜測是emacs處理了Shift keydown和Shift keyup之間的其他字符按鍵事件,輸入法不知道Shift鍵和字符鍵並用。

問題是我也一直使用Emacs,系統是macOS 10.14.6,並未遇到過這種情況。

lotem avatar Nov 19 '19 02:11 lotem

https://github.com/rime/librime/blob/master/src/rime/engine.cc#L99 Debug build會輸出這項日誌。Release build沒有。

这个有点难度, 抽时间尝试一下.

我猜測是emacs處理了Shift keydown和Shift keyup之間的其他字符按鍵事件,輸入法不知道Shift鍵和字符鍵並用。

就是说emacs过滤掉了回车的按键事件? 但是shift加普通字母或数字符号键组合不会出问题, 只有跟回车, tab, backspace, F1, F2等这些会出问题, 可能emacs对两者处理不一样.

問題是我也一直使用Emacs,系統是macOS 10.14.6,並未遇到過這種情況。

我的系统是10.13.6, 可以稳定重现.

netjune avatar Nov 19 '19 11:11 netjune

Mac上Emacs會先於輸入法處理按鍵(功能鍵、組合鍵),這一點幾乎可以確認。 因爲 C-` 在Emacs裏無法打開方案選單,而是被Emacs截獲並報錯 C-` is undefinedF4 也無效。

lotem avatar Nov 20 '19 03:11 lotem

那很可能是emacs把shift加回车的keydown和回车的keyup事件都处理掉了, 最后到输入法可能就剩了一个shift的keyup事件(先松开回车, 然后松开shift).

netjune avatar Nov 20 '19 06:11 netjune

我给emacs提交了个bug, 看有没有效果. https://debbugs.gnu.org/cgi/bugreport.cgi?bug=38293

netjune avatar Nov 20 '19 08:11 netjune

在 Xcode 中使用 XVim 插件的情况下有类似问题,在 Normal 模式下按大写字母的命令时会触发 shift 切换中英文,感觉和你的问题类似。 Debug 查了下 handleEvent 是无法接收到 Normal 模式的字母按键输入(但 Shift 键可以)。可能除了监听系统全局按键之外无法避免被其他程序处理掉的按键了。

-- 另外请问我想临时调整一下 Shift 的短按长按的时长判断,是否有配置项可以调整? 用于临时解决这个问题。

JoneWang avatar Dec 13 '19 17:12 JoneWang

在 Xcode 中使用 XVim 插件的情况下有类似问题,在 Normal 模式下按大写字母的命令时会触发 shift 切换中英文,感觉和你的问题类似。 Debug 查了下 handleEvent 是无法接收到 Normal 模式的字母按键输入(但 Shift 键可以)。可能除了监听系统全局按键之外无法避免被其他程序处理掉的按键了。

看上去字母的按键事件被程序吃掉了, 然后把一个shift给传出来了. 这个shift的事件是keyup吗? 还是keydown加keyup?

另外, 跟emacs的情况有一点差别: emacs里shift加字母不会出现这情况, shift加回车或者f1,f2这种会出现. 感觉上app完全有能力控制shift按键是否传出来. 但是我看不懂objc代码, 没法具体分析.

-- 另外请问我想临时调整一下 Shift 的短按长按的时长判断,是否有配置项可以调整? 用于临时解决这个问题。

你是说让它忽略掉持续时间短的? 这样也不太好, 不能shift快速切换了. 最好是收到shift的keydown时记录状态, 然后等收到shift的keyup后切换.

netjune avatar Jan 14 '20 17:01 netjune

Mac上Emacs會先於輸入法處理按鍵(功能鍵、組合鍵),這一點幾乎可以確認。 因爲 C-` 在Emacs裏無法打開方案選單,而是被Emacs截獲並報錯 C-` is undefined 。F4 也無效。

C-`無法打開方案選單的問題除了用emacs-rime還有別的解決方法嗎?

jameswhqi avatar Aug 14 '20 06:08 jameswhqi

我设置了用ctrl来切换中英文,但是在iterm中也会出现这种情况,用组合键的时候基本都会中英文乱跳

cledwynl avatar Nov 26 '20 03:11 cledwynl

您好,我在多个需要使用 shift+enter 来换行的程序中复现了这个问题,我想问一下现在是否有什么解决方案?

xiaolanglanglang avatar Feb 18 '22 07:02 xiaolanglanglang

我现在使用的方式几乎完美解决了这个问题,但需要依赖 Karabiner-Elements:

  1. 禁用 Squirrel 自己的中英切换;
  2. 将系统中输入源仅保留英文和 Squirrel;
  3. 将切换输入法的快捷键修改为 F13;
  4. 在 Karabiner-Elements 中将 left_shift(或其他你想设置的键,例如 left_control)映射到 F13。

这样设置后,如果 left_shift 单独按就是切换输入法,如果是 left_shift + 其他键 就只会触发组合键功能, 这不是解决 Squirrel 切换中英问题,本质上是在切换系统的输入源,但可以完美解决在 vim、Xcode 等软件中组合键被识别成切换中英的问题。

JoneWang avatar Feb 18 '22 13:02 JoneWang

我现在使用的方式几乎完美解决了这个问题,但需要依赖 Karabiner-Elements:

  1. 禁用 Squirrel 自己的中英切换;
  2. 将系统中输入源仅保留英文和 Squirrel;
  3. 将切换输入法的快捷键修改为 F13;
  4. 在 Karabiner-Elements 中将 left_shift(或其他你想设置的键,例如 left_control)映射到 F13。

这样设置后,如果 left_shift 单独按就是切换输入法,如果是 left_shift + 其他键 就只会触发组合键功能, 这不是解决 Squirrel 切换中英问题,本质上是在切换系统的输入源,但可以完美解决在 vim、Xcode 等软件中组合键被识别成切换中英的问题。

我一直是这么做的,但有个问题,在iterm2里使用vim,经常会按了shift之后,系统显示的输入法已经切换到鼠须管,但实际出的还是英文。再连续切换两次,进入鼠须管后,变成正常的中文。在钉钉里也能复现,其他app不出现。

YLShiJustFly avatar Jun 22 '22 12:06 YLShiJustFly

这时候状态栏的标志也有问题。 image

YLShiJustFly avatar Jun 22 '22 12:06 YLShiJustFly

更新到最新版本0.16.2, 这个问题还存在. 比如在emacs里, shift与enter或backspace的组合键, 会切换中英文

netjune avatar Mar 28 '23 16:03 netjune

我这边也有相同问题,可能和 osx 上面有的软件(Karabiner-Elements)有关,我的现象是按下 shift 就会触发,看上去像是 shift down 和 shift up 一起触发了,但是 shift + space 的全角半角切换却挺正常的(一样会触发中英文切换),有空换个 debug 看看日志

zeromake avatar Oct 14 '23 02:10 zeromake

@lotem   我自己尝试编译却发现 cmake 版本太高, librime/deps/googletest 依赖的 cmake_minimum_required(VERSION 2.8.12)。 尝试更新 librime 到最新发现 squirrel 的 makefile 没有适配一些 xcode 的 target 消失了,手动改成没有 xcode 开头的。 发现编译错误:

/Users/zero/project/squirrel/SquirrelInputController.m:232:31: error: no member named 'change_page' in 'struct rime_api_t'
    handled = rime_get_api()->change_page(_session, True);
              ~~~~~~~~~~~~~~  ^
/Users/zero/project/squirrel/SquirrelInputController.m:234:31: error: no member named 'change_page' in 'struct rime_api_t'
    handled = rime_get_api()->change_page(_session, False);

 看起来是 squirrel 未适配最新版本 librime ?是否有编译好的 debug 版本的 squirrel

zeromake avatar Oct 16 '23 02:10 zeromake

 看起来是 squirrel 未适配最新版本 librime ?是否有编译好的 debug 版本的 squirrel

用 git 子模块引用的 librime 版本。

lotem avatar Oct 16 '23 02:10 lotem

@lotem 手动下载 cmake 2x 版,也会报错,我在考虑直接用 github action 编译一个算了

> ~/p/squirrel on master ◦ cmake --version                      (base) 11:06:57
cmake version 2.8.12.2
⋊> ~/p/squirrel on master ◦ make debug                           (base) 11:07:12
/Applications/Xcode.app/Contents/Developer/usr/bin/make librime
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C librime xcode/deps
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f xcode.mk deps
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f deps.mk
cd /Users/zero/project/squirrel/librime/deps/googletest; \
	cmake . -Bbuild \
	-DBUILD_GMOCK:BOOL=OFF \
	-DCMAKE_BUILD_TYPE:STRING="Release" \
	-DCMAKE_INSTALL_PREFIX:PATH="/Users/zero/project/squirrel/librime" \
	&& cmake --build build --target install
-- The C compiler identification is unknown
-- The CXX compiler identification is unknown
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- broken
CMake Error at /Users/zero/Downloads/cmake/CMake.app/Contents/share/cmake-2.8/Modules/CMakeTestCCompiler.cmake:61 (message):
  The C compiler "/usr/bin/cc" is not able to compile a simple test program.

  It fails with the following output:

   Change Dir: /Users/zero/project/squirrel/librime/deps/googletest/build/CMakeFiles/CMakeTmp



  Run Build Command:/usr/bin/make "cmTryCompileExec2916201814/fast"

  /Applications/Xcode.app/Contents/Developer/usr/bin/make -f
  CMakeFiles/cmTryCompileExec2916201814.dir/build.make
  CMakeFiles/cmTryCompileExec2916201814.dir/build

  /Users/zero/Downloads/cmake/CMake.app/Contents/bin/cmake -E
  cmake_progress_report
  /Users/zero/project/squirrel/librime/deps/googletest/build/CMakeFiles/CMakeTmp/CMakeFiles
  1

  Building C object
  CMakeFiles/cmTryCompileExec2916201814.dir/testCCompiler.c.o

  /usr/bin/cc -o CMakeFiles/cmTryCompileExec2916201814.dir/testCCompiler.c.o
  -c
  /Users/zero/project/squirrel/librime/deps/googletest/build/CMakeFiles/CMakeTmp/testCCompiler.c


  clang: error: invalid version number in
  'MACOSX_DEPLOYMENT_TARGET=$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)'

  make[6]: *** [CMakeFiles/cmTryCompileExec2916201814.dir/testCCompiler.c.o]
  Error 1

  make[5]: *** [cmTryCompileExec2916201814/fast] Error 2





  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:10 (project)


-- Configuring incomplete, errors occurred!
See also "/Users/zero/project/squirrel/librime/deps/googletest/build/CMakeFiles/CMakeOutput.log".
See also "/Users/zero/project/squirrel/librime/deps/googletest/build/CMakeFiles/CMakeError.log".
make[4]: *** [gtest] Error 1
make[3]: *** [deps] Error 2
make[2]: *** [xcode/deps] Error 2
make[1]: *** [librime/lib/libmarisa.a] Error 2
make: *** [lib/librime.1.dylib] Error 2

zeromake avatar Oct 16 '23 03:10 zeromake

这个问题在 Swift 版本的 Telegram 中也可以得到复现. 具体步骤如下:

  1. Focus 到消息输入框
  2. 使用 Squirrel 输入中文并上屏
  3. Shift + Enter 换行
  4. 发现 Squirrel 的输入模式被切换到了英文输入

s-kk avatar Jan 16 '24 21:01 s-kk

MacOS 14.5 + Emacs 29.3也有这个问题

huwenbiao avatar Aug 09 '24 10:08 huwenbiao

我 100% 确信这是程序本身的 bug,上面已有的分析是正确的。macOS 上按键事件首先发送给应用程序,由 keyDown: 处理。若 keyDown: 中不使用 interpretKeyEvents: 把事件转发给输入管理器,则输入法根本不会接收到对应事件。

在 Emacs (NSport) 中,keyDown: 中简单分类了按键事件,若是功能键,则直接进入 Emacs 快捷键逻辑,不会使用 interpretKeyEvents:。因此,虽然用户快速按下的是 Shift+Enter,但输入法看到的是 Shift 按下和释放,导致了中英文切换。事实上,正确调用了 interpretKeyEvents:Emacs MacPort 的确不存在该问题,而且 Ctrl+` 等快捷键也能正常工作。我已经写好了 Emacs NSport 的 patch,进一步测试后会提交给官方。

Telegram Swift 的问题大概是完全一样的。已报告

ksqsf avatar Aug 09 '24 22:08 ksqsf