Xlib в центре окна - PullRequest
       14

Xlib в центре окна

9 голосов
/ 15 января 2012

Я пишу Xlib приложение, в котором я хочу, чтобы окно было в центре. Я использовал XMoveWindow с (desktopWidth - width) / 2, (desktopHeight - height) / 2, и он примерно в нужном месте.

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

Мне нужно использовать Xlib, потому что я использую Glx и OpenGL. Я не хочу использовать SDL и не иметь громоздкой графической библиотеки.

Ответы [ 2 ]

10 голосов
/ 22 января 2012

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

Семантическая

Спецификации рекомендуют использовать _NET_WM_WINDOW_TYPE вместо установки позиции, если имеет смысл сделать это.См. http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html#id2507144

Например, тип DIALOG (или окно с набором подсказок WM_TRANSIENT_FOR) обычно центрируется в его родительском окне или на экране, а тип _NET_WM_WINDOW_TYPE_SPLASH (splashscreen) обычно центрируетсяна экране.«Обычно» здесь означает, что «разумные оконные менеджеры, вероятно, центрируют его, и люди, использующие странные оконные менеджеры, не являются вашей проблемой, пусть они страдают».

(Еще один намек в том же духе, хотя и не тот, что вы хотите здесь,is _NET_WM_STATE_FULLSCREEN, что позволяет избежать ручного изменения размера / позиционирования, чтобы быть полноэкранным.)

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

Гравитация

Если в спецификациях, которые помогут вам, нет семантического намека, то вы можете сосредоточиться нарука.Важно отметить, что оконным менеджерам разрешено игнорировать ручной запрос позиции, а некоторые из них будут.Некоторые могут удовлетворить запрос, только если вы установите флаг USPosition в WM_NORMAL_HINTS (этот флаг предполагается устанавливать только в том случае, если пользователь явно запросил позицию, например, с параметром командной строки -geometry).Другие могут игнорировать запрос всегда.Но вы, вероятно, можете игнорировать WM, которые делают это;пользователь решил использовать этот WM.

Способ компенсации декораций окон (заголовок и т. д.) заключается в использовании поля win_gravity в WM_NORMAL_HINTS, которое изначально находится в ICCCM (см. http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.2.3), но лучше указать в примечании к реализации в EWMH: http://standards.freedesktop.org/wm-spec/latest/ar01s09.html#id2570420

Для WM_NORMAL_HINTS см. http://tronche.com/gui/x/xlib/ICC/client-to-window-manager/wm-normal-hints.html#XSizeHints (примечание: тип свойства - WM_SIZE_HINTS, а имя свойства - WM_NORMAL_HINTS, поэтому задействованы два разных имени атома).

Для центра вы должны установить win_gravity в Center, что позволяет вам позиционировать центр окна (включая его декорации) вместо верхнего левого угла..

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

Обновление возможнопутаница: в протоколе X есть и другие «гравитации», в частности, запрос CreateWindow позволяет установить «bit_gravity»и "win_gravity";они отличаются от XSizeHints.win_gravity.Гравитация CreateWindow описывает, как содержимое (пиксели / подокна) окна обрабатывается при изменении размера окна.

Хаки, основанные на угадывании размера декорации

Это хрупкий взлом, но ...Вы можете попытаться выяснить размер декорации и затем включить его в свое позиционирование.

Чтобы получить размер декораций окна, одним из способов является подсказка _NET_FRAME_EXTENTS, см. http://standards.freedesktop.org/wm-spec/latest/ar01s05.html#id2569862

Дляоконные менеджеры старшей школы (но не новые необычные композиторы, хотя, надеюсь, они поддерживают _NET_FRAME_EXTENTS), декорации окон - это окно X, так что вы можете получить родительское окно и посмотреть на его размер.

Проблема соба эти подхода заключаются в том, что вы должны отобразить окно перед добавлением декораций, поэтому вы должны отобразить карту;ждать получения события MapNotify;затем получить размер украшения;затем переместите окно.Это, к сожалению, вызовет видимое пользователю мерцание (окно сначала появится, а затем переместится)Я не думаю, что есть способ получить размер оформления окна без предварительного отображения.

Спускаясь дальше в область ужасных хаков, вы могли бы предположить, что для окон после первого отображенного вами изображения украшения будут соответствовать ранее отображенным окнам.(Не то, чтобы это было здравым предположением: разные виды окон могут иметь разную декорацию.)

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

Перенаправление переопределения

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

Если вы установите флаг перенаправления переопределения при создании окна, то диспетчер окон не будет управлять его размером, положением, порядком расположения, декорациямиили состояние карты (перенаправление оконного менеджера ConfigureRequest и MapRequest отменено).

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

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

(ЕслиВы просто не хотите украшений, используйте семантический тип, такой как SPLASH, или используйте подсказки «MWM», не используйте переадресацию переопределения.)

Сводка

Короткий ответ - это семантическая подсказка, еслилюбое применимо, и в противном случае используйте XSizeHints.win_gravity = Center.

Вы можете понять, почему люди используют наборы инструментов и SDL ;-) много странного исторического багажа и угловых случаев в менеджере клиента к окнуКак правило, взаимодействие, установка положения окна - это только начало волнения!

0 голосов
/ 12 апреля 2018

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

Очевидно, что Unity не реализовала это. Тестирование показывает, что XCB_GRAVITY_STATIC не соблюдается, и, бросив быстрый взгляд на исходный код Unity, я не смог найти код, реализующий эту часть спецификации.

...