梱包しようとしています。メニュー一部のスクリプトでは入力が提供され操作されますが、Returnキーを押していくつかのdmenu入力を選択すると、KeyReleaseイベントはdmenuが閉じたときにフォーカスされたウィンドウに送信されます。アプリケーションがこれに反応すると(私の場合はFirefoxのjavascriptで発生しました)、望ましくないことが発生する可能性があります。
しかし、これは私のスクリプトやdmenuに限定されていません。これは、私がテストした他のダイアログスタイルのXアプリケーション、特にssh-askpass、ksshaskpass、gpgパスワードダイアログなどでも発生します。
簡単なテストは次のとおりです。
- ssh-askpassをキー(組み合わせ)にバインドします。これを達成するために、i3-wm構成を使用します。
端末で次のコマンドを実行します。
xev | grep -EA2 --line-buffered '^Key(Press|Release)' | sed -n 's/^.*\(Press\|Release\|keysym[^)]*\).*$/\1/p'
- バインドキーの組み合わせを押します。
Enterを押して、端末で次の出力を観察します。
Release keysym 0xff0d, Return
Press
過去を観察しないでくださいReturn
Release
これらのアプリケーションがXイベントキューのイベントを使用しないのはなぜですか?私の考えでは、これがバグのようです。しかし、Xでですか、それともアプリケーションからですか?
このようなアプリケーションを(Python?)スクリプトにラップするときにこの問題をどのように解決できますか?
答え1
すでにイベントを処理しているアプリケーションはKeyPress
通常、後続のイベントを処理しませんKeyRelease
。ユーザーがキーを押してから別のアプリケーションに切り替えてからキーを離すと、要求に応じてフォーカス変更が発生することが予想され、ユーザーがキーを離すまで遅延しないでください。
X11で入力イベントを処理するためのアーキテクチャは非常に簡単です。クライアントがイベントをキャプチャした場合クライアントがイベントを受信した場合、またはイベントがまだキャプチャされていない場合、現在フォーカスがあるクライアントはイベントを受け取ります。イベント。イベントをKeyRelease
受け取ったクライアントに応じてKeyPress
イベントを個別に配信する規制はありません。
KeyRelease
イベントを受信するクライアントにイベントを再ルーティングするために修飾子を使用する例は、明らかに間違っています。KeyPress
フォーカスが変わったときにモディファイアを押すと、押したままになります。KeyRelease
このイベントは、修飾子キーが押されなくなったときに送信されます。KeyRelease
フォーカスが失われたときに押されたすべての修飾子のイベントを送信し、新しくフォーカスされたウィンドウにそのイベントを送信することは合理的ですが、KeyPress
これは実際のユーザー入力の正確なレポートではなく、特に破壊的なウィンドウ間のフォーカス変更の場合です。 。同じアプリケーションのウィジェット。
X11の動作が明らかに正確であり、キーイベントを再ルーティングするという提案が間違っている別の例は、同じアプリケーションのウィジェット間でフォーカスが変わる場合です。アプリケーションがこの特定のキーに興味を持ち、どのウィジェットに焦点が当てられているのか気にしない場合は、偽のイベントを送信するとエラーになります。ただし、アプリがどのウィジェットがイベントKeyRelease
を受信しているかに興味がある場合は、そのイベントをフォーカスのあるウィジェットに確実に送信する必要があります。
ほとんどのアプリケーション操作は、キードロップイベントではなくキー押下イベントによってトリガーされます。イベントのためにボタンが押されると、ボタンが押されたときではなく、ボタンが押されたときにボタンの効果が実行されると予想されます。ウィンドウを閉じるイベントが異なる動作をしている場合、これは奇妙なユーザーエクスペリエンスになります。
キーを押してウィンドウが閉じたときにフォーカスを別のウィンドウに移動することが明らかに正しい例は、キーをEsc押して複数のダイアログボックスを終了することです。アプリケーションがウィンドウを閉じるためにキーを離す必要がある場合、Escこれは破壊的です。
説明したシナリオでは、明らかに問題があるのはFirefox / JavaScriptアプリケーションです。ほとんどのキーボードインターフェイスは、キーを離すのではなくキーを押すことに基づいています。特に、緊急 Enterこれにより、代わりに何かが起こるはずです。解放それ。アプリケーションがキーリリースイベントに応答する場合、KeyRelease
一致が受信されず、イベントが受信される状況を合理的な方法で処理することはアプリケーションの責任です。KeyPress
マウスクリックは少し異なります。ほとんどの場合、インターフェイスはドラッグアンドドロップやクリック期間に応じたイベントなどのリリースイベントに反応する必要があるためです。それにもかかわらず、アプリケーションがButtonRelease
適用されますButtonPress
。