1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-21 06:55:39 +00:00

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.
This commit is contained in:
Po Lu 2022-06-16 14:33:30 +08:00
parent 55e9d729ca
commit e5dbe60e3c

View File

@ -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