Touch не работает с Qt5.1.1 при использовании с Wayland & qtwayland
Я хочу, чтобы пример приложения Qt 5.1.1 touch работал с модулем qtwayland.
Я получаю окно на дисплее, а также я получаю следы касания от Уэстона. Я вижу, что qtwayland также запускается с функцией обратного вызова, которая зарегистрирована для касания, касания, движения касанием.
Но QT не вызывает обработчик QPushButton в приложении QT.
API подключения, который я использую, как показано ниже: connect(ui->b_audio, SIGNAL(нажат ()), this, SLOT(on_b_audio_clicked()));
Любая подсказка, почему это могло произойти? Пожалуйста, предложите возможные проблемы, чтобы я мог исследовать и отлаживать.
Заранее спасибо. Бхушан.
2 ответа
В QtWayland QWaylandInputDevice::touch_frame() передает точки касания во внутреннюю оконную систему Qt через QWindowSystemInterface::handleTouchEvent(). Weston вообще не отправляет событие WL_TOUCH_FRAME, поэтому кнопки или QML MouseArea никогда не получают событие касания. Вы можете добавить следующую строку в конец evdev_flush_motion() в weston/src/evdev.c:
notify_touch(master, time, 0, 0, 0, WL_TOUCH_FRAME);
И переписать notify_touch() в weston/src/input.c:
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 не обрабатывает multi-touch должным образом, потому что его структура 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
Уэстон обрабатывает события от первого слота до события EV_SYN и вызывает notify_touch(), если встречается EV_SYN. Поэтому 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;
- num_down_event: отследить, сколько пальцев приземляется
- num_motion_event: отслеживать, сколько пальцев движется
- num_up_event: отследить, сколько пальцев поднялось
- слоты: отслеживать номера слотов в каждом сенсорном кадре
Это https://bugreports.qt-project.org/browse/QTBUG-36602 и мы планируем обойти это в Qt 5.4.0. К тому времени, когда мы это сделали, кажется, что touch_frame отправляется для touch_motion, но не для touch_up. (Тестирование с последними версиями Wayland, Weston и libinput)