Как перенести QApplication :: x11EventFilter в XCB QAbstractNativeEventFilter - PullRequest
0 голосов
/ 17 апреля 2019

Я уже разместил вопрос на форуме Qt (здесь: https://forum.qt.io/topic/101608/how-to-port-qapplication-x11eventfilter-to-xcb-qabstractnativeeventfilter), но пока безуспешно, я также размещаю его здесь, если у кого-то есть решение.

Теперь вот первый пост вссылка выше:

В настоящее время мы переносим приложение с Qt4 на Qt5, и документации о том, как заменить реализацию MyApplication :: x11EventFilter на QAbstractNativeEventFilter , не так много.с QCoreApplication :: installNativeEventFilter (как описано в https://doc.qt.io/qt-5/sourcebreaks.html#changes-to-qcoreapplication). Мы только что начали реализацию

MyXcbEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *)

, как описано в https://doc.qt.io/qt-5/qabstractnativeeventfilter.html#nativeEventFilter в «примере Linux»и тем, что мы нашли в Интернете, например, заменив это в MyApplication :

bool MyApplication::x11EventFilter(XEvent* p_event)
{
    int eventType = p_event->type;

    QSharedPointer<QEvent> eventToSend;

    if (eventType == ButtonPress)
    {
        XButtonPressedEvent& bpe = p_event->xbutton;
        const QPoint pos(bpe.x_root,bpe.y_root);
        QWidget* widget = qApp->widgetAt(pos);
        if (widget && widget->window() != qApp->activeWindow())
        {
            QPoint local_pos = widget->mapFromGlobal(pos);
            eventToSend = QSharedPointer<QEvent>((QEvent*)new QMouseEvent(QEvent::MouseButtonPress, local_pos, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
        }
    }

    return false;
}

На что-то подобное (с installNativeEventFilter (m_myXcbEventFilter) вызывается в MyApplication конструктор):

bool MyXcbEventFilter::nativeEventFilter(const QByteArray& p_eventType, void* p_message, long*)
{
    if (p_eventType == "xcb_generic_event_t")
    {
        xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(p_message);
        uint16_t xcbEventType = ev->response_type & ~0x80;

        if (xcbEventType == XCB_BUTTON_PRESS)
        {
            xcb_button_press_event_t* buttonPressEvent = static_cast<xcb_button_press_event_t*>(p_message);
            // Do stuff
        }
    }
}

Но мы никогда не попадем в xcbEventType == XCB_BUTTON_PRESS , кажется, вместо этого есть (вминимум для нажатия / отпускания кнопки) XCB_GE_GENERIC , который мы можем привести к xcb_ge_generic_event_t , который имеет event_type члена, который содержит, например, XCB_BUTTON_PRESS затем код изменился на:

bool MyXcbEventFilter::nativeEventFilter(const QByteArray& p_eventType, void* p_message, long*)
{
    if (p_eventType == "xcb_generic_event_t")
    {
        xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(p_message);
        uint16_t xcbEventType = ev->response_type & ~0x80;

        if (xcb_eventType == XCB_GE_GENERIC)
        {
            xcb_ge_generic_event_t* genericEvent = static_cast<xcb_ge_generic_event_t*>(p_message);
            xcbEventType = genericEvent->event_type;
        }

        if (xcbEventType == XCB_BUTTON_PRESS)
        {
            xcb_button_press_event_t* buttonPressEvent = static_cast<xcb_button_press_event_t*>(p_message);
            // Do stuff
        }
    }
}

Теперь мы попадаем в xcbEventType == XCB_BUTTON_PRESS при нажатии кнопки, но приведение к xcb_button_press_event_t , похоже, не имеет смысла с тех пор root_x , root_y , event_y и event_y члены всегда имеют одинаковые значения везде, где мы нажимаем.

Любой знает, какправильно реализовать это?

Спасибо

...