From ebd980bc7e45acaa65adae91400903384fd6dfb2 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Thu, 30 Jun 2022 16:41:58 +0800 Subject: [PATCH] Disable unrelated drag-and-drop protocols during XDS drop * doc/lispref/frames.texi (Drag and Drop): Document variables used to control drag-and-drop protocols. * lisp/x-dnd.el (x-dnd-do-direct-save): Disable irrelevant DND protocols. * src/xterm.c (x_dnd_get_target_window_1): (x_dnd_get_target_window): (handle_one_xevent): Respect new variable. (syms_of_xterm): New variable `x-dnd-disable-motif-protocol'. --- doc/lispref/frames.texi | 22 ++++++++++++++++++++++ lisp/x-dnd.el | 6 ++++++ src/xterm.c | 16 ++++++++++++++-- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 860258a9648..720753edad6 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -4258,6 +4258,28 @@ chosen by the target. For example, callers should delete the buffer text that was dragged if this function returns @code{XdndActionMove}. @end defun +@cindex drag and drop protocols, X + + On X Windows, several different drag-and-drop protocols are +supported by @code{x-begin-drag}. When dragging content that is known +to not be supported by a specific drag-and-drop protocol, it might be +desirable to turn that protocol off, by changing the values of the +following variables: + +@defvar x-dnd-disable-motif-protocol +When this is non-@code{nil}, the Motif drag and drop protocols are +disabled, and dropping onto programs that only understand them will +not work. +@end defvar + +@defvar x-dnd-use-offix-drop +When this is @code{nil}, the OffiX (old KDE) drag and drop protocol is +disabled. When this is the symbol @code{files}, the OffiX protocol +will only be used if @code{"FILE_NAME"} is one of the targets given to +@code{x-begin-drag}. Any other value means to use the OffiX protocol +to drop all supported content. +@end defvar + @node Color Names @section Color Names diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el index 762d42175e7..c3d56f327dd 100644 --- a/lisp/x-dnd.el +++ b/lisp/x-dnd.el @@ -1143,6 +1143,8 @@ ACTION is the action given to `x-begin-drag'." (defvar x-dnd-xds-performed nil "Whether or not the drop target made a request for `XdndDirectSave0'.") +(defvar x-dnd-disable-motif-protocol) + (defun x-dnd-handle-direct-save (_selection _type _value) "Handle a selection request for `XdndDirectSave'." (setq x-dnd-xds-performed t) @@ -1198,6 +1200,10 @@ was taken, or the direct save failed." (x-dnd-xds-current-file nil) (x-dnd-xds-source-frame frame) (x-dnd-xds-performed nil) + ;; The XDS protocol is built on top of XDND, and cannot + ;; possibly work with Motif or OffiX programs. + (x-dnd-disable-motif-protocol t) + (x-dnd-use-offix-drop nil) (prop-deleted nil) encoded-name) (unwind-protect diff --git a/src/xterm.c b/src/xterm.c index 9d260ded831..500443ebaa1 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -3542,6 +3542,7 @@ x_dnd_get_target_window_1 (struct x_display_info *dpyinfo, root_x and root_y are. */ *motif_out = XM_DRAG_STYLE_NONE; + for (tem = x_dnd_toplevels; tem; tem = tem->next) { if (!tem->mapped_p || tem->wm_state != NormalState) @@ -3616,7 +3617,9 @@ x_dnd_get_target_window_1 (struct x_display_info *dpyinfo, if (chosen) { - *motif_out = chosen->xm_protocol_style; + *motif_out = (x_dnd_disable_motif_protocol + ? XM_DRAG_STYLE_NONE + : chosen->xm_protocol_style); return chosen->window; } else @@ -4147,7 +4150,8 @@ x_dnd_get_target_window (struct x_display_info *dpyinfo, || proto != -1 || motif != XM_DRAG_STYLE_NONE) { *proto_out = proto; - *motif_out = motif; + *motif_out = (x_dnd_disable_motif_protocol + ? XM_DRAG_STYLE_NONE : motif); *toplevel_out = child_return; x_uncatch_errors (); @@ -18925,6 +18929,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (!xm_read_drag_receiver_info (dpyinfo, x_dnd_last_seen_window, &drag_receiver_info) + && !x_dnd_disable_motif_protocol && drag_receiver_info.protocol_style != XM_DRAG_STYLE_NONE && (x_dnd_allow_current_frame || x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))) @@ -20330,6 +20335,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (!xm_read_drag_receiver_info (dpyinfo, x_dnd_last_seen_window, &drag_receiver_info) + && !x_dnd_disable_motif_protocol && drag_receiver_info.protocol_style != XM_DRAG_STYLE_NONE && (x_dnd_allow_current_frame || x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))) @@ -28063,4 +28069,10 @@ This lets you inspect the contents of `XdndSelection' after a drag-and-drop operation, which is useful when writing tests for drag-and-drop code. */); x_dnd_preserve_selection_data = false; + + DEFVAR_BOOL ("x-dnd-disable-motif-protocol", x_dnd_disable_motif_protocol, + doc: /* Disable the Motif drag-and-drop protocols. +When non-nil, `x-begin-drag' will not drop onto any window that only +supports the Motif drag-and-drop protocols. */); + x_dnd_disable_motif_protocol = false; }