如何通过命令行关闭 Caps Lock(锁,而不是键)?

Ech*_*ene 109 command-line capslock xmodmap

出于某种原因,我的笔记本电脑卡在 Caps Lock 中。我有Caps Lockxmodmapto映射的键hyper_l,所以我没有caps_lock关闭它的键。有没有办法通过命令行关闭它?如果我可以在不重置计算机的情况下重置锁定状态,那就太好了,尤其是供将来参考。这种情况以前发生过,但我现在想知道这次如何正确地做到这一点。

Gil*_*il' 140

I don't know of any command line tool for that in Ubuntu. (For Num Lock, there is numlockx 安装 numlockx.) Here's a one-liner that you can copy-paste into a terminal window:

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)'
Run Code Online (Sandbox Code Playgroud)

Here it is again in a more expanded form. We use the Python ctypes library to call C functions from the X library directly. The function XkbLockModifiers changes the state of the keyboard locks, on the core keyboard (XkbUseCoreKbd = 0x0100), affecting Caps Lock (2), setting it to 0 (off).

#!/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)
Run Code Online (Sandbox Code Playgroud)

如果您有一个卡住的修改器,请将 2 更改为要关闭的修改器的蒙版。修饰符为 1=Shift、2=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-essentialslibx11-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;
}
Run Code Online (Sandbox Code Playgroud)

同样可能感兴趣的是一种暂时忽略 Caps Lock 的方法:

xkbset nullify lock
Run Code Online (Sandbox Code Playgroud)

在此之后,Caps Lock 将有效地永久关闭,直到您使用 重新启用它xkbset nullify -lock

  • 我得到一个段错误:由信号 SIGSEGV(地址边界错误)终止…… (4认同)
  • 我在 python (2) 上有段错误,但它在 python3 上工作 (2认同)
  • python 代码以前可以工作,但现在不行了。请参阅下面的 @diegogs 答案,了解仍然存在的问题。`xset nullify lock` 修复了某些应用程序 (emacs) 上的问题,但没有修复其他应用程序 (terminator) 上的问题。之前或之后都不起作用。xdotool 有效。 (2认同)

use*_*.dz 75

X 自动化工具可用于发送所需的关键事件。

注意:
首次使用时,如果您的 CAPS 当前处于活动状态,此解决方案需要您输入正确的密码以安装新工具:

  • 使用SHIFT键键入小写字母。
  • 启用辅助功能,覆盖虚拟键盘。
  • 重新插入外接键盘。(感谢chris455
  • 打开office writer,在那里写密码,更改字母大小写,复制它,然后将其粘贴到密码对话框中。

如果所有以前的选项都不可能或不起作用,请使用Gilles 的答案/python 脚本。它不需要安装任何额外的工具,它仅使用pythonlibX11共享库被预先安装。

使用 xdotool

  1. 安装它

    sudo apt-get install xdotool
    
    Run Code Online (Sandbox Code Playgroud)
  2. 发送大写向下/向上事件

    xdotool key Caps_Lock
    
    Run Code Online (Sandbox Code Playgroud)

另一个工具是 xte

  1. 安装它

    sudo apt-get install xautomation
    
    Run Code Online (Sandbox Code Playgroud)
  2. 发送大写锁定/向上事件

    xte "key Caps_Lock"
    
    Run Code Online (Sandbox Code Playgroud)

参考:

  • 无法安装,不接受密码。:( (15认同)
  • 这是唯一对我有用的方法。无效和其他人没有工作。 (3认同)
  • 启用 Caps Lock 时,您可以使用 Shift 键输入小写字母。 (2认同)

小智 19

至于 Gilles 的 Python 版本在较新的 Ubuntu 中不起作用,为打开显示设置正确的返回似乎可以解决问题:

#!/usr/bin/env python

from ctypes import *

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)
Run Code Online (Sandbox Code Playgroud)

(代码改编自/sf/ask/2074674731/


小智 10

如果您因为在 .bashrc 中重新映射而无法访问 CAPS,就像我一样,那么只需切换到虚拟终端 (alt+ctl+fN),然后切换回来对我有用。


小智 7

我遇到了这个问题,并且能够通过使用 OnBoard 键盘(在 Ubuntu Mate 中的 Universal Access 下)来修复它。

打开后,您应该会看到 CapsLock 键呈红色,或者以某种方式表明它已锁定。然后您可以按 来关闭。