如何提取未设置_NET_WM_ICON属性的X窗口图标(以Obsidian为例)
提取未设置_NET_WM_ICON的X窗口图标(以Obsidian为例)
如果目标窗口未设置_NET_WM_ICON属性,你可以尝试以下几种方法:
1. 通过WM_CLASS关联桌面文件提取
X窗口都带有WM_CLASS属性,先通过python-xlib获取该属性:
from Xlib.display import Display display = Display() window = display.create_resource_object('window', 你的窗口ID) wm_class = window.get_wm_class() # 结果为(实例名, 类名),Obsidian一般返回('obsidian', 'Obsidian')
拿到类名后,前往系统桌面文件目录(/usr/share/applications/或~/.local/share/applications/)查找匹配的.desktop文件(比如obsidian.desktop)。打开文件找到Icon字段:
- 如果是绝对路径,直接读取该路径的图标文件即可
- 如果是图标名称,去系统图标目录(
/usr/share/icons/或~/.local/share/icons/),按当前主题的常用尺寸(如24x24、32x32)查找对应图标
2. 捕获窗口像素并裁剪图标区域
如果桌面文件方法行不通,可以直接抓取窗口像素数据,手动裁剪标题栏的图标区域:
from Xlib.display import Display from Xlib.X import ZPixmap from PIL import Image display = Display() window = display.create_resource_object('window', 你的窗口ID) geom = window.get_geometry() # 获取窗口像素缓冲区(窗口不能处于最小化状态) pixmap = window.get_image(0, 0, geom.width, geom.height, ZPixmap, 0xffffffff) img = Image.frombytes("RGB", (geom.width, geom.height), pixmap.data, "raw", "BGRX") # 裁剪标题栏左侧的图标区域,尺寸根据桌面环境调整(常见32x32) icon_img = img.crop((0, 0, 32, 32)) icon_img.save("obsidian_icon.png")
注意:不同桌面环境的标题栏布局不同,需调整裁剪的坐标和尺寸;窗口最小化时该方法失效。
3. 借助系统工具辅助查找
可以用xdotool和图标主题工具配合:
- 先用
xdotool getactivewindow getwindowname获取窗口名称,再用wmctrl -lx找到对应的WM_CLASS - GTK环境下用
gtk-icon-theme-lookup查找图标路径:gtk-icon-theme-lookup --size 32 obsidian - Qt环境可使用
qt5-iconfinder,在Python中通过subprocess调用这些命令,拿到路径后读取图标文件即可。
4. 针对Electron应用的特殊处理(Obsidian属于此类)
Obsidian是Electron应用,自身安装目录通常包含图标文件:
- 先通过
ps aux | grep obsidian找到Obsidian的进程执行路径,比如/opt/Obsidian/obsidian或~/.local/share/obsidian/obsidian - 进入安装目录,一般在
resources/app.asar.unpacked/static/或根目录就能找到图标文件(比如obsidian.png)
内容的提问来源于stack exchange,提问作者glades
相关产品推荐
相关产品推荐

