我在 ubuntu 笔记本电脑上使用 i3-wm。我的屏幕尺寸是 3200x1800。对于某些事情来说,这很棒,但对于其他事情来说却很糟糕。(Netflix 与 gvim)。
我想更改我的一个或多个工作区的分辨率。但我不知道这是否可行...我可以使用 compton 来执行此操作吗?或者可以使用其他程序?
答案1
1. 假设你正在使用 Unity
下面的脚本应该会根据 Unity 中的当前视口更改分辨率。我在几台计算机上测试了一段时间,运行起来没有错误。
不过我建议也测试一下,看看它是否能不间断地运行;重复的wmctrl
命令有时会意外地退出“非零”。如果是这样,我们需要建立一个try / except
。
笔记
- 我在单显示器设置上对其进行了测试。多显示器可能需要另一种方式来解析输出
xrandr
。 在脚本的开头,您需要为每个视口设置所需的分辨率,我按照您的评论中提到的方式进行设置,但您可以随时更改它。使用格式:
resolutions = [[<horizontal>, <vertical], [<horizontal>, <vertical], ......]
就像脚本中所展示的那样。
- 无需说您应该使用受支持的分辨率,就像
xrandr
您的显示器的输出一样。
如何使用
该脚本需要
wmctrl
:sudo apt-get install wmctrl
将以下脚本复制到一个空文件中,并将其另存为
screen_res.py
使用以下命令在终端窗口中测试运行一段时间:
python3 screen_res.py
如果一切正常,请将其添加到您的启动应用程序中:Dash > 启动应用程序 > 添加...
剧本
#!/usr/bin/env python3
import subprocess
import time
# list of resolution per viewport, for each viewport a separate [hor, vert]
# I pre- entered your viewports. quite some! listing takes more space than the script :)
resolutions = [
[3200, 1800],
[3200, 1800],
[3200, 1800],
[3200, 1800],
[3200, 1800],
[3200, 1800],
[3200, 1800],
[1920, 1080],
[1920, 1080],
[1920, 1080],
]
def get_xr():
return subprocess.check_output(["xrandr"]).decode("utf-8").split()
check = get_xr()
plus = 2 if check[check.index("connected")+1] == "primary" else 1
while True:
# resolution:
xr = get_xr()
res = [int(n) for n in xr[xr.index("connected")+plus].split("+")[0].split("x")]
# get current viewport
vp_data = subprocess.check_output(["wmctrl", "-d"]).decode("utf-8").split()
dt = [int(n) for n in vp_data[3].split("x")]
cols = int(dt[0]/res[0])
curr_vpdata = [int(n) for n in vp_data[5].split(",")]
curr_col = int(curr_vpdata[0]/res[0])+1; curr_row = int(curr_vpdata[1]/res[1])
curr_vp = curr_col+curr_row*cols
# check and change resolution if needed
if res != resolutions[curr_vp-1]:
new_res = ("x").join([str(n) for n in resolutions[curr_vp-1]])
subprocess.call(["xrandr", "-s", new_res])
time.sleep(1)
解释
在循环中,脚本首先通过以下命令检查屏幕的当前分辨率:
xrandr
随后,脚本通过以下命令检查桌面总大小(所有视口):
wmctrl -d
然后,根据分辨率除以总桌面大小,计算出列数,该数等于总桌面大小除以水平分辨率。
- 输出中还
wmctrl -d
显示了当前视口在跨越桌面上的位置:例如:VP: 1680,0
。 有了这些信息,我们可以确定我们位于哪一列和哪一行,并检查当前设置的分辨率是否与我们在脚本头部的列表中定义的分辨率相匹配。
如果不匹配,脚本会发出命令来更改分辨率,命令如下:xrandr -s <xres>x<yres>
2.XFCE 版本
- 像上面的版本一样设置(也需要
wmctrl
)
#!/usr/bin/env python3
import subprocess
import time
# list of resolution per viewport, for each viewport a separate [hor, vert]
# below just an example! set resolutions for your own screen
resolutions = [
[1280, 1024],
[1280, 960],
[1280, 1024],
[1280, 1024],
]
def get_xr():
return subprocess.check_output(["xrandr"]).decode("utf-8").split()
check = get_xr()
plus = 2 if check[check.index("connected")+1] == "primary" else 1
while True:
# resolution:
xr = get_xr()
res = [int(n) for n in xr[xr.index("connected")+plus].split("+")[0].split("x")]
# get current workspace
vp_data = subprocess.check_output(["wmctrl", "-d"]).decode("utf-8").splitlines()
curr_ws = int([l.split()[0] for l in vp_data if "*" in l][0])
# check and change resolution if needed
if res != resolutions[curr_ws]:
new_res = ("x").join([str(n) for n in resolutions[curr_ws]])
subprocess.call(["xrandr", "-s", new_res])
time.sleep(1)
答案2
我为 XFCE 实现了 @Jacob Vlijm 的 python 脚本。除了一个老的通过 wine 运行的 Windows 程序。每次脚本循环时,鼠标光标都会冻结不到一秒钟。检查 1x/sec 意味着很多卡顿。我将其移植到 bash 脚本中,将其修改为每次检查仅调用一次 wmctrl,并且仅在需要更改分辨率时调用 xrandr。请注意,它确实需要安装 wmctrl。
#!/usr/bin/env bash
#Tested in XFCE 4.12.3 on Ubuntu 18.04
#Requires wmctrl. Install with:
#$ sudo apt-get install wmctrl
#Note: This checks current workspace res 1x/sec. To change rate, change "sleep" parameter below
#Enter appropriate resolution for each workspace, in order, in the same format as below.
RESOLUTIONS=('1920x1080' '1368x768')
check_and_change_res() {
#echo "Parsing wmctrl -d"
while read line; do
#example line from wmctrl:
#$ wmctrl -d
#0 - DG: 1368x768 VP: N/A WA: 0,25 1368x743 1
#1 * DG: 1368x768 VP: 0,0 WA: 0,25 1368x743 2
#If your line does not have a "DG:" (desktop geometry) preceding the current resolution, you
# will need to change the regex below.
if [[ ${line} =~ ([[:digit:]]+)[[:space:]]+\*[[:space:]]+DG:[[:space:]]+([[:alnum:]]+) ]]; then
current_ws="${BASH_REMATCH[1]}"
current_res="${BASH_REMATCH[2]}"
target_res="${RESOLUTIONS[current_ws]}"
#echo "Current workspace: ${current_ws}; Current resolution: ${current_res}; Target resolution: ${target_res}"
if [[ ! ${current_res} =~ ${target_res} ]]; then
#echo "Switching resolution to ${target_res}."
xrandr -s ${target_res}
fi
fi
done
}
while true
do
check_and_change_res < <(wmctrl -d)
#This waits for 1 second between checks. To change to a 5-second delay (e.g. performance), use:
#sleep 5
sleep 1
done