LINUX.ORG.RU

Оконные сообщения X Windows


0

0

Здравствуйте! В моей программе необходимо реагировать определенным образом на создание окон, изменение их размеров, перемещении и т. д. Для этого я получаю сообщения от рутового окна с маской SubstructureNotifyMask. Но вся беда в том, что, например, при создании окна (я запускаю какое-либо приложение) начинают приходить не только сообщения CreateNotify, ConfigureNotify и MapNotify. А так же приходят сообщения и DestroyNotify. Получается, что создается не только одно окно, а несколько, а некоторые из них сразу же после создания уничтожаются. Такое же происходит и при попытке реагировать на другие действия с окнами. Подскажите пожалуйста: 1. Есть ли другой способ реагировать на описанные действия с конами? 2. Почему приходят сообщения о создании еще каких-то окон и об уничтожении каких-то окон? Привожу небольшой лог (запускал клнсоль из KDE): defRootWnd = 0x44 The dispatching of events: 'DestroyNotify' event come for window 0x1000003 'CreateNotify' event come for window 0x1000004 parent = 0x44 x = 0 y = 0 width = 1 height = 1 border_width = 0 'CreateNotify' event come for window 0x16000F2 parent = 0x44 x = 320 y = 307 width = 640 height = 409 border_width = 0 'ConfigureNotify' event come for window 0x16000F2 x = 320 y = 307 width = 16 height = 16 border_width = 0 'ConfigureNotify' event come for window 0x16000F2 x = 320 y = 307 width = 20 height = 20 border_width = 0 'CreateNotify' event come for window 0x3A00001 x = 0 y = 0 width = 1 height = 1 border_width = 0 'DestroyNotify' event come for window 0x3A00001 'ConfigureNotify' event come for window 0x16000F2 x = 129 y = 1029 width = 20 height = 20 border_width = 0 'MapNotify' event come for window 0x16000F2 'CreateNotify' event come for window 0x3A00002 x = 0 y = 0 width = 1 height = 1 border_width = 0 'DestroyNotify' event come for window 0x3A00002 'ConfigureNotify' event come for window 0x16000F2 x = 129 y = 1033 width = 20 height = 20 border_width = 0 'CreateNotify' event come for window 0x3C00001 x = 320 y = 307 width = 640 height = 409 border_width = 0 'CreateNotify' event come for window 0x3C00002 x = 0 y = 0 width = 1 height = 1 border_width = 0 'ConfigureNotify' event come for window 0x16000F2 x = 129 y = 1036 width = 20 height = 20 border_width = 0 'ConfigureNotify' event come for window 0x16000F2 x = 129 y = 1036 width = 20 height = 20 border_width = 0 'ConfigureNotify' event come for window 0x16000F2 x = 129 y = 1039 width = 20 height = 20 border_width = 0 'CreateNotify' event come for window 0x3C00007 x = 320 y = 307 width = 640 height = 409 border_width = 0 'CreateNotify' event come for window 0x3C00018 x = 320 y = 307 width = 640 height = 409 border_width = 0 'ConfigureNotify' event come for window 0x16000F2 x = 129 y = 1042 width = 20 height = 20 border_width = 0 'ConfigureNotify' event come for window 0x16000F2 x = 129 y = 1042 width = 20 height = 20 border_width = 0 'CreateNotify' event come for window 0x3C0001A x = 320 y = 307 width = 640 height = 409 border_width = 0 'CreateNotify' event come for window 0x3C0001B x = 320 y = 307 width = 640 height = 409 border_width = 0 'CreateNotify' event come for window 0x3C0001C x = 320 y = 307 width = 640 height = 409 border_width = 0 'CreateNotify' event come for window 0x3C0001D x = 320 y = 307 width = 640 height = 409 border_width = 0 'CreateNotify' event come for window 0x3C0001E x = 320 y = 307 width = 640 height = 409 border_width = 0 'CreateNotify' event come for window 0x3C0001F x = 320 y = 307 width = 640 height = 409 border_width = 0 'ConfigureNotify' event come for window 0x3C00007 x = 320 y = 307 width = 321 height = 321 border_width = 0 'CreateNotify' event come for window 0x3C00020 x = 320 y = 307 width = 640 height = 409 border_width = 0 'CreateNotify' event come for window 0x3C00021 x = 320 y = 307 width = 640 height = 409 border_width = 0 'CreateNotify' event come for window 0x3C0002C x = 320 y = 307 width = 640 height = 409 border_width = 0 'CreateNotify' event come for window 0x3C0002D x = 320 y = 307 width = 640 height = 409 border_width = 0 'CreateNotify' event come for window 0x3C0002E x = 320 y = 307 width = 640 height = 409 border_width = 0 'CreateNotify' event come for window 0x3C0002F x = 320 y = 307 width = 640 height = 409 border_width = 0 'ConfigureNotify' event come for window 0x16000F2 x = 129 y = 1044 width = 20 height = 20 border_width = 0 'ConfigureNotify' event come for window 0x16000F2 x = 129 y = 1044 width = 20 height = 20 border_width = 0 'DestroyNotify' event come for window 0x3C00047 'ConfigureNotify' event come for window 0x3C00007 x = 320 y = 307 width = 746 height = 430 border_width = 0 'CreateNotify' event come for window 0x1201070 x = 0 y = 0 width = 1 height = 1 border_width = 0 'ConfigureNotify' event come for window 0x1200032 x = 0 y = 0 width = 100 height = 100 border_width = 0 'CreateNotify' event come for window 0x1201088 x = 320 y = 307 width = 640 height = 409 border_width = 0 'ConfigureNotify' event come for window 0x1201088 x = 320 y = 307 width = 100 height = 100 border_width = 0 'ConfigureNotify' event come for window 0x1200032 x = 0 y = 0 width = 754 height = 462 border_width = 0 'ConfigureNotify' event come for window 0x1201070 x = 0 y = 0 width = 1 height = 1 border_width = 0 'ConfigureNotify' event come for window 0x1201070 x = 526 y = 0 width = 754 height = 462 border_width = 0 'MapNotify' event come for window 0x1201070 'ConfigureNotify' event come for window 0x1201070 x = 526 y = 0 width = 754 height = 462 border_width = 0 'ConfigureNotify' event come for window 0x16000F2 x = 129 y = 1046 width = 20 height = 20 border_width = 0 'ConfigureNotify' event come for window 0x16000F2 x = 129 y = 1047 width = 20 height = 20 border_width = 0 'ConfigureNotify' event come for window 0x16000F2 x = 129 y = 1049 width = 20 height = 20 border_width = 0 'CreateNotify' event come for window 0x3C000B8 x = 320 y = 307 width = 640 height = 409 border_width = 0 'UnmapNotify' event come for window 0x16000F2 'UnmapNotify' event come for window 0x16000F2 'DestroyNotify' event come for window 0x16000F2 'DestroyNotify' event come for window 0x3C000B8 'ConfigureNotify' event come for window 0x180011A x = 93 y = 898 width = 206 height = 86 border_width = 0 'ConfigureNotify' event come for window 0x180011A x = 133 y = 898 width = 206 height = 86 border_width = 0


во первых укажи првильное форматирование во вторых почему ты полез в XLib а не заюзал какой нить тулкит, фреймворк и т.п.?

cvv ★★★★★
()
Ответ на: комментарий от cvv

Полез в XLib, потому что все это должно работать безо всяких тулкитов, на более низком уровне.

pavelp
() автор топика

> Здравствуйте!

и вам не болеть.

> В моей программе необходимо реагировать определенным образом на создание окон, изменение их размеров, перемещении и т. д. Для этого я получаю сообщения от рутового окна с маской SubstructureNotifyMask. Но вся беда в том, что, например, при создании окна (я запускаю какое-либо приложение) начинают приходить не только сообщения CreateNotify, ConfigureNotify и MapNotify. А так же приходят сообщения и DestroyNotify.

а вы манул читали? уверены?

SubstructureNotifyMask включает: ConfigureNotify CreateNotify ***DestroyNotify*** GravityNotify MapNotify ReparentNotify UnmapNotify

> Получается, что создается не только одно окно, а несколько, а некоторые из них сразу же после создания уничтожаются.

хм, а что в этом странного?

> 1. Есть ли другой способ реагировать на описанные действия с конами?

есть способ реагироть на events правильно. структура любого события содепжит указаль на Window, от которого это событие пришло. если оно пришло не от вашего окна, просто игнорируйте это событие.

> 2. Почему приходят сообщения о создании еще каких-то окон и об уничтожении каких-то окон

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

asgard
()
Ответ на: комментарий от asgard

Мануал читал и что включает SubstructureNotifyMask знаю.

В том, что создается несколько окон ничего странного нет. Даже, наверное, нет ничего странного в том, что некоторые из них сразу уничтожаются. Но мне не понятно, что это за окна, почему они сразу уничтожаются и как среди всего множества создаваемых окон выделить главное окно приложения?

Все создаваемые окна в моем случае в качестве родительского окна имеют указатель на рутовое окно, потому что именно на сообщения от него я подписался:
XSetWindowAttributes setAttrs;
setAttrs.event_mask = SubstructureNotifyMask;
XChangeWindowAttributes(display, defRootWnd, CWEventMask, &setAttrs);

Суть модуля состоит в том, чтобы следить за всеми окнами в системе и при появление нового окна, уничтожении существующего окна, изменении положения, размеров и других свойств окон, передавать изменившуюся информацию другому модулю. Если окно имеет дочерние, то пока рассматриваются только главные окна.

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

pavelp
() автор топика
Ответ на: комментарий от pavelp

>Если знаете, какие-нибудь другие способы достижения указанной цели, буду весьма признателен.

посмотреть как это делает любой оконный манагер...

я кстати так и не понял зачем тебе низкий уровень, особенно с твоими познаниями. пользовал бы gtk/gdk и имел бы себе счастье...

cvv ★★★★★
()
Ответ на: комментарий от asgard

>а телепатов здесь всех забанили

уточняю - тех немногих, которые вернулись с тарифного отпуска

cvv ★★★★★
()
Ответ на: комментарий от cvv

Познания тут ни при чем, так задача - есть задача. И ее надо сделать с использованием XLib.

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

Я попробую поточнее сформулировать вопросы: 1. Что это за окна, которые создаются и сразу уничтожаются при запуске приложения? 2. Почему все создаваемые окна при запуске приложения имеют рутовое окно в качестве родителя? 3. Как среди всего потока сообщений при запуске приложения выделить те, которые относятся к главному окну запускаемого приложения? 4. Иногда приходит сообщение ConfigureNotify для какого-либо окна. Я пытаюсь получить какую-либо дополнительную информацию о нем, но возникает ошибка BadWindow, потому что это окно уже уничтожено (сообщение об этом прийдет позже, но сервер уже знает, что окна нет). Есть какой-либо способ узнать о том, валиден ли Window, который мы передаем в такие функции, как XGetWMHints, XFetchName и др. без установки обработчика ошибок функцией XSetErrorHandler (это единственный способ, который я пока нашел)?

pavelp
() автор топика
Ответ на: комментарий от pavelp

>Суть модуля состоит в том, чтобы следить за всеми окнами в системе и >при появление нового окна, уничтожении существующего окна, изменении >положения, размеров и других свойств окон, передавать изменившуюся >информацию другому модулю. Если окно имеет дочерние, то пока >рассматриваются только главные окна.

периодически вызывать XQueryTree + XGetWindowAttributes "за всеми окнами",
и сравнивать с предыдущим запросом .. и конечно использовать XSync и
XSetErrorHandler.

Valeriy_Onuchin ★★
()
Ответ на: комментарий от Valeriy_Onuchin

Спасибо за совет.

А помимо XGetQueryTree нет никакого известного Вам способа? Он не совсем подходит с той точки зрения, что изменения должны передаваться, как только они произошли. Поэтому необходимо именно каким-либо образом реагировать на события. Тем более, окон может быть достаточно много, поэтому будет тратиться время на рассмотрение их всех.

Если есть какой-либо другой способ, XGetQueryTree не пригоден.

А Вы не знаете ответы на перечисленные мною вопросы?

pavelp
() автор топика
Ответ на: комментарий от pavelp

на вопрос 1,2 - размеры окон подозрительные "больно": 16x16, 20x20, 1x1
могут быть чем угодно: иконки на рабочем столе, может быть даже
mouse cursor (у нас такой фокус используется, для dra&drop cursor),
могут "виртуальные окна" используемые WM (кстати какой?) или кем-нибудь
другим (тоже распространенный фокус для перехвата events для
какого-нибудь окна, чаще всего keyboard-events).

3. свое окно можно различить из внешней программы по имени
4. похоже без XSync + XSetErrorHandler - не обойтись.
Если кто знает как - напишете, буду признателен.

Valeriy_Onuchin ★★
()
Ответ на: комментарий от Valeriy_Onuchin

> XGetQueryTree не пригоден.
Почему? Скажем, каждые 100 ms, рассматривая только "верхние окна".

У Вас чистый Х11? или какая-нибудь lib (в этом случае, как правило, все окна созданные регистрируются этой lib)?

Возможно средствами WM ... не знаю

Valeriy_Onuchin ★★
()
Ответ на: комментарий от pavelp

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

asgard
()
Ответ на: комментарий от asgard

> Поэтому необходимо именно каким-либо образом реагировать на события

на какие события и для каких окон (своих)?
Интересно из какой области вопросы? GUI recording? regression tests?

Valeriy_Onuchin ★★
()
Ответ на: комментарий от Valeriy_Onuchin

Использую KDE.

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

Как узнать, какие из них отображаются на экране? В моем случае при запуске консоли сообщение MapNotify приходит только один раз для какого-то левого окна, хотя UnmapNotify - несколько раз, но что при этом пропадает с экрана я так и не понял.

pavelp
() автор топика
Ответ на: комментарий от pavelp

Я использую чистый X11, потому что пока только пытаюсь разобраться. А какую lib Вы бы могли посоветовать?

Вопрос стоит не в том, что бы реагировать на события для своих окон, а чтобы реагировать на описанные события для всех окон в системе и передавать информацию о измененившимся параметре определенного окна дальше.

pavelp
() автор топика
Ответ на: комментарий от pavelp

> создается окон больше, чем уничтожается

нормальная ситуация - это могут быть popup menus, tool tips,
и др. которые создаются in unmapped state ... а могут быть и bugs :)

Valeriy_Onuchin ★★
()
Ответ на: комментарий от Valeriy_Onuchin

> о измененившимся параметре определенного окна дальше

нарисовалась линия, поменялся фон - сюда входят?
или интерсуют только размеры, позиция ?

Valeriy_Onuchin ★★
()
Ответ на: комментарий от Valeriy_Onuchin

К вопросу о Map. Чтобы окно было видимым, нужно, чтобы после CreateNotify пришло MapNotify? Просто, когда я запускаю, скажем, консоль MapNotify приходит только 1 раз. И то для какого-то непонятного окна.

Непонятность заключается в том, что при получении любого сообщения я пытаюсь получить некоторую информацию об окне. Иногда все происходит успешно, иногда функция возвращает ошибку, а иногда происходит BadWindow error. Так вот для этого окна функция получения его имени XFetchName() возвращает ошибку, тогда как к этому времени уже создано окно, для которого XFetchName() возвращает строку 'Shell - Konsole', и было бы логично предположить, что это и есть то главное окно (потому что я запускаю консоль), но MapNotify для него не приходит.

pavelp
() автор топика
Ответ на: комментарий от Valeriy_Onuchin

Интересует создание, удаление, минимизация, максимизация, свертывание, изменение размеров, позиции и т. д.

pavelp
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.