Bir tuşa basmak için hangi klavyenin kullanıldığını nasıl anlarım?


16

Sıklıkla birden fazla klavyenin yüklü olduğu eşleştirme istasyonlarında çalışıyorum. Ben kullanabilirsiniz setxkbmapile -device <ID>(bir kullanarak belirli klavye için düzenini ayarlamak için kimliğini danxinput ), ancak çoğu zaman ben de değilim hangi klavye belli değil. Her iki klavyeyi de denemekten kaçınmak daha iyi olurdu, bu yüzden bu bilgiyi almak için hızlı bir araç yazmak istiyorum setxkbmap. Aşağıdaki gibi tipik bir kullanım durumu beklenir:

$ setxkbmap -device "$(get-keyboard-id)" -layout gb
Press Enter to detect keyboard ID

Hangi arayüz Linux'ta bu bilgileri sağlar? İdeal olarak X olmadan çalışması gerekir, ancak bu bir gereklilik değildir (bunu X olmadan destekleyen birçok araç yoktur).


Şimdiye kadar olan bulgular:

  • Linux , aynı anda birden çok klavye için farklı düzenleri desteklemek için hangi klavyeyi yazdığımı bilmelidir.
  • xinput→ list.c → list_xi2XIQueryDevice, tarafından kullanılabilen cihaz kimlikleri sağlar setxkbmap.
  • showkeyve xevklavye kimlikleri baskı yoktur.
  • xinput list-props $IDklavye olaylarının nereye gönderileceğini gösterir . Ancak, başka bir cevabın kodunu kullanarak bu cihazın klavyeyi tanımlamak için hiçbir şey yazdırmıyor gibi görünüyor.
  • Neredeyse olası bir çözüm, xinput --test <ID> &her klavye kimliği için çalıştırmak ve hangisinin önce bir şey döndürdüğünü görmek. Sorun, hangi "klavyelerin" aslında klavyeler olduğunu bulmaktır :

    $ xinput | grep keyboard
    ⎣ Virtual core keyboard                         id=3    [master keyboard (2)]
        ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
        ↳ Power Button                              id=6    [slave  keyboard (3)]
        ↳ Video Bus                                 id=7    [slave  keyboard (3)]
        ↳ Power Button                              id=8    [slave  keyboard (3)]
        ↳ Sleep Button                              id=9    [slave  keyboard (3)]
        ↳ WebCam SC-13HDL10931N                     id=10   [slave  keyboard (3)]
        ↳ AT Translated Set 2 keyboard              id=11   [slave  keyboard (3)]
    

1
Belki de MPX arıyorsunuz.
Ignacio Vazquez-Abrams

@ IgnacioVazquez-Abrams Bu çok daha karmaşık bir çözüm değil mi?
l0b0

Bu sorunun ne olduğuna bağlı.
Ignacio Vazquez-Abrams

"Bu cihaz klavyeyi tanımlamak için hiçbir şey yazdırmıyor gibi görünüyor": ne demek istiyorsun? Siz less -f /dev/input/eventXve ilgili klavyede bir tuşa basarsanız, "çöp" ifadesinin göründüğünü görmelisiniz, böylece tuş basışlarınız gerçekten diğerlerine değil, bir dev dosyasına yönlendirilir.
L. Levrel

Eğer denediniz Bu (eğer alıntı bu diğer sorunun başka cevabı başvurulan)?
L. Levrel

Yanıtlar:


4

Cihazı devre dışı bırak

Hangi klavyenin hangisi olduğunu belirlemeye yönelik bir fikir. Xinput komutunu kullanabilirsiniz etkinleştirmek ve devre dışı bırakmak için .

Misal

$ xinput list
⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad                id=12   [slave  pointer  (2)]
⎜   ↳ TPPS/2 IBM TrackPoint                     id=13   [slave  pointer  (2)]
⎜   ↳ Logitech USB Receiver                     id=9    [slave  pointer  (2)]
⎜   ↳ Logitech USB Receiver                     id=10   [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Video Bus                                 id=7    [slave  keyboard (3)]
    ↳ Sleep Button                              id=8    [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=11   [slave  keyboard (3)]
    ↳ ThinkPad Extra Buttons                    id=14   [slave  keyboard (3)]

Yukarıdaki çıktı, Thinkpad dizüstü bilgisayarımda bulunan çeşitli cihazları gösteriyor. Sadece 1 klavye takılı, bu bir:

    ↳ AT Translated Set 2 keyboard              id=11   [slave  keyboard (3)]

Şimdi bu cihazda bulunan özelliklere bir göz atın:

$ xinput list-props "AT Translated Set 2 keyboard"
Device 'AT Translated Set 2 keyboard':
    Device Enabled (124):   1
    Coordinate Transformation Matrix (126): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.

Yukarıdan etkinleştirildiğini görebilirsiniz, bu yüzden devre dışı bırakalım:

$ xinput set-prop "AT Translated Set 2 keyboard" "Device Enabled" 0

Etkinleştirmek için:

$ xinput set-prop "AT Translated Set 2 keyboard" "Device Enabled" 1

Fikir?

Hangisinde olduğunuzu belirlemek için bu komutu kullanarak klavyelerden birini devre dışı bırakabilirsiniz.

Referanslar


Bu daha fazla iş değil mi? Yaklaşımım en az bir komut, en fazla üç komut içerir. Bu yaklaşım her zaman üç komut içerir - düzeni devre dışı bırak, etkinleştir, sonra ayarla (artı muhtemelen bir klavye anahtarı).
l0b0

@ l0b0 - evet ben de bu yaklaşımdan memnun değilim. Bakmaya devam ediyorum ama bu yöntemi buraya "1 yol" olarak koyuyordum. İdeal olanı değil, katılıyorum.
slm

@lobo - Bu cevap ödül almayacak, bu yüzden endişelenmeyin, ödülün başlamadan önce oyları vardı. stackoverflow.com/help/bounty . Ayrıca burada bana yardım etmeye çalışan öfken ne? Size ideal bir çözüm değil, görevinizi gerçekleştirmenin 1 yolunu verdim. Bunu 2 yıldan fazla bir süre önce sağladım ve bu Q burada w / 0 alternatifleri ile oturdu. Sanırım kendinize belki de sorunun sorusu / yaklaşımı olup olmadığını sormanız gerekiyor. Açıkçası sadece benim 0.02 $ ama zaten yeterli.
slm

Benim kötü x 2: "ödül başladıktan sonra yaratıldı" hakkında biraz fark etmedim ve çok iyi formüle edilmiş bir cevap yazdığınızı takdir ediyorum. Ancak orijinal çözümden daha karmaşık bir çözümü değerlendiremiyorum ve başkalarının neden yaptığını anlamıyorum.
l0b0

1
@ l0b0 Yükseltme nedenim: Sabit diskimi silmediğinden emin olmak için komut dosyasının tamamını okumak zorunda kalmadan, hangi klavyeyi olduğunu şüphe ile hızlı ve kolay bir şekilde onaylamak için kullanabileceğim tek bir komut. Onu çalıştır. Veya şu ana kadar verilen en yüksek oylama durumunda C kodunu derleyin. Ayrıca, bunun gibi yaratıcı fikirler upvotes hak ediyor.
Fabian Röling

4

X araçlarına atıfta bulunduğunuz, ancak "ideal olarak X olmadan çalışması gereken" bir çözüm istediğiniz için soru biraz çelişkili geliyor.

Senin 4 Hakkında inci bulgu: xinputsize yazışmaları verecek

$ xinput list-props 11
Device 'AT Translated Set 2 keyboard':
    Device Enabled (145):   1
    Coordinate Transformation Matrix (147): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
    Device Product ID (266):    1, 1
    Device Node (267):  "/dev/input/event0"

en azından aşağıdaki sürümle

$ xinput --version
xinput version 1.6.1
XI version on server: 2.3


İlk adım: C'de klavye olay cihazını algılama

#include <stdio.h>
//#include <unistd.h>
#include <fcntl.h>
#include <linux/input.h>

// typical use : sudo ./a.out /dev/input/event*
int main (int argc, char *argv[])
{
  struct input_event ev[64];
  int fd[argc],rd,idev,value, size = sizeof (struct input_event);
  char name[256] = "Unknown";

  if(argc==1) return -1;

  int ndev=1;
  while(ndev<argc && (fd[ndev] = open (argv[ndev], O_RDONLY|O_NONBLOCK)) != -1){
    ndev++;
  }
  fprintf (stderr,"Found %i devices.\n", ndev);
  if(ndev==1) return -1;

  while (1){
    for(idev=1; idev<argc; idev++){
      if( (rd=read (fd[idev], ev, size * 64)) >= size){
      value = ev[0].value;
      if (value != ' ' && ev[1].value == 1 && ev[1].type == 1){
        ioctl (fd[idev], EVIOCGNAME (sizeof (name)), name);
        printf ("%s\n", name);
        return idev;
      }
      }
    }
//    sleep(1);
  }
  return -1;
}

Bu sayfa için çok teşekkürler . Açıkçası, muhtemelen onları istediğiniz gerçek kod, orada ödünç koddan en güvenlik kontrolleri elimden.

Tuşa basma işlemlerinin yankılandığını unutmayın, bu nedenle kullanıcıdan kullanıcıdan herhangi bir tuş yerine bir değiştirici tuşa (Shift, Control ...) basmasını isteyebilirsiniz .

İkinci adım: cihaz adından X kimliğini almak için xinput komutunu kullanın

Yukarıdaki C kaynağını derleyin ve şu şekilde kullanın:

xinput list --id-only "keyboard:$(sudo ./a.out /dev/input/event*)"


Ayrıca var/dev/input/by-id
jthill

Bahşiş için teşekkürler. En araçları Ben do X'i gerektirecek gibi görünüyor çünkü sadece ben X'in araçları alıntı yaptığınız değil çalışmak için biliyorum /dev/input/event*Denedim - tailama boşuna ting.
l0b0

by-id, X'e gerek kalmadan, olay kuyruğuna sembolik eşleme cihazı adı verir.
jthill

@jthill Şu anda çalıştığım makinede, bu dizin yalnızca fare için bağlantılar içeriyor.
L. Levrel

Hunh. Tamam, yaşa ve öğren, benim klavyemi çok iyi listeledi.
jthill

1

Daha fazla kazma, düz Bash ve normal bir kullanıcı hesabı kullanan başka bir çözüm ortaya çıkardı . Senaryo :

#!/usr/bin/env bash

set -o errexit -o nounset -o noclobber -o pipefail

# Remove leftover files and processes on exit
trap 'rm --recursive -- "$dir"; kill -- -$$' EXIT
dir="$(mktemp --directory)"
cd "$dir"

# Log key presses to file
xinput --list --id-only | while read id
do
    # Only check devices linked to an event source
    if xinput --list-props "$id" | grep --quiet --extended-regexp '^\s+Device Node.*/dev/input/event'
    then
        xinput test "$id" > "$id" &
    fi
done

# Check for key presses
while sleep 0.1
do
    for file in *
    do
        if [[ -s "$file" ]]
        then
            echo "$file"
            exit
        fi
    done
done
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.