为何gedit、Nautilus无法在wmctrl、xlib等工具中被识别?
问题分析与解决办法
为什么gedit和Nautilus无法被识别?
核心原因分为两种情况:
- Wayland会话限制:Ubuntu当前默认使用Wayland作为显示服务器,而
wmctrl、python-xlib、EWMH这类工具均基于X11协议开发。Wayland与X11是完全独立的显示架构,X11工具无法直接识别Wayland原生窗口——现代版本的gedit和Nautilus已默认以Wayland原生应用模式运行。 - X11下的窗口过滤:若在X11会话中遇到此问题,
wmctrl默认仅列出标记为_NET_WM_STATE_NORMAL的普通窗口,部分特殊类型窗口(如部分桌面集成窗口)会被自动过滤。
如何查询所有打开窗口并获取信息?
根据你使用的显示服务器(Wayland/X11),可选择以下方案:
方案1:切换到X11会话(快速兼容旧工具)
登录Ubuntu时,点击登录界面用户名旁的齿轮图标,选择Ubuntu on Xorg。进入X11会话后,原有工具可正常识别所有窗口:
- 执行
wmctrl -l列出所有窗口,添加-x参数可显示窗口类名; - 执行
xwininfo -root -tree可列出系统内所有X11窗口(含被wmctrl过滤的窗口),从中提取坐标与标题; - python-xlib、EWMH等Python工具也可正常工作。
方案2:Wayland下的原生查询方式
若不想切换到X11,可通过以下方式获取窗口信息:
命令行方式
使用gdbus调用GNOME Shell接口直接查询窗口数据:
gdbus call --session --dest org.gnome.Shell --object-path /org/gnome/Shell --method org.gnome.Shell.Eval ' global.get_window_actors().map(actor => { const win = actor.meta_window; return `标题: ${win.get_title()}, 坐标: ${win.get_position()}`; }).join("\n") '
输出结果需手动去除开头的返回标记,即可得到所有窗口的标题与(x,y)坐标。
Python模块方式
使用PyGObject结合GNOME窗口管理API,示例代码如下:
import gi gi.require_version('Gtk', '3.0') gi.require_version('Meta', '10') from gi.repository import Gtk, Meta def get_all_windows(): display = Meta.Display.get_default() windows = [] for window in display.get_tab_list(Meta.TabList.NORMAL_ALL, None): title = window.get_title() x, y = window.get_position() windows.append({"title": title, "x": x, "y": y}) return windows if __name__ == "__main__": for win in get_all_windows(): print(f"标题: {win['title']}, X: {win['x']}, Y: {win['y']}")
运行前需安装依赖:sudo apt install python3-gi gir1.2-meta-10
内容的提问来源于stack exchange,提问作者user1994584
相关产品推荐
相关产品推荐

