Вопросы по оформлению 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, и вы найдете ответы на все вопросы.
- Проверьте флажок " переопределить перенаправление"
- Вы пытаетесь уничтожить окно, которое уже уничтожено. Вместо использования идентификатора окна event.xdestroywindow.event просто удалите окно оформления.
- Не забудьте добавить клиентское окно для сохранения набора, если вы пишете родительский WM. Таким образом, если вы убьете окна приложения wm, они не будут уничтожены, а перезапущены обратно в корневое окно.