Glfw: Добавить поддержку инкрементальной передачи выборок

Созданный на 15 апр. 2014  ·  5Комментарии  ·  Источник: glfw/glfw

Вы можете воспроизвести это с помощью приложения с нежелательный файл размером 26214 байт , скопируйте его и вставьте в окно, вы получите:

Error: X11: Failed to convert selection to string
Clipboard does not contain a string
X11 bug verified

Самый полезный комментарий

Я сам разбирался в этом, но не смог завершить его реализацию. Надеюсь, некоторый опыт, полученный при попытке реализовать это, может быть полезен кому-то другому, пытающемуся сделать то же самое. Вкратце, вот что происходит и что ICCCM ожидает от нас для обработки этого атома INCR:

Ниже при вызове _glfwPlatformGetClipboardString становится очень грустным для X11:

if (_glfwGetWindowPropertyX11(event.xselection.requestor,
                              event.xselection.property,
                              event.xselection.target,
                              (unsigned char**) &data))
    _glfw.x11.clipboardString = strdup(data);

Причина в том, что мы запрашиваем event.xselection.target типа UTF8_STRING , который будет работать большую часть времени, за исключением случаев, когда мы передали максимально разрешенный размер разовой передачи владельцем выбора (262146 байт в этот случай). Владелец выбора вместо этого даст нам actualType из INCR который не совпадает с запрошенным типом UTF8_STRING . Владелец хочет отправлять данные постепенно , то есть порциями по несколько XGetWindowProperty s, содержащих UTF8_STRING s.

Чтобы решить эту проблему, нам необходимо следовать рекомендации ICCCM «INCR Properties». Но в двух словах:

  1. Получите дескриптор INCR -атома с помощью XInternAtom например, с именем INCR_STRING .
  2. Посмотрите в _glfwGetWindowPropertyX11 получили ли мы actualType из INCR_STRING , если да:
    a) Получить INCR_STRING с помощью XGetWindowProperty , он содержит нижнюю границу передачи.
    б) Удалите это свойство INCR_STRING чтобы владелец мог начать присылать нам хорошие вещи.
    c) Дождитесь события PropertyNotify , сигнализирующего о прибытии части полных данных.
    г) Получить данные блока с помощью XGetWindowProperty , добавить их в буфер.
    e) Удалить свойство, сигнализируя владельцу о необходимости отправки дополнительных фрагментов.
    f) Проверьте, равен ли размер данных нулю, если нет, вернитесь к c.
    g) Перенос завершен, теперь у вас есть все данные!

Если вам интересно, вот наполовину готовая реализация инкрементного выбора, которую я написал.
Вот несколько ссылок, которые мне пригодились при рассмотрении проблемы:

Надеюсь, это будет кому-то полезно, но, к сожалению, я не смог это понять.

Все 5 Комментарий

GLFW пока не поддерживает инкрементную передачу данных из буфера обмена.

Примечание для себя: UTF8_STRING

Я сам разбирался в этом, но не смог завершить его реализацию. Надеюсь, некоторый опыт, полученный при попытке реализовать это, может быть полезен кому-то другому, пытающемуся сделать то же самое. Вкратце, вот что происходит и что ICCCM ожидает от нас для обработки этого атома INCR:

Ниже при вызове _glfwPlatformGetClipboardString становится очень грустным для X11:

if (_glfwGetWindowPropertyX11(event.xselection.requestor,
                              event.xselection.property,
                              event.xselection.target,
                              (unsigned char**) &data))
    _glfw.x11.clipboardString = strdup(data);

Причина в том, что мы запрашиваем event.xselection.target типа UTF8_STRING , который будет работать большую часть времени, за исключением случаев, когда мы передали максимально разрешенный размер разовой передачи владельцем выбора (262146 байт в этот случай). Владелец выбора вместо этого даст нам actualType из INCR который не совпадает с запрошенным типом UTF8_STRING . Владелец хочет отправлять данные постепенно , то есть порциями по несколько XGetWindowProperty s, содержащих UTF8_STRING s.

Чтобы решить эту проблему, нам необходимо следовать рекомендации ICCCM «INCR Properties». Но в двух словах:

  1. Получите дескриптор INCR -атома с помощью XInternAtom например, с именем INCR_STRING .
  2. Посмотрите в _glfwGetWindowPropertyX11 получили ли мы actualType из INCR_STRING , если да:
    a) Получить INCR_STRING с помощью XGetWindowProperty , он содержит нижнюю границу передачи.
    б) Удалите это свойство INCR_STRING чтобы владелец мог начать присылать нам хорошие вещи.
    c) Дождитесь события PropertyNotify , сигнализирующего о прибытии части полных данных.
    г) Получить данные блока с помощью XGetWindowProperty , добавить их в буфер.
    e) Удалить свойство, сигнализируя владельцу о необходимости отправки дополнительных фрагментов.
    f) Проверьте, равен ли размер данных нулю, если нет, вернитесь к c.
    g) Перенос завершен, теперь у вас есть все данные!

Если вам интересно, вот наполовину готовая реализация инкрементного выбора, которую я написал.
Вот несколько ссылок, которые мне пригодились при рассмотрении проблемы:

Надеюсь, это будет кому-то полезно, но, к сожалению, я не смог это понять.

Спасибо, отличное описание! Это немного абсурдно, что нужно делать клиентам, чтобы выполнять задачи, которые представляют собой пару вызовов функций на других платформах.

Я начал внедрять INCR два дня назад. У меня есть работа с чтением, а также преобразование из STRING / Latin-1, но был краткий момент отчаяния, когда я понял, что INCR, MULTIPLE и STRING могут объединяться для записи. Необходимо провести некоторую реструктуризацию, прежде чем ее можно будет провести чисто.

Переместил его только что в ветку selection-fixes если кто-то хочет взглянуть.

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

Была ли эта страница полезной?
0 / 5 - 0 рейтинги