Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Alex Custov от Октябрь 12, 2008, 23:26



Название: сделать окно активным
Отправлено: Alex Custov от Октябрь 12, 2008, 23:26
это обсуждали в qt-interest. Окно (в X11 по крайней мере) средствами Qt нельзя сделать выше других (чтобы это работало в 100% случаев). Нужно использовать платформенно-зависимый код для общения с window manager'ом, и для каждой платформы оборачивать его ifdef-ами. В X11 используйте NETWM.


Название: Re: сделать окно активным
Отправлено: ритт от Октябрь 13, 2008, 00:00
это к чему было?

вообще, т.к. Х-сервер не занимается окнами, а оставляет эту задачу оконному менеджеру, код будет не платформо-зависимым, а оконно-менеджеро-зависимым. причём, в некторых оконных менеджерах сделать как требуется так и не удастся по причине их кривизны.
используйте КДЕ :)


Название: Re: сделать окно активным
Отправлено: Пантер от Октябрь 13, 2008, 06:22
Нужно ориентироваться на самые основные: KDE, Gnome, XFCE. Кстати, начиная с 4 версии, KDE доступен и для винды.


Название: Re: сделать окно активным
Отправлено: lana от Октябрь 13, 2008, 11:14
Спасибо.

это обсуждали в qt-interest. Окно (в X11 по крайней мере) средствами Qt нельзя сделать выше других (чтобы это работало в 100% случаев). Нужно использовать платформенно-зависимый код для общения с window manager'ом, и для каждой платформы оборачивать его ifdef-ами. В X11 используйте NETWM.


Название: Re: сделать окно активным
Отправлено: Alex Custov от Октябрь 13, 2008, 16:18
это к чему было?

вообще, т.к. Х-сервер не занимается окнами, а оставляет эту задачу оконному менеджеру

X сервер создаёт почву для работы wm.

вообще, т.к. Х-сервер не занимается окнами, а оставляет эту задачу оконному менеджеру, код будет не платформо-зависимым, а оконно-менеджеро-зависимым. причём, в некторых оконных менеджерах сделать как требуется так и не удастся по причине их кривизны.
используйте КДЕ :)

Если wm netwm-совместим (большинство современных wm, в т.ч. и KWin), то нас недолжно волновать, что

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

достаточно дёрнуть атом _NET_ACTIVE_WINDOW для нашего окна, и всё остальное должен сделать wm.

Это будет решение для X11. Для винды нужно писать, как я уже говорил, другой код и оборачивать его в #ifdef

Вообще, если интересно как это работает со стороны клиента, то можно посмотреть код fspanel - это предок fbpanel, прога на чистом Xlib, и использует X11 вызовы для работы с netwm-совместимым wm-ом.


Название: Re: сделать окно активным
Отправлено: shadone от Октябрь 19, 2008, 01:34
Вышенаписанное верно. Хочу только добавить что в Qt есть функции для управления окном - QWidget::activateWindow() и QWidget::raise()


Название: Re: сделать окно активным
Отправлено: Racheengel от Ноябрь 19, 2008, 12:00
Вышенаписанное верно. Хочу только добавить что в Qt есть функции для управления окном - QWidget::activateWindow() и QWidget::raise()

Да они то есть... Но похоже, что в КДЕ 4.1 они не работают. Сам сейчас не могу разобраться, как заставить окошко показаться на экране по клику на иконке в трее (QTrayIcon). В винде все работает, в КДЕ не хотит...
Правда в винде другой баг - если окно имеет флаг Qt::Tools, то при клике по десктопу оно пропадает :(


Название: Re: сделать окно активным
Отправлено: shadone от Ноябрь 26, 2008, 16:31
Да они то есть... Но похоже, что в КДЕ 4.1 они не работают. Сам сейчас не могу разобраться, как заставить окошко показаться на экране по клику на иконке в трее (QTrayIcon). В винде все работает, в КДЕ не хотит...

будет ли это работать зависит от реализации window manager'а т.к. общего стандарта поведения в X11-мире нет.

Правда в винде другой баг - если окно имеет флаг Qt::Tools, то при клике по десктопу оно пропадает :(
я видел подобное поведение в некоторых window manager в X11 (и это не баг т.к. опять же поведение зависит от реализации window manager'а), но не в винде - проверил сейчас в windows xp в примере examples/widgets/windowflags - окна с типом Qt::Tool не пропадают при потере фокуса. Если вы можете воспроизвести проблему, создайте таску в task-tracker.


Название: Re: сделать окно активным
Отправлено: Alex Custov от Ноябрь 26, 2008, 18:10
Да они то есть... Но похоже, что в КДЕ 4.1 они не работают. Сам сейчас не могу разобраться, как заставить окошко показаться на экране по клику на иконке в трее (QTrayIcon). В винде все работает, в КДЕ не хотит...

будет ли это работать зависит от реализации window manager'а т.к. общего стандарта поведения в X11-мире нет.

http://www.prog.org.ru/topic_7365_0.html


Название: Re: сделать окно активным
Отправлено: Racheengel от Ноябрь 26, 2008, 19:13
я видел подобное поведение в некоторых window manager в X11 (и это не баг т.к. опять же поведение зависит от реализации window manager'а), но не в винде - проверил сейчас в windows xp в примере examples/widgets/windowflags - окна с типом Qt::Tool не пропадают при потере фокуса. Если вы можете воспроизвести проблему, создайте таску в task-tracker.

Окно пропадает не при потере фокуса (такого я тоже ни разу не видел), а именно при клике по десктопу и только в винде. У меня при этом parent=0, т.к. окно главное. Думаю, что это все таки баг. Какой бы ни был WM, нет причин самостоятельно скрывать окна.
Тролям написал, но они что то не расчехляются...


Название: Re: сделать окно активным
Отправлено: shadone от Ноябрь 26, 2008, 20:45
достаточно дёрнуть атом _NET_ACTIVE_WINDOW для нашего окна, и всё остальное должен сделать wm.

ой, я пропустил это предложение. Никогда не отправляйте сообщения с временной меткой CurrentTime! не забывайте указывать корректную временную метку которую можно получить из QX11Info::appUserTime().

вкратце - система передачи фокуса в X11 основана на временных метках (timestamp) которые хранятся для каждого (top-level) окна (в свойстве _NET_WM_USERTIME) и которые отмечают время когда пользователь последний раз взаимодействовал с этим окном. На основе этих меток windowmanager решает какое из окон должно иметь фокус.

Вот пример взаимодействия пользователя с системой: имеется терминальное приложение где пользователь набирает команду запуска приложения xclock, и каждый раз когда пользователь нажимает клавишу на клавиатуре терминал сообщает windowmanager'у об обновлении временной метки. Далее пользователь нажимает enter для запуска приложения, это приложение создает окно (но пока его не показывает на экране!) и отмечает меткой время создания окна, и затем показывает окно на экране (XMapWindow), после чего windowmanager ищет окно с самой свежей временной меткой, "поднимает" его и передает ему фокус. Но система X11 сетевая и асинхронная, поэтому еще до того как xclock создаст свое окно, либо между созданием окна и его отображанием на экране пользователь может продолжать взаимодействовать с терминальным приложением, вследствии чего его временная метка будет более новая, соответственно после отображения окна xclock на экране он не должен перехватить фокус.

Поэтому в пользовательском приложении есть два способа поднять окно - XRaiseWindow/XSetInputFocus или же послать сообщение  _NET_ACTIVE_WINDOW корневому окну. Проблема в том что не гарантируется что windowmanager поддерживает любой из этих способов (и существует много "поломанных" WM который криво реализуют стандарт netwm (kwin не исключение ;). Qt использует первый способ.


Окно пропадает не при потере фокуса (такого я тоже ни разу не видел), а именно при клике по десктопу и только в винде. У меня при этом parent=0, т.к. окно главное. Думаю, что это все таки баг. Какой бы ни был WM, нет причин самостоятельно скрывать окна.
Тролям написал, но они что то не расчехляются...

такого поведения я у себя тоже не вижу. какой номер таски?


Название: Re: сделать окно активным
Отправлено: Alex Custov от Ноябрь 26, 2008, 21:04
Денис Д. вы ли это? :)

ой, я пропустил это предложение. Никогда не отправляйте сообщения с временной меткой CurrentTime! не забывайте указывать корректную временную метку которую можно получить из QX11Info::appUserTime().

вкратце - система передачи фокуса в X11 основана на временных метках (timestamp) которые хранятся для каждого (top-level) окна (в свойстве _NET_WM_USERTIME) и которые отмечают время когда пользователь последний раз взаимодействовал с этим окном. На основе этих меток windowmanager решает какое из окон должно иметь фокус.

Всё верно, но разве это важно для окна, которое активизируется насильно через _NET_ACTIVE_WINDOW?

А где в KWin кривости netwm? Чтобы знать на будущее.


Название: Re: сделать окно активным
Отправлено: shadone от Ноябрь 26, 2008, 21:14
Денис Д. вы ли это? :)
ммм. как видно из ника это я. Либо я не понял вопроса :)

Всё верно, но разве это важно для окна, которое активизируется насильно через _NET_ACTIVE_WINDOW?
все равно важно передать правильную временную метку иначе окно будет активировано насильно невзирая на то что пользователь в данный момент печатает что-то в другом окне. Мне бы такое поведение ооооочень сильно не понравилось.

А где в KWin кривости netwm? Чтобы знать на будущее.
сходу ничего не вспоминается кроме неподдержки _NET_WM_USER_TIME_WINDOW и во всех случаях работающей возможности отключить функциональности окна (например убрать кнопку закрытия окна), хм. хотя это не относится к спецификации netwm.


Название: Re: сделать окно активным
Отправлено: Alex Custov от Ноябрь 26, 2008, 21:16
Денис Д. вы ли это? :)
ммм. как видно из ника это я. Либо я не понял вопроса :)

Всегда приятно видеть отечественных сотрудников Троллтеха! ;)


Название: Re: сделать окно активным
Отправлено: Alex Custov от Ноябрь 26, 2008, 21:22
Раз уж пошла такая пьянка, м.б. активацию окон в Qt сделать через netwm? Потому что чем только люди не занимаются под иксами, чтобы окна активизировать :) Тут уже несколько тем было. Да и на лоре тоже. Очень, очень животрепещущая тема.


Название: Re: сделать окно активным
Отправлено: Racheengel от Ноябрь 27, 2008, 11:03
Номер проблемы N235809 :)


Название: Re: сделать окно активным
Отправлено: shadone от Ноябрь 27, 2008, 12:58
Раз уж пошла такая пьянка, м.б. активацию окон в Qt сделать через netwm? Потому что чем только люди не занимаются под иксами, чтобы окна активизировать :) Тут уже несколько тем было. Да и на лоре тоже. Очень, очень животрепещущая тема.
попробовать стоит. но нужно проверить текущую реализацию и реализацию через _NET_ACTIVE_WINDOW во всех популярных window manager'ах. Очень странно если текущая реализация не работает в kwin - это один из WM в котором обычно тестируем.

Номер проблемы N235809 :)
ок, вижу ваши письма. саппортеру отписался по поводу первой проблемы, а вторая - с типом окна Qt::Tool - не знаю, сходу не воспроизводится, нужно тестовое приложение от вас.