dmen をスクリプト内でラップして入力をフィードし、それに基づいて操作しようとしていますが、Returnキーを押してdmenu入力を選択すると、dmenu時にフォーカスされているウィンドウにKeyReleaseイベントが送信されます。閉じます。そのアプリがそれに反応すると(私の場合はFirefoxのJavaScriptで発生しました)、望ましくないことが起こる可能性があります。
しかし、これは私のスクリプトやdmenuに固有のものではありません。また、私がテストした他のダイアログスタイルのXアプリ、特にssh-askpass、ksshaskpass、gpgパスフレーズダイアログなどでも発生します。
簡単なテストは次のとおりです。
ターミナルで以下を実行します。
xev | grep -EA2 --line-buffered '^Key(Press|Release)' | sed -n 's/^.*\(Press\|Release\|keysym[^)]*\).*$/\1/p'
Returnキーを押して、ターミナルで次の出力を確認します。
Release
keysym 0xff0d, Return
Press
の前のReturn
を観察しないでくださいこれらのアプリがXイベントキューのRelease
を消費しないのはなぜですか?私はバグについて議論しますが、Xまたはアプリでは?
そのようなアプリを(python?)スクリプトでラップする場合、どうすればこれを修正できますか?
KeyPress
イベントを処理したアプリケーションは、通常、後続のKeyRelease
イベントを処理することは期待されていません。ユーザーがキーを押してから別のアプリケーションに切り替えてからキーを離すと、要求されたときにフォーカスの変更が発生することが予想されます。ユーザーがキーを離すまで遅延することは想定されていません。
入力イベントを処理するためのX11のアーキテクチャは非常に単純です。イベントがクライアントによって取得された場合、クライアントはイベントを受信します。または、イベントが取得されていない場合、現在フォーカスを持っているクライアントは、イベント。どのクライアントがKeyRelease
イベントを受信したかに基づいて、KeyPress
イベントを個別にディスパッチする規定はありません。
KeyRelease
を受信したクライアントにKeyPress
イベントを再ルーティングすることが明らかに間違っている例は、修飾子を使用する場合です。フォーカスの変更時に、モディファイヤが押された場合、それは押されたままになります。 KeyRelease
イベントは、修飾子が押されなくなったときに送信されます。フォーカスが失われたときに押されたすべての修飾子に対してKeyRelease
イベントを送信し、対応するKeyPress
イベントを新しくフォーカスされたウィンドウに送信することは理にかなっていますが、実際の正確なレポートではありません。ユーザー入力。これは、同じアプリケーションのウィジェット間のフォーカス変更で特に混乱を招きます。
X11の動作が明らかに正しく、キー押下イベントの再ルーティングの提案が間違っている別の例は、同じアプリケーションのウィジェット間でフォーカスを変更する場合です。アプリケーションがどのウィジェットにフォーカスされているかを気にせずにこの特定のキーを気にする場合、偽のイベントを送信するのは誤りです。ただし、アプリケーションがどのウィジェットがKeyRelease
イベントを受信するかを気にする場合、このイベントは、その時点でフォーカスがあるウィジェットに確実に送信される必要があります。
ほとんどのアプリケーションには、キーリリースイベントではなく、キー押下イベントによってトリガーされるアクションがあります。イベントによってボタンが押された場合、ボタンの効果は、離したときではなく、押したときにトリガーされると予想されます。ウィンドウの閉鎖を引き起こすイベントの動作が異なる場合、ユーザーエクスペリエンスは奇妙になります。
キーを押したためにウィンドウが閉じたときにフォーカスを別のウィンドウに移動させることが明らかに正しい例は、 Esc キーを押したままにして、複数のダイアログボックスを終了します。アプリケーションがリリースを必要とする場合、それは破壊的です Esc ウィンドウを閉じるために離すキー。
あなたが説明するシナリオでは、明らかに何か問題を起こしているのはFirefox/JavaScriptアプリケーションです。ほとんどのキーボードインターフェイスは、キーのリリースではなく、キーの押下に基づいています。特に、それは押す Enterリリースそれではなく、何かが起こることになっています。アプリケーションがキーリリースイベントに反応する場合、適切な方法で一致するKeyRelease
を受信せずに、KeyPress
イベントを受信する状況を処理する責任がアプリケーションにあります。
ドラッグアンドドロップやクリックの長さに依存するイベントなど、リリースイベントにインターフェイスが反応すると予想される状況が多数あるため、マウスクリックは多少異なります。それでも、アプリケーションは通常、対応するButtonRelease
を取得しなかった場合、ButtonPress
イベントに反応しないはずです。