我有两个不同的桌面主机通过DisplayPort输出连接到同一4K显示器上的两个DisplayPort输入:
这两个系统都运行完全最新的Debian 9,并且配置与我可以管理的完全相同。特别是:
grep DPI /var/log/Xorg.0.log
和xdpyinfo | grep dots
检查xrdb -query | grep dpi
检查。xrdb -cpp cpp -merge $HOME/.Xresources
进行配置,并且我已经确认xrdb -query
在两者上都生成相同的输出。我也在两个系统上加载到~/.fonts
中的源代码专业字体集完全相同。在其中任何一个上我都可以开始一个80列的xterm,配置有XTerm*VT100*font: -misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1
,它们看起来相同,宽484像素。如果我使用ssh -X
在本地X服务器上显示的另一台机器上启动xterm客户端,则不会更改。
但是,urxvt
根据我正在使用的X服务器而有所不同。我已将字体X资源配置为:
Rxvt.font: xft:Source Code Pro:size=9,xft:Source Han Sans,xft:DejaVu Serif:size=8,xft:DejaVu Sans Mono:size=8
当我启动urxvt
以显示在田园诗般的X服务器上时,无论是在本地还是在ssh -X
的另一台主机上启动,80列终端的宽度为644像素,垂直最大化时为106列高。但是,当我开始在对数的X服务器上显示(再次在本地或使用ssh -X
的远程客户端)时,80列urxvt
是726像素宽,但在垂直最大化时仍然是106列高。
那么,问题是:
是什么导致urxvt
在对数上更宽,我如何使它与田园诗般相同的窄尺寸?即使你不知道,调试提示将不胜感激。我很乐意编写与X11服务器通信的程序(更喜欢Python或类似的C或类似程序),让我玩urxvt
正在做的类似渲染,看看问题是否可以通过这种方式找到,如果你有关于我应该调用哪些API以及我应该寻找什么样的结果的具体建议。
一个侧面问题:xft:
字体由X客户端呈现,对吧?如果这是正确的,那么X11服务器中的某些设置正在改变同一主机上的同一客户端呈现字体的方式似乎是一个很大的提示,具体取决于它正在与哪个X11服务器进行通信。
xfce4-terminal
Information我尝试启动一个xfce4-terminal
并将字体设置为9点源代码专业媒体;它在两台X11服务器上都是一样的,总是采用urxvt
在对数上使用的更广泛的格式。这似乎表明它与urxvt
本身或者Xft
库有关(如果xfce4-terminal
不使用它;我很确定urxvt
会这样做),而不是FreeType?
xtrace
Information我从xtrace
获得了进一步的信息(感谢你的想法,@Uli Schlachter!),至少让我看到问题更加详细。即使只运行xtrace urxvt -e true
也会产生几百千字节的输出,所以很明显我不会在这里包含所有内容,但这里有一些关键部分。下面的差异是会话田园→田园和田园→对数,即田园诗在两种情况下运行urxvt
但首先在自身上显示,第二次在对数上远程显示。
在每个CreateWindow
调用的第156行确认正在创建具有相同高度但不同宽度的窗口,如上所述(我测量了一个窗口宽度死,但其他两个像素输出):
-000:<:005e: 48: Request(1): CreateWindow depth=0x18 window=0x03200009 parent=0x000000e7 x=0 y=0 width=644 height=904 border-width=0 class=InputOutput(0x0001) visual=0x00000021 value-list={background-pixel=0x00ffffe0 border-pixel=0x00ffffe0 override-redirect=false(0x00) colormap=0x00000020}
+000:<:005e: 48: Request(1): CreateWindow depth=0x18 window=0x05400009 parent=0x000004bb x=0 y=0 width=724 height=904 border-width=0 class=InputOutput(0x0001) visual=0x00000021 value-list={background-pixel=0x00ffffe0 border-pixel=0x00ffffe0 override-redirect=false(0x00) colormap=0x00000020}
从每一行的第138行开始,我看到这个差异(为理智而截断的第二行),这似乎证实了,width=7
与width=9
正在创建的字形,它是一个字符宽度问题。
-000:<:004c: 12: RENDER-Request(139,17): CreateGlyphSet gsid=0x03200008 format=0x00000024
-000:<:004d:108: RENDER-Request(139,20): AddGlyphs glyphset=0x03200008 glyphids=0x0000036d; glyphs={width=7 height=10 x=-1 y=10 xOff=9 yOff=0}; data=0x00,0x3e,...
+000:<:004c: 12: RENDER-Request(139,17): CreateGlyphSet gsid=0x05400008 format=0x00000026
+000:<:004d:388: RENDER-Request(139,20): AddGlyphs glyphset=0x05400008 glyphids=0x0000036d; glyphs={width=9 height=10 x=0 y=10 xOff=9 yOff=0}; data=0x00,0x00,...
(这继续用于更多角色,宽度为8对10,9对11,等等)
因此,无论是什么导致这种情况发生在第138行之前的某个地方。在此之前,大多数差异似乎是用于对象的ID号的变化,因此找出真正的差异是多么痛苦。
那么我看到的主要差异是什么?好吧,客户端连接后的初始响应几乎完全相同,只是对数(带有离散Radeon图形卡的那个)返回了更多的视觉效果。两者都以:
{id=0x00000021 class=TrueColor(0x04) bits/rgb-value=8 colormap-entries=256 red-mask=0x00ff0000 green-mask=0x0000ff00 blue-mask=0x000000ff},
{id=0x00000022 class=DirectColor(0x05) bits/rgb-value=8 colormap-entries=256 red-mask=0x00ff0000 green-mask=0x0000ff00 blue-mask=0x000000ff},
之后的列表似乎主要是重复的,只是在对数方面有更多的重复。
下一个最大的区别在于Reply to QueryPictFormats
:在对数方面,screens=... depths=... visuals={...}
视觉列表再次长得多。
但在最后,有一个更显着的差异:
-subpixels=Unknown(0x0);
+subpixels=HorizontalRGB(0x1);
之后有一个QueryFont
for fixed,它返回一些不同的数据,看起来就像只有ID,而且无论如何似乎只用于创建一个游标,因为它之后会立即关闭。然后它去了,似乎几乎相同(再次,模数ID,除非我错过了一些东西)直到第139行。
我也尝试用FC_DEBUG
检查FC_DEBUG=8191 urxvt -e true 2>outputfile
对每个服务器。我确认这样做时宽度确实不同。区分两个输出文件在8.5 MB的输出中只产生以下差异的三个实例(-
是_idyllic,
+`是对数):
- rgba: 0(i)(s)
+ rgba: 1(i)(s)
问题是Xft / FreeType的子像素渲染,与其他一些设置一样,可以对渲染的字体宽度产生显着影响,而不会改变高度。
FontConfig调试清楚地表明子像素渲染设置不同。在X资源中明确设置它将使两个系统的工作方式相同:
Xft.rgba: rgb
将使两个系统在两个X11服务器上呈现更宽的字体(当它们呈现为没有这个集合的对数时它们的方式)。Xft.rgba: none
将使两个系统在两个X11服务器上呈现更窄的字体(当它们呈现为没有此设置的田园时它们的方式)。因此,将Xft.rgba: none
添加到~/.Xresources
可以解决问题。
虽然这个答案目前是被接受的,因为它解决了这个问题,但我很乐意改变接受另一个答案,更深入地解释这里到底发生了什么。