Так что в этом случае я думаю, что это Gtk, который применяет оформление окна. Как это работает?
Правильный. Приложения GTK говорят оконному менеджеру не украшать их, устанавливая ширину границы на 0. На данный момент я предлагаю реализовать только это: если окно устанавливает ширину границы на 0, игнорируйте для него украшения. Я бы не стал заморачиваться ни с чем другим в начале. На самом деле вы можете даже игнорировать этот намек на данный момент.
Я читал, что свойство окна EWMH […]
Не заморачивайтесь пока с EWMH. Просто декорируйте все управляемые окна, для которых граница не равна 0. Кроме того, я не вижу веской причины, по которой другие типы окон, такие как диалоги, не должны быть декорированы; Я не думаю, что оконные менеджеры действительно используют это свойство, чтобы определить это, но я могу сказать наверняка только о паре.
Это то, как вы обычно должны рисовать свои оконные украшения? Или я могу использовать Gtk (или что-то еще) для этого?
Хотя вы явно не просили об этом, последнее предложение в этой цитате говорит мне, что вы, возможно, не полностью понимаете, как работают украшения. Самый распространенный способ, и я настоятельно рекомендую вам использовать его, называется перевоспитание.
Переназначение означает, что когда вы управляете окном, вы создаете новое окно (которым, конечно же, вы не должны не управлять как обычным окном клиента), называемое окном frame, а затем переназначаете родителем окно. окно клиента в окно фрейма. Таким образом, фактическим окном верхнего уровня является окно фрейма, принадлежащее оконному менеджеру; клиентское окно (окно, с которым взаимодействует пользователь) является его прямым потомком.
Теперь вы просто делаете окно фрейма немного больше, чем окно клиента, и правильно размещаете окно клиента внутри него. Конечно, вам нужно отслеживать изменения размеров окна клиента и действовать в соответствии с ними.
Итак, почему мы создали это рамочное окно? Простой! Потому что вы можете создать растровое изображение, которое вы используете для этого и на котором вы рисуете свой заголовок. Это лучше, чем рисовать непосредственно в дочернем окне, потому что вы не будете возиться с окном, которым на самом деле не владеете.
Рисование можно выполнить с помощью «сырых» и простых вызовов, таких как xcb_poly_fill_rectangle
, или вы можете использовать более сложный подход, например, с помощью библиотеки, такой как cairo (которую я бы рекомендовал). Оконный менеджер i3, например, использует простую абстракцию, которая поддерживает обе функции через флаг компиляции (libi3/draw_util.c).
Этот подход к переназначению является причиной того, что такие инструменты, как xwininfo
или xprop
, имеют параметр -frame
. По умолчанию эти инструменты фактически игнорируют окно фрейма и спускаются в окно клиента, в значительной степени скрывая тот факт, что окно фрейма существует. Просто попробуйте xprop
и xprop -frame
в одном и том же окне, и вы увидите, что к окну фрейма прикреплено гораздо меньше информации.
После того, как у вас есть переподготовка и рисование, вы можете больше думать о случаях, когда вам не нужно / не хочется украшать окно. Учитывая, что здесь нужно отслеживать довольно много, я думаю, что реализация этого сначала займет вас на некоторое время. Настоятельно рекомендую изучить код других простых оконных менеджеров, которые перестраиваются.
person
Ingo Bürk
schedule
28.05.2016