キーを押すために使用されたキーボードを確認する方法は?


16

複数のキーボードがインストールされているペアリングステーションで頻繁に作業しています。setxkbmapwith -device <ID>を使用して特定のキーボードのレイアウトを設定することができます(からxinputIDを使用)が、多くの場合、どのキーボードを使用しているかは明らかではありません。両方のキーボードを試してみることの前後を避けた方がよいので、この情報を取得するための簡単なツールを作成したいと思いsetxkbmapます。私は次のような典型的なユースケースを期待しています:

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

Linuxでこの情報を提供するインターフェースはどれですか?理想的にはXなしでも動作するはずですが、それは要件ではありません(Xなしでこれをサポートするツールは多くないようです)。


これまでの調査結果:

  • Linux 、複数のキーボードの異なるレイアウトを同時にサポートするために、入力しているキーボードを知る必要があります。
  • xinput→list.c→ list_xi2→は、XIQueryDeviceデバイスIDにより使用可能提供しますsetxkbmap
  • showkeyそしてxev、キーボードIDを印刷しません。
  • xinput list-props $IDキーボードイベントの送信先を示します。ただし、別の回答のコードを使用すると、このデバイスはキーボードを識別するために何も印刷しないようです。
  • ほとんど可能な解決策の1つは、xinput --test <ID> &キーボードIDごとに実行し、最初に返されるものを確認することです。それに伴う問題は、実際にキーボードである「キーボード」を特定することです。

    $ 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
おそらくあなたはMPXを探しています。
イグナシオバスケス-エイブラムス

@ IgnacioVazquez-Abramsそれは非常に複雑なソリューションではありませんか?
l0b0

それは問題が何であるかに依存します。
イグナシオバスケス-エイブラムス

「このデバイスは、キーボードを識別するために何も印刷しないようです」:どういう意味ですか?あなたの場合はless -f /dev/input/eventX、対応するキーボードのキーを打つ、あなたが現れて「ゴミ」を参照してください必要がありますので、あなたのキー押下は確かに1つのdevのファイルではなく他の人に向けられています。
L. Levrel

あなたはこれを試しましたか(引用した他の質問の別の回答で参照されています)?
L. Levrel

回答:


4

デバイスを無効にする

これは、どのキーボードがどれであるかを特定するためのアイデアです。コマンドxinputを使用して、デバイスを有効または無効にできます。

$ 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)]

上記の出力は、Thinkpadラップトップ上にあるさまざまなデバイスを示しています。キーボードが1つしか接続されていません。これは次のとおりです。

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

次に、このデバイスで利用可能なプロパティを見てみましょう。

$ 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.

上記から、有効になっていることがわかりますので、無効にしましょう。

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

有効にするには:

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

アイデア?

このコマンドを使用してキーボードのいずれかを無効にすると、どのキーボードを使用しているかを判断できます。

参照資料


それ以上の仕事ではないですか?私のアプローチには、少なくとも1つ、最大3つのコマンドが含まれます。このアプローチには、常に3つのコマンドが含まれます-無効化、有効化、レイアウトの設定(さらにキーボードスイッチ)。
l0b0

@ l0b0-はい、私もこのアプローチに興奮していません。私は見続けていますが、この方法をここに「一方向」として置いていました。理想的なものではありませんが、私は同意します。
slm

@lobo-この回答は報奨金を取得するものではありませんので、心配する必要はありません。報奨金を開始する前に票がありました。stackoverflow.com/help/bounty。また、ここであなたを助けようとしている私に対するあなたの怒りは何ですか?私はあなたに理想的な解決策ではなく、あなたの仕事を達成する1つの方法を与えました。これを2年以上前に提供しましたが、このQは代替案なしでここにありました。質問/アプローチが問題なのかどうかを自問する必要があると思います。明らかに私の$ 0.02だけですが、すでに十分です。
slm

私の悪いx 2:「報奨金が始まった後に作成された」ということに少しも気づかなかったので、非常によく練られた答えを書いてくれたことに感謝します。しかし、私は元のソリューションよりも複雑なソリューションに賛成することはできませんし、他の人がそうする理由を理解していません。
-l0b0

1
@ l0b0賛成票を投じる理由:スクリプト全体を読んでハードドライブを消去してから保存し、それを実行します。または、これまでで最高の票を得た回答の場合、Cコードをコンパイルします。また、このような創造的なアイデアは賛成に値します。
ファビアンレーリング

4

あなたはXツールを引用しているので、質問は少し矛盾しているように聞こえますが、「理想的にはXなしで動作するはずです」という解決策を求めます。

4 番目の調査結果について: xinput連絡を取ります

$ 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"

少なくとも次のバージョンでは

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


最初のステップ:Cでキーボードイベントデバイスを検出する

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

このページに感謝します。わかりやすくするために、実際に必要なコードでは、そこから借りたコードからほとんどの安全性チェックを削除しました。

キーを押すとエコーされることに注意してください。そのため、実際にユーザーにキーではなく修飾キー(Shift、Control ...)を押すように親切に求めることができます。

2番目のステップ:xinputを使用して、デバイス名からX IDを取得します

上記のCソースをコンパイルし、次の方法を使用します。

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


またあります/dev/input/by-id
jthill

ヒントをありがとう。ほとんどのツールは、私はXを必要とするように見えるだけので、私はXツールを引用してきたではないとの仕事にどのように知っている/dev/input/event*私が試した- tailしかし、無駄にティンを。
-l0b0

by-idは、Xを必要とせずに、デバイス名をイベントキューにマッピングするシンボリックリンクを提供します
。– jthill

@jthill現在使用しているマシンでは、このディレクトリにはマウスへのリンクのみがあります。
L.レヴレル16年

フン。さて、生きて学び、私のキーボードはきれいにリストされています。
-jthill

1

さらに掘り下げると、プレーンBashと通常のユーザーアカウントを使用した別のソリューションが明らかになりました。スクリプト

#!/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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.