如何在KDE Plasma中用Bash脚本+Xrandr切换显示器布局?
问题场景
在搭载内置屏幕(eDP-1)和外接显示器(HDMI-A-1)的KDE Plasma笔记本上,需要编写Bash脚本实现外接显示器布局在「内置屏幕上方」和「内置屏幕右侧」之间切换。
现有xrandr输出(内置屏幕上方布局):
eDP-1 connected primary 1920x1080+0+1080 (0x25) normal (normal left inverted right x axis y axis) 293mm x 165mm HDMI-A-1 connected 1920x1080+0+0 (0x25) normal (normal left inverted right x axis y axis) 531mm x 299mm
右侧布局的xrandr输出:
eDP-1 connected primary 1920x1080+0+0 (0x25) normal (normal left inverted right x axis y axis) 293mm x 165mm HDMI-A-1 connected 1920x1080+1920+0 (0x25) normal (normal left inverted right x axis y axis) 531mm x 299mm
现有脚本尝试通过检测eDP-1的位置判断布局并切换,但执行时出现错误:
X Error of failed request: BadMatch (invalid parameter attributes)
怀疑是KDE自带屏幕配置工具冲突,希望得到更可靠的xrandr用法、KDE专属工具方案,以及脚本鲁棒性优化建议。
解决方案
一、修复xrandr脚本(规避KDE冲突)
错误根源是KDE的KScreen后台服务会自动管理显示设置,直接多次调用xrandr容易触发参数冲突。改进方案如下:
#!/bin/bash PRIMARY="eDP-1" SECONDARY="HDMI-A-1" # 提取内置屏幕的Y坐标(简化位置判断逻辑) PRIMARY_Y=$(xrandr --query | grep "^$PRIMARY connected" | grep -oP '\+\d+\+\d+' | cut -d'+' -f3) # 临时让KScreen进入配置模式,避免后台覆盖设置 qdbus org.kde.KScreen /org/kde/KScreen org.kde.KScreen.setConfiguring true if [[ "$PRIMARY_Y" -eq 1080 ]]; then # 当前外接在上方,切换到右侧 xrandr --output "$PRIMARY" --primary --mode 1920x1080 --pos 0x0 \ --output "$SECONDARY" --mode 1920x1080 --right-of "$PRIMARY" elif [[ "$PRIMARY_Y" -eq 0 ]]; then # 当前外接在右侧,切换到上方 xrandr --output "$PRIMARY" --primary --mode 1920x1080 --pos 0x1080 \ --output "$SECONDARY" --mode 1920x1080 --pos 0x0 else # 未知状态,默认切换到右侧布局 xrandr --output "$PRIMARY" --primary --mode 1920x1080 --pos 0x0 \ --output "$SECONDARY" --mode 1920x1080 --right-of "$PRIMARY" fi # 恢复KScreen正常工作模式 qdbus org.kde.KScreen /org/kde/KScreen org.kde.KScreen.setConfiguring false
关键优化:
- 只提取Y坐标判断布局,减少字符串匹配误差
- 合并xrandr命令,一次完成双屏参数设置,避免多次调用的冲突
- 通过
qdbus临时锁定KScreen配置,防止后台自动覆盖
二、使用KDE专属工具(更适配)
KDE官方提供kscreen-doctor工具,专门用于控制显示设置,完全兼容KScreen服务,不会出现参数冲突:
#!/bin/bash PRIMARY="eDP-1" SECONDARY="HDMI-A-1" # 获取当前外接显示器的相对布局 CURRENT_LAYOUT=$(kscreen-doctor -o | grep "$SECONDARY" | grep -oP 'relativePosition:\s*\K\w+') if [[ "$CURRENT_LAYOUT" == "above" ]]; then # 切换到右侧 kscreen-doctor output.$SECONDARY.relativePosition.rightOf output.$PRIMARY elif [[ "$CURRENT_LAYOUT" == "rightOf" ]]; then # 切换到上方 kscreen-doctor output.$SECONDARY.relativePosition.above output.$PRIMARY else # 未知状态,默认设置为右侧 kscreen-doctor output.$SECONDARY.relativePosition.rightOf output.$PRIMARY fi
优势:
- 原生适配KDE Plasma,无兼容性问题
- 无需手动处理分辨率、位置数值,工具自动管理
- 支持动态检测显示器连接状态
三、鲁棒性优化建议
- 添加外接显示器连接检测:避免无外接时执行无效操作
if ! xrandr | grep -q "^$SECONDARY connected"; then echo "外接显示器未连接" exit 1 fi - 分辨率自适应:适配非固定分辨率的屏幕
PRIMARY_RES=$(xrandr --query | grep "^$PRIMARY connected" | grep -oP '\d+x\d+' | head -n1) SECONDARY_RES=$(xrandr --query | grep "^$SECONDARY connected" | grep -oP '\d+x\d+' | head -n1) - 赋予脚本可执行权限:
chmod +x switch-display-layout.sh - 绑定快捷键:在KDE系统设置中,将脚本设置为自定义全局快捷键,快速触发切换
内容的提问来源于stack exchange,提问作者minecraftchest2
相关产品推荐
相关产品推荐

