3

私は学習目的のために非常にシンプルなウィンドウマネージャーを作ろうとしています。Cxcbライブラリを使用しています。新しいアプリケーションが起動された場合にイベントを発生させようとしています。

今のところ、マウスとキーボードのイベントを受信できるルートウィンドウを作成します。また、ウィンドウの上部に色付きのバーを描画します。Enterキーを押すと、xtermはforkとexecvpを使用して起動します。これはすべてうまくいきます。

xterm(または私が思う任意のアプリケーション)が起動すると、バーの上に描画されます(x = 0、y = 0)。少し下げたい(x = 0、y = 16)。を使用してウィンドウを移動する方法を知っていると思いますxcb_configure_window。しかし、新しく起動したアプリケーションのイベントを取得する方法がわかりません。

編集:
いじり回した後、次の結論に達しました。次のよう
に親ウィンドウを作成した場合:

xcb_window_t window_root = screen->root;
uint32_t mask = 0;    
uint32_t values[2];
mask = XCB_CW_EVENT_MASK;
values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY;
xcb_change_window_attributes_checked(connection, window_root, mask, values);
xcb_flush(connection);

新しい端末をスポーンすると、XCB_CREATE_NOTIFYを受け取ります。XCB_EVENT_MASK_EXPOSEただし、イベントに「登録」していないため、画面に何も描画できません。values [0]行を次のように変更すると、次のようになります。

values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_EXPOSURE;

作成イベントは引き続き受信しますが、プログラムの開始直後に公開イベントが呼び出されないため、バーが描画されません。新しい端末を起動するとすぐに公開イベントが発生しますが、最初の描画は行われません。

親ウィンドウを作成する私の古い方法は次のとおりです。

xcb_window_t window = xcb_generate_id(connection);
uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
uint32_t values[2] = {screen->white_pixel, XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY };
xcb_create_window(connection, 0, window, screen->root, 0, 0, screen->width_in_pixels, screen->height_in_pixels, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, mask, values);
xcb_map_window(connection, window);

これにより、XCB_EVENT_MASK_EXPOSUREイベントがすぐに取得されるため、白い背景が描画され、色付きのバーが描画されます。ただし、XCB_CREATE_NOTIFYイベントは取得されません。

では、XCB_CREATE_NOTIFYイベントとXCB_EVENT_MASK_EXPOSUREイベントの両方を取得する正しい方法は何ですか?

4

1 に答える 1

4

私はばかげていたので、それを修正しました!

新しいターミナルを立ち上げて初めて公開イベントが発生したと思いました。しかし、イベントループに入る前にバーと背景を描画することすらしませんでしたXCB_EXPOSE。ループに描画するだけでした。そのため、新しいターミナルが起動すると、exposureイベントが呼び出され、バーと背景が表示されました。

これで、イベントループの前にも描画関数を配置しましたが、すべてが正常に機能します。これが正しい/最善の方法かどうかはわかりませんが、今後の参考のために、以下を使用してルート画面を作成してください。

xcb_window_t window_root = screen->root;
uint32_t mask = 0;    
uint32_t values[2];
mask = XCB_CW_EVENT_MASK;
values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY;
xcb_change_window_attributes_checked(connection, window_root, mask, values);
xcb_flush(connection);

公開イベントが発生し、新しく起動されたプログラムがXCB_CREATE_NOTIFYイベントに表示されます。

于 2012-10-18T09:58:16.823 に答える