X11: update XDND protocol from version 4 to 5 (#988)

Some applications insist on sending XDND protocol version 5 and
rejected (ignored) FLTK as DND receiver because we allowed only
protocol version 4. Known apps: Google Chrome and Chromium.

This commit enables XDND protocol version 5 in FLTK programs as
DND receiver.
This commit is contained in:
Albrecht Schlosser
2024-06-15 11:33:44 +02:00
parent 7d98413d46
commit 3cc5c090f9
+18 -13
View File
@@ -580,7 +580,6 @@ void open_display_i(Display* d) {
fl_XdndStatus = XInternAtom(d, "XdndStatus", 0); fl_XdndStatus = XInternAtom(d, "XdndStatus", 0);
fl_XdndActionCopy = XInternAtom(d, "XdndActionCopy", 0); fl_XdndActionCopy = XInternAtom(d, "XdndActionCopy", 0);
fl_XdndFinished = XInternAtom(d, "XdndFinished", 0); fl_XdndFinished = XInternAtom(d, "XdndFinished", 0);
fl_XdndEnter = XInternAtom(d, "XdndEnter", 0);
fl_XdndURIList = XInternAtom(d, "text/uri-list", 0); fl_XdndURIList = XInternAtom(d, "text/uri-list", 0);
fl_Xatextplainutf = XInternAtom(d, "text/plain;charset=UTF-8",0); fl_Xatextplainutf = XInternAtom(d, "text/plain;charset=UTF-8",0);
fl_Xatextplainutf2 = XInternAtom(d, "text/plain;charset=utf-8",0); // Firefox/Thunderbird needs this - See STR#2930 fl_Xatextplainutf2 = XInternAtom(d, "text/plain;charset=utf-8",0); // Firefox/Thunderbird needs this - See STR#2930
@@ -1471,13 +1470,19 @@ int fl_handle(const XEvent& thisevent)
} }
Fl::e_number = old_event; Fl::e_number = old_event;
// Detect if this paste is due to Xdnd by the property name (I use // Detect if this paste is due to Xdnd by the property name (I use
// XA_SECONDARY for that) and send an XdndFinished message. It is not // XA_SECONDARY for that) and send an XdndFinished message.
// clear if this has to be delayed until now or if it can be done // This has to be delayed until now rather than sending it immediately
// immediately after calling XConvertSelection. // after calling XConvertSelection because we need to send the success
if (fl_xevent->xselection.property == XA_SECONDARY && // status (retval) and the performed action to the sender - at least
fl_dnd_source_window) { // since XDND protocol version 5 (see docs).
fl_sendClientMessage(fl_dnd_source_window, fl_XdndFinished, // [FIXME: is the condition below really correct?]
fl_xevent->xselection.requestor);
if (fl_xevent->xselection.property == XA_SECONDARY && fl_dnd_source_window) {
fl_sendClientMessage(fl_dnd_source_window, // send to window
fl_XdndFinished, // XdndFinished message
fl_xevent->xselection.requestor, // data.l[0] target window
retval ? 1 : 0, // data.l[1] Bit 0: 1 = success
retval ? fl_dnd_action : None); // data.l[2] action performed
fl_dnd_source_window = 0; // don't send a second time fl_dnd_source_window = 0; // don't send a second time
} }
return 1; return 1;
@@ -1591,22 +1596,22 @@ int fl_handle(const XEvent& thisevent)
- data.l[0] contains the XID of the source window. - data.l[0] contains the XID of the source window.
- data.l[1]: - data.l[1]:
Bit 0 is set if the source supports more than three data types. Bit 0 is set if the source supports more than three data types.
The high byte contains the protocol version to use (minimum of the source's and The high byte contains the protocol version to use (minimum of the source's and
target's highest supported versions). The rest of the bits are reserved for future use. target's highest supported versions). The rest of the bits are reserved for future use.
- data.l[2,3,4] contain the first three types that the source supports. Unused slots are set - data.l[2,3,4] contain the first three types that the source supports. Unused slots are set
to None. The ordering is arbitrary. to None. The ordering is arbitrary.
If the Source supports more than three data types, bit 0 of data.l[1] is set. This tells the If the Source supports more than three data types, bit 0 of data.l[1] is set. This tells the
Target to check the property XdndTypeList on the Source window for the list of available Target to check the property XdndTypeList on the Source window for the list of available
types. This property should contain all the available types. types. This property should contain all the available types.
BUT wayland gnome apps (e.g., gnome-text-editor) set bit 0 of data.l[1] BUT wayland gnome apps (e.g., gnome-text-editor) set bit 0 of data.l[1]
even though their source supports 2 data types (UTF8 text + a gnome-specific type) even though their source supports 2 data types (UTF8 text + a gnome-specific type)
and put None (==0) in each of data.l[2,3,4]. and put None (==0) in each of data.l[2,3,4].
The same gnome apps run in X11 mode (GDK_BACKEND=x11) clear bit 0 of data.l[1] The same gnome apps run in X11 mode (GDK_BACKEND=x11) clear bit 0 of data.l[1]
and support only UTF8 text announced in data.l[2]. and support only UTF8 text announced in data.l[2].
FLTK wayland apps set bit 0 of data.l[1] and support only UTF8 text. FLTK wayland apps set bit 0 of data.l[1] and support only UTF8 text.
Overall, the correct procedure is Overall, the correct procedure is
if (bit 0 of data.l[1] is set) { if (bit 0 of data.l[1] is set) {
get the XdndTypeList property get the XdndTypeList property
@@ -2686,7 +2691,7 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
} }
// Make it receptive to DnD: // Make it receptive to DnD:
long version = 4; Atom version = 5; // max. XDND protocol version we understand
XChangeProperty(fl_display, xp->xid, fl_XdndAware, XChangeProperty(fl_display, xp->xid, fl_XdndAware,
XA_ATOM, sizeof(int)*8, 0, (unsigned char*)&version, 1); XA_ATOM, sizeof(int)*8, 0, (unsigned char*)&version, 1);