如何找到在 linux 中放置特定 window 的显示器的 dpi?
How to find the dpi of a monitor on which a specific window is placed in linux?
我想在我的应用程序 window 根据目标监视器的基础 dpi 从一个监视器移动到另一个监视器时更改字体大小。
我玩过 xrandr、xdpyinfo 和 xlib。我查看了源代码,但找不到关联放置 window(window id)的监视器的方法。
Qt 有 QDesktopWidget,它提供 physicalDpiX/Y 但仅(看起来)用于主监视器。
xrandr.h 包含传送 mm_width 和 mm_height 的 XRROutputInfo,但我怎样才能连接到 window id?
既然这个问题得到了一些关注,我想分享一下我的研究。我还没有找到完美的解决方案。好像不行。
但使用以下代码片段可能会对您有所帮助。思路是通过比较window位置来计算底层显示。如果位置大于第一个屏幕的分辨率,则必须是第二个显示器。非常直接。
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#include <stdio.h>
#include <stdlib.h>
// compile: g++ screen_dimension.cpp -lX11 -lXrandr
int main()
{
int wid = atoi( getenv( "WINDOWID" ) );
printf("window id: %i\n", wid);
Display * dpy = XOpenDisplay(NULL);
int screen = DefaultScreen(dpy);
Window root = DefaultRootWindow(dpy);
XRRScreenResources * res = XRRGetScreenResourcesCurrent(dpy, root);
XRROutputInfo * output_info;
for (int i = 0; i < res->noutput; i++)
{
output_info = XRRGetOutputInfo (dpy, res, res->outputs[i]);
if( output_info->connection ) continue; // No connection no crtcs
printf(" (%lu %lu) mm Name: %s connection: %i ncrtc: %i \n", output_info->mm_width
, output_info->mm_height
, output_info->name
, output_info->connection
, output_info->ncrtc
);
}
printf("crtcs:\n");
for( int j = 0; j < output_info->ncrtc; j++ ) {
XRRCrtcInfo * crtc_info = XRRGetCrtcInfo( dpy, res, res->crtcs[ j ] );
if( not crtc_info->noutput ) continue;
printf("%i w: %5i h: %5i x: %5i y: %i\n", j
, crtc_info->width
, crtc_info->height
, crtc_info->x
, crtc_info->y
);
}
}
查询屏幕资源实际上有2个函数:
XRRGetScreenResourcesCurrent 和 XRRGetScreenResources。第一个 returns 一些缓存值,而后一个询问可能引入轮询的服务器。描述(搜索 RRGetScreenResources):
https://www.x.org/releases/X11R7.6/doc/randrproto/randrproto.txt
有人在计时时遇到了麻烦:
https://github.com/glfw/glfw/issues/347
XRRGetScreenResourcesCurrent:通常为 20 到 100 us。 H
XRRGetScreenResources:通常从 13600 到 13700 us。
好的,因为这里没有进一步的讨论,而且我确信我的小程序(见上文)有效,我现在声明它:已回答!
编译指令为
g++ screen_dimension.cpp -lX11 -lXrandr
(也添加为上面的评论)
为什么这么复杂?!只需从附加了 window 的屏幕获取信息。
double dDisplayDPI_H,dDisplayDPI_V;
dDisplayDPI_H = ((double)DisplayWidth( dpy, scr ))/(((double)DisplayWidthMM( dpy, scr ))/25.4);
dDisplayDPI_V = ((double)DisplayHeight( dpy, scr ))/(((double)DisplayHeightMM( dpy, scr ))/25.4);
我想在我的应用程序 window 根据目标监视器的基础 dpi 从一个监视器移动到另一个监视器时更改字体大小。
我玩过 xrandr、xdpyinfo 和 xlib。我查看了源代码,但找不到关联放置 window(window id)的监视器的方法。
Qt 有 QDesktopWidget,它提供 physicalDpiX/Y 但仅(看起来)用于主监视器。
xrandr.h 包含传送 mm_width 和 mm_height 的 XRROutputInfo,但我怎样才能连接到 window id?
既然这个问题得到了一些关注,我想分享一下我的研究。我还没有找到完美的解决方案。好像不行。
但使用以下代码片段可能会对您有所帮助。思路是通过比较window位置来计算底层显示。如果位置大于第一个屏幕的分辨率,则必须是第二个显示器。非常直接。
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#include <stdio.h>
#include <stdlib.h>
// compile: g++ screen_dimension.cpp -lX11 -lXrandr
int main()
{
int wid = atoi( getenv( "WINDOWID" ) );
printf("window id: %i\n", wid);
Display * dpy = XOpenDisplay(NULL);
int screen = DefaultScreen(dpy);
Window root = DefaultRootWindow(dpy);
XRRScreenResources * res = XRRGetScreenResourcesCurrent(dpy, root);
XRROutputInfo * output_info;
for (int i = 0; i < res->noutput; i++)
{
output_info = XRRGetOutputInfo (dpy, res, res->outputs[i]);
if( output_info->connection ) continue; // No connection no crtcs
printf(" (%lu %lu) mm Name: %s connection: %i ncrtc: %i \n", output_info->mm_width
, output_info->mm_height
, output_info->name
, output_info->connection
, output_info->ncrtc
);
}
printf("crtcs:\n");
for( int j = 0; j < output_info->ncrtc; j++ ) {
XRRCrtcInfo * crtc_info = XRRGetCrtcInfo( dpy, res, res->crtcs[ j ] );
if( not crtc_info->noutput ) continue;
printf("%i w: %5i h: %5i x: %5i y: %i\n", j
, crtc_info->width
, crtc_info->height
, crtc_info->x
, crtc_info->y
);
}
}
查询屏幕资源实际上有2个函数: XRRGetScreenResourcesCurrent 和 XRRGetScreenResources。第一个 returns 一些缓存值,而后一个询问可能引入轮询的服务器。描述(搜索 RRGetScreenResources): https://www.x.org/releases/X11R7.6/doc/randrproto/randrproto.txt
有人在计时时遇到了麻烦: https://github.com/glfw/glfw/issues/347
XRRGetScreenResourcesCurrent:通常为 20 到 100 us。 H XRRGetScreenResources:通常从 13600 到 13700 us。
好的,因为这里没有进一步的讨论,而且我确信我的小程序(见上文)有效,我现在声明它:已回答!
编译指令为
g++ screen_dimension.cpp -lX11 -lXrandr
(也添加为上面的评论)
为什么这么复杂?!只需从附加了 window 的屏幕获取信息。
double dDisplayDPI_H,dDisplayDPI_V;
dDisplayDPI_H = ((double)DisplayWidth( dpy, scr ))/(((double)DisplayWidthMM( dpy, scr ))/25.4);
dDisplayDPI_V = ((double)DisplayHeight( dpy, scr ))/(((double)DisplayHeightMM( dpy, scr ))/25.4);