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