【问题标题】:XCB Pointer Coordinates are Stuck at (0,0)XCB 指针坐标卡在 (0,0)
【发布时间】:2019-08-14 20:35:53
【问题描述】:

我在一个游戏引擎中实现了 Wayland 合成器(通过 wlroots),该引擎为 X 应用程序配备了 XWayland/XCB 支持。当我启动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

注意:

  • 我的游戏引擎会处理所有光标内容,因此我省略了通过 XCB/XWayland 显式创建光标(尽管尝试添加,但似乎无法解决坐标问题)。
  • 我尝试将硬编码坐标发送到我的窗口,但无济于事。似乎没有任何东西可以更新它的 X 坐标(我已经尝试通过 xwayland 设施以及直接通过xcb_warp_pointer 调用)。
  • 我已通过 WAYLAND_DEBUG=server 标志验证,坐标已成功通过 Wayland 线发送,并且在帧调用之间的每一帧都具有正确的坐标。

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

为了让我的问题更具体:必须在 XCB 中初始化什么状态才能使指针运动成为 (0,0) 以外的状态?


编辑:这是一些 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

#...

这可以与运行xev 的正常运行的rootston(wlroot 的示例合成器)进行比较:

$ 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

【问题讨论】:

  • "它似乎接收到 ButtonNotify 事件就好了" 这些 ButtonNotify 事件中的坐标是否正确?
  • @UliSchlachter:不。他们也被困在 (0,0)。

标签: x11 xcb wayland


【解决方案1】:

问题在于 XWayland 的屏幕上有一个width_in_pixels == height_in_pixels == 0。这迫使所有指针运动到(0,0)。强制屏幕的初始化区域为正解决了这个问题。

【讨论】:

    【解决方案2】:

    我不能说我知道如何解决这个问题(我不认为这是一个 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 提供了光标位置。

    【讨论】:

    • 光标坐标是通过wlr_seat_pointer_notify_enterwlr_seat_pointer_notify_motion发送的,我已经验证这些函数发送的坐标是正确的。我的代码中没有实际的wlr_cursor,因为我正在让游戏引擎处理它。是这个问题吗?
    • 我认为这不是问题,因为注释掉 wlr_cursor_warp_absolutewlr_cursor_move 会调用,即rootston(wlroots 示例合成器)不会调用 X 坐标来停留在 ( 0,0) 和我的合成器一样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多