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

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

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

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

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 (недопустимый параметр окна)

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

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

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


person Ivan    schedule 16.12.2013    source источник


Ответы (1)


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

  1. Проверить "переопределить перенаправление" флаг окна
  2. Вы пытаетесь уничтожить окно, которое уже разрушено. Вместо использования идентификатора окна event.xdestroywindow.event просто удалите свое декоративное окно.
  3. Не забудьте добавить окно клиента в сохраните набор, если вы пишете переподготовку WM. Таким образом, если вы убиваете окно wm-приложения, окна не уничтожаются, а возвращаются в корневое окно.
person Andrey Sidorov    schedule 17.12.2013
comment
по №2: проблема в том, что я не понимаю, как удалить окно декорации. Поскольку, если дочернее окно разрушается, я не могу получить доступ к родительскому окну. Вы можете объяснить? - person Ivan; 17.12.2013
comment
где-нибудь запомните свой new_win (например, в хеше, где ключ - это идентификатор главного окна) - person Andrey Sidorov; 17.12.2013
comment
Хорошо понял! Спасибо. - person Ivan; 17.12.2013