Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: andrew.k от Октябрь 20, 2010, 22:47



Название: Синхронное перемещение двух окон
Отправлено: andrew.k от Октябрь 20, 2010, 22:47
Задача: есть редактор сообщений. который состоит из двух отдельных окон. "Шапка", где выставляются атрибуты сообщения и сам редактор в котором правится текст. Оба окна это разные процессы. Шапка - несекретный процесс, редактор - секретный.
Действите происходит в недружественной среде МСВС :)
Соответственно необходимо сделать так, чтобы два отдельных окна выглядели как одно. Т.е. при перемещении "шапки", окно редактора должно перемещаться вслед.
Как сделал. При перемещении "шапки" вычисляю куда нужно подвинуть редактор и отсылаю эти координаты редактору.
Он получив их перемещает себя.
Проблемы:
1. Не получается отслеживать перемещение окна. Так как тасканием окна занимается оконный менеджер, то я получаю событие о перемещении только в момент отпускания окна "на новом" месте. В этот момент редактор перескакивает куда надо.
Такое решение меня не устраивает, но другое найти не удалось.
Т.е. видимо надо как-то взаимодействовать с Х11 и получать координаты от него, но как это сделать. В ассистенте были какие-то классы или методы, что-то с "X11Events" но разобраться не удалось, так как нет примера. Кто решал подобную задачу? Помогите, направьте.
2. Вторую проблему, которую вызывает подобная организация, это то, что отрисовкой оформления окна занимается тоже не кути, а оконный менеджер и делает он это в произвольный момент времени. Т.е. в момент когда окно создано и возникло событие о перемещении окна оно может еще быть с рамкой, а может без. Соответственно неправильно определяются высота окна и ширина или позиция (а почему?) и окно редактора оказывается сдвинутым на 4 пиксела. Иногда и на другое значение. Иногда позиционируется точно. Т.е. совершенно случайно. Решить это можно видимо при момощи таймера, например, но это будет заметно и не красиво. Как отследить отрисовку оформления окна? Вопрос №2!

 ???


Название: Re: Синхронное перемещение двух окон
Отправлено: DpoHro от Октябрь 21, 2010, 08:05
1. Не получается отслеживать перемещение окна. Так как тасканием окна занимается оконный менеджер, то я получаю событие о перемещении только в момент отпускания окна "на новом" месте. В этот момент редактор перескакивает куда надо.
Такое решение меня не устраивает, но другое найти не удалось.
Т.е. видимо надо как-то взаимодействовать с Х11 и получать координаты от него, но как это сделать. В ассистенте были какие-то классы или методы, что-то с "X11Events" но разобраться не удалось, так как нет примера. Кто решал подобную задачу? Помогите, направьте.
Кури разбор очереди иксовой.
В кутях есть у виджета помоему x11event, но оно вроде работает только толи на события самого окна либо при активном окне, не помню точно но у меня были проблемы с моей задачей.
Я пошел другим путем и стал использовать XLib для своих нужд.
Выкури это http://www.linux.org.ru/wiki/en/NETWM


Цитировать
2. Вторую проблему,
...
Соответственно неправильно определяются высота окна и ширина или позиция (а почему?) и окно редактора оказывается сдвинутым на 4 пиксела. Иногда и на другое значение. Иногда позиционируется точно. Т.е. совершенно случайно. Решить это можно видимо при момощи таймера, например, но это будет заметно и не красиво. Как отследить отрисовку оформления окна?

Не знаю как отследить отрисовку, видимо если сделаешь разбор очереди сообщений то получится.

По поводу смещения. В МСВС все через жопу, это древний RedHat. Мне надо было из своего приложения расставить кучу окон vncviewer-а мозайкой, каскадом и так и эдак, убрать их из таскбара и т.п., для этого нужно было научиться искать id этих окон. В отдельном потоке я это все делаю, ид находятся.
xprop кажет мне совсем другие ид а у меня как правило ид отличаются на +-2. Дело в том, что elk (а может и другие оконные манагеры) походу для приложения создает свое окно и вставляет в себя окно приложения, вся красота (бордер, заголовок) отрисовывается в елкшном окне в которое вставлено твое. Как то так, и ты получаешь координаты походу без учета бордера и заголовка. Если я правильно понял о чем речь идет.

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


Название: Re: Синхронное перемещение двух окон
Отправлено: GreatSnake от Октябрь 21, 2010, 09:23
Если я правильно понял, у вас внешне эти 2 окна должны выглядеть как одно.
Первое с декорациями, а второе как под-окно в пределах первого и без декораций?
Если так, то вы идёте довольно-таки сложным путём.
Можно сделать может и не проще, но совершенно не завязываясь на WM:
1. В процессе, который создаёт под-окно, получаете win_id окна и передаёте его первому процессу, например, через XSelection.
2. Первый процесс получает win_id под-окна, получает его размеры и встраивает его.

Когда-то давно я всё это проделывал, правда на Motif/Xt.


Название: Re: Синхронное перемещение двух окон
Отправлено: andrew.k от Октябрь 22, 2010, 12:03
Если я правильно понял, у вас внешне эти 2 окна должны выглядеть как одно.
Первое с декорациями, а второе как под-окно в пределах первого и без декораций?
Если так, то вы идёте довольно-таки сложным путём.
Можно сделать может и не проще, но совершенно не завязываясь на WM:
1. В процессе, который создаёт под-окно, получаете win_id окна и передаёте его первому процессу, например, через XSelection.
2. Первый процесс получает win_id под-окна, получает его размеры и встраивает его.

Когда-то давно я всё это проделывал, правда на Motif/Xt.

Полагаю, что понял правильно. И похоже твой метод хорош. Не мог бы описать подробнее. Возможно есть рабочий пример?
Что такое XSelection?
Кратко. Задача получить редактор в котором шапка несекретная и редактор секретный.


Название: Re: Синхронное перемещение двух окон
Отправлено: GreatSnake от Октябрь 22, 2010, 12:29
Цитировать
Не мог бы описать подробнее. Возможно есть рабочий пример?
Посмотри на QX11EmbedWidget и QX11EmbedContainer. Он использует XEmbed Protocol (http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html). Как раз то, что тебе нужно. Мне же когда-то пришлось самому всё это делать на Motif/Xt/Xlib, когда этого протокола не было и в помине.

Цитировать
Что такое XSelection?
Это механизм обмена данными между X11 клиентами. Подробнее тут (https://www.msu.edu/~huntharo/xwin/docs/xwindows/selection.pdf).
На нём реализован clipboard в X-ах. Можешь использовать любой другой механизм. Причём наверняка уже используешь, коли пытался синхронизировать окна.


Название: Re: Синхронное перемещение двух окон
Отправлено: andrew.k от Октябрь 22, 2010, 13:52
Цитировать
Не мог бы описать подробнее. Возможно есть рабочий пример?
Посмотри на QX11EmbedWidget и QX11EmbedContainer. Он использует XEmbed Protocol (http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html). Как раз то, что тебе нужно. Мне же когда-то пришлось самому всё это делать на Motif/Xt/Xlib, когда этого протокола не было и в помине.

Да. Похоже это то что нужно! Сейчас буду изучать. Мне приходили мысли по этому поводу, не знал с чего начать. Теперь есть с чего :) Спасибо.
Попробовал. Получилось. но если на виджете который встраивается есть редакторы текста (QLineEdit, QTextEdit), то они не работают. Просто висят и не получают фокус, не позволяют редактировать текст. QPushButton прекрасно встроился и работает.
Контейнер на косоль пишет ошибку:
X error of failed request: BadWindow (invalid Window Parameter )
далее подробности об ошибки.

В чем может быть проблема?