LINUX.ORG.RU

xdamage: qt4+xlib - работает, qt5+xcb - не работает

 , , ,


0

1

в qt4 работает:

// init:
m_isXDamageAvailable = XDamageQueryExtension(QX11Info::display(), &m_damageEvent, &m_damageError);

// add window:
XDamageCreate(QX11Info::display(), w.id, XDamageReportNonEmpty);

// x11EventFilter(XEvent* event):
if(event->type == m_damageEvent + XDamageNotify)
{
  XDamageNotifyEvent* e = reinterpret_cast<XDamageNotifyEvent*>(event);
  XDamageSubtract(QX11Info::display(), e->damage, None, None);

  emit windowContentChanged(e->drawable);
}

в qt5 x11EventFilter удалили и нужно юзать xcb:

// init:
xcb_prefetch_extension_data(m_xcb_connection, &xcb_damage_id);
const auto* reply = xcb_get_extension_data(m_xcb_connection, &xcb_damage_id);
if(reply->present)
{
  m_damageEventBase = reply->first_event;
  xcb_damage_query_version_unchecked(m_xcb_connection, XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION);
}

// add window:
const auto damageId = xcb_generate_id(m_xcb_connection);
m_damageWatches[w.id] = damageId;
xcb_damage_create(m_xcb_connection, damageId, w.id, XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY);
xcb_flush(m_xcb_connection);

// nativeEventFilter(const QByteArray& eventType, void* message, long* result):
xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(message);
const auto responseType = XCB_EVENT_RESPONSE_TYPE(ev);
if (responseType == app->m_damageEventBase + XCB_DAMAGE_NOTIFY)
{
  // здесь можно размещать любой код, нужно не выполнять
}

В nativeEventFilter приходит куча событий, но XCB_DAMAGE_NOTIFY - никогда.

Так как c xcb впервые столкнулся сегодня, то очевидно, что я где-то допустил элементарную ошибку. Помогите, добрые люди.


Да вроде все верно. А ты проверил, он находит расширение Damage? Все ли правильно возвращает (версию, например)? И откуда w.id берется? И какой WM?

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Значение m_damageEventBase возвращается такое же как из xlib.
w.id - это Window - получаю через xlib. Но тут разве важно как получаю?
WM - KWin.
if(reply->present) - всегда ок.

Ower
() автор топика
Ответ на: комментарий от Ower

w.id - это Window - получаю через xlib. Но тут разве важно как получаю?

Если это случайно какое-то окно (или другой drawable), с которым просто ничего не происходит, то и сообщений Damage может не быть. Из поста этого не понять, поэтому остается выдвигать бредположения или просить уточнений.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 3)
Ответ на: комментарий от Zubok

это окно с которым что-то происходит:) qt4+xlib при тех же изменениях в окне получают damage события.

Ower
() автор топика
Ответ на: комментарий от Ower

это окно с которым что-то происходит:) qt4+xlib при тех же изменениях в окне получают damage события.

Ну вот ты можешь не упираться, например, а проверить w.id такой же получает? Я эе не просто так спрашиваю. Ведь ты полностью эксперимент не описываешь. Может, версия на qt4 - это старая, которая когда-то работала. Сейчас я вот понимаю, что ты их запускаешь одновременно. Одна работает, а другая нет. Хорошо бы все-таки обстоятельно сравнить, прежде чем дальше думать.

Zubok ★★★★★
()
Ответ на: комментарий от Ower

Ну и хорошо бы глянуть, что происходит в обоих случаях при помощи xtrace. Все ли одинаково. по крайней мере, можно увидеть общение и параметры.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

проверил - значения Window совпадают. qt4 и qt5 версии поддерживаются одновременно - том все одинаково кроме qt4/qt5 различий.

Ower
() автор топика
Ответ на: комментарий от Zubok

xtrace почти совпадает: xlib:

000:<:00a9: 16: Request(98): QueryExtension name='DAMAGE'
000:>:00a9:32: Reply to QueryExtension: present=true(0x01) major-opcode=143 first-event=91 first-error=151
000:<:00aa: 12: DAMAGE-Request(143,0): QueryVersion major version=1 minor version=1
000:>:00aa:32: Reply to QueryVersion: major version=1 minor version=1


000:<:0194: 16: DAMAGE-Request(143,1): Create damage=0x0fe0001e drawable=0x0f0000a5 level=report non-empty(0x03)
000:<:0195:  8: Request(3): GetWindowAttributes window=0x0f0000a5
000:<:0196:  8: Request(14): GetGeometry drawable=0x0f0000a5
000:>:0196: Event DAMAGE-Notify(91) level=report non-empty(0x03) drawable=0x0f0000a5 damage=0x0fe0001e timestamp=0x0b5703d7 area={x=0 y=0 w=640 h=441}; geometry={x=559 y=487 w=640 h=441};

xcb:

000:<:018e: 16: Request(98): QueryExtension name='DAMAGE'
000:>:018e:32: Reply to QueryExtension: present=true(0x01) major-opcode=143 first-event=91 first-error=151
000:<:018f: 12: DAMAGE-Request(143,0): QueryVersion major version=1 minor version=1
000:>:018f:32: Reply to QueryVersion: major version=1 minor version=1

000:<:01e2: 16: DAMAGE-Request(143,1): Create damage=0x0fe00004 drawable=0x0f0000a5 level=report non-empty(0x03)
000:<:01e3:  8: Request(3): GetWindowAttributes window=0x0f0000a5
000:>:01e3: Event DAMAGE-Notify(91) level=report non-empty(0x03) drawable=0x0f0000a5 damage=0x0fe00004 timestamp=0x0b548b07 area={x=0 y=0 w=640 h=441}; geometry={x=559 y=487 w=640 h=441};

1-й DAMAGE-Notify отправляется в обоих случаях, но я его не получаю

Ower
() автор топика
Ответ на: комментарий от Ower

Надо это проанализировать. Может qt5 зарубает его? Надо в кишках покопаться. Нет, ну раз event есть, если сервер его в обоих случаях посылает, то код твой правильный. Проблема дальше где-то.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Ower

Может, проблема где-то в коде, где installNativeEventFilter ты делаешь? Я не спец по Qt - это быстрый гуглинг. Может быть, у тебя есть еще один nativeEventFilter, который до твоего отрабатывает и не дает событию проходить дальше?

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

заработало

Application_X11::Application_X11(int& argc, char** argv)
  : QApplication(argc, argv)
{
  m_eventFilter = new EventFilter_X11; 
  // изначалоно installNativeEventFilter был здесь
  installNativeEventFilter(m_eventFilter);
}

...

app = new Application_X11(argc, argv);
// перенес сюда
// app->installNativeEventFilter(app->m_eventFilter);

не могу понять в чем разница, и почему другие события, кроме damage приходят в обоих вариантах?

Ower
() автор топика
Ответ на: комментарий от Ower

Понятия не имею. Могу только предположить. Возможно, что указание installNativeEventFilter в первом случае - это слишком рано, так как после добавления твоего фильтра инициализируется какой-то умолчательный фильтр. Везде написано, что тот фильтр, который установлен (installed) последним, срабатывает *первым*! Вполне может быть, что умолчательный фильтр пропускает только определенные стандартные события типа мышки, клавиатуры, изменения размеров окон и пр., а остальные зарубает и не дает им дальше по цепочке фильтров проходить.

http://doc.qt.io/qt-5/qcoreapplication.html#installNativeEventFilter

If multiple event filters are installed, the filter that was installed last is activated first.

А вот во втором случае, скорее всего, ты ставишь фильтр уже после умолчательного. В этом случае твой фильтр будет срабатывать первым. Это предположения без заглядывания в код.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 4)
Ответ на: комментарий от Ower

возможно, дело в том, что xcb асинхронный, и в qt5 ты вызываешь installNativeEventFilter слишком рано, ещё до того как что-нибудь важное успело доделаться.

thesame ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.