我想使用qtwayland模块制作Qt 5.1.1触摸示例应用程序。
我看到了显示的窗口,而且我还得到了韦斯顿的触摸痕迹。我看到qtwayland也被触发了回调功能,该功能已注册为触摸,触摸,触摸动作。
但是,QT不会在QT应用程序中调用QPushButton处理程序。
我正在使用的连接API如下: connect(ui-> b_audio,SIGNAL(pressed()),this,SLOT(on_b_audio_clicked()));
有任何线索可能会发生这种情况吗?请提出可能的问题,以便我可以进行探索和调试。
先谢谢。 普山
答案 0 :(得分:0)
在QtWayland中,QWaylandInputDevice :: touch_frame()通过QWindowSystemInterface :: handleTouchEvent()将触摸点传递给Qt内部窗口系统。 Weston根本不发送WL_TOUCH_FRAME事件,因此按钮或QML MouseArea永远不会接收触摸事件。 您可以在weston / src / evdev.c中的evdev_flush_motion()末尾添加以下行:
notify_touch(master, time, 0, 0, 0, WL_TOUCH_FRAME);
并在weston / src / input.c中重写notify_touch():
WL_EXPORT void
notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
wl_fixed_t x, wl_fixed_t y, int touch_type)
{
struct weston_compositor *ec = seat->compositor;
struct weston_touch *touch = seat->touch;
struct weston_touch_grab *grab = touch->grab;
struct weston_surface *es;
wl_fixed_t sx, sy;
struct weston_touch *grab_touch = grab->touch;
/* Update grab's global coordinates. */
touch->grab_x = x;
touch->grab_y = y;
switch (touch_type) {
case WL_TOUCH_DOWN:
weston_compositor_idle_inhibit(ec);
seat->num_tp++;
/* the first finger down picks the surface, and all further go
* to that surface for the remainder of the touch session i.e.
* until all touch points are up again. */
if (seat->num_tp == 1) {
es = weston_compositor_pick_surface(ec, x, y, &sx, &sy);
weston_touch_set_focus(seat, es);
} else if (touch->focus) {
es = (struct weston_surface *) touch->focus;
weston_surface_from_global_fixed(es, x, y, &sx, &sy);
} else {
/* Unexpected condition: We have non-initial touch but
* there is no focused surface.
*/
weston_log("touch event received with %d points down"
"but no surface focused\n", seat->num_tp);
return;
}
grab->interface->down(grab, time, touch_id, sx, sy);
if (seat->num_tp == 1) {
touch->grab_serial =
wl_display_get_serial(ec->wl_display);
touch->grab_time = time;
touch->grab_x = x;
touch->grab_y = y;
}
break;
case WL_TOUCH_MOTION:
es = (struct weston_surface *) touch->focus;
if (!es)
break;
weston_surface_from_global_fixed(es, x, y, &sx, &sy);
grab->interface->motion(grab, time, touch_id, sx, sy);
break;
case WL_TOUCH_UP:
weston_compositor_idle_release(ec);
seat->num_tp--;
grab->interface->up(grab, time, touch_id);
break;
case WL_TOUCH_FRAME:
if (grab_touch->focus_resource) {
wl_touch_send_frame(grab_touch->focus_resource);
if (seat->num_tp == 0)
weston_touch_set_focus(seat, NULL);
}
}
}
与此同时,我发现weston没有正确处理多点触摸,因为它的mt结构(下面)使用了一个int值'slot',它只能跟踪当前的插槽号。
struct {
int slot;
int32_t x[MAX_SLOTS];
int32_t y[MAX_SLOTS];
} mt;
在多点触控协议类型B中,每个插槽与手指接触相关联,您可以在触摸框中获得多个插槽事件,例如touch_down帧;
ABS_MT_SLOT
ABS_MT_TRACKING_ID
ABS_MT_POSITION_X
ABS_MT_POSITION_Y
ABS_MT_SLOT
ABS_MT_TRACKING_ID
ABS_MT_POSITION_X
ABS_MT_POSITION_Y
EV_SYN
weston处理从第一个插槽事件到EV_SYN事件的事件,如果遇到EV_SYN则调用notify_touch()。因此,weston不能通过具有不同槽号参数的notify_touch()顺序发送两个触摸事件。
在我的重新实现中,我改变了mt结构:
struct {
int current_slot;
uint32_t num_down_event;
uint32_t num_motion_event;
uint32_t num_up_event;
int slots[MAX_CONTACTS];
int32_t x[MAX_SLOTS];
int32_t y[MAX_SLOTS];
} mt;
答案 1 :(得分:0)
这是https://bugreports.qt-project.org/browse/QTBUG-36602,我们计划在Qt 5.4.0中找到解决方法。到我们这样做的时候,似乎正在为touch_motion发送touch_frame,而不是为touch_up发送。 (使用最新版本的wayland,weston和libinput进行测试)