оконный менеджер: недавно запущенные приложения не видны во время работы wm - PullRequest
0 голосов
/ 19 апреля 2020

TL; DR

Я пишу простой диспетчер окон для родителей. Я проверяю это с помощью Xephyr. Во время работы оконного менеджера любое приложение, запущенное в течение этого времени, не отображается (не отображается) на экране, тогда как любое приложение, запущенное до запуска оконного менеджера, отображается (отображается).

Полный вопрос

Я пишу простой диспетчер окон для родителей. В настоящее время я обрабатываю только два события XCB_CREATE_NOTIFY и XCB_BUTTON_PRESS. Я зарегистрировался на XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT и XCB_EVENT_MASK_EXPOSURE в окне root.

Я тестирую wm с Xephyr. И при тестировании любое приложение, запущенное после запуска wm, не отображается (не видно) на экране, в то время как приложения, запущенные до запуска wm, отображаются идеально (видимо).

Я где-то читал что регистрация события EXPOSURE в окне root решит проблему, но для меня это не так. Ниже приведен мой код для события CREATE_NOTIFY, которое пытается перерисовать окно клиента и отобразить его на экране (я думаю, что именно здесь я делаю что-то не так):

case XCB_CREATE_NOTIFY:
    {
        xcb_create_notify_event_t *cre;
        cre = (xcb_create_notify_event_t *)evt;

        xcb_window_t frame = xcb_generate_id(conn);
        uint32_t frameMask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
        uint32_t fM_values[2];
        fM_values[0] = custTeal->pixel; //custTeal is a custom Teal color that I've defined
        fM_values[1] = XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_POINTER_MOTION;

        xcb_window_t toBeMapped = cre->window;
        xcb_get_geometry_reply_t *tbm_window_geo = xcb_get_geometry_reply(conn,xcb_get_geometry(conn,toBeMapped),NULL);

        xcb_create_window(conn,0,frame,screen->root,tbm_window_geo->x,tbm_window_geo->y,(tbm_window_geo->width+4),(tbm_window_geo->height+4),1,XCB_WINDOW_CLASS_INPUT_OUTPUT,screen->root_visual,frameMask,fM_values);

        xcb_reparent_window(conn,toBeMapped,frame,2,2);

        xcb_map_window(conn,frame);
        xcb_map_window(conn,toBeMapped);

        xcb_flush(conn);
    }
    break;

Я не могу понять что я тут делаю не так (я новичок в этом). Должен ли я обрабатывать событие EXPOSE тоже? Как мне с этим справиться?

Тестирование

Я запускаю Xephyr с

Xephyr -br -ac -noreset -screen 1240x720 :2 &

и запускаю новые приложения с помощью (возьмите xterm как пример):

DISPLAY=:2 xterm &

Теперь любое приложение, запущенное до запуска wm (или когда wm не запущен), отлично отображается в Xephyr. Но после запуска wm любое запущенное приложение не показывается.

1 Ответ

1 голос
/ 20 апреля 2020

SubstructureRedirect означает, что, когда что-то еще пытается отобразить окно, сервер X11 вместо этого генерирует событие MapRequest и отправляет его в WM. Таким образом, вы должны обработать XCB_MAP_REQUEST события. Самый простой способ сделать это - xcb_map_window окно из события.

...