You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

GNOME/Wayland会话中从Mutter获取活动窗口的技术疑问

嘿,我之前也折腾过Wayland下这种按应用响应手势的需求,确实踩过焦点检测的坑,给你几个实际可行的方向:

Wayland下活动应用焦点检测的解决方案

Wayland本身确实没有像X11那样统一的全局焦点查询接口,因为每个**compositor(窗口管理器)**都有自己的实现逻辑,所以得针对不同的桌面环境做适配:

1. 调用各Compositor专属的DBus接口

主流Wayland compositor都会暴露自己的DBus服务来提供窗口信息,这是最直接的方式:

  • GNOME Shell:通过org.gnome.Shell接口的GetFocusedWindow方法获取焦点窗口,你可以用gdbus先测试:
    gdbus call --session --dest org.gnome.Shell --object-path /org/gnome/Shell --method org.gnome.Shell.GetFocusedWindow
    
    返回结果里包含窗口对应的应用ID(比如org.gnome.Nautilus),解析这个就能判断当前活动应用。
  • KDE Plasma:借助org.kde.KWin的接口,先查活动窗口ID,再关联应用信息:
    # 获取活动窗口ID
    ACTIVE_WIN=$(qdbus org.kde.KWin /KWin activeWindow)
    # 查询窗口对应的应用类名
    qdbus org.kde.KWin /KWin/window/$ACTIVE_WIN className
    
  • Sway/i3(wlroots系):用swaymsg配合jq解析窗口树,直接拿到焦点应用的标识:
    swaymsg -t get_tree | jq 'recurse(.nodes[]?, .floating_nodes[]?) | select(.focused==true) | .app_id // .class'
    

2. 写轻量监听程序订阅焦点事件

如果需要实时监听焦点变化(而不是每次手势触发才查询),可以基于libwayland-client写一个简单的程序,订阅 compositor 的焦点变更事件。不过要注意:

  • wlroots系 compositor(比如Sway、Hyprland)遵循标准的Wayland协议,通过wl_seat接口的focus_in事件获取焦点窗口
  • GNOME/KDE有自己的扩展接口,比如GNOME需要对接Shell的窗口跟踪API

3. 结合libinput-gestures的配置技巧

其实不用单独写一个完整的应用,你可以把焦点检测逻辑封装成脚本,直接嵌入到libinput-gestures的配置里:

  1. 写一个脚本get_active_app.sh,根据当前运行的compositor返回活动应用ID:
    #!/bin/bash
    if pgrep -x "gnome-shell" > /dev/null; then
        # GNOME下获取应用ID
        gdbus call --session --dest org.gnome.Shell --object-path /org/gnome/Shell --method org.gnome.Shell.GetFocusedWindow | grep -oP "'app-id': '\K[^']+"
    elif pgrep -x "sway" > /dev/null; then
        # Sway下获取应用ID
        swaymsg -t get_tree | jq -r 'recurse(.nodes[]?, .floating_nodes[]?) | select(.focused==true) | .app_id // .class'
    fi
    
  2. libinput-gestures.conf里配置手势,根据脚本返回值发送不同DBus信号:
    # 针对不同应用发送不同DBus信号
    gesture swipe right 3 bash -c 'APP=$(./get_active_app.sh); if [ "$APP" = "org.gnome.Terminal" ]; then dbus-send --session --dest org.gnome.Terminal --object-path /org/gnome/Terminal/org/gnome/Terminal/Window/1 --method org.gnome.Terminal.Window.NextTab; else dbus-send ...; fi'
    

小提示

  • Wayland的安全模型会限制全局窗口信息的获取,比如GNOME下你的脚本/应用可能需要申请org.gnome.shell.permissions.desktop权限才能调用Shell接口
  • 如果要做跨桌面环境兼容,记得先检测当前运行的compositor类型,再调用对应的接口

内容的提问来源于stack exchange,提问作者Petrosyan Alexander

火山引擎 最新活动