XCB 指针坐标停留在 (0,0)

XCB Pointer Coordinates are Stuck at (0,0)

我已经在配备 XWayland/XCB 支持 X 应用程序的游戏引擎中实现了 Wayland 合成器(通过 wlroots)。当我启动 xev 时,它似乎可以很好地接收 ButtonNotify 事件(因此我可以很好地输入 windows)。它还每帧接收MotionNotify个事件,但问题是它的坐标卡在原点!

# This repeats every frame when I mouse over windows:

MotionNotify event, serial 32, synthetic NO, window 0x400001,
    root 0x29c, subw 0x0, time 1275037533, (-2,-2), root:(0,0),
    state 0x0, is_hint 0, same_screen YES

注意:

我知道抽象出所有其他细节很难调试这个问题,但我很好奇是否有一些众所周知的东西需要在指针事件更新之前进行初始化。因为我的合成器是如此精简(游戏引擎处理大部分事情),是否有一些我需要让指针更新工作但我没有意识到我需要的东西?

为了使我的问题更具体:在指针运动可以是 (0,0) 以外的东西之前,必须在 XCB 中初始化什么状态?


编辑: 这是一些 xev 日志数据,以查看我可能缺少的状态:

$ DISPLAY=:2 xev & # `DISPLAY=:2` is where XWayland is located
[1] 26726
Outer window is 0x400001, inner window is 0x400002

PropertyNotify event, serial 8, synthetic NO, window 0x400001,
    atom 0x27 (WM_NAME), time 1549489650, state PropertyNewValue

PropertyNotify event, serial 9, synthetic NO, window 0x400001,
    atom 0x22 (WM_COMMAND), time 1549489650, state PropertyNewValue

PropertyNotify event, serial 10, synthetic NO, window 0x400001,
    atom 0x28 (WM_NORMAL_HINTS), time 1549489650, state PropertyNewValue

CreateNotify event, serial 11, synthetic NO, window 0x400001,
    parent 0x400001, window 0x400002, (10,10), width 50, height 50
border_width 4, override NO

PropertyNotify event, serial 14, synthetic NO, window 0x400001,
    atom 0xf7 (WM_PROTOCOLS), time 1549489650, state PropertyNewValue

MapNotify event, serial 15, synthetic NO, window 0x400001,
    event 0x400001, window 0x400002, override NO

ClientMessage event, serial 28, synthetic YES, window 0x400001,
    message_type 0xf7 (WM_PROTOCOLS), format 32, message 0x10a (_NET_WM_PING)

PropertyNotify event, serial 29, synthetic NO, window 0x400001,
    atom 0x10b (WM_STATE), time 1549489661, state PropertyNewValue

PropertyNotify event, serial 29, synthetic NO, window 0x400001,
    atom 0x100 (_NET_WM_STATE), time 1549489661, state PropertyNewValue

MapNotify event, serial 29, synthetic NO, window 0x400001,
    event 0x400001, window 0x400001, override NO

VisibilityNotify event, serial 29, synthetic NO, window 0x400001,
    state VisibilityUnobscured

Expose event, serial 29, synthetic NO, window 0x400001,
    (0,0), width 178, height 10, count 3

Expose event, serial 29, synthetic NO, window 0x400001,
    (0,10), width 10, height 58, count 2

Expose event, serial 29, synthetic NO, window 0x400001,
    (68,10), width 110, height 58, count 1

Expose event, serial 29, synthetic NO, window 0x400001,
    (0,68), width 178, height 110, count 0

EnterNotify event, serial 29, synthetic NO, window 0x400001,
    root 0x29c, subw 0x0, time 1549489662, (-2,-2), root:(0,0),
    mode NotifyNormal, detail NotifyAncestor, same_screen YES,
    focus YES, state 0

KeymapNotify event, serial 29, synthetic NO, window 0x0,
    keys:  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   
           0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   

MotionNotify event, serial 31, synthetic NO, window 0x400001,
    root 0x29c, subw 0x0, time 1549495244, (-2,-2), root:(0,0),
    state 0x0, is_hint 0, same_screen YES

MotionNotify event, serial 31, synthetic NO, window 0x400001,
    root 0x29c, subw 0x0, time 1549495260, (-2,-2), root:(0,0),
    state 0x0, is_hint 0, same_screen YES

MotionNotify event, serial 31, synthetic NO, window 0x400001,
    root 0x29c, subw 0x0, time 1549495260, (-2,-2), root:(0,0),
    state 0x0, is_hint 0, same_screen YES

MotionNotify event, serial 31, synthetic NO, window 0x400001,
    root 0x29c, subw 0x0, time 1549495277, (-2,-2), root:(0,0),
    state 0x0, is_hint 0, same_screen YES

#...

这可以与适当的 运行 rootston(wlroot 的示例合成器)运行 xev:

进行比较
$ Outer window is 0x400001, inner window is 0x400002

MappingNotify event, serial 0, synthetic NO, window 0x0,
    request MappingKeyboard, first_keycode 8, count 248

MappingNotify event, serial 0, synthetic NO, window 0x0,
    request MappingModifier, first_keycode 0, count 0

PropertyNotify event, serial 8, synthetic NO, window 0x400001,
    atom 0x27 (WM_NAME), time 1549619590, state PropertyNewValue

PropertyNotify event, serial 9, synthetic NO, window 0x400001,
    atom 0x22 (WM_COMMAND), time 1549619590, state PropertyNewValue

PropertyNotify event, serial 10, synthetic NO, window 0x400001,
    atom 0x28 (WM_NORMAL_HINTS), time 1549619590, state PropertyNewValue

CreateNotify event, serial 11, synthetic NO, window 0x400001,
    parent 0x400001, window 0x400002, (10,10), width 50, height 50
border_width 4, override NO

PropertyNotify event, serial 14, synthetic NO, window 0x400001,
    atom 0xf7 (WM_PROTOCOLS), time 1549619590, state PropertyNewValue

MapNotify event, serial 15, synthetic NO, window 0x400001,
    event 0x400001, window 0x400002, override NO

PropertyNotify event, serial 29, synthetic NO, window 0x400001,
    atom 0x10b (WM_STATE), time 1549619590, state PropertyNewValue

PropertyNotify event, serial 29, synthetic NO, window 0x400001,
    atom 0x100 (_NET_WM_STATE), time 1549619590, state PropertyNewValue

MapNotify event, serial 29, synthetic NO, window 0x400001,
    event 0x400001, window 0x400001, override NO

VisibilityNotify event, serial 29, synthetic NO, window 0x400001,
    state VisibilityUnobscured

Expose event, serial 29, synthetic NO, window 0x400001,
    (0,0), width 178, height 10, count 3

Expose event, serial 29, synthetic NO, window 0x400001,
    (0,10), width 10, height 58, count 2

Expose event, serial 29, synthetic NO, window 0x400001,
    (68,10), width 110, height 58, count 1

Expose event, serial 29, synthetic NO, window 0x400001,
    (0,68), width 178, height 110, count 0

EnterNotify event, serial 34, synthetic NO, window 0x400001,
    root 0x29c, subw 0x0, time 1549638410, (153,0), root:(155,2),
    mode NotifyNormal, detail NotifyAncestor, same_screen YES,
    focus YES, state 0

KeymapNotify event, serial 34, synthetic NO, window 0x0,
    keys:  68  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   
           0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   

MotionNotify event, serial 34, synthetic NO, window 0x400001,
    root 0x29c, subw 0x0, time 1549638410, (153,0), root:(155,2),
    state 0x0, is_hint 0, same_screen YES

MotionNotify event, serial 34, synthetic NO, window 0x400001,
    root 0x29c, subw 0x0, time 1549638417, (154,4), root:(156,6),
    state 0x0, is_hint 0, same_screen YES

MotionNotify event, serial 34, synthetic NO, window 0x400001,
    root 0x29c, subw 0x0, time 1549638426, (155,9), root:(157,11),
    state 0x0, is_hint 0, same_screen YES

MotionNotify event, serial 34, synthetic NO, window 0x400001,
    root 0x29c, subw 0x0, time 1549638434, (157,13), root:(159,15),
    state 0x0, is_hint 0, same_screen YES

MotionNotify event, serial 34, synthetic NO, window 0x400001,
    root 0x29c, subw 0x0, time 1549638442, (161,18), root:(163,20),
    state 0x0, is_hint 0, same_screen YES

MotionNotify event, serial 34, synthetic NO, window 0x400001,
    root 0x29c, subw 0x0, time 1549638450, (165,25), root:(167,27),
    state 0x0, is_hint 0, same_screen YES

MotionNotify event, serial 34, synthetic NO, window 0x400001,
    root 0x29c, subw 0x0, time 1549638458, (172,30), root:(174,32),
    state 0x0, is_hint 0, same_screen YES

我不能说我知道解决这个问题的方法(而且我不认为这是一个 xcb 问题),但是您调用 wlroots 中的哪些函数来移动光标? 例如,我快速浏览了 wlroots 多指针示例,发现了这个:

static void handle_cursor_motion(struct wl_listener *listener, void *data) {
    struct sample_cursor *cursor =
        wl_container_of(listener, cursor, cursor_motion);
    struct wlr_event_pointer_motion *event = data;
    wlr_cursor_move(cursor->cursor, event->device, event->delta_x,
        event->delta_y);
}

static void handle_cursor_motion_absolute(struct wl_listener *listener,
        void *data) {
    struct sample_cursor *cursor =
        wl_container_of(listener, cursor, cursor_motion_absolute);
    struct wlr_event_pointer_motion_absolute *event = data;
    wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y);
}

所以,我会说是您的代码为 wlroots 提供了光标位置。

问题是 XWayland 的屏幕有 width_in_pixels == height_in_pixels == 0。这迫使所有指针移动到 (0,0)。强制屏幕的初始化区域为正可以解决此问题。