You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Wayland环境下如何接收指针事件并透传至下层客户端?

Wayland录屏光标高亮方案:无需libinput的纯客户端实现

针对你的需求,最优方案是结合Wayland官方的屏幕录制扩展与全屏透明overlay层,完全绕开直接处理输入事件的问题,自然实现事件透传与光标状态监听:

核心思路

利用wp_screen_cast_v1扩展(Wayland Protocols稳定扩展)从compositor获取光标位置、点击状态等元数据,同时创建无输入区域的全屏overlay层负责绘制高亮效果。这样overlay层不接收任何输入事件,所有操作直接透传至下层应用,而光标状态由compositor主动推送,无需额外权限。

具体实现步骤

1. 初始化屏幕录制流,获取光标元数据

  • 从Wayland display获取wp_screen_cast_manager_v1对象,创建wp_screen_cast_stream_v1用于屏幕录制。
  • 设置流的cursor_mode为WP_SCREEN_CAST_STREAM_V1_CURSOR_MODE_METADATA:
    wp_screen_cast_stream_v1_set_cursor_mode(stream, WP_SCREEN_CAST_STREAM_V1_CURSOR_MODE_METADATA);
    
  • 注册以下事件回调:
    • cursor_position:接收光标实时坐标,用于更新高亮圆圈位置。
    • cursor_button:接收鼠标按键的按下/释放状态,用于切换高亮颜色(比如点击时改为红色,松开后恢复半透明)。

2. 创建全屏透明overlay层

  • 使用zwlr_layer_surface_v1创建全屏层,配置参数如下:
    • 设置layer为ZWLR_LAYER_SURFACE_V1_LAYER_OVERLAY(确保层在所有窗口之上)。
    • anchor设为所有四边(ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT),实现全屏覆盖。
    • exclusive_zone设为-1,告知compositor该层不占用布局空间,不影响下层窗口。
  • 清空输入区域与不透明区域,确保事件透传与层透明:
    wl_surface_set_input_region(surface, nullptr);
    wl_surface_set_opaque_region(surface, nullptr);
    
  • 提交surface完成初始化:
    zwlr_layer_surface_v1_commit(layer_surface);
    

3. 绘制光标高亮效果

  • 收到cursor_position事件时,计算高亮圆圈的绘制坐标(以光标为中心),调用wl_surface_damage标记需要更新的区域。
  • 收到cursor_button事件时,切换高亮圆圈的颜色(比如按下时使用不透明度更高的红色,释放后恢复半透明蓝色)。
  • 每次状态更新后调用wl_surface_commit提交绘制,compositor会自动刷新overlay层。

替代方案(无法使用录屏扩展时)

如果因环境限制无法使用wp_screen_cast_v1,可以尝试以下方法:

  • 使用wl_seat获取wl_pointer对象,注册motion与button事件回调。
  • 为overlay层设置全屏输入区域,但在事件回调中调用wl_pointer_set_input_region临时清空输入区域,让compositor将事件透传至下层应用,之后再恢复输入区域以继续接收后续事件。这种方法依赖compositor的事件处理逻辑,兼容性可能较差,不推荐作为首选。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 13:14:56