Como desativo o Caps Lock (o bloqueio, não a chave) pela linha de comando?

72

Por algum motivo, meu laptop está preso no Caps Lock. Eu tenho a tecla Caps Lock mapeada por xmodmap to hyper_l , então eu não tenho uma chave caps_lock para desativá-la. Existe uma maneira que eu possa desligá-lo por linha de comando? Seria bom se eu pudesse redefinir o estado de bloqueio sem redefinir meu computador, especialmente para referência futura. Isso já aconteceu antes, mas gostaria de saber agora como fazer isso corretamente desta vez.

    
por Echogene 17.11.2011 / 18:51

4 respostas

113

Eu não conheço nenhuma ferramenta de linha de comando para isso no Ubuntu. (Para o Num Lock, existe numlockx .) Aqui está um verso que você pode copiar e colar em uma janela de terminal:

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)'

Aqui está novamente em uma forma mais expandida. Usamos o Python biblioteca ctypes para chamar funções C da biblioteca X diretamente. A função XkbLockModifiers altera o estado dos bloqueios do teclado , no teclado do núcleo ( XkbUseCoreKbd = 0x0100), afetando Caps Lock (2), definindo-o como 0 (desativado).

#!/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)

Se você tiver um modificador emperrado, altere 2 para a máscara dos modificadores que deseja desativar. Os modificadores são 1 = Shift, 2 = Lock (Caps Lock), 4 = Controle, 8 = Mod1, 16 = Mod2, 32 = Mod3, 64 = Mod4, 128 = Mod5. Execute xmodmap -pm para ver o que Mod1 a Mod5 corresponde. Por exemplo, para desativar todos os modificadores, chame X11.XkbLockModifiers(display, c_uint(0x0100), c_uint(255), c_uint(0)) . Para ativar o Num Lock que está no Mod2 e ao mesmo tempo desativar o Caps Lock, chame X11.XkbLockModifiers(display, c_uint(0x0100), c_uint(2 | 16), c_uint(16)) .

Aqui está uma versão em C, se você quiser fazer um pequeno binário em vez de invocar o Python. Compile com gcc -O -Wall -o caps_lock_off caps_lock_off.c -lX11 , com os pacotes build-essentials e libx11-dev instalados.

#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;
}

Também possivelmente de interesse é uma forma de ignorar temporariamente o Caps Lock:

xkbset nullify lock

Depois disso, o Caps Lock ficará efetivamente desativado permanentemente, até você reativá-lo com xkbset nullify -lock .

    
por Gilles 17.11.2011 / 23:26
38
As ferramentas

X automation podem ser usadas para enviar os principais eventos necessários.

  

Nota:
  Essa solução precisa que você grave a senha correta, se o seu   O CAPS está ativo no momento: escritor de escritório aberto, escreva a senha lá,   mude o caso de letras, copie-o e cole-o na caixa de diálogo de senha.

     

Se o passo anterior não for possível ou não funcionar, vá com script de resposta / python de Gilles . Ele não precisa instalar nenhuma ferramenta adicional, ele usa apenas python & amp; libX11 lib compartilhada que está pré-instalada.

Usando xdotool

  1. Instale-o

    sudo apt-get install xdotool
    
  2. Envie um evento de down / up de CAPS

    xdotool key Caps_Lock
    

Outra ferramenta é xte

  1. Instale-o

    sudo apt-get install xautomation
    
  2. Enviar um evento de trava para baixo / para cima do CAPS

    xte "key Caps_Lock"
    

Referências:

por user.dz 11.04.2015 / 10:41
5

Quanto à versão Python do Gilles que não funciona no ubuntus mais recente, configurar o retorno correto para a tela aberta parece funcionar:

#! /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)

(Código adaptado de link )

    
por diegogs 30.07.2017 / 17:37
3

Se você não pode acessar o CAPS porque você o remapeamou no .bashrc, como eu fiz, então simplesmente mudei para um terminal virtual (alt + ctl + fN) e depois mudei de volta para mim.

    
por Benjamin 27.06.2017 / 08:01