/* Ручная проверка EWMH на настоящем X11/XWayland: настройки рабочих столов пользователя не меняются. */ #include "../src/message_notification.h" #include "../../../lib/debug_config.h" #include #include #include class NotificationDesktopTest : public QObject { Q_OBJECT Display* m_display = nullptr; qint64 desktop(Window window, const char* property = "_NET_WM_DESKTOP") { Atom type = None; int format = 0; unsigned long count = 0, remaining = 0; unsigned char* data = nullptr; const Atom atom = XInternAtom(m_display, property, False); const int status = XGetWindowProperty(m_display, window, atom, 0, 1, False, XA_CARDINAL, &type, &format, &count, &remaining, &data); qint64 value = -1; if (status == Success && type == XA_CARDINAL && format == 32 && count == 1 && data) value = *reinterpret_cast(data) & 0xffffffffUL; if (data) XFree(data); return value; } private slots: void initTestCase() { debug_config_init(); debug_set_level(DEBUG_LEVEL_DEBUG); m_display = XOpenDisplay(nullptr); QVERIFY(m_display); } void cleanupTestCase() { if (m_display) XCloseDisplay(m_display); } void allDesktopsOnFirstShowUpdateAndReshow() { MessageNotification notification; notification.showMessage("42", "Alice", "Desktop test", {}); const Window window = Window(notification.winId()); QTest::qWait(200); // Проверяем состояние после обработки MapRequest оконным менеджером. DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "notification desktop test: mapped desktop=%lld root_current=%lld root_count=%lld", (long long)desktop(window), (long long)desktop(DefaultRootWindow(m_display), "_NET_CURRENT_DESKTOP"), (long long)desktop(DefaultRootWindow(m_display), "_NET_NUMBER_OF_DESKTOPS")); QTRY_COMPARE_WITH_TIMEOUT(desktop(window), qint64(0xffffffffUL), 2000); QVERIFY(!notification.parentWidget()); QVERIFY(notification.windowFlags() & Qt::WindowDoesNotAcceptFocus); DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "notification desktop test: first show window=0x%lx desktop=all", window); // Переносим только своё окно на стол 0; активный стол пользователя может изменяться во время проверки. const qint64 singleDesktop = 0; XEvent event{}; event.xclient.type = ClientMessage; event.xclient.window = window; event.xclient.message_type = XInternAtom(m_display, "_NET_WM_DESKTOP", False); event.xclient.format = 32; event.xclient.data.l[0] = long(singleDesktop); event.xclient.data.l[1] = 1; QVERIFY(XSendEvent(m_display, DefaultRootWindow(m_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &event)); XFlush(m_display); QTRY_COMPARE_WITH_TIMEOUT(desktop(window), singleDesktop, 2000); notification.showMessage("dm:7", "Bob", "Desktop test", {}); QTRY_COMPARE_WITH_TIMEOUT(desktop(window), qint64(0xffffffffUL), 2000); DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "notification desktop test: updated visible window desktop=all"); notification.dismiss("test-reshow"); QTest::qWait(50); notification.showMessage("43", "Charlie", "Desktop test", {}); QTRY_COMPARE_WITH_TIMEOUT(desktop(Window(notification.winId())), qint64(0xffffffffUL), 2000); DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "notification desktop test: withdrawn window shown again desktop=all"); notification.dismiss("test-complete"); } }; int main(int argc, char** argv) { if (qEnvironmentVariableIsEmpty("DISPLAY")) return 77; qputenv("QT_QPA_PLATFORM", "xcb"); QApplication application(argc, argv); NotificationDesktopTest test; return QTest::qExec(&test, argc, argv); } #include "test_message_notification_x11.moc"