DnD of filenames: make Wayland behave as Windows and macOS

and also add more detailed documentation of platform-specific behaviors.
This commit is contained in:
ManoloFLTK 2023-03-06 11:08:04 +01:00
parent a52811567e
commit f89a9f9efc
3 changed files with 33 additions and 15 deletions

View File

@ -268,16 +268,7 @@ selection indication. Most modern programs ignore this.
FLTK supports drag and drop of text and files from any
application on the desktop to an FLTK widget. Text is transferred
using UTF-8 encoding. Files are received as a list of full path
and file names, separated by newline.
On some X11 platforms and with Wayland, files are received as a URL-encoded UTF-8 string,
that is, non-ASCII bytes (and a few others such as space and %) are
replaced by the 3 bytes "%XY" where XY are the byte's hexadecimal value.
The \ref fl_decode_uri() function can be used to transform in-place
the received string into a proper UTF-8 string. On these platforms,
strings corresponding to dropped files are further prepended
by <tt>file://</tt> (or other prefixes such as <tt>computer://</tt>).
using UTF-8 encoding.
See Fl::dnd() for drag and drop from an FLTK widget.
@ -290,6 +281,20 @@ depends on the protocol used on each platform.
\p FL_DND_* events cannot be used in widgets derived
from Fl_Group or Fl_Window.
\subsection events_fl_dnd_files Dropped filenames
Files are received as a list of full path and file names.
- On some X11 platforms, files are received as a URL-encoded UTF-8 string,
that is, non-ASCII bytes (and a few others such as space and %) are
replaced by the 3 bytes "%XY" where XY are the byte's hexadecimal value.
The \ref fl_decode_uri() function can be used to transform in-place
the received string into a proper UTF-8 string. On these platforms,
strings corresponding to dropped files are further prepended
by <tt>file://</tt> (or other prefixes such as <tt>computer://</tt>).
- Other X11 situations put all dropped filenames in a single line, separated by
spaces.
- On non-X11 platforms, including Wayland, files dropped are received one
pathname per line, with no <tt>'\\n'</tt> after the last pathname.
\subsection events_fl_dnd_enter FL_DND_ENTER
The mouse has been moved to point at this widget. A widget that is

View File

@ -763,8 +763,7 @@ FLTK can copy or paste plain UTF-8 text or image data to/from the clipboard. Ima
clipboard as \c image/bmp mime type. Images in \c image/bmp or \c image/png mime types from the
clipboard can be pasted to FLTK apps.
Files dropped are received one per line with URL-encoded UTF-8 names prepended by
<tt>file://</tt> (see \ref events_dnd).
Files dropped are received one pathname per line, with no '\n' after the last pathname.
\section wayland-egl EGL as support for OpenGL

View File

@ -328,6 +328,7 @@ static void data_device_handle_selection(void *data, struct wl_data_device *data
// which is enlarged if necessary.
static void get_clipboard_or_dragged_text(struct wl_data_offer *offer) {
int fds[2];
char *from;
if (pipe(fds)) return;
wl_data_offer_receive(offer, fl_selection_offer_type, fds[1]);
close(fds[1]);
@ -341,7 +342,7 @@ static void get_clipboard_or_dragged_text(struct wl_data_offer *offer) {
close(fds[0]);
fl_selection_length[1] = to - fl_selection_buffer[1];
fl_selection_buffer[1][ fl_selection_length[1] ] = 0;
return;
goto way_out;
}
n = Fl_Screen_Driver::convert_crlf(to, n);
to += n;
@ -360,7 +361,7 @@ static void get_clipboard_or_dragged_text(struct wl_data_offer *offer) {
}
//fprintf(stderr, "get_clipboard_or_dragged_text: size=%ld\n", rest);
// read full clipboard data
if (pipe(fds)) return;
if (pipe(fds)) goto way_out;
wl_data_offer_receive(offer, fl_selection_offer_type, fds[1]);
close(fds[1]);
wl_display_flush(Fl_Wayland_Screen_Driver::wl_display);
@ -369,7 +370,7 @@ static void get_clipboard_or_dragged_text(struct wl_data_offer *offer) {
fl_selection_buffer[1] = new char[rest+1000+1];
fl_selection_buffer_length[1] = rest+1000;
}
char *from = fl_selection_buffer[1];
from = fl_selection_buffer[1];
while (true) {
ssize_t n = read(fds[0], from, rest);
if (n <= 0) {
@ -381,6 +382,19 @@ static void get_clipboard_or_dragged_text(struct wl_data_offer *offer) {
}
fl_selection_length[1] = from - fl_selection_buffer[1];
fl_selection_buffer[1][fl_selection_length[1]] = 0;
way_out:
if (strcmp(fl_selection_offer_type, "text/uri-list") == 0) {
fl_decode_uri(fl_selection_buffer[1]); // decode encoded bytes
char *p = fl_selection_buffer[1];
while (*p) { // remove prefixes
if (strncmp(p, "file://", 7) == 0) {
memmove(p, p+7, strlen(p+7)+1);
}
p = strchr(p, '\n');
if (!p) break;
if (*++p == 0) *(p-1) = 0; // remove last '\n'
}
}
Fl::e_clipboard_type = Fl::clipboard_plain_text;
}