Вы можете воспроизвести это с помощью приложения с нежелательный файл размером 26214 байт , скопируйте его и вставьте в окно, вы получите:
Error: X11: Failed to convert selection to string
Clipboard does not contain a string
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». Но в двух словах:
INCR
-атома с помощью XInternAtom
например, с именем INCR_STRING
._glfwGetWindowPropertyX11
получили ли мы actualType
из INCR_STRING
, если да:INCR_STRING
с помощью XGetWindowProperty
, он содержит нижнюю границу передачи.INCR_STRING
чтобы владелец мог начать присылать нам хорошие вещи.PropertyNotify
, сигнализирующего о прибытии части полных данных.XGetWindowProperty
, добавить их в буфер.Если вам интересно, вот наполовину готовая реализация инкрементного выбора, которую я написал.
Вот несколько ссылок, которые мне пригодились при рассмотрении проблемы:
Надеюсь, это будет кому-то полезно, но, к сожалению, я не смог это понять.
Спасибо, отличное описание! Это немного абсурдно, что нужно делать клиентам, чтобы выполнять задачи, которые представляют собой пару вызовов функций на других платформах.
Я начал внедрять INCR два дня назад. У меня есть работа с чтением, а также преобразование из STRING / Latin-1, но был краткий момент отчаяния, когда я понял, что INCR, MULTIPLE и STRING могут объединяться для записи. Необходимо провести некоторую реструктуризацию, прежде чем ее можно будет провести чисто.
Переместил его только что в ветку selection-fixes
если кто-то хочет взглянуть.
Мне нужно какое-то время сосредоточиться на проверках запросов на вытягивание. Я держал много прекрасного кода в ожидании постыдного количества времени. Если кто-то пока что хочет продолжить работу над этим, основываясь на приведенном выше коде или нет, пожалуйста, сделайте это.
Самый полезный комментарий
Я сам разбирался в этом, но не смог завершить его реализацию. Надеюсь, некоторый опыт, полученный при попытке реализовать это, может быть полезен кому-то другому, пытающемуся сделать то же самое. Вкратце, вот что происходит и что ICCCM ожидает от нас для обработки этого атома INCR:
Ниже при вызове
_glfwPlatformGetClipboardString
становится очень грустным для X11:Причина в том, что мы запрашиваем
event.xselection.target
типаUTF8_STRING
, который будет работать большую часть времени, за исключением случаев, когда мы передали максимально разрешенный размер разовой передачи владельцем выбора (262146 байт в этот случай). Владелец выбора вместо этого даст намactualType
изINCR
который не совпадает с запрошенным типомUTF8_STRING
. Владелец хочет отправлять данные постепенно , то есть порциями по несколькоXGetWindowProperty
s, содержащихUTF8_STRING
s.Чтобы решить эту проблему, нам необходимо следовать рекомендации ICCCM «INCR Properties». Но в двух словах:
INCR
-атома с помощьюXInternAtom
например, с именемINCR_STRING
._glfwGetWindowPropertyX11
получили ли мыactualType
изINCR_STRING
, если да:a) Получить
INCR_STRING
с помощьюXGetWindowProperty
, он содержит нижнюю границу передачи.б) Удалите это свойство
INCR_STRING
чтобы владелец мог начать присылать нам хорошие вещи.c) Дождитесь события
PropertyNotify
, сигнализирующего о прибытии части полных данных.г) Получить данные блока с помощью
XGetWindowProperty
, добавить их в буфер.e) Удалить свойство, сигнализируя владельцу о необходимости отправки дополнительных фрагментов.
f) Проверьте, равен ли размер данных нулю, если нет, вернитесь к c.
g) Перенос завершен, теперь у вас есть все данные!
Если вам интересно, вот наполовину готовая реализация инкрементного выбора, которую я написал.
Вот несколько ссылок, которые мне пригодились при рассмотрении проблемы:
Надеюсь, это будет кому-то полезно, но, к сожалению, я не смог это понять.