记一次BUG修复

现象

使用top工具查看系统中进程的CPU使用率,可以看到xfdesktop和Xorg的CPU使用率较没有一个图标被选中时明显上升。

在启用GTK调试快捷键的情况下,按Ctrl + Shift + I打开GTK+检查器,选择可视化选项卡,启用显示图形更新选项,可以看到整个桌面都在以红颜色闪烁。

切换到对象选项卡,点击左上角的显示所有对象,在下面的列表中选中XfdesktopIconView,点击左上角的显示细节,在左上角的下拉列表中选择信号,点击旁边的实心圆按钮以追踪此对象发出的信号,可以观察到,style-setstyle-updated信号的数量在不正常地增加。

对上述现象的解释

怀疑某些程序逻辑有误,导致选中桌面图标时,上述的两个信号不断被抛出,进而使得整个桌面都在不停地重绘,造成CPU使用率不断攀升。

环境

软件包版本:

  • xfdesktop 4.16.0-2 x86_64
  • gtk3 3.24.29-2 x86_64

系统版本:

  • Manjaro 21.0.7 Ornara
  • Linux 4.19.193-1-MANJARO x86_64

GTK 主题:Adapta-Eta-Maia

复现步骤

  1. 点击任意一个桌面图标

寻找办法

初步怀疑是某个组件的样式中设置了透明属性导致反复地重绘。下载xfdesktop的源代码,在src/xfdesktop-application.c的第140行看到这样一段代码:

const gchar *fallback_CSS =
"XfdesktopIconView.view {"
"	background: transparent;"
"	color: @theme_selected_fg_color;"
"	border-radius: 3px;"
"}"
"XfdesktopIconView.view:active {"
"	background: alpha(@theme_selected_bg_color, 0.5);"
"	text-shadow: 0 1px 1px black;"
"}"
"XfdesktopIconView.view .label {"
"	text-shadow: 1px 1px 2px black;"
"}"
"XfdesktopIconView.view .label:active {"
"	color: @theme_selected_fg_color;"
"}"
"XfdesktopIconView .rubberband {"
"	background: alpha(@theme_selected_bg_color, 0.2);"
"	border: 1px solid @theme_selected_bg_color;"
"	border-radius: 0;"
"}"
"XfdesktopIconView:active {"
"	color: @theme_selected_bg_color;"
"}";

看到包含透明度设置的几行可疑代码,随即想到直接将background设成none,试一下会不会好一些。

打开GTK+检查器,选择CSS选项卡,在其中输入:

.view:active { 
    background: none; 
}

发现相关进程的CPU使用率降下来了,恢复了正常。

之后了解到在系统当前的主题文件中,可以找到相对应的样式代码。

解决办法

解决办法是修改GTK主题样式文件。

以下是对gtk.css所引用gtk-contained.css的修改记录,主要修改了两部分:

  1. XfdesktopIconView.viewXfdesktopIconView.view:active中的background设置为none,这样可以避免上述的BUG。
  2. 第一步修改后,会导致选中桌面图标后,图标下面文本标签的背景色消失,为了模拟丢失的背景,对文本标签添加一些样式代码。
--- gtk-contained.css.bak	2021-06-24 17:11:24.997967279 +0800
+++ gtk-contained.css	2021-06-24 17:10:40.347967896 +0800
@@ -4692,9 +4692,11 @@
 
 .xfce4-panel widget.tasklist > button.toggle { font-weight: 400; }
 
-XfdesktopIconView.view { border-radius: 2px; background: transparent; color: #FFFFFF; text-shadow: 0 0 1px rgba(0, 0, 0, 0.26), 0 1px 2px rgba(0, 0, 0, 0.26), 0 2px 3px rgba(0, 0, 0, 0.32); }
+XfdesktopIconView.view { border-radius: 2px; background: none; color: #FFFFFF; text-shadow: 0 0 1px rgba(0, 0, 0, 0.26), 0 1px 2px rgba(0, 0, 0, 0.26), 0 2px 3px rgba(0, 0, 0, 0.32); }
 
-XfdesktopIconView.view:active { background-color: #16a085; text-shadow: none; }
+XfdesktopIconView.view:active { background: none; text-shadow: none; }
+
+XfdesktopIconView.view .label:active { color: green; background: alpha(#16a085, 0.7); text-shadow: 0 1px 2px black; }
 
 window#whiskermenu-window { background-color: #fdfdfe; }

图标选中效果如下:

记一次BUG修复

总结

没有找到BUG发生的原因,但是找到了一个躲开BUG的办法。

附录

启用GTK+检查器:

gsettings set org.gtk.Settings.Debug enable-inspector-keybinding true

提取主题打包资源文件:

gresource extract gtk.gresource /org/adapta-project/gtk-3.24-eta/gtk-contained.css > /tmp/aa.css

主题安装路径:/usr/share/themes/

记一次BUG修复

上一篇:电路交换、报文交换、分组交换


下一篇:366. Find Leaves of Binary Tree