Glfw: Agregar soporte para transferencia incremental de selecciones

Creado en 15 abr. 2014  ·  5Comentarios  ·  Fuente: glfw/glfw

Puede reproducir esto con la aplicación del un archivo basura de 26214 bytes , cópielo todo y péguelo en la ventana, obtendrá:

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

Comentario más útil

He estado investigando esto yo mismo, pero no he podido completar su implementación. Es de esperar que parte de la experiencia al intentar implementarlo pueda ser de utilidad para otra persona que intente hacer lo mismo. En pocas palabras, esto es lo que sucede y lo que ICCCM espera que hagamos para manejar este átomo de INCR:

A continuación, al llamar a _glfwPlatformGetClipboardString es donde X11 se pone muy triste:

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

Y la razón es porque estamos solicitando event.xselection.target de tipo UTF8_STRING , que funcionará la mayor parte del tiempo, excepto cuando hayamos superado el tamaño máximo de transferencia de un solo lote permitido por el propietario de la selección (262146 bytes en este caso). En cambio, el propietario de la selección nos dará un actualType de INCR que no es el mismo que el tipo solicitado UTF8_STRING . El propietario desea enviar datos de forma incremental , es decir, en trozos de varios XGetWindowProperty s que contienen UTF8_STRING s.

Para solucionar esto, debemos seguir la recomendación de ICCCM "Propiedades INCR". Pero en pocas palabras:

  1. Obtenga un identificador para el INCR -atom con XInternAtom por ejemplo, con el nombre INCR_STRING .
  2. Vea en _glfwGetWindowPropertyX11 si recibimos actualType de INCR_STRING , si es así:
    a) Obtenga INCR_STRING usando XGetWindowProperty , contiene un límite de transferencia inferior.
    b) Elimine esta propiedad INCR_STRING para que el propietario pueda comenzar a enviarnos las cosas buenas.
    c) Espere un evento PropertyNotify , que indique la llegada de una parte de los datos completos.
    d) Recupere fragmentos de datos usando XGetWindowProperty , añádalos a un búfer.
    e) Eliminar la propiedad, indicando al propietario que envíe fragmentos adicionales.
    f) Compruebe si el tamaño de los datos es cero, si no, vuelva a c.
    g) Transferencia completa, ¡ahora tiene todos los datos!

Si está interesado, aquí hay una esencia de
Aquí hay un par de enlaces que encontré útiles al investigar el problema:

Con suerte, esto es de alguna utilidad para alguien, desafortunadamente no pude resolverlo por mí mismo.

Todos 5 comentarios

GLFW aún no admite la transferencia de datos incremental del portapapeles.

Nota personal: UTF8_STRING

He estado investigando esto yo mismo, pero no he podido completar su implementación. Es de esperar que parte de la experiencia al intentar implementarlo pueda ser de utilidad para otra persona que intente hacer lo mismo. En pocas palabras, esto es lo que sucede y lo que ICCCM espera que hagamos para manejar este átomo de INCR:

A continuación, al llamar a _glfwPlatformGetClipboardString es donde X11 se pone muy triste:

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

Y la razón es porque estamos solicitando event.xselection.target de tipo UTF8_STRING , que funcionará la mayor parte del tiempo, excepto cuando hayamos superado el tamaño máximo de transferencia de un solo lote permitido por el propietario de la selección (262146 bytes en este caso). En cambio, el propietario de la selección nos dará un actualType de INCR que no es el mismo que el tipo solicitado UTF8_STRING . El propietario desea enviar datos de forma incremental , es decir, en trozos de varios XGetWindowProperty s que contienen UTF8_STRING s.

Para solucionar esto, debemos seguir la recomendación de ICCCM "Propiedades INCR". Pero en pocas palabras:

  1. Obtenga un identificador para el INCR -atom con XInternAtom por ejemplo, con el nombre INCR_STRING .
  2. Vea en _glfwGetWindowPropertyX11 si recibimos actualType de INCR_STRING , si es así:
    a) Obtenga INCR_STRING usando XGetWindowProperty , contiene un límite de transferencia inferior.
    b) Elimine esta propiedad INCR_STRING para que el propietario pueda comenzar a enviarnos las cosas buenas.
    c) Espere un evento PropertyNotify , que indique la llegada de una parte de los datos completos.
    d) Recupere fragmentos de datos usando XGetWindowProperty , añádalos a un búfer.
    e) Eliminar la propiedad, indicando al propietario que envíe fragmentos adicionales.
    f) Compruebe si el tamaño de los datos es cero, si no, vuelva a c.
    g) Transferencia completa, ¡ahora tiene todos los datos!

Si está interesado, aquí hay una esencia de
Aquí hay un par de enlaces que encontré útiles al investigar el problema:

Con suerte, esto es de alguna utilidad para alguien, desafortunadamente no pude resolverlo por mí mismo.

Gracias, ¡es una descripción excelente! Es un poco absurdo lo que los clientes deben hacer para lograr cosas que son un par de llamadas a funciones en otras plataformas.

Comencé a implementar INCR hace dos días. Tengo la lectura funcionando, así como la conversión de STRING / Latin-1, pero tuve un breve momento de desesperación cuando me di cuenta de que INCR, MULTIPLE y STRING se pueden combinar para escribir. Es necesario realizar alguna reestructuración antes de que pueda implementarse limpiamente.

Lo empujó ahora a la rama selection-fixes si alguien quiere echar un vistazo.

Necesito concentrarme en las revisiones de las solicitudes de extracción por un tiempo. He guardado mucho código fino esperando una cantidad de tiempo vergonzosa. Si alguien quiere seguir trabajando en esto mientras tanto, según el código anterior o no, hágalo.

¿Fue útil esta página
0 / 5 - 0 calificaciones