From e5dbe60e3cfbdfd3a3e1a045e8557a92cb146af0 Mon Sep 17 00:00:00 2001 From: Po Lu <luangruo@yahoo.com> Date: Thu, 16 Jun 2022 14:33:30 +0800 Subject: [PATCH] Improve handling of fallback drop protocols * lisp/x-dnd.el (x-dnd-use-offix-drop): New value `files', which means to only drop files using the OffiX protocol. Make it the default. (x-dnd-handle-old-kde): Handle other data types correctly. (x-dnd-offix-old-kde-to-name): New variable. (x-dnd-offix-id-to-name): Fix typo in doc string. (x-dnd-handle-unsupported-drop): Implement new value. --- lisp/x-dnd.el | 55 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el index aa4eb8849f9..3b15eb432e3 100644 --- a/lisp/x-dnd.el +++ b/lisp/x-dnd.el @@ -24,8 +24,9 @@ ;;; Commentary: -;; This file provides the drop part only. Currently supported protocols -;; are XDND, Motif and the old KDE 1.x protocol. +;; This file provides the receiving side of the XDND and Motif +;; protocols, and both the receiving and initiating ends of the old +;; KDE (OffiX) and new OffiX protocols. ;;; Code: @@ -103,14 +104,20 @@ The types are chosen in the order they appear in the list." :type '(repeat string) :group 'x) -(defcustom x-dnd-use-offix-drop nil +(defcustom x-dnd-use-offix-drop 'files "If non-nil, use the OffiX protocol to drop files and text. This allows dropping (via `dired-mouse-drag-files' or `mouse-drag-and-drop-region-cross-program') on some old Java applets and old KDE programs. Turning this off allows dropping -only text on some other programs such as xterm and urxvt." +only text on some other programs such as xterm and urxvt. + +If the symbol `files', use the OffiX protocol when dropping +files, and the fallback drop method (which is used with programs +like xterm) for text." :version "29.1" - :type 'boolean + :type '(choice (const "Don't use the OffiX protocol for drag-and-drop") + (const "Only use the OffiX protocol to drop files") + (const "Use the OffiX protocol for both files and text")) :group 'x) ;; Internal variables @@ -402,21 +409,43 @@ Currently XDND, Motif and old KDE 1.x protocols are recognized." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Old KDE protocol. Only dropping of files. +;;; Old KDE protocol. (declare-function x-window-property "xfns.c" (prop &optional frame type source delete-p vector-ret-p)) -(defun x-dnd-handle-old-kde (_event frame window _message _format data) - "Open the files in a KDE 1.x drop." +(defvar x-dnd-offix-old-kde-to-name '((-1 . DndTypeInvalid) + (0 . DndTypeUnknown) + (1 . DndTypeRawData) + (2 . DndTypeFile) + (3 . DndTypeFiles) + (4 . DndTypeText) + (5 . DndTypeDir) + (6 . DndTypeLink) + (7 . DndTypeExe) + (8 . DndTypeUrl)) + "Alist of old KDE data types to their names.") + +(defun x-dnd-handle-old-kde (event frame window _message _format data) + "Handle an old KDE (OffiX) drop. +EVENT, FRAME, WINDOW and DATA mean the same thing they do in +`x-dnd-handle-offix.'" (let ((proto (aref data 4))) ;; If PROTO > 0, this is an old KDE drop emulated by a program ;; supporting a newer version of the OffiX protocol, so we should ;; wait for the corresponding modern event instead. (when (zerop proto) - (let ((values (x-window-property "DndSelection" frame nil 0 t))) - (x-dnd-handle-uri-list window 'private - (replace-regexp-in-string "\0$" "" values)))))) + (let ((type (cdr (assq (aref data 0) x-dnd-offix-old-kde-to-name))) + (data (x-window-property "DndSelection" frame nil 0 t))) + ;; First save state. + (x-dnd-save-state window nil nil (vector type) nil) + ;; Now call the test function to decide what action to perform. + (x-dnd-maybe-call-test-function window 'private) + (unwind-protect + (x-dnd-drop-data event frame window data + (symbol-name type)) + (x-dnd-forget-drop window)))))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; New OffiX protocol. @@ -432,7 +461,7 @@ Currently XDND, Motif and old KDE 1.x protocols are recognized." (8 . DndTypeUrl) (9 . DndTypeMime) (10 . DndTypePixmap)) - "Alist of OffiX protocol types to their names.") + "Alist of OffiX data types to their names.") (defun x-dnd-handle-offix-file (window action string) "Convert OffiX file name to a regular file name. @@ -1031,6 +1060,8 @@ WINDOW-ID is the X window the drop should happen to." (not (and (or (eq action 'XdndActionCopy) (eq action 'XdndActionMove)) (not (and x-dnd-use-offix-drop + (or (not (eq x-dnd-use-offix-drop 'files)) + (member "FILE_NAME" targets)) (x-dnd-do-offix-drop targets x y frame window-id))) (or -- 2.39.5