Как получить событие при запуске нового приложения с помощью XCB

Я пытаюсь сделать очень простой оконный менеджер для учебных целей. Я использую C и библиотеку xcb. Я пытаюсь вызвать событие, если запускается новое приложение.

На данный момент я создаю корневое окно, в котором я могу получать события мыши и клавиатуры. Я также рисую цветную полосу в верхней части окна. Когда я нажму 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?


person Carlito    schedule 15.10.2012    source источник
comment
@JoachimPileborg Спасибо за ваш комментарий. Я попробовал это, используя XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY, потому что я читал нечто подобное в коде других WM, но я никогда не получаю никаких событий XCB_MAP_REQUEST или XCB_MAP_NOTIFY в своем цикле событий. Я обновил свой пост, добавив немного больше информации.   -  person Carlito    schedule 16.10.2012
comment
Ранее в этом году я сделал очень очень простой оконный менеджер на Python и XCB. Кроме XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY у меня были еще XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT и XCB_EVENT_MASK_STRUCTURE_NOTIFY.   -  person Some programmer dude    schedule 16.10.2012
comment
И вы только что добавили их в свою маску для родительского окна? Я делаю это прямо сейчас без каких-либо результатов. Возможно, мне нужен другой способ создать новый терминал? Есть ли шанс увидеть ваш код?   -  person Carlito    schedule 16.10.2012
comment
У меня были все те для корневого окна.   -  person Some programmer dude    schedule 16.10.2012
comment
@JoachimPileborg Теперь у меня немного больше успехов с XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY, но я не буду получать события разоблачения. Я думаю, это зависит от того, как я создаю свое корневое окно. Я обновил свой пост с некоторым кодом. Как создать корневое окно?   -  person Carlito    schedule 16.10.2012


Ответы (1)


Я был глуп, и я исправил это!

Я думал, что получаю события разоблачения только после того, как запустил новый терминал. Но я даже не рисовал свою полосу и фон перед входом в цикл событий, я рисовал их только в цикле XCB_EXPOSE. Поэтому, когда запускался новый терминал, вызывалось событие разоблачения, и появлялись моя панель и фон.

Теперь я поместил функции рисования перед своим циклом обработки событий, и все работает как надо. Я не знаю, является ли это правильным/лучшим способом, но для дальнейшего использования используйте следующее для создания корневого экрана:

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);

Вы получите события expose, а новые запущенные программы появятся в событии XCB_CREATE_NOTIFY.

person Carlito    schedule 18.10.2012
comment
Как выглядит ваш цикл событий, например, для захвата события EXPOSE? - person smac89; 27.12.2020