我正在用 Python 开发一个模块,我想找出一种方法来获得显示器分辨率减去任务栏,而无需任何用户交互,并且最好以不干扰视觉界面的方式。如果我能得到任务栏的大小和位置,我可以很容易地从显示器分辨率中减去它。但是,我似乎无法找到方法。
在 Windows 中,我能够使用该win32api
模块并用于GetMonitorInfo
获取显示器分辨率。但是,我还没有想出某种方法可以在 Ubuntu 或一般的 Linux 中做到这一点。如果您也有在 macOS 中执行此操作的方法,那也很高兴知道,但对于此问题不是必需的。
我想支持尽可能多的桌面环境,但我意识到这样做有多么困难,因为每个环境都可能有自己的解决方案。考虑到这一点,我更愿意从这些桌面环境开始:
如果这需要一些外部程序来获取它,我更愿意使用桌面环境或操作系统自带的东西。
我想找出一种方法,在没有任何用户交互的情况下获得显示器分辨率减去任务栏,并且最好以不干扰视觉界面的方式。
这就是被问到的问题,我将根据我的发现将重点放在这个答案中。获取任务栏的大小和位置是一个原始想法,但正如评论中所讨论的那样,如果不了解大量信息,这将很难实现 - 哪个面板或停靠栏正在运行,它们是否_NET_WM_STRUT
设置了属性,它们是否通过以下方式公开该信息GSettings 数据库或其他方法。我确信这不是不可能的,但相当困难。
根据根窗口的规范,_NET_WORKAREA 定义如下:
_NET_WORKAREA,x,y,宽度,高度 CARDINAL/32
该属性必须由窗口管理器在计算每个桌面的工作区时设置。包含每个桌面的几何图形。这些几何图形是相对于每个桌面上的视口指定的,并指定一个完全包含在视口内的区域。桌面应用程序应该使用工作区来适当地放置桌面图标。
窗口管理器应该通过获取当前页面减去停靠和面板窗口占用的空间来计算此空间,如客户端窗口上设置的 _NET_WM_STRUT 或 _NET_WM_STRUT_PARTIAL 属性所示。
有几点需要注意:
_NET_WM_STRUT
或_NET_WM_STRUT_PARTIAL
是由码头和面板设置属性。这意味着,如果面板或停靠栏不设置它,它们的行为基本上就像一个普通窗口,只是位于所有其他窗口之上(并可能使用户感到恼火1)。也就是说,这对我们来说已经足够了。我已经在 Ubuntu 18.04 之上的 Cinnamon、LXQt 和 XFCE 上测试了这个属性。在所有情况下,坞站和面板都将其支柱区域正确通知窗口管理器。这意味着,_NET_WORKAREA
将在 99% 的情况下为您工作。可以通过xprop
根窗口上的实用程序在 shell 中查询此属性。
$ xprop -root _NET_WORKAREA
_NET_WORKAREA(CARDINAL) = 0, 32, 3120, 974, 0, 32, 3120, 974
这是我的双显示器设置的输出,两个显示器沿顶部对齐,一个底座和顶部面板。如果您注意到只有前四个值是重要的,而其他四个值是重复的。特别感兴趣的是3120
和974
。这就是我们感兴趣的值。前两个告诉我们桌面最左边的角落从哪里开始。我的顶部面板占据 32 点,因此桌面的最左角从左侧开始,向下偏移 32 点。从底部偏移通常对窗口无关紧要 - 它们会填满可用的工作区。
如果我将 Dock 放在主显示器的右侧,您会注意到宽度减少了,但高度有:
$ xprop -root _NET_WORKAREA
_NET_WORKAREA(CARDINAL) = 0, 32, 3059, 1018, 0, 32, 3059, 1018
高度变化为 44 点。再添加 32(顶部面板窗口的大小),您将获得 1050 与我桌面的几何形状完全相同(请注意之前的 3120 没有停靠尺寸,因此使用了完整的桌面宽度):
$ xprop -root _NET_DESKTOP_GEOMETRY
_NET_DESKTOP_GEOMETRY(CARDINAL) = 3120, 1050
xprop
xprop
上面的命令随大多数桌面一起提供,并且属于x11-utils包,因此如果您的目标是基于 Debian 的主要系统,您应该在大多数情况下都可以使用它。我会做的是使用 Python 的subprocess,并利用subprocess.check_output()
orsubprocess.run()
命令并通过re
模块解析输出。
>>> import re,subprocess
>>> out = subprocess.check_output(['xprop','-root','_NET_WORKAREA'])
>>> workarea_tokens = re.split('=|,',out.decode())
>>> workarea_tokens[1:5]
[' 0', ' 32', ' 3059', ' 1018']
另一种方法(通常是我的首选方式)是使用与其他 GNOME 项目库密切相关的 Gdk库。如果您正在使用 Gtk 开发桌面应用程序,那么您已经拥有了可用的必要工具,那么为什么不使用它们呢?棘手的部分是您必须为每个单独的监视器计算工作区。
#!/usr/bin/env python3
import gi
gi.require_version('Gtk','3.0')
gi.require_version('Gdk','3.0')
from gi.repository import Gdk,Gtk,GdkX11
display = Gdk.Display().get_default()
for i in range(display.get_n_monitors()):
monitor = display.get_monitor(i)
w_area = monitor.get_workarea()
print(w_area.x, w_area.y,
w_area.width, w_area.height)
这个程序的结果:
$ python3 display_area.py
1440 32 1619 1018
0 0 1440 900
# width of two monitors with dock on right adds up to _NET_WORKAREA
$ echo $((1619+1440))
3059
$ xprop -root _NET_WORKAREA
_NET_WORKAREA(CARDINAL) = 0, 32, 3059, 1018, 0, 32, 3059, 1018
现在,还记得我说过我有双显示器吗?这种设置打开了很多可能性,但也揭示了某些奇怪的行为。
# added xfce4-panel at the bottom of second screen, no change in height - 900
$ python3 display_area.py ; xprop -root _NET_WORKAREA
1440 32 1619 1018
0 0 1440 900
_NET_WORKAREA(CARDINAL) = 526, 32, 2533, 1018, 526, 32, 2533, 1018
# stopped xfce4-panel process, same height - 900
$ python3 display_area.py ; xprop -root _NET_WORKAREA
1440 32 1619 1018
0 0 1440 900
_NET_WORKAREA(CARDINAL) = 0, 32, 3059, 1018, 0, 32, 3059, 1018
# added xfce4-panel to the top of second monitor
$ python3 display_area.py ; xprop -root _NET_WORKAREA
1440 49 1619 1001
0 0 1440 900
_NET_WORKAREA(CARDINAL) = 0, 49, 3059, 1001, 0, 49, 3059, 1001
请记住,我在一个屏幕上有一个面板和一个底座,并在另一个屏幕上添加了用于测试xfce4-panel
。Gdk 的错误结果是第二个监视器工作区没有改变。xprop
还报告了错误的数字——526
从左侧偏移的第一个输出点根本不是真的。然而,在最后一个输出中,垂直偏移增加了,这是一件好事 - 增加的额外宽度xfce4-panel
应该添加到总数中,可能有帮助的是我的两个显示器在顶部对齐。
换句话说,如果您的应用程序计划确定没有底座和面板的区域,这些方法最适合单显示器设置。在双显示器设置中 - 结果可能会不一致。请注意,我正在使用 Metacity 窗口管理器,并且错误可能归因于此。但是,我目前没有办法用双显示器设置测试其他 WM,所以我将把这一部分留作不确定。
C 或 Python 中的 libx11 示例
使用替代窗口管理器进行双显示器测试
查找坞站和面板位置
1功能未记录,取决于用户的耐心程度。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句