unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
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


  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).