Glfw: Tambahkan dukungan untuk transfer pilihan bertahap

Dibuat pada 15 Apr 2014  ·  5Komentar  ·  Sumber: glfw/glfw

Anda dapat melakukan repro ini dengan aplikasi clipboard dari folder tes, inilah file sampah 26214 byte , salin semuanya dan tempel ke jendela, Anda akan mendapatkan:

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

Komentar yang paling membantu

Saya telah memeriksanya sendiri tetapi saya belum dapat menyelesaikan implementasinya. Semoga beberapa pengalaman dalam mencoba menerapkannya dapat bermanfaat bagi orang lain yang mencoba melakukan hal yang sama. Singkatnya, inilah yang terjadi dan apa yang diharapkan ICCCM untuk kita lakukan untuk menangani atom INCR ini:

Di bawah ini, ketika menelepon _glfwPlatformGetClipboardString adalah saat X11 menjadi sangat sedih:

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

Dan alasannya adalah karena kita meminta event.xselection.target tipe UTF8_STRING , yang akan bekerja hampir sepanjang waktu, kecuali jika kita telah melewati ukuran transfer batch tunggal maksimum yang diizinkan pemilik pilihan (262146 byte dalam kasus ini). Pemilik pilihan akan memberi kita actualType dari INCR yang tidak sama dengan jenis yang diminta UTF8_STRING . Pemilik ingin mengirim data secara bertahap , yaitu dalam potongan beberapa XGetWindowProperty s berisi UTF8_STRING s.

Untuk mengatasi ini kita perlu mengikuti rekomendasi ICCCM "INCR Properties". Tapi secara singkat:

  1. Dapatkan pegangan ke INCR -atom dengan XInternAtom misalnya dengan nama INCR_STRING .
  2. Lihat di _glfwGetWindowPropertyX11 jika kita menerima actualType dari INCR_STRING , jika demikian:
    a) Ambil INCR_STRING menggunakan XGetWindowProperty , ini berisi batas transfer yang lebih rendah.
    b) Hapus properti INCR_STRING ini agar pemiliknya dapat mulai mengirimkan barang bagus kepada kami.
    c) Tunggu acara PropertyNotify , menandakan kedatangan sebagian data lengkap.
    d) Ambil data potongan menggunakan XGetWindowProperty , tambahkan ke buffer.
    e) Hapus properti, memberi isyarat kepada pemilik untuk mengirim potongan tambahan.
    f) Periksa apakah ukuran data nol, jika tidak loop kembali ke c.
    g) Transfer selesai, Anda sekarang memiliki seluruh data!

Jika Anda tertarik, berikut adalah inti implementasi yang sudah setengah selesai dari pilihan inkremental yang saya tulis.
Berikut ini beberapa tautan yang menurut saya berguna saat menyelidiki masalah tersebut:

Mudah-mudahan ini berguna bagi seseorang, sayangnya saya tidak bisa mengetahuinya sendiri.

Semua 5 komentar

GLFW belum mendukung transfer data papan klip tambahan.

Catatan untuk diri sendiri: UTF8_STRING

Saya telah memeriksanya sendiri tetapi saya belum dapat menyelesaikan implementasinya. Semoga beberapa pengalaman dalam mencoba menerapkannya dapat bermanfaat bagi orang lain yang mencoba melakukan hal yang sama. Singkatnya, inilah yang terjadi dan apa yang diharapkan ICCCM untuk kita lakukan untuk menangani atom INCR ini:

Di bawah ini, ketika menelepon _glfwPlatformGetClipboardString adalah saat X11 menjadi sangat sedih:

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

Dan alasannya adalah karena kita meminta event.xselection.target tipe UTF8_STRING , yang akan bekerja hampir sepanjang waktu, kecuali jika kita telah melewati ukuran transfer batch tunggal maksimum yang diizinkan pemilik pilihan (262146 byte dalam kasus ini). Pemilik pilihan akan memberi kita actualType dari INCR yang tidak sama dengan jenis yang diminta UTF8_STRING . Pemilik ingin mengirim data secara bertahap , yaitu dalam potongan beberapa XGetWindowProperty s berisi UTF8_STRING s.

Untuk mengatasi ini kita perlu mengikuti rekomendasi ICCCM "INCR Properties". Tapi secara singkat:

  1. Dapatkan pegangan ke INCR -atom dengan XInternAtom misalnya dengan nama INCR_STRING .
  2. Lihat di _glfwGetWindowPropertyX11 jika kita menerima actualType dari INCR_STRING , jika demikian:
    a) Ambil INCR_STRING menggunakan XGetWindowProperty , ini berisi batas transfer yang lebih rendah.
    b) Hapus properti INCR_STRING ini agar pemiliknya dapat mulai mengirimkan barang bagus kepada kami.
    c) Tunggu acara PropertyNotify , menandakan kedatangan sebagian data lengkap.
    d) Ambil data potongan menggunakan XGetWindowProperty , tambahkan ke buffer.
    e) Hapus properti, memberi isyarat kepada pemilik untuk mengirim potongan tambahan.
    f) Periksa apakah ukuran data nol, jika tidak loop kembali ke c.
    g) Transfer selesai, Anda sekarang memiliki seluruh data!

Jika Anda tertarik, berikut adalah inti implementasi yang sudah setengah selesai dari pilihan inkremental yang saya tulis.
Berikut ini beberapa tautan yang menurut saya berguna saat menyelidiki masalah tersebut:

Mudah-mudahan ini berguna bagi seseorang, sayangnya saya tidak bisa mengetahuinya sendiri.

Terima kasih, itu deskripsi yang sangat bagus! Agak tidak masuk akal apa yang perlu dilakukan klien untuk mencapai hal-hal yang merupakan beberapa pemanggilan fungsi di platform lain.

Saya mulai menerapkan INCR dua hari lalu. Saya telah membaca bekerja, serta konversi dari STRING / Latin-1, tetapi sempat putus asa sejenak ketika saya menyadari bahwa INCR, MULTIPLE dan STRING dapat digabungkan untuk menulis. Beberapa restrukturisasi dilakukan agar dapat dilaksanakan dengan bersih.

Mendorongnya sekarang ke cabang selection-fixes jika ada yang ingin mengintip.

Saya perlu fokus pada ulasan permintaan tarik untuk sementara waktu. Saya telah menyimpan banyak kode bagus menunggu waktu yang sangat lama. Jika ada yang ingin terus mengerjakan ini sementara, berdasarkan kode di atas atau tidak, silakan lakukan.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat