Как я могу получить обновленную информацию о системном DPI из X11 в программе C?

Я пытаюсь создать приложение с поддержкой DPI, которое реагирует на запрошенные пользователем события изменения DPI, изменяя размер окна.

Рассматриваемая программа создана на C и использует SDL2, однако для получения информации о системном DPI я использую xlib напрямую, поскольку поддержка SDL DPI в X11 отсутствует.

Я нашел два способа получить правильную информацию о DPI при запуске программы, оба из которых связаны с получением информации Xft.dpi из Xresource: один — использовать XGetDefault(display, «Xft», «dpi»), а другой — использовать XResourceManagerString, XrmGetStringDatabase. и XrmGetResource. Оба они возвращают правильное значение DPI при создании программы.

Проблема в том, что если пользователь изменяет масштаб системы во время работы программы, оба XGetDefault и XrmGetResource по-прежнему возвращают старое значение DPI, хотя когда я запускаю «xrdb -query | grep Xft.dpi», значение действительно изменилось.

Кто-нибудь знает способ получить обновленное значение Xft.dpi?


person José Cadete    schedule 26.01.2019    source источник


Ответы (2)


Я нашел способ сделать именно то, что хотел, хотя он довольно хакерский.

Решение (используя XLib) состоит в том, чтобы создать новое временное соединение с X-сервером, используя XOpenDisplay и XCloseDisplay, и опросить информацию о ресурсах из этого нового соединения.

Причина, по которой это необходимо, заключается в том, что X извлекает информацию о ресурсах только один раз для каждого нового соединения и никогда не обновляет ее. Следовательно, открывая новое соединение, X получит обновленные данные xresource, которые затем можно будет использовать для старого основного соединения.

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

person José Cadete    schedule 04.02.2019
comment
как вы получили событие изменения высоты заголовка? Благодарю. - person Liang Qi; 17.06.2020
comment
Это было давно, поэтому я не очень хорошо помню, но это было либо во время перемещения окна, либо во время изменения размера окна. Изменение DPI запускает событие изменения размера окна (или перемещения...?) и изменяет высоту строки заголовка. Таким образом, сравнивая высоту старой строки заголовка с новой, я мог определить, происходит ли перемещение/изменение размера из-за перемещения/изменения размера окна пользователем или возможного изменения DPI. - person José Cadete; 18.06.2020

Вы можете попробовать использовать xdpyinfo(1); в моей системе он выводит, среди прочего:

  dimensions:    1280x1024 pixels (332x250 millimeters)
  resolution:    98x104 dots per inch
  depths (7):    24, 1, 4, 8, 15, 16, 32

Я не знаю, может ли это помочь вам, потому что я не знаю, как изменить DPI вашего экрана, но есть вероятность, что это работает. Удачи!

--- ОБНОВЛЕНИЕ после комментария --- В комментарии ниже от ОП сказано, что «есть настройка для изменения DPI»… но я еще не знаю, какая. Во всяком случае, я попробовал Ctrl+Alt+Plus и Ctrl+Alt+Minus, чтобы изменить разрешение X-сервера на лету. Изменив разрешение и увидев, что все больше, чем раньше, я снова запустил xdpyinfo. ЭТО НЕ РАБОТАЕТ: все тот же результат. Но может быть метод, который вы используете (какой?), Вместо этого работает...

person linuxfan says Reinstate Monica    schedule 26.01.2019
comment
В Ubuntu и Linux Mint (единственные дистрибутивы, которые я пробовал) вы можете изменить настройку, чтобы масштабировать окна до 1x, 2x или 3x. Те обновляют Xfi.dpi. Спасибо за предложение, но получение размеров монитора не идеально, поскольку пользователь может выбирать разные масштабы независимо от физического DPI монитора. - person José Cadete; 26.01.2019
comment
@JoséCadete смотрите обновленный ответ. В любом случае, вы можете просто попробовать, нет? - person linuxfan says Reinstate Monica; 26.01.2019
comment
В Ubuntu, чтобы изменить DPI, перейдите в «Настройки» > «Устройства» > «Дисплей» > «Масштаб». Я думаю, что эта опция появляется только на мониторах с определенным разрешением, в любом случае это настройка, которая отображается на изображении по следующей ссылке: reddit.com/r/linux/comments/8bt4eg/ - person José Cadete; 26.01.2019
comment
@JoséCadete Я больше работаю с голым железом ... но масштабирование на 200% 300% может быть полностью связано с менеджером рабочего стола, а не с голым железом X11. Я имею в виду, особенно Ubuntu, и многие менеджеры настольных компьютеров пытаются скрыть детали системы, что может быть хорошо для пользователя, но неприятно для разработчиков. Так что я не знаю... - person linuxfan says Reinstate Monica; 26.01.2019
comment
Я думаю, вы правы, и Wayland использует совершенно другой метод. Думаю, я подожду, пока все станет более последовательным/SDL улучшит поддержку DPI... - person José Cadete; 26.01.2019