Проверять переписанные события закрытия окна

Я пытаюсь создать панель для xlib для X11, где он встраивает значки в трее, используя XEMBED, как описано в спецификации в трее. Однако, когда я закрываю приложение с иконкой в ​​трее, оно просто удаляет его из окна контейнера, но черный прямоугольник окна контейнера и запись в моем коде все еще существует.

В документации XEMBED сказано

Ответственность за отслеживание всех переадресованных ускорителей и удаление их при закрытии окна клиента лежит на ответственном за внедрение.

Однако мое приложение не получает никаких событий или указаний, когда умирает встроенное окно.

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

enum trayIconSize = 24; // dimensions of icon

icon.trayWindow = XCreateWindow(x.display, panel.window, 0, 0, ...);
icon.ownerHandle = event.data.l[2]; // window id of icon which wants to dock

XReparentWindow(x.display, icon.ownerHandle, icon.trayWindow, 0, 0);
XMoveResizeWindow(x.display, icon.ownerHandle, 0, 0, trayIconSize, trayIconSize);

Добавление его в панель работает без проблем, но я не знаю, как проверить, когда удалить его снова.

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

1 ответ

Решение

На самом деле я сделал это перед собой: https://github.com/adamdruppe/taskbar него есть хаки для моей конкретной настройки ширины, но большинство из них должно быть разумно использовано, и код может помочь вам.

Но то, что вы хотите сделать, это спросить о событиях в окне значков. Это было какое-то время, так что я как бы использую свой собственный код в качестве руководства, но когда я получил запрос на док, я позвонил XSelectInput(dd, id, EventMask.StructureNotifyMask);

StructureNotifyMask подписывается на события, включая MapNotify, DestroyNotifyВидишь, куда это идет:)

После того, как вы выбрали вход в окне значков, вы можете проверить цикл DestroyNotify а также UnmapNotify события (мой код проверяет оба, tbh, я не уверен, какой из них на самом деле срабатывает при удалении значка) и сравнить .window Участник мероприятия с идентификатором окна вашего значка. Если он совпадает, то удалите его из списка, потому что его больше нет.

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

Другие вопросы по тегам