XLib - не могу отправить клиенту список selection TARGETS

Всех с наступающим!

У меня тут возникли некоторые трудности с использованием библиотеки XLib в Linux:
Есть С++ программа, содержащая строку с UTF8 текстом. Я хочу посредством XLib объявить эту программу как selection owner, чтобы все selection реквесты от клиентов поступали в программу. Программа должна предоставить клиентам текст из строки в ответ на selection request. Некоторые клиенты, отправляя selection request, сначала запрашивают у владельца лист атомов, описывающих типы данных, которые владелец может предоставить(selection TARGETS), и, если находят в этом списке интересующий их тип данных(строка, картинка...), запрашивают у владельца данные этого типа. Программа должна при запросе клиента предоставить ему список торгетов, состоящий из единственного атома "UTF8_STRING", и, если клиент пожелает запросить данные типа "UTF8_STRING", нужно ему эти данные любезно предоставить. Если вкратце, то что-то типа этого:

#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
 
int selectionRequested(Display*, XEvent* event, XPointer arg)
{
    return event->type == SelectionRequest;
}
 
int main()
{
    // ...
    Display* display = XOpenDisplay(NULL);
    int screen = XDefaultScreen(display);
    Window rootWindow = XRootWindow(display, screen);
    Atom selection = XInternAtom(display, "CLIPBOARD", false);
    Atom selectionType = XInternAtom(display, "UTF8_STRING", false);
    Atom targets = XInternAtom(display, "TARGETS", false);
    Window owner = XCreateSimpleWindow(display, rootWindow,
            -10, -10, 1, 1, 0, 0, 0);
    XSetSelectionOwner(display, selection, owner, CurrentTime);
    XEvent event;
    while (true)
    {
        XIfEvent(display, &event, selectionRequested, NULL);
        XEvent selectionResponse;
        selectionResponse.type = SelectionNotify;
        selectionResponse.xselection.send_event = true;
        selectionResponse.xselection.requestor =
            event.xselectionrequest.requestor;
        selectionResponse.xselection.property =
            event.xselectionrequest.property;
        selectionResponse.xselection.display =
            event.xselectionrequest.display;
        selectionResponse.xselection.selection =
            event.xselectionrequest.selection;
        selectionResponse.xselection.target =
            event.xselectionrequest.target;
        selectionResponse.xselection.time =
            event.xselectionrequest.time;
        Atom targetRequsted = event.xselectionrequest.target;
        std::cout << "REQUESTED TARGET \"" <<
            XGetAtomName(display, targetRequsted) << "\"" << '\n';
        if (targetRequsted == targets)
        {
            XChangeProperty(selectionResponse.xselection.display,
                    selectionResponse.xselection.requestor,
                    selectionResponse.xselection.property,
                    XA_ATOM, 32, PropModeReplace,
                    reinterpret_cast<unsigned char*>(&selectionType), 1);
            XSendEvent(selectionResponse.xselection.display,
                    selectionResponse.xselection.requestor, 0,
                    0, &selectionResponse);
        }
        else if (targetRequsted == selectionType)
        {
            // Code for sending data to the requestor...
        }
        else
        {
            // ...
        }
    }
    return 0;
}

Здесь я, судя по всему, как-то некорректно использую XChangeProperty() в условном блоке if (targetRequested == targets), поскольку при попытке вставить строку в окно клиента, клиент продолжает многократно запрашивать selection targets после того, как я ему отвечаю, и, не добившись ответа, запрашивает типы, которые я не объявлял. Например, вот что я вижу, когда пытаюсь вставить текст в Firefox:

REQUESTED TARGET "TARGETS"
REQUESTED TARGET "TARGETS"
REQUESTED TARGET "TARGETS"
REQUESTED TARGET "TARGETS"
REQUESTED TARGET "TARGETS"
REQUESTED TARGET "TARGETS"
REQUESTED TARGET "TARGETS"
REQUESTED TARGET "TARGETS"
REQUESTED TARGET "text/plain;charset=utf-8"
REQUESTED TARGET "text/plain;charset=utf-8"
REQUESTED TARGET "text/x-moz-text-internal"

Клиенты по какой-то причине не воспринимают атом, который я им отправляю в ответ на запрос торгетов, и, соответственно, не видят тип "UTF8_STRING", который я им предоставляю. Если же клиент не запрашивает сначала тип "TARGETS", а сразу запрашивает тип "UTF8_STRING", то дальнейший код(я его здесь опустил) работает прекрасно, и строка из программы успешно вставляется в окно клиента.

Я, если честно, только начал разбираться с XLib. Читал вот это - там всё, вроде бы, и расписано, но совсем нет даже элементарных примеров использования, одна сухая теория.

Что я делаю не так?


Ответы (0 шт):