From: Cecilio Pardo <cpardo@imayhem.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 3468@debbugs.gnu.org
Subject: bug#3468: drag and drop text
Date: Wed, 23 Oct 2024 19:16:51 +0200 [thread overview]
Message-ID: <3adf9bbb-5c6a-4e6d-83f5-c1d2c6a059d6@imayhem.com> (raw)
In-Reply-To: <86o73uspkk.fsf@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 344 bytes --]
On 08/10/2024 15:15, Eli Zaretskii wrote:
> I'm not closing the bug, because you said you want to add support for
> the dnd-* variables.
This add support for dnd-scroll-margin and dnd-indicate-insertion-point
on MS-Windows.
BTW, I think this variables should be enabled by default. I'd say that
is the expected behaviour for drag and drop.
[-- Attachment #2: 0001-Improve-drag-and-drop-on-MS-Windows-bug-3468.patch --]
[-- Type: text/plain, Size: 6973 bytes --]
From 5c0f2a1b40931824df75a620d2494f2031bf0f83 Mon Sep 17 00:00:00 2001
From: Cecilio Pardo <cpardo@imayhem.com>
Date: Wed, 23 Oct 2024 14:41:24 +0200
Subject: [PATCH] Improve drag and drop on MS-Windows (bug#3468)
Add support for dnd-scroll-margin and dnd-indicate-insertion-point by
calling dnd-handle-movement when dragging the mouse.
* lisp/term/w32-win.el (w32-drag-n-drop): Call dnd-handle-movement
when applicable.
* src/w32fns.c (w32_handle_drag_movement): New function, sends a
WM_EMACS_DRAGOVER message.
(w32_drop_target_DragEnter): Call w32_handle_drag_movement.
(w32_drop_target_DragOver): Call w32_handle_drag_movement.
* src/w32term.c: (w32_read_socket): Handle WM_EMACS_DRAGOVER,
sending an drag-n-drop event.
* src/w32term.h (): Define new WM_EMACS_DRAGOVER message.
---
lisp/term/w32-win.el | 54 ++++++++++++++++++++++++--------------------
src/w32fns.c | 17 +++++++++++++-
src/w32term.c | 18 +++++++++++++++
src/w32term.h | 5 ++--
4 files changed, 66 insertions(+), 28 deletions(-)
diff --git a/lisp/term/w32-win.el b/lisp/term/w32-win.el
index 541fef2ced3..b47b5f21f05 100644
--- a/lisp/term/w32-win.el
+++ b/lisp/term/w32-win.el
@@ -137,35 +137,39 @@ w32-drag-n-drop
If EVENT is for text, insert that text at point into the buffer
shown in the window that is the target of the drop; if that buffer is
read-only, add the dropped text to kill-ring.
+If EVENT payload is nil, then this is a drag event.
If the optional argument NEW-FRAME is non-nil, perform the
drag-n-drop action in a newly-created frame using its selected-window
and that window's buffer."
(interactive "e")
- (save-excursion
- ;; Make sure the drop target has positive co-ords
- ;; before setting the selected frame - otherwise it
- ;; won't work. <skx@tardis.ed.ac.uk>
- (let* ((window (posn-window (event-start event)))
- (coords (posn-x-y (event-start event)))
- (arg (car (cdr (cdr event))))
- (x (car coords))
- (y (cdr coords)))
- (if (and (> x 0) (> y 0))
- (set-frame-selected-window nil window))
-
- (when new-frame
- (select-frame (make-frame)))
- (raise-frame)
- (setq window (selected-window))
-
- ;; arg (the payload of the event) is a string when the drop is
- ;; text, and a list of strings when the drop is one or more files.
- (if (stringp arg)
- (dnd-insert-text window 'copy arg)
- (dnd-handle-multiple-urls
- window
- (mapcar #'w32-dropped-file-to-url arg)
- 'private)))))
+ ;; Make sure the drop target has positive co-ords
+ ;; before setting the selected frame - otherwise it
+ ;; won't work. <skx@tardis.ed.ac.uk>
+ (let* ((window (posn-window (event-start event)))
+ (coords (posn-x-y (event-start event)))
+ (arg (car (cdr (cdr event))))
+ (x (car coords))
+ (y (cdr coords)))
+
+ (if (and (> x 0) (> y 0) (window-live-p window))
+ (set-frame-selected-window nil window))
+ ;; Don't create new frame if we are just dragging
+ (and arg new-frame
+ (select-frame (make-frame)))
+ (raise-frame)
+ (setq window (selected-window))
+
+ ;; arg (the payload of the event) is a string when the drop is
+ ;; text, and a list of strings when the drop is one or more files.
+ ;; It is nil if the event is a drag event.
+ (if arg
+ (if (stringp arg)
+ (dnd-insert-text window 'copy arg)
+ (dnd-handle-multiple-urls
+ window
+ (mapcar #'w32-dropped-file-to-url arg)
+ 'private))
+ (dnd-handle-movement (event-start event)))))
(defun w32-drag-n-drop-other-frame (event)
"Edit the files listed in the drag-n-drop EVENT, in other frames.
diff --git a/src/w32fns.c b/src/w32fns.c
index 3ee13dcbbdd..eb42d3b61b2 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -2505,7 +2505,6 @@ process_dropfiles (DROPFILES *files)
return lisp_files;
}
-
/* This function can be called ONLY between calls to
block_input/unblock_input. It is used in w32_read_socket. */
Lisp_Object
@@ -2572,6 +2571,19 @@ w32_drop_target_Release (IDropTarget *This)
return 0;
}
+static void
+w32_handle_drag_movement (IDropTarget *This, POINTL pt)
+{
+ struct w32_drop_target *target = (struct w32_drop_target *)This;
+
+ W32Msg msg = {0};
+ msg.dwModifiers = w32_get_modifiers ();
+ msg.msg.time = GetMessageTime ();
+ msg.msg.pt.x = pt.x;
+ msg.msg.pt.y = pt.y;
+ my_post_msg (&msg, target->hwnd, WM_EMACS_DRAGOVER, 0, 0 );
+}
+
static HRESULT STDMETHODCALLTYPE
w32_drop_target_DragEnter (IDropTarget *This, IDataObject *pDataObj,
DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
@@ -2581,6 +2593,7 @@ w32_drop_target_DragEnter (IDropTarget *This, IDataObject *pDataObj,
happen on drop. We send COPY because our use cases don't modify
or link to the original data. */
*pdwEffect = DROPEFFECT_COPY;
+ w32_handle_drag_movement (This, pt);
return S_OK;
}
@@ -2590,6 +2603,7 @@ w32_drop_target_DragOver (IDropTarget *This, DWORD grfKeyState, POINTL pt,
{
/* See comment in w32_drop_target_DragEnter. */
*pdwEffect = DROPEFFECT_COPY;
+ w32_handle_drag_movement (This, pt);
return S_OK;
}
@@ -3607,6 +3621,7 @@ #define M(msg) { msg, # msg }
M (WM_EMACS_PAINT),
M (WM_EMACS_IME_STATUS),
M (WM_CHAR),
+ M (WM_EMACS_DRAGOVER),
M (WM_EMACS_DROP),
#undef M
{ 0, 0 }
diff --git a/src/w32term.c b/src/w32term.c
index 3a627308137..88622700386 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -5629,6 +5629,24 @@ w32_read_socket (struct terminal *terminal,
}
break;
+ case WM_EMACS_DRAGOVER:
+ {
+ f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
+ if (!f)
+ break;
+ XSETFRAME (inev.frame_or_window, f);
+ inev.kind = DRAG_N_DROP_EVENT;
+ inev.code = 0;
+ inev.timestamp = msg.msg.time;
+ inev.modifiers = msg.dwModifiers;
+ ScreenToClient (msg.msg.hwnd, &msg.msg.pt);
+ XSETINT (inev.x, msg.msg.pt.x);
+ XSETINT (inev.y, msg.msg.pt.y);
+ /* This is a drag movement. */
+ inev.arg = Qnil;
+ break;
+ }
+
case WM_HSCROLL:
{
struct scroll_bar *bar =
diff --git a/src/w32term.h b/src/w32term.h
index 39e2262e2a8..cad9fcf8cb1 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -711,8 +711,9 @@ #define WM_EMACS_BRINGTOTOP (WM_EMACS_START + 23)
#define WM_EMACS_INPUT_READY (WM_EMACS_START + 24)
#define WM_EMACS_FILENOTIFY (WM_EMACS_START + 25)
#define WM_EMACS_IME_STATUS (WM_EMACS_START + 26)
-#define WM_EMACS_DROP (WM_EMACS_START + 27)
-#define WM_EMACS_END (WM_EMACS_START + 28)
+#define WM_EMACS_DRAGOVER (WM_EMACS_START + 27)
+#define WM_EMACS_DROP (WM_EMACS_START + 28)
+#define WM_EMACS_END (WM_EMACS_START + 29)
#define WND_FONTWIDTH_INDEX (0)
#define WND_LINEHEIGHT_INDEX (4)
--
2.35.1.windows.2
next prev parent reply other threads:[~2024-10-23 17:16 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-06-04 7:03 bug#3468: drag and drop text Erdkern Erdkern
2019-09-30 15:29 ` Lars Ingebrigtsen
2019-09-30 15:49 ` Eli Zaretskii
2024-09-28 21:52 ` Cecilio Pardo
2024-09-29 7:19 ` Eli Zaretskii
2024-09-29 11:17 ` Cecilio Pardo
2024-09-29 11:36 ` Eli Zaretskii
2024-09-29 11:45 ` Cecilio Pardo
2024-09-30 21:20 ` Cecilio Pardo
2024-10-05 11:07 ` Eli Zaretskii
2024-10-05 12:07 ` Cecilio Pardo
2024-10-05 12:30 ` Eli Zaretskii
2024-10-05 12:34 ` Eli Zaretskii
2024-10-05 21:41 ` Cecilio Pardo
2024-10-05 21:43 ` Cecilio Pardo
2024-10-06 6:10 ` Eli Zaretskii
2024-10-07 10:28 ` Cecilio Pardo
2024-10-07 12:00 ` Eli Zaretskii
2024-10-08 13:15 ` Eli Zaretskii
2024-10-08 18:51 ` Cecilio Pardo
2024-10-23 17:16 ` Cecilio Pardo [this message]
2024-10-24 7:37 ` Eli Zaretskii
2024-10-24 7:56 ` Cecilio Pardo
2024-10-24 8:16 ` Eli Zaretskii
2024-10-24 8:46 ` Cecilio Pardo
2024-10-24 9:40 ` Eli Zaretskii
2024-10-24 16:52 ` Cecilio Pardo
2024-10-25 10:43 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3adf9bbb-5c6a-4e6d-83f5-c1d2c6a059d6@imayhem.com \
--to=cpardo@imayhem.com \
--cc=3468@debbugs.gnu.org \
--cc=eliz@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).