抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

又是一次令人感慨的Bug溯源经历…

起因

和往常一样…我背着笔记本去上班, 当我将其连上 显卡拓展坞 之后, 也是和往常一样把笔记本盒盖了

这时发现我才发觉, 外置显示器居然不再点亮了!

再随手打开笔记本屏幕查看…上面居然出现了几行报错信息

bACLh8.md.jpg

在几次尝试重启后发现问题依旧…于是先开着屏幕等下班再折腾

尝试

一开始以为是 显卡拓展坞 的问题…换了普通的 雷电拓展坞 直接 直连显示屏 也是如此…

当我对比 xorgwayland 下的行为后, 发现 只有在 xrog 才会造成致命的报错 (如上一节), 在后者则会表现为, 盒盖后没有关内置屏幕事件

接着, 我试图将 systemd-logind 的配置稍微修改了一下

1
2
3
#HandleLidSwitch=suspend
HandleLidSwitchExternalPower=ignore # 忽略掉当连接外置电源时盒盖的默认 suspend 处理
#HandleLidSwitchDocked=ignore

这下在 xorg 下就不会崩溃了….

接着我想着要么就在这种情况下, 直接监听笔记本 LID 事件然后再执行开启/关闭内置屏幕的命令就算解决了吧?!

说干就干! 首先是如何去开启关闭屏幕…最开始我想到了 xsetxrand 命令…但是转念一想, 那 wayland 下咋办?

研究了一圈可以用 dbus 接口去调用 mutter 的接口来实现

1
2
3
4
5
6
# 例如获取当前 Mutter 的显示器配置资源
$ gdbus call \
--session \
--dest=org.gnome.Mutter.DisplayConfig \
--object-path /org/gnome/Mutter/DisplayConfig \
--method org.gnome.Mutter.DisplayConfig.GetResources

当我想调用开关某个屏幕的接口时…发现有点劝退了, 因为命令太长了…当然不是因为我懒啦

于是我又发现了三年前就有人写好了这玩意 gnome-randr, 这下就方便很多了

但是 AUR 里还没有人打包这个软件, 所以我动了下手将它打包了 aur/gnome-randr

命令就变成了

1
2
$ gnome-randr --output ${DISPLAY} --off # 关闭屏幕
$ gnome-randr --output ${DISPLAY} --auto # 以自动模式开启屏幕

接下来用 acpi 服务来监听盒盖事件变化

1
2
3
$ paru -S acpi # 安装相关软件包
$ systemctl enable --now acpid # 启动服务
$ sudo nvim /etc/acpi/handler.sh # 然后编辑这个脚本, 修改事件处理逻辑

在对应的事件中加入如下代码即可 (比较水, 如有需要可以自行修改)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

...

case "$3" in
close)
logger 'LID closed'
INDP='eDP-1' # 内置屏幕标识
[ $(ls /dev/dri/card1) ] && INDP='eDP-1-1' # 内置屏幕标识 (在egpu下)
# 切换到普通用户 并设置好DBUS地址环境变量
su - icepie -c "DBUS_SESSION_BUS_ADDRESS='unix:path=/run/user/1000/bus' gnome-randr --output "$INDP" --off"
cp /home/icepie/.config/monitors.xml /var/lib/gdm/.config/ # gdm 下也用当前的屏幕配置
chown gdm:gdm /var/lib/gdm/.config/monitors.xml # 修复一下权限
;;
open)
logger 'LID opened'
INDP='eDP-1'
[ $(ls /dev/dri/card1) ] && INDP='eDP-1-1'
su - icepie -c "DBUS_SESSION_BUS_ADDRESS='unix:path=/run/user/1000/bus' gnome-randr --output "$INDP" --auto"
cp /home/icepie/.config/monitors.xml /var/lib/gdm/.config/
chown gdm:gdm /var/lib/gdm/.config/monitors.xml
;;
*)
logger "ACPI action undefined: $3"
;;

...

最后成功实现了原先正常的效果…虽然比不上之前的感觉 :(

思考

今天早上我还是有点不甘心, 于是在 ArchLinux 的官网的 bugtracker 找到了和我一样的用户发的帖子

最后定位到了是 upower 上游的问题

所以我只需要降级 upower 的版本就好了(等上游解决掉的时候再更新), 我清晰记得前几天滚动更新的时候有它…可我却没有以一种正常的方式去对待突然出现的问题…

没有去思考其问题的本质…看来是最近业务写多了, 平时面对业务问题的时候经常会用一些 “骚操作” 去解决…

希望自己以后能多多从 事物的本质 出发再去思考吧!

回顾

现在再来回头看待这个过程, 其实我不过是陷入了一个工程领域常见的 X-Y问题 的困境

对于 X-Y Problem 的意思如下:

1
2
3
4
1)有人想解决问题X
2)他觉得Y可能是解决X问题的方法
3)但是他不知道Y应该怎么做
4)于是他去问别人Y应该怎么做?

简而言之,没有去问怎么解决问题X,而是去问解决方案Y应该怎么去实现和操作。于是乎:

1
2
3
1)热心的人们帮助并告诉这个人Y应该怎么搞,但是大家都觉得Y这个方案有点怪异。
2)在经过大量地讨论和浪费了大量的时间后,热心的人终于明白了原始的问题X是怎么一回事。
3)于是大家都发现,Y根本就不是用来解决X的合适的方案。

X-Y Problem最大的严重的问题就是:在一个根本错误的方向上浪费他人大量的时间和精力!

评论