当前位置: 首页>>技术教程>>正文


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

, , ,

问题描述

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

最佳解决思路

我不知道Ubuntu中的任何命令行工具。 (对于Num Lock,有numlockx。)下面是一个one-liner,您可以将copy-paste放入终端窗口中:

command-line,xmodmap,capslock,ubuntu

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 library直接从X library调用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-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;
}

也可能感兴趣的是暂时忽略Caps Lock的方式:

xkbset nullify lock

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

次佳解决思路

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

Note:
This solution needs you to tape the correct password, if your CAPS is currently active: open office writer, write password there, change the letter case, copy it, then paste it to password dialog.

If that previous step is not possible or doesn’t work, Go with Gilles’ answer / python script. It does not need to install any additional tool, it uses only python & libX11 shared lib which are pre-installed.

使用xdotool

  1. 安装它

    sudo apt-get install xdotool
    
  2. 发送CAPS向下/向上事件

    xdotool key Caps_Lock
    

另一个工具是xte

  1. 安装它

    sudo apt-get install xautomation
    
  2. 发送CAPS锁定/关闭事件

    xte "key Caps_Lock"
    

参考文献:

第三种解决思路

如果因为在.bashrc中重新映射它而无法访问CAPS,那么只需切换到虚拟终端(alt + ctl + fN),然后切换回给我工作。

第四种思路

至于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)

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/979.html,未经允许,请勿转载。