Как нарисовать заголовок с помощью XCB
Я работаю над простым оконным менеджером с libxcb
и я пытаюсь украсить окно заголовком, значком и кнопками min/max/close.
Я проверяю свой WM в Xephyr. Я могу создать новое окно xterm, переместить его и изменить его размер. Но теперь я хотел бы украсить новое окно xterm (или любое другое приложение в этом отношении), чтобы оно имело заголовок, значок и кнопки min/max/close.
На моей машине с Linux я только что установил тему Gtk, и если я, например, запускаю Firefox, окно оформляется после того, как я установил эту тему в своих настройках. Так что в этом случае я думаю, что Gtk применяет декорации окон. Как это работает?
Я прочитал, что свойство окна EWMH, _NET_WM_WINDOW_TYPE
, может быть использован, чтобы определить, как обрабатывать украшения вашего окна. Так что я думаю, что я мог бы проверить, если тип окна _NET_WM_WINDOW_TYPE_NORMAL
, получить WM_NAME
из приложения, а затем вручную нарисуйте заголовок поверх него.
Это то, как вы должны рисовать свои декорации окна нормально? Или я могу использовать Gtk (или что-то еще) для этого?
1 ответ
Так что в этом случае я думаю, что Gtk применяет декорации окон. Как это работает?
Правильный. Приложения GTK говорят оконному менеджеру не украшать их, устанавливая ширину границы равной 0. На данный момент мое предложение будет заключаться только в том, чтобы реализовать это: если окно устанавливает ширину границы 0, игнорируйте декорации для него. Я не стал бы беспокоиться ни о чем другом в начале. На самом деле вы могли бы даже игнорировать этот намек на данный момент.
Я прочитал, что свойство окна EWMH […]
Не беспокойтесь с EWMH сейчас. Просто украсьте все управляемые окна, которые не устанавливают границу на 0. Кроме того, я не вижу веской причины, по которой другие типы окон, такие как диалоги, не должны быть украшены; Я не думаю, что оконные менеджеры действительно используют это свойство, чтобы определить это, но я могу сказать наверняка только для пары.
Это то, как вы должны рисовать свои декорации окна нормально? Или я могу использовать Gtk (или что-то еще) для этого?
Хотя вы явно не просили об этом, последнее предложение в этой цитате говорит мне, что вы, возможно, не полностью понимаете, как работают украшения. Наиболее распространенный способ, и я настоятельно рекомендую вам сделать это так, называется воспитанием детей.
Воспроизведение означает, что когда вы управляете окном, вы создаете новое окно (которым, конечно, вы не должны управлять, как обычное окно клиента), называемое окном фрейма, а затем переопределяете окно клиента в окно фрейма. Таким образом, фактическое окно верхнего уровня является рамочным окном, принадлежащим оконному менеджеру; клиентское окно (окно, с которым взаимодействует пользователь) является его прямым потомком.
Теперь вы просто делаете окно фрейма немного больше окна клиента и правильно размещаете окно клиента внутри него. Конечно, вам нужно отслеживать размеры окна клиента и действовать в соответствии с ними.
Так почему же мы создали это рамочное окно? Просто! Потому что вы можете создать растровое изображение, которое вы используете для него и на котором вы рисуете свой заголовок. Это лучше, чем рисовать непосредственно в дочернем окне, потому что вы не связываетесь с окном, которым вы на самом деле не владеете.
Рисование может быть сделано с помощью "сырых" и простых вызовов, таких как xcb_poly_fill_rectangle
или вы можете использовать более сложный подход, например, используя библиотеку типа cairo (которую я бы порекомендовал). Например, менеджер окон i3 использует простую абстракцию, которая поддерживает оба с помощью флага компиляции (libi3/draw_util.c).
Такой подход к воспитанию является причиной, по которой инструменты xwininfo
или же xprop
иметь -frame
вариант. По умолчанию эти инструменты фактически игнорируют окно фрейма и спускаются в окно клиента, в значительной степени скрывая факт наличия окна фрейма. Просто попробуй xprop
а также xprop -frame
в том же окне вы увидите, что к рамочному окну прикреплено гораздо меньше информации.
После того, как у вас появятся отцовство и рисование, вы сможете больше думать о тех случаях, когда вам не нужно / не нужно украшать окно. Учитывая, что здесь есть, что отследить, я думаю, что реализация этого на первых порах заставит вас ненадолго заняться. Я настоятельно рекомендую изучить код других простых оконных менеджеров, которые являются родительскими.