Вопросы по оформлению XLIB

Я пишу небольшой оконный менеджер, который добавляет базовое оформление вокруг окна, но на самом деле у меня есть несколько вопросов о добавлении / удалении оформления окна.

Первый вопрос

На самом деле оформление добавляется во время события MapNotify, но это, кажется, не очень хорошая идея, потому что оно добавляет оформление также к меню, открываемому приложением, каждый раз, когда mapnotify запускается с новым окном, но я хочу только добавить оформление к основному. окно. Может быть, я должен проверить, является ли текущее окно дочерним по отношению к другому окну? На самом деле мой код просто создает окно декорации с определенным именем, поэтому при каждом запросе MapNotify я присваиваю окну декорации фиктивное имя (Parent), чтобы таким образом отличать его от всех других окон, если событие MapNotify запускается в окне декорации, по крайней мере, это не добавляет другого украшения. Но я не понимаю, запускается ли MapNotify не только для родительского окна, но и для childrend. Вероятно, есть риск, что я добавлю более одного окна оформления. Фактический код следующий:

void map_notify_handler(XEvent local_event, Display* display, ScreenInfos infos){
    printf("Map Notify\n");
    XWindowAttributes win_attr;
    char *child_name;
    XGetWindowAttributes(display, local_event.xmap.window, &win_attr);
    XFetchName(display, local_event.xmap.window, &child_name);
    printf("Attributes: W: %d - H: %d - Name: %s\n", win_attr.width, win_attr.height, child_name);
    if(child_name!=NULL){
      if(strcmp(child_name, "Parent")){
        Window new_win = draw_window_with_name(display, RootWindow(display, infos.screen_num), "Parent", infos.screen_num, 
                           win_attr.x, win_attr.y, win_attr.width, win_attr.height+DECORATION_HEIGHT, 0, 
                           BlackPixel(display, infos.screen_num));
        XMapWindow(display, new_win);
        XReparentWindow(display,local_event.xmap.window, new_win,0, DECORATION_HEIGHT);
        XSelectInput(display, local_event.xmap.window, SubstructureNotifyMask);
        put_text(display, new_win, child_name, "9x15", 10, 10, BlackPixel(display,infos.screen_num), WhitePixel(display, infos.screen_num));
      }
    }
    XFree(child_name);
}

Итак, как избежать добавления украшений в каждом окне, кроме основного окна приложения (или всплывающих окон, есть способ различить тип окна? Как я могу это выяснить?)

Второй вопрос

Когда я выхожу из программы, разрушаемое окно - это просто окно приложения, а не родительское оформление, как уничтожить текущее окно, а также оформление?

Я пытался со следующим:

void destroy_notify_handler(XEvent local_event, Display *display){
    Window window = local_event.xdestroywindow.event;
    XDestroyWindow(display, window);
}

Но я получаю следующую ошибку:

Произошла ошибка: BadWindow (неверный параметр Window)

Я использую событие вместо окна, потому что кажется, что оно содержит родительское окно (я прочитал его оттуда: http://tronche.com/gui/x/xlib/events/window-state-change/destroy.html), но даже если я использую окно, у меня та же проблема.

Или, может быть, я должен уничтожить родительское окно раньше? Может быть, во время UnMapNotify? Но как понять, запускается ли событие только потому, что окно будет закрыто или по каким-то другим причинам?

Спасибо за помощь:)

1 ответ

Решение

Прочтите спецификацию EWMH, и вы найдете ответы на все вопросы.

  1. Проверьте флажок " переопределить перенаправление"
  2. Вы пытаетесь уничтожить окно, которое уже уничтожено. Вместо использования идентификатора окна event.xdestroywindow.event просто удалите окно оформления.
  3. Не забудьте добавить клиентское окно для сохранения набора, если вы пишете родительский WM. Таким образом, если вы убьете окна приложения wm, они не будут уничтожены, а перезапущены обратно в корневое окно.
Другие вопросы по тегам