%3F.png)
Problema
Ao usar determinados softwares, comoLiquidificador, é importante poder usar o teclado numérico para que o usuário possa fazer coisas como se orientar no espaço de design, mas muitos laptops não vêm com um teclado numérico físico. Isso se torna mais complicado pelo fato de que as entradas regulares da barra numérica (1-9 na parte superior do teclado) representam, na verdade, "símbolos" diferentes para o computador, portanto, muitas vezes têm funções completamente diferentes nesses tipos de software.
Tentativas de soluções
Como muitos laptops não vêm com teclado numérico,uma solução comum em muitas plataformas é emular o teclado numérico, por exemplo, mantendo pressionada uma tecla enquanto usa outras teclas do teclado (como jkluio789 para representar 123456789). Muitos laptops implementam isso no nível do BIOS (como usar a tecla Fn). No entanto, sem uma implementação de baixo nível, implementar esta emulação é muito difícil.
Algumas soluções existem online, maseles geralmente são insuficientes para uso com software de design(já que não implementam o símbolo correto e também exigem o uso de teclas modificadoras), oueles não são explicados em profundidade. A maioria das soluções concentra-se no usoxkb, que é uma arquitetura complicada e notoriamente difícil de começar a usar.
Requisitos para uma boa solução
Uma boa solução para este problema será um teclado emulado que o software gráfico aceitará como sendo uma entrada de teclado verdadeira e que seja fácil de usar. Uma limitação adicional é o fato de que o Blender detecta o uso de teclas modificadoras (como Shift
, Alt
, Super
("Command", "Windows Key", etc.), Hyper
) mesmo quando xkb
é informado de modificadores claros e, portanto, interpretará uma "emulação de teclado enquanto segurando uma solução de tecla modificadora" como uma entrada completamente diferente (ou seja, [ Numpad1
+ Alt
] em vez de apenas Numpad1
). Portanto, uma solução ideal envolverá, na verdade, um mecanismo de bloqueio (por exemplo, capitalização Caps Lock) em vez de um mecanismo de retenção (por exemplo, capitalização Shift) para que nenhum modificador seja acidentalmente passado para o software.
Responder1
Começo rápido
Se você não se importa com nenhuma explicação (eu sei que posso ser demorado), basta seguir o{números em negrito entre chaves}no início de alguns parágrafos. Siga cada uma dessas etapas em ordem e provavelmente você poderá implementar isso em alguns minutos. Observe que este guia pressupõe alguma competência em Unix (ser capaz de criar diretórios, criar arquivos, sudo
elevar o acesso root, etc.). Observe também queo acesso root só é necessário quando indicado, então você não precisa usar sudo
, a menos que seja solicitado.
Descrição Geral da Solução
Estaremos usando xkb para adicionar uma emulação de teclado numérico de "bloqueio" (como Caps lock) ao Linux. Gostaria que minhas chaves "jkluio789" representassem as representações do teclado numérico dos números "123456789", bem como algumas outras inclusões ("m,"->"0", "-=[]"->[numpad]" -+*", "."->[teclado numérico]"."). Alternarei esse "modo teclado numérico" usando a combinação de teclas [ Shift
+ Mod4
+ [key]
], onde Mod4
está o código modificador da tecla do meu sistema operacional (também chamado de "Comando" ou "Tecla do Windows", e às vezes atribuído ao código modificador de Super
ou Hyper
) , e [key]
é qualquer uma das teclas usadas no meu teclado numérico emulado (como "j" ou "["). Modificações simples nesta configuração devem ser relativamente simples após a leitura da solução completa.
Para fazer isso, definiremos um arquivo de "tipo" xkb personalizado, que informa ao xkb como interpretar as várias teclas modificadoras que usaremos para inicializar nossa emulação de teclado, bem como um arquivo de "símbolos" personalizado do xkb, que informa ao xkb como cada A tecla que pressionamos deve se comportar normalmente (Grupo 1), como deve se comportar durante a emulação do teclado numérico (Grupo 2) e como alternar entre os dois (ação de nível 3 para ambos os grupos). Por fim, tornaremos nossa solução permanente integrando-a ao xkbmap atual usando sed
cada vez que iniciarmos uma nova sessão (para que nossa solução não seja apagada cada vez que xkb
for atualizada).
Descrição detalhada da solução
Estrutura de diretório
{1}A primeira coisa que faremos é definir um diretório para mantermos nossos vários arquivos. O seu pode se parecer com praticamente qualquer coisa, mas o meu se parece com isto
/home
+-<username>
+-.xkb
+-symbols
+-types
+-keymap
+-log
Tipo de arquivo
Assim que tivermos nossa árvore de diretórios, vamos definir os arquivos reais em nossa solução. A primeira coisa que faremos é definir nosso arquivo “type”. Este arquivo dirá xkb
como mover-se entre os "níveis" (como Shift
colocar uma letra em maiúscula, passando do primeiro nível de uma letra minúscula para um nível maiúsculo da letra maiúscula). Esses níveis são um pouco difíceis de entender, principalmente para falantes nativos de inglês, mas os teclados internacionais os utilizam com grande efeito para letras e símbolos alternativos, bem como sinais diacríticos.
Iremos utilizá-lo para definir como pretendemos indicar uma alteração em nossas chaves. Em outras palavras, dizemos que esperamos um comportamento de "nível 1" quando nenhum modificador é pressionado (geralmente, uma letra minúscula padrão quando em nosso "modo normal"), comportamento de "nível 2" quando mantemos pressionada a Shift
tecla (geralmente, uma letra maiúscula padrão em nosso "modo normal") e comportamento de "nível 3" quando mantemos ambos Shift
+ Mod4
(um caso especial para nossos propósitos, que usamos para indicar que, quando usado para modificar uma chave, a chave agora irá alternar entre modos).
{2}Abra um novo arquivo, que chamaremos de togglekeypad
. Copie o seguinte bloco de código nele e salve-o em seu types
diretório em \home\<username>\.xkb\types
. NOTA: Você pode precisar alterar todas as instâncias de Mod4
qualquer modificador ao qual o botão "Command"/"Windows Key" corresponde (talvez seja necessário experimentar, consulteesta página da web em Teclas modificadoraspara orientação) ou qualquer outro modificador que você desejar.
partial default xkb_types "togglekeypad" { // Name of this type file
type "TOGGLEKEYPAD" { // Name of this "type"
modifiers = Shift+Mod4; // The modifiers that this type concerns itself with
map[Shift] = level2; // Shift brings us to level 2
map[Mod4+Shift] = level3; // Windows key plus shift brings us to level 3
level_name[Level1] = "Base"; // Human-readable names for each level (not really used, but convenient)
level_name[Level2] = "Shift";
level_name[Level3] = "Transfer";
};
};
{3}Devemos também copiar este arquivo para o diretório /usr/share/X11/xkb/types/
. Isso exigirá privilégios de root, o que infelizmente anula o propósito de xkb
ser um aplicativo de espaço do usuário, mas não consigo setxkbmap
reconhecer o arquivo sem fazer isso. Sugestões são bem-vindas!
Arquivo de símbolos
A próxima coisa que faremos é dizer xkb
o que cada chave deve fazer quando modificada em cada uma das maneiras que descrevemos no arquivo de tipos.
Diremos que queremos usar dois Grupos em nosso arquivo de símbolos. Isso significa que cada tecla tem dois comportamentos gerais diferentes entre os quais iremos alternar de alguma forma, sendo esses comportamentos o comportamento normal de digitação e o novo comportamento de emulação do teclado numérico. Para cada chave, diremos que 1) queremos usar o TOGGLEKEYPAD
tipo, 2) definiremos os símbolos (ou seja, o que o computador vê) associados a cada uma das chaves físicas em ambos os grupos para todos os níveis, e 3) iremos defina quaisquer ações (quaisquer coisas especiais que xkb
devam ser feitas) associadas a cada chave para ambos os grupos em todos os níveis. Isso parece um pouco confuso, mas deve fazer um pouco mais de sentido quando olhamos para um exemplo.
A primeira chave que vemos no arquivo de símbolos que colei abaixo é a <AC07>
chave. Isto corresponde à tecla "J" na maioria dos teclados,de acordo com o mapa visto aqui(Figura 2). Para esta chave física, estamos dizendo que, no modo normal: no nível 1 (sem modificadores, conforme nosso arquivo de tipo) irá digitar apenas "j", e no nível 2 ( Shift
modificador) irá digitar apenas "J". No nível 3, faz algo especial: não há nenhum símbolo associado ao nível 3, mas há uma ação, e essa ação é LockGroup(group=2)
. Em outras palavras, mude-nos para o nosso segundo grupo, o nosso grupo “Teclado”. Se olharmos nas próximas linhas, vemos que temos mais símbolos e ações definidas para o grupo 2 para esta mesma chave. Diz que, no nível 1 (sem modificadores), não digite nenhum símbolo, mas RedirectKey(keycode=<KP1>)
. Em outras palavras, registre esta tecla como se na verdade tivéssemos acabado de pressionar a <KP1>
tecla, que corresponde ao “1” em um teclado. (Nota: poderíamos ter colocado NoAction() novamente e usado o símbolo KP_1
, que é o símbolo ao qual a chave <KP1>
corresponde, mas achei que isso daria a melhor compatibilidade). Para o nível 2, faça a mesma coisa, mas adicione o Shift
modificador à tonalidade. Finalmente, para o nível 3, voltamos ao Grupo 1, modo “Padrão”.
{4}Abra um novo arquivo, que chamaremos de togglekeypad_symbols
. Copie o seguinte bloco de código nele e salve-o em seu symbols
diretório em \home\<username>\.xkb\symbols
.
default partial
xkb_symbols "togglekeypad" {
name[Group1]= "Standard";
name[Group2]= "Keypad";
key <AC07> { // J
type = "TOGGLEKEYPAD",
symbols[Group1] = [ j, J, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP1>), RedirectKey(keyCode=<KP1>, modifiers=Shift), LockGroup(group=1)]
};
key <AC08> { // K
type = "TOGGLEKEYPAD",
symbols[Group1] = [ k, K, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP2>), RedirectKey(keyCode=<KP2>, modifiers=Shift), LockGroup(group=1)]
};
key <AC09> { // L
type = "TOGGLEKEYPAD",
symbols[Group1] = [ l, L, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP3>), RedirectKey(keyCode=<KP3>, modifiers=Shift), LockGroup(group=1)]
};
key <AD07> { // U
type = "TOGGLEKEYPAD",
symbols[Group1] = [ u, U, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP4>), RedirectKey(keyCode=<KP4>, modifiers=Shift), LockGroup(group=1)]
};
key <AD08> { // I
type = "TOGGLEKEYPAD",
symbols[Group1] = [ i, I, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP5>), RedirectKey(keyCode=<KP5>, modifiers=Shift), LockGroup(group=1)]
};
key <AD09> { // O
type = "TOGGLEKEYPAD",
symbols[Group1] = [ o, O, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP6>), RedirectKey(keyCode=<KP6>, modifiers=Shift), LockGroup(group=1)]
};
key <AE07> { // 7
type = "TOGGLEKEYPAD",
symbols[Group1] = [ 7, ampersand, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP7>), RedirectKey(keyCode=<KP7>, modifiers=Shift), LockGroup(group=1)]
};
key <AE08> { // 8
type = "TOGGLEKEYPAD",
symbols[Group1] = [ 8, asterisk, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP8>), RedirectKey(keyCode=<KP8>, modifiers=Shift), LockGroup(group=1)]
};
key <AE09> { // 9
type = "TOGGLEKEYPAD",
symbols[Group1] = [ 9, parenleft, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP9>), RedirectKey(keyCode=<KP9>), LockGroup(group=1)]
};
// NumLock
key <AE06> { // 6
type = "TOGGLEKEYPAD",
symbols[Group1] = [ 6, asciicircum, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<NMLK>), RedirectKey(keyCode=<NMLK>), LockGroup(group=1)]
};
// Bottom Row (and zero)
key <AB07> { // M
type = "TOGGLEKEYPAD",
symbols[Group1] = [ m, M, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP0>), RedirectKey(keyCode=<KP0>, modifiers=Shift), LockGroup(group=1)]
};
key <AE10> { // 0
type = "TOGGLEKEYPAD",
symbols[Group1] = [ 0, parenright, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP0>), RedirectKey(keyCode=<KP0>, modifiers=Shift), LockGroup(group=1)]
};
key <AB09> { // .
type = "TOGGLEKEYPAD",
symbols[Group1] = [ period, greater, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KPDL>), RedirectKey(keyCode=<KPDL>, modifiers=Shift), LockGroup(group=1)]
};
// Arithmetic Operators
key <AE11> { // -
type = "TOGGLEKEYPAD",
symbols[Group1] = [ minus, underscore, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KPSU>), RedirectKey(keyCode=<KPSU>, modifiers=Shift), LockGroup(group=1)]
};
key <AE12> { // +
type = "TOGGLEKEYPAD",
symbols[Group1] = [ equal, plus, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KPAD>), RedirectKey(keyCode=<KPAD>, modifiers=Shift), LockGroup(group=1)]
};
key <AD12> { // [
type = "TOGGLEKEYPAD",
symbols[Group1] = [ bracketleft, braceleft, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KPDV>), RedirectKey(keyCode=<KPDV>, modifiers=Shift), LockGroup(group=1)]
};
key <AD12> { // ]
type = "TOGGLEKEYPAD",
symbols[Group1] = [ bracketright, braceright, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KPMU>), RedirectKey(keyCode=<KPMU>, modifiers=Shift), LockGroup(group=1)]
};
};
Teste nosso teclado
{5}Para testar a configuração do teclado como está, abra uma Terminal
janela e digite
setxkbmap -types complete+togglekeypad -print | sed -e '/xkb_symbols/s/"[[:space:]]/+togglekeypad_symbols(togglekeypad)&/' > $HOME/.xkb/keymap/customMap
xkbcomp -I$HOME/.xkb -R$HOME/.xkb keymap/customMap $DISPLAY
Isso irá capturar as configurações atuais do nosso xkb
mapa (usando setxkbmap - print
) enquanto define os tipos usados complete+togglekeypad
(tudo no arquivo /usr/share/X11/xkb/types/complete
e também incluindo nosso arquivo de tipos em /usr/share/X11/xkb/types/togglekeypad
). Em seguida, ele alimentará isso no sed
, que adicionará nossos símbolos togglekeypad
do nosso arquivo togglekeypad_symbols
aos arquivos de símbolos usados. Finalmente, compilamos xkbcomp
o novo mapa de teclado.
Observe que, na minha máquina, presume-se que o NumLock esteja desativado (porque não há teclado numérico na minha máquina), portanto, as teclas do teclado numérico enviarão suas funções primárias para o computador, ou seja, Home, End, PG Up, PG Down, etc. . Para obter os números digitados ao usar o teclado numérico emulado, mantenha pressionada a tecla Shift. Eu tentei vários métodos para inverter esse comportamento (trocar o modifers
argumento entre os níveis no arquivo de símbolos, atribuir uma nova chave para emular a tecla NumLock <NMLK>
e alterná-la), mas nada ainda funcionou para mim. Felizmente, porém, quando testado no Blender, ele funciona exatamente como esperado, sem a necessidade de manter Shift pressionado.
{6}Se as coisas deram terrivelmente errado neste ponto, não se preocupe, apenas faça logout/login (ou, na pior das hipóteses, reinicie), depure e tente novamente. Se tudo estiver funcionando, vamos torná-lo permanente.
Tornando a solução permanente
Certamente existem maneiras mais elegantes de tornar nossa solução persistente entre as sessões, mas o método mais fácil e confiável para mim foi simplesmente colocar os comandos acima no final do meu ~/.bashrc
arquivo. Eu usei osolução proposta aquique adiciona um pouco de verificação de erros e um pouco mais (para que eu possa ver quaisquer saídas de erro).
{7}Abra o arquivo ~/.bashrc
. Adicione o seguinte script ao final:
# Setup custom keyboard remapping to emulate a number pad when "Shift+Cmd+numap_key" is pressed to initialize
if [ -d $HOME/.xkb/keymap ]; then
setxkbmap -types complete+togglekeypad -print | \
sed -e '/xkb_symbols/s/"[[:space:]]/+togglekeypad_symbols(togglekeypad)&/' > $HOME/.xkb/keymap/customMap 2> $HOME/.xkb/log/sedErrors
xkbcomp -w0 -I$HOME/.xkb -R$HOME/.xkb keymap/customMap $DISPLAY > $HOME/.xkb/log/outputOfCommand 2>&1
fi
{8}Ao reiniciar, a emulação do teclado numérico agora deve se tornar permanente!
Conclusão
Embora a explicação seja longa, o método em si é relativamente curto. As deficiências são que o Blender requer um método de bloqueio para funcionar corretamente, enquanto eu teria preferido um método de retenção, e também requer acesso root para reconhecer xkb
nosso arquivo de tipos personalizados por algum motivo. No entanto, no geral, isso parece estar funcionando bem para mim. Se você tiver alguma dúvida ou sugestão, fique à vontade para deixá-las abaixo!