Você pode reproduzir isso com o aplicativo da um arquivo lixo de 26214 bytes , copie tudo e cole na janela, você obterá:
Error: X11: Failed to convert selection to string
Clipboard does not contain a string
O GLFW ainda não suporta transferência incremental de dados da área de transferência.
Nota para mim mesmo: UTF8_STRING
Estive investigando isso sozinho, mas não consegui concluir a implementação. Esperançosamente, parte da experiência na tentativa de implementá-lo pode ser útil para outra pessoa que esteja tentando fazer o mesmo. Em poucas palavras, aqui está o que acontece e o que o ICCCM espera que façamos para lidar com este átomo INCR:
Abaixo, ao chamar _glfwPlatformGetClipboardString
é onde X11 fica muito triste:
if (_glfwGetWindowPropertyX11(event.xselection.requestor,
event.xselection.property,
event.xselection.target,
(unsigned char**) &data))
_glfw.x11.clipboardString = strdup(data);
E a razão é porque estamos solicitando event.xselection.target
do tipo UTF8_STRING
, que funcionará na maior parte do tempo, exceto quando tivermos passado o tamanho máximo de transferência de lote único permitido pelo proprietário da seleção (262146 bytes em este caso). Em vez disso, o proprietário da seleção nos dará um actualType
de INCR
que não é o mesmo que o tipo solicitado UTF8_STRING
. O proprietário deseja enviar dados de forma incremental , ou seja, em blocos de vários XGetWindowProperty
s contendo UTF8_STRING
s.
Para resolver isso, precisamos seguir a recomendação do ICCCM "Propriedades INCR". Mas em poucas palavras:
INCR
-atom com XInternAtom
por exemplo, com o nome INCR_STRING
._glfwGetWindowPropertyX11
se recebemos actualType
de INCR_STRING
, se assim for:INCR_STRING
usando XGetWindowProperty
, ele contém um limite de transferência inferior.INCR_STRING
propriedade para que o proprietário possa começar a nos enviar as coisas boas.PropertyNotify
, sinalizando a chegada de uma parte dos dados completos.XGetWindowProperty
e anexe-os a um buffer.Se você estiver interessado, aqui está um resumo da
Aqui estão alguns links que achei úteis ao analisar o problema:
Espero que isso seja útil para alguém, mas eu não fui capaz de descobrir sozinho, infelizmente.
Obrigado, é uma excelente descrição! É um pouco absurdo o que os clientes precisam fazer para realizar coisas que são algumas chamadas de função em outras plataformas.
Comecei a implementar o INCR há dois dias. Tenho leitura funcionando, assim como conversão de STRING / Latin-1, mas tive um breve momento de desespero quando percebi que INCR, MULTIPLE e STRING podem se combinar para escrever. Alguma reestruturação é necessária antes que possa ser implementada de forma limpa.
Empurrei agora para o branch selection-fixes
se alguém quiser dar uma olhada.
Preciso me concentrar nas revisões de solicitação de pull por um tempo. Eu mantive muitos códigos finos esperando por um período vergonhoso de tempo. Se alguém quiser continuar trabalhando nisso, com base no código acima ou não, por favor, continue.
Comentários muito úteis
Estive investigando isso sozinho, mas não consegui concluir a implementação. Esperançosamente, parte da experiência na tentativa de implementá-lo pode ser útil para outra pessoa que esteja tentando fazer o mesmo. Em poucas palavras, aqui está o que acontece e o que o ICCCM espera que façamos para lidar com este átomo INCR:
Abaixo, ao chamar
_glfwPlatformGetClipboardString
é onde X11 fica muito triste:E a razão é porque estamos solicitando
event.xselection.target
do tipoUTF8_STRING
, que funcionará na maior parte do tempo, exceto quando tivermos passado o tamanho máximo de transferência de lote único permitido pelo proprietário da seleção (262146 bytes em este caso). Em vez disso, o proprietário da seleção nos dará umactualType
deINCR
que não é o mesmo que o tipo solicitadoUTF8_STRING
. O proprietário deseja enviar dados de forma incremental , ou seja, em blocos de váriosXGetWindowProperty
s contendoUTF8_STRING
s.Para resolver isso, precisamos seguir a recomendação do ICCCM "Propriedades INCR". Mas em poucas palavras:
INCR
-atom comXInternAtom
por exemplo, com o nomeINCR_STRING
._glfwGetWindowPropertyX11
se recebemosactualType
deINCR_STRING
, se assim for:a) Busque
INCR_STRING
usandoXGetWindowProperty
, ele contém um limite de transferência inferior.b) Exclua esta
INCR_STRING
propriedade para que o proprietário possa começar a nos enviar as coisas boas.c) Aguarde um evento
PropertyNotify
, sinalizando a chegada de uma parte dos dados completos.d) Recupere os dados do bloco usando
XGetWindowProperty
e anexe-os a um buffer.e) Exclua a propriedade, sinalizando ao proprietário para enviar pedaços adicionais.
f) Verifique se o tamanho dos dados é zero, caso contrário, volte para c.
g) Transferência concluída, agora você tem todos os dados!
Se você estiver interessado, aqui está um resumo da
Aqui estão alguns links que achei úteis ao analisar o problema:
Espero que isso seja útil para alguém, mas eu não fui capaz de descobrir sozinho, infelizmente.