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

Wayland的data_device_listener未触发data offer事件问题求助

Wayland的data_device_listener未触发data offer事件问题求助

大家好,我最近在写一个基于Wayland的程序,想要实现从系统剪贴板接收数据的功能,但现在卡在了获取wl_data_offer对象这一步——我注册了data_device_listener,但对应的data offer事件完全没触发,实在搞不定了,来请教下各位大佬!

我目前写的代码片段如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include <wayland-client.h>


typedef struct {
    struct wl_data_device_manager *manager;
    struct wl_seat *seat;
} State;

State global_state = {0};

void global(void *data, struct wl_registry *wl_registry, uint32_t name,
        const char *interface, uint32_t version) {
    State *state = data;
    if (strcmp(interface, wl_data_device_manager_interface.name) == 0) {
        state->manager = wl_registry_bind(wl_registry, name, &wl_data_device_manager_interface, 1);
    } else if (strcmp(interface, wl_seat_interface.name) == 0) {
        state->seat = wl_registry_bind(wl_registry, name, &wl_seat_interface, 1);
    }
}

// 我期望这个回调能触发,但实际完全没反应
static void data_device_offer(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer) {
    printf("收到data offer对象!\n");
    // 后续打算在这里处理剪贴板数据的类型和内容
}

static const struct wl_data_device_listener data_device_listener = {
    .offer = data_device_offer,
};

int main(int argc, char *argv[]) {
    struct wl_display *display = wl_display_connect(NULL);
    if (!display) {
        fprintf(stderr, "无法连接到Wayland显示\n");
        return 1;
    }

    struct wl_registry *registry = wl_display_get_registry(display);
    wl_registry_add_listener(registry, &(struct wl_registry_listener){
        .global = global,
    }, &global_state);

    // 同步获取全局对象
    wl_display_roundtrip(display);

    // 获取data_device并注册监听
    struct wl_data_device *data_device = wl_data_device_manager_get_data_device(global_state.manager, global_state.seat);
    if (!data_device) {
        fprintf(stderr, "无法获取data device实例\n");
        return 1;
    }
    wl_data_device_add_listener(data_device, &data_device_listener, NULL);

    printf("程序已启动,等待剪贴板事件...\n");
    // 进入事件循环
    while (wl_display_dispatch(display) != -1) {
        // 持续处理事件
    }

    wl_display_disconnect(display);
    return 0;
}

我已经排查过的点:

  • 确认wl_data_device_managerwl_seat都成功绑定,指针不为空
  • 事件循环正常运行,wl_display_dispatch没有报错退出
  • 尝试过在程序启动后复制不同类型的内容(文本、图片),甚至切换应用复制,但回调始终没触发

想请教各位:

  1. 是不是我漏了主动请求剪贴板数据的步骤?比如Wayland是不是需要显式调用某个函数来触发data offer的推送?
  2. listener的注册时机有没有问题?是不是应该在更早/更晚的时机注册?
  3. 还有没有其他Wayland剪贴板相关的细节是我没注意到的?

麻烦各位大佬帮忙看看,实在卡在这里好几天了,谢谢!

火山引擎 最新活动