由于某种原因,我的笔记本电脑卡在了Caps Lock中。我有Caps Lock映射xmodmap
到的键hyper_l
,所以没有caps_lock
关闭它的键。有什么方法可以通过命令行将其关闭吗?如果我可以在不重置计算机的情况下重置锁定状态,那会很好,尤其是供将来参考。这以前曾经发生过,但是我现在想知道这次如何正确地做。
由于某种原因,我的笔记本电脑卡在了Caps Lock中。我有Caps Lock映射xmodmap
到的键hyper_l
,所以没有caps_lock
关闭它的键。有什么方法可以通过命令行将其关闭吗?如果我可以在不重置计算机的情况下重置锁定状态,那会很好,尤其是供将来参考。这以前曾经发生过,但是我现在想知道这次如何正确地做。
Answers:
我不知道在Ubuntu中有任何命令行工具。(对于Num Lock,有numlockx 。)这是一个单行代码,您可以将其复制粘贴到终端窗口中:
python -c 'from ctypes import *; X11 = cdll.LoadLibrary("libX11.so.6"); display = X11.XOpenDisplay(None); X11.XkbLockModifiers(display, c_uint(0x0100), c_uint(2), c_uint(0)); X11.XCloseDisplay(display)'
这里再次以更扩展的形式。我们使用Python ctypes 库直接从X库调用C函数。该功能XkbLockModifiers
更改核心键盘(XkbUseCoreKbd
= 0x0100)上的键盘锁定状态,从而影响Caps Lock(2),将其设置为0(关闭)。
#!/usr/bin/env python
from ctypes import *
X11 = cdll.LoadLibrary("libX11.so.6")
display = X11.XOpenDisplay(None)
X11.XkbLockModifiers(display, c_uint(0x0100), c_uint(2), c_uint(0))
X11.XCloseDisplay(display)
如果修改器卡住,请将要关闭的修改器的遮罩更改为2。修饰符为1 = Shift,2 = Lock(Caps Lock),4 = Control,8 = Mod1、16 = Mod2、32 = Mod3、64 = Mod4、128 = Mod5。运行xmodmap -pm
以查看Mod1到Mod5对应的内容。例如,要关闭所有修饰符,请调用X11.XkbLockModifiers(display, c_uint(0x0100), c_uint(255), c_uint(0))
。要打开Mod2上的Num Lock,同时关闭Caps Lock,请致电X11.XkbLockModifiers(display, c_uint(0x0100), c_uint(2 | 16), c_uint(16))
。
如果您想制作一个小的二进制文件而不是调用Python,那么这是C版本。与gcc -O -Wall -o caps_lock_off caps_lock_off.c -lX11
一起编译,附带软件包build-essentials
并libx11-dev
安装。
#include <stdio.h>
#include <X11/X.h>
#include <X11/XKBlib.h>
int main()
{
Display *display = XOpenDisplay(NULL);
if (display == NULL) {
fprintf(stderr, "Couldn't open display\n");
return 2;
}
Bool sent = XkbLockModifiers(display, XkbUseCoreKbd, LockMask, 0);
if (!sent) {
fprintf(stderr, "Couldn't send LatchLockState\n");
return 1;
}
#ifdef REPORT_STATE
XkbStateRec xkb_state;
Status status = XkbGetState(display, XkbUseCoreKbd, &xkb_state);
if (status) {
fprintf(stderr, "XkbGetState returned %d\n", status);
return 1;
}
printf("state.group=%02x\n", xkb_state.group);
printf("state.locked_group=%02x\n", xkb_state.locked_group);
printf("state.base_group=%02x\n", xkb_state.base_group);
printf("state.latched_group=%02x\n", xkb_state.latched_group);
printf("state.mods=%02x\n", xkb_state.mods);
printf("state.base_mods=%02x\n", xkb_state.base_mods);
printf("state.latched_mods=%02x\n", xkb_state.latched_mods);
printf("state.locked_mods=%02x\n", xkb_state.locked_mods);
printf("state.compat_state=%02x\n", xkb_state.compat_state);
printf("state.grab_mods=%02x\n", xkb_state.grab_mods);
printf("state.compat_grab_mods=%02x\n", xkb_state.compat_grab_mods);
printf("state.lookup_mods=%02x\n", xkb_state.lookup_mods);
printf("state.compat_lookup_mods=%02x\n", xkb_state.compat_lookup_mods);
printf("state.ptr_buttons=%02x\n", xkb_state.ptr_buttons);
#endif
int err = XCloseDisplay(display);
if (err) {
fprintf(stderr, "XCloseDisplay returned %d\n", err);
return 1;
}
return 0;
}
也可能感兴趣的是暂时忽略Caps Lock的方法:
xkbset nullify lock
之后,Caps Lock将有效地永久关闭,直到您使用启用它xkbset nullify -lock
。
xtrace
并运行xtrace python -c 'from ctypes import *; X11 = cdll.LoadLibrary("libX11.so.6"); buf = (c_char*16)(); display = X11.XOpenDisplay(None); X11.XkbLockModifiers(display, c_uint(0x0100), c_uint(2), c_uint(0)); X11.XkbGetState(display, 0x0100, buf); X11.XCloseDisplay(display)'
并发布最后几行,从包含的那一行开始QueryExtension name='XKEYBOARD'
。我并不是说我会理解输出,但我会尝试。
X自动化工具可用于发送所需的键事件。
注意:
首次使用时,如果CAPS当前处于活动状态,则此解决方案需要您使用正确的密码来安装新工具:
- 使用SHIFT键输入小写字母。
- 启用辅助功能,覆盖虚拟键盘。
- 重新插入外部键盘。(感谢chris455)
- 打开Office书写器,在其中写密码,更改字母大小写,将其复制,然后将其粘贴到密码对话框中。
如果所有先前的选项都不可行或不起作用,请使用Gilles的answer / python脚本。它不需要安装任何额外的工具,它仅使用
python
和libX11
共享库被预先安装。
使用 xdotool
安装它
sudo apt-get install xdotool
发送CAPS向下/向上事件
xdotool key Caps_Lock
另一个工具是 xte
安装它
sudo apt-get install xautomation
发送CAPS锁定/锁定事件
xte "key Caps_Lock"
参考文献:
至于Gilles python版本在较新的ubuntus中不起作用,为打开的显示设置正确的返回值似乎可以解决问题:
#! /usr/bin/env python
from ctypes import *
import subprocess
class Display(Structure):
""" opaque struct """
X11 = cdll.LoadLibrary("libX11.so.6")
X11.XOpenDisplay.restype = POINTER(Display)
display = X11.XOpenDisplay(c_int(0))
X11.XkbLockModifiers(display, c_uint(0x0100), c_uint(2), c_uint(0))
X11.XCloseDisplay(display)
(代码改编自https://stackoverflow.com/questions/29638210/how-can-i-use-python-xlib-to-generate-a-single-keypress)