12.1 Pointer Grabbing

Xlib provides functions that you can use to control input from the pointer, which usually is a mouse. Usually, as soon as keyboard and mouse events occur, the X server delivers them to the appropriate client, which is determined by the window and input focus. The X server provides sufficient control over event delivery to allow window managers to support mouse ahead and various other styles of user interface. Many of these user interfaces depend upon synchronous delivery of events. The delivery of pointer and keyboard events can be controlled independently.
Xlib にはポインタ(普通はマウス)からの入力の制御に使える関数が用意されている。 普通はキーボードやマウスのイベントが起きるとすぐに X サーバはこれらのイベントを適切なクライアントに配送する。 配送先はウィンドウや入力フォーカスによって決められる。 X サーバはウィンドウマネージャがマウスや他の種類の様々なスタイルのユーザインタフェースに対応できるようにイベント配送を十分に制御できる。 これらのユーザインタフェースの多くはイベントが同期的に配送されることを前提としている。 ポインタイベントとキーボードイベントの配送は独立に制御できる。

When mouse buttons or keyboard keys are grabbed, events will be sent to the grabbing client rather than the normal client who would have received the event. If the keyboard or pointer is in asynchronous mode, further mouse and keyboard events will continue to be processed. If the keyboard or pointer is in synchronous mode, no further events are processed until the grabbing client allows them (see XAllowEvents()). The keyboard or pointer is considered frozen during this interval. The event that triggered the grab can also be replayed.
マウスのボタンやキーボードのキーがグラブされると、 イベントはそのイベントが通常行くはずのクライアントではなく、 グラブを行っているクライアントに送られる。 キーボードやポインタが非同期モードならば、 以降のマウスイベントやキーボードイベントは処理が続けられる。 キーボードやポインタが同期モードならば、 グラブを行っているクライアントが許可するまでは (XAllowEvents() を参照) イベントは全く処理されない。 キーボードやイベントはこの間、 止まっていると見なされる。 グラブを引き起こしたイベントも再現される。

Note that the logical state of a device (as seen by client applications) may lag the physical state if device event processing is frozen.
デバイスのイベント処理が止まっていると、 デバイスの論理的状態 (クライアント側から見える) と物理的状態にずれが出るかもしれない点に注意すること。

There are two kinds of grabs: active and passive. An active grab occurs when a single client grabs the keyboard and/or pointer explicitly (see XGrabPointer() and XGrabKeyboard()). A passive grab occurs when clients grab a particular keyboard key or pointer button in a window, and the grab will activate when the key or button is actually pressed. Passive grabs are convenient for implementing reliable pop-up menus. For example, you can guarantee that the pop-up is mapped before the up pointer button event occurs by grabbing a button requesting synchronous behavior. The down event will trigger the grab and freeze further processing of pointer events until you have the chance to map the pop-up window. You can then allow further event processing. The up event will then be correctly processed relative to the pop-up window.
グラブには種類が2つある: すなわちアクティブグラブとパッシブグラブである。 アクティブグラブは 1 つのクライアントがキーボードやポインタを 明示的にグラブしたときに起こる。 ( XGrabPointer()XGrabKeyboard() を参照) パッシブグラブは複数のクライアントが ある特定のキーボードのキーやポインタボタンをウィンドウ内で グラブしたときに起こる。 グラブはキーやボタンが実際に押されたときに有効になる。 パッシブグラブは信頼性の高いポップアップメニューを実装するときに 便利である。 例えばボタンをグラブして動作が同期するようにしておけば、 ポインタボタンアップのイベントが起こる前に ポップアップがマップされることを保証できる。 つまりポインタボタンダウンのイベントがグラブを引き起こし、 ポップアップウィンドウをマップできるまでポインタボタンの イベント処理を止めることができる。 その後で以降のイベントを処理できる。 したがってポインタボタンアップのイベントは ポップアップウィンドウに対して正しく処理される。

For many operations, there are functions that take a time argument. The X server includes a timestamp in various events. One special time, called CurrentTime, represents the current server time. The X server maintains the time when the input focus was last changed, when the keyboard was last grabbed, when the pointer was last grabbed, or when a selection was last changed. Your application may be slow reacting to an event. You often need some way to specify that your request should not occur if another application has in the meanwhile taken control of the keyboard, pointer, or selection. By providing the timestamp from the event in the request, you can arrange that the operation not take effect if someone else has performed an operation in the meanwhile.
多くの操作について、 時刻を引数にとる関数がある。 X サーバは多くのイベントにタイムスタンプを入れる。 CurrentTime という特別な時刻は現在のサーバ時刻を表す。 X サーバは入力フォーカスが最後に変化した時刻、 キーボードが最後にグラブされた時刻、 ポインタが最後にグラブされた時刻、 セレクションが最後に変化した時刻のいずれかを管理している。 アプリケーションはイベントに反応すると遅くなるかもしれない。 他のアプリケーションがキーボードやポインタ、セレクションを制御しているならば、 自分はリクエストを出さないことを指定する何らかの方法が必要なことも多い。 リクエスト中のイベントからタイムスタンプを与えることにより、 他の誰かが操作を行っていたら自分の操作が効果を持たないようにすることができる。

A timestamp is a time value, expressed in milliseconds. It typically is the time since the last server reset. Timestamp values wrap around (after about 49.7 days). The server, given its current time is represented by timestamp T, always interprets timestamps from clients by treating half of the timestamp space as being later in time than T. One timestamp value, named CurrentTime, is never generated by the server. This value is reserved for use in requests to represent the current server time.
タイムスタンプは時刻を表す値であり、 ミリ秒単位で表現される。 この時刻は最後にサーバがリセットされてからの時間である。 タイムスタンプはある間隔で一回りする(約 49.7 日間隔)。 したがってサーバが持つ現在時刻がタイムスタンプ T であるとすると、 クライアントから得たタイムスタンプの解釈の際、 タイムスタンプ空間の半分は必ず T より遅い時刻として扱われ、 半分は T より早い時刻として表される。 CurrentTime という特別なタイムスタンプ値をサーバが生成することはない。 この値は現在のサーバ時刻を表すリクエストで使うために予約されている。

For many functions in this section, you pass pointer event mask bits. The valid pointer event mask bits are: ButtonPressMask, ButtonReleaseMask, EnterWindowMask, LeaveWindowMask, PointerMotionMask, PointerMotionHintMask, Button1MotionMask, Button2MotionMask, Button3MotionMask, Button4MotionMask, Button5MotionMask, ButtonMotionMask, and KeymapStateMask. For other functions in this section, you pass keymask bits. The valid keymask bits are: ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask.
この節で説明する多くの関数にはポインタイベントマスクビットを渡すこと。 有効なポインタイベントマスクは次のとおりである。 ButtonPressMask, ButtonReleaseMask, EnterWindowMask, LeaveWindowMask, PointerMotionMask, PointerMotionHintMask, Button1MotionMask, Button2MotionMask, Button3MotionMask, Button4MotionMask, Button5MotionMask, ButtonMotionMask, KeymapStateMask
この節の他の関数に対してはキーマスクビットを渡すこと。 有効なキーマスクビットは次のとおりである。 ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask

To grab the pointer, use XGrabPointer().
ポインタをグラブするには XGrabPointerを用いる。

To ungrab the pointer, use XUngrabPointer().
ポインタのグラブを解除するには XUngrabPointerを使う。

To change an active pointer grab, use XChangeActivePointerGrab().
ポインタのアクティブなグラブを変更するには XChangeActivePointerGrabを使う。

To grab a pointer button, use XGrabButton().
ポインタのボタンをグラブするには XGrabButtonを用いる。

To ungrab a pointer button, use XUngrabButton().
ポインタボタンのグラブを解除するには XUngrabButtonを用いる。

Next: Keyboard Grabbing

Christophe Tronche, ch.tronche@computer.org