ポインターの動きについて通知を受けようとしています。ウィンドウマネージャーとして実行したくないので、XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_POINTER_MOTION
起動時と作成通知イベントの両方で行うすべてのウィンドウで設定する必要があります。
これは一般的にうまく機能しているようで、すべてのウィンドウでモーション通知イベントを受け取ります。ただし、どういうわけか、これは Google Chrome ウィンドウには当てはまりません。後で明示的にクエリを実行してイベント マスクを確認したところ、正しく設定されています。伝播マスクにも異常は見られません。
Google Chrome がモーション通知イベントを報告しない原因は何ですか? 私の知る限り、X プロトコルでは、Chrome にはないアクティブなポインター グラブを除いて、それが許可されていません。
これが、既存のすべてのウィンドウに自分自身を登録する方法です。ルート ウィンドウを呼び出しregister_events
、create notify イベントも受け取るたびに、次のようにします。
static void register_events(xcb_window_t window) {
xcb_void_cookie_t cookie = xcb_change_window_attributes_checked(connection,
window, XCB_CW_EVENT_MASK, (uint32_t[]) { XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_LEAVE_WINDOW });
xcb_generic_error_t *error = xcb_request_check(connection, cookie);
if (error != NULL) {
xcb_disconnect(connection);
errx(EXIT_FAILURE, "could not subscribe to events on a window, bailing out");
}
}
static void register_existing_windows(void) {
xcb_query_tree_reply_t *reply;
if ((reply = xcb_query_tree_reply(connection, xcb_query_tree(connection, root), 0)) == NULL) {
return;
}
int len = xcb_query_tree_children_length(reply);
xcb_window_t *children = xcb_query_tree_children(reply);
for (int i = 0; i < len; i++) {
register_events(children[i]);
}
xcb_flush(connection);
free(reply);
}