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

Add user options to move point and scroll window during DND

* doc/emacs/frames.texi (Drag and Drop):
* etc/NEWS: Document new options 'dnd-scroll-margin' and
'dnd-indicate-insertion-point'.
* lisp/dnd.el (dnd-protocol-alist):
(dnd-open-remote-file-function):
(dnd-open-file-other-window): Add right group to defcustoms.
(dnd-scroll-margin, dnd-indicate-insertion-point): New user
options.
(dnd-handle-movement): New function.
* lisp/x-dnd.el (x-dnd-handle-xdnd):
(x-dnd-handle-motif): Call `dnd-handle-movement' when
appropriate.
This commit is contained in:
Po Lu 2022-04-03 09:14:24 +08:00
parent 4afd34edd3
commit 1694f82e5f
4 changed files with 74 additions and 7 deletions

View File

@ -1196,6 +1196,18 @@ the variable @code{dnd-open-file-other-window}.
The XDND and Motif drag and drop protocols, and the old KDE 1.x
protocol, are currently supported.
@vindex dnd-indicate-insertion-point
@vindex dnd-scroll-margin
It can be difficult to scroll a window or determine where dropped
text will be inserted while dragging text onto an Emacs window.
Setting the option @var{dnd-indicate-insertion-point} to a
non-@code{nil} value makes point move to the location any dropped text
will be inserted when the mouse moves in a window during drag, and
setting @code{dnd-scroll-margin} to an integer value causes a window
to be scrolled if the mouse moves within that many lines of the top
or bottom of the window during drag.
@vindex mouse-drag-and-drop-region
Emacs can also optionally drag the region with the mouse into
another portion of this or another buffer. To enable that, customize

View File

@ -195,6 +195,11 @@ to another program.
If non-nil, this option allows scrolling a window while dragging text
around without a scroll wheel.
+++
** New user options 'dnd-indicate-insertion-point' and 'dnd-scroll-margin'.
These options allow adjusting point and scrolling a window when
dragging items from another program.
+++
** New function 'command-query'.
This function makes its argument command prompt the user for

View File

@ -42,8 +42,7 @@
`((,(purecopy "^file:///") . dnd-open-local-file) ; XDND format.
(,(purecopy "^file://") . dnd-open-file) ; URL with host
(,(purecopy "^file:") . dnd-open-local-file) ; Old KDE, Motif, Sun
(,(purecopy "^\\(https?\\|ftp\\|file\\|nfs\\)://") . dnd-open-file)
)
(,(purecopy "^\\(https?\\|ftp\\|file\\|nfs\\)://") . dnd-open-file))
"The functions to call for different protocols when a drop is made.
This variable is used by `dnd-handle-one-url' and `dnd-handle-file-name'.
@ -57,7 +56,8 @@ If no match is found, the URL is inserted as text by calling `dnd-insert-text'.
The function shall return the action done (move, copy, link or private)
if some action was made, or nil if the URL is ignored."
:version "22.1"
:type '(repeat (cons (regexp) (function))))
:type '(repeat (cons (regexp) (function)))
:group 'dnd)
(defcustom dnd-open-remote-file-function
@ -73,17 +73,66 @@ Predefined functions are `dnd-open-local-file' and `dnd-open-remote-url'.
is the default on MS-Windows. `dnd-open-remote-url' uses `url-handler-mode'
and is the default except for MS-Windows."
:version "22.1"
:type 'function)
:type 'function
:group 'dnd)
(defcustom dnd-open-file-other-window nil
"If non-nil, always use `find-file-other-window' to open dropped files."
:version "22.1"
:type 'boolean)
:type 'boolean
:group 'dnd)
(defcustom dnd-scroll-margin nil
"The scroll margin inside a window underneath the cursor during drag-and-drop.
If the mouse moves this many lines close to the top or bottom of
a window while dragging text, then that window will be scrolled
down and up respectively."
:type '(choice (const :tag "Don't scroll during mouse movement")
(integer :tag "This many lines from window top or bottom"))
:version "29.1"
:group 'dnd)
(defcustom dnd-indicate-insertion-point nil
"Whether or not point should follow the position of the mouse.
If non-nil, the point of the window underneath the mouse will be
adjusted to reflect where any text will be inserted upon drop
when the mouse moves while receiving a drop from another
program."
:type 'boolean
:version "29.1"
:group 'dnd)
;; Functions
(defun dnd-handle-movement (posn)
"Handle mouse movement to POSN when receiving a drop from another program."
(when dnd-scroll-margin
(ignore-errors
(let* ((row (cdr (posn-col-row posn)))
(window (when (windowp (posn-window posn))
(posn-window posn)))
(text-height (window-text-height window))
;; Make sure it's possible to scroll both up
;; and down if the margin is too large for the
;; window.
(margin (min (/ text-height 3) dnd-scroll-margin)))
;; At 2 lines, the window becomes too small for any
;; meaningful scrolling.
(unless (<= text-height 2)
(cond
;; Inside the bottom scroll margin, scroll up.
((> row (- text-height margin))
(with-selected-window window
(scroll-up 1)))
;; Inside the top scroll margin, scroll down.
((< row margin)
(with-selected-window window
(scroll-down 1))))))))
(when dnd-indicate-insertion-point
(ignore-errors
(goto-char (posn-point posn)))))
(defun dnd-handle-one-url (window action url)
"Handle one dropped url by calling the appropriate handler.
The handler is first located by looking at `dnd-protocol-alist'.

View File

@ -499,7 +499,7 @@ FORMAT is 32 (not used). MESSAGE is the data part of an XClientMessageEvent."
)))
(x-send-client-message
frame dnd-source frame "XdndStatus" 32 list-to-send)
))
(dnd-handle-movement (event-start event))))
((equal "XdndLeave" message)
(x-dnd-forget-drop window))
@ -676,7 +676,8 @@ FORMAT is 32 (not used). MESSAGE is the data part of an XClientMessageEvent."
frame
"_MOTIF_DRAG_AND_DROP_MESSAGE"
8
reply)))
reply)
(dnd-handle-movement (event-start event))))
((eq message-type 'XmOPERATION_CHANGED)
(let* ((state (x-dnd-get-state-for-frame frame))