emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 8ba0f19064: Allow dragging files from dired to windows on the sam


From: Po Lu
Subject: master 8ba0f19064: Allow dragging files from dired to windows on the same frame
Date: Fri, 25 Mar 2022 09:24:39 -0400 (EDT)

branch: master
commit 8ba0f190642d20e8f9caa7472c12674c7ba65a69
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Allow dragging files from dired to windows on the same frame
    
    * doc/lispref/frames.texi (Drag and Drop): Document new
    parameter to `x-begin-drag'.
    * lisp/dired.el (dired-mouse-drag): Utilize new parameter.
    * lisp/term/haiku-win.el (x-begin-drag): Add new parameter.
    * src/xfns.c (Fx_begin_drag): New parameter
    `allow-current-frame'.  Fix typo and update doc string.
    * src/xterm.c (x_dnd_get_window_proto): Respect
    `x_dnd_allow_current_frame'.
    (x_dnd_begin_drag_and_drop): New parameter
    `allow_current_frame'.
    * src/xterm.h: Update prototypes.
---
 doc/lispref/frames.texi |  8 +++++---
 lisp/dired.el           |  3 ++-
 lisp/term/haiku-win.el  |  2 +-
 src/xfns.c              | 17 +++++++++++------
 src/xterm.c             |  9 ++++++---
 src/xterm.h             |  2 +-
 6 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index a031b25e47..90924cf47b 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -4042,12 +4042,13 @@ you want to alter Emacs behavior, you can customize 
these variables.
   On capable window systems, Emacs also supports dragging contents
 from its frames to windows of other applications.
 
-@defun x-begin-drag targets &optional action frame return-frame
+@defun x-begin-drag targets &optional action frame return-frame 
allow-current-frame
 This function begins a drag from @var{frame}, and returns when the
 drag-and-drop operation ends, either because the drop was successful,
 or because the drop was rejected.  The drop occurs when all mouse
 buttons are released on top of an X window other than @var{frame} (the
-@dfn{drop target}).
+@dfn{drop target}), or any X window if @var{allow-current-frame} is
+non-@code{nil}.
 
 @var{targets} is a list of strings describing selection targets, much
 like the @var{data-type} argument to @code{gui-get-selection}, that
@@ -4070,7 +4071,8 @@ If @var{return-frame} is non-nil and the mouse moves over 
an Emacs
 frame after first moving out of @var{frame}, then the frame to which
 the mouse moves will be returned immediately.  This is useful when you
 want to treat dragging content from one frame to another specially,
-while also being able to drag content to other programs.
+while also being able to drag content to other programs, but is not
+guaranteed to work on all systems and window managers.
 
 If the drop was rejected or no drop target was found, this function
 returns @code{nil}.  Otherwise, it returns a symbol describing the
diff --git a/lisp/dired.el b/lisp/dired.el
index d6c5721ca2..b1208cec25 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -1710,7 +1710,8 @@ see `dired-use-ls-dired' for more details.")
                                 "text/x-dnd-username")
                               (if (eq 'dired-mouse-drag-files 'link)
                                   'XdndActionLink
-                                'XdndActionCopy)))
+                                'XdndActionCopy)
+                              nil nil t))
             (error (when (eq (event-basic-type new-event) 'mouse-1)
                      (push new-event unread-command-events)))))))))
 
diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el
index 1433620875..d04da2fdae 100644
--- a/lisp/term/haiku-win.el
+++ b/lisp/term/haiku-win.el
@@ -199,7 +199,7 @@ This is necessary because on Haiku `use-system-tooltip' 
doesn't
 take effect on menu items until the menu bar is updated again."
   (force-mode-line-update t))
 
-(defun x-begin-drag (targets &optional action frame _return-frame)
+(defun x-begin-drag (targets &optional action frame _return-frame 
_allow-current-frame)
   "SKIP: real doc in xfns.c."
   (unless haiku-dnd-selection-value
     (error "No local value for XdndSelection"))
diff --git a/src/xfns.c b/src/xfns.c
index 52649b38dd..3f3054422a 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -6582,7 +6582,7 @@ The coordinates X and Y are interpreted in pixels 
relative to a position
   return Qnil;
 }
 
-DEFUN ("x-begin-drag", Fx_begin_drag, Sx_begin_drag, 1, 4, 0,
+DEFUN ("x-begin-drag", Fx_begin_drag, Sx_begin_drag, 1, 5, 0,
        doc: /* Begin dragging contents on FRAME, with targets TARGETS.
 TARGETS is a list of strings, which defines the X selection targets
 that will be available to the drop target.  Block until the mouse
@@ -6612,7 +6612,7 @@ https://freedesktop.org/wiki/Specifications/XDND/.
 
 If RETURN-FRAME is non-nil, this function will return the frame if the
 mouse pointer moves onto an Emacs frame, after first moving out of
-FRAME.
+FRAME.  (This is not guaranteed to work on some systems.)
 
 If ACTION is a list and not nil, its elements are assumed to be a cons
 of (ITEM . STRING), where ITEM is the name of an action, and STRING is
@@ -6620,9 +6620,13 @@ a string describing ITEM to the user.  The drop target 
is expected to
 prompt the user to choose between any of the actions in the list.
 
 If ACTION is not specified or nil, `XdndActionCopy' is used
-instead.  */)
+instead.
+
+If ALLOW-CURRENT-FRAME is not specified or nil, then the drop target
+is allowed to be FRAME.  Otherwise, no action will be taken if the
+mouse buttons are released on top of FRAME.  */)
   (Lisp_Object targets, Lisp_Object action, Lisp_Object frame,
-   Lisp_Object return_frame)
+   Lisp_Object return_frame, Lisp_Object allow_current_frame)
 {
   struct frame *f = decode_window_system_frame (frame);
   int ntargets = 0, nnames = 0;
@@ -6650,7 +6654,7 @@ instead.  */)
          scratch = SSDATA (XCAR (targets));
          len = strlen (scratch);
          target_names[ntargets] = SAFE_ALLOCA (len + 1);
-         strncpy (target_names[ntargets], scratch, len + 1);;
+         strncpy (target_names[ntargets], scratch, len + 1);
          ntargets++;
        }
       else
@@ -6725,7 +6729,8 @@ instead.  */)
   x_set_dnd_targets (target_atoms, ntargets);
   lval = x_dnd_begin_drag_and_drop (f, FRAME_DISPLAY_INFO (f)->last_user_time,
                                    xaction, !NILP (return_frame), action_list,
-                                   (const char **) &name_list, nnames);
+                                   (const char **) &name_list, nnames,
+                                   !NILP (allow_current_frame));
 
   SAFE_FREE ();
   return lval;
diff --git a/src/xterm.c b/src/xterm.c
index 968ea78c1a..6bd43511f8 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -799,6 +799,7 @@ static bool x_dnd_in_progress;
 static bool x_dnd_waiting_for_finish;
 static Window x_dnd_pending_finish_target;
 static int x_dnd_waiting_for_finish_proto;
+static bool x_dnd_allow_current_frame;
 
 /* Whether or not to return a frame from `x_dnd_begin_drag_and_drop'.
 
@@ -1368,7 +1369,8 @@ x_dnd_get_window_proto (struct x_display_info *dpyinfo, 
Window wdesc)
   unsigned long n, left;
   bool had_errors;
 
-  if (wdesc == None || wdesc == FRAME_OUTER_WINDOW (x_dnd_frame))
+  if (wdesc == None || (!x_dnd_allow_current_frame
+                       && wdesc == FRAME_OUTER_WINDOW (x_dnd_frame)))
     return -1;
 
   x_catch_errors (dpyinfo->display);
@@ -7310,7 +7312,7 @@ Lisp_Object
 x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
                           bool return_frame_p, Atom *ask_action_list,
                           const char **ask_action_names,
-                          size_t n_ask_actions)
+                          size_t n_ask_actions, bool allow_current_frame)
 {
 #ifndef USE_GTK
   XEvent next_event;
@@ -7394,7 +7396,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, 
Atom xaction,
 
   x_dnd_in_progress = true;
   x_dnd_frame = f;
-  x_dnd_last_seen_window = FRAME_OUTER_WINDOW (f);
+  x_dnd_last_seen_window = None;
   x_dnd_last_protocol_version = -1;
   x_dnd_mouse_rect_target = None;
   x_dnd_action = None;
@@ -7405,6 +7407,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, 
Atom xaction,
   x_dnd_use_toplevels
     = x_wm_supports (f, FRAME_DISPLAY_INFO 
(f)->Xatom_net_client_list_stacking);
   x_dnd_toplevels = NULL;
+  x_dnd_allow_current_frame = allow_current_frame;
 
   if (x_dnd_use_toplevels)
     {
diff --git a/src/xterm.h b/src/xterm.h
index 5a7b09925e..a155245f81 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1383,7 +1383,7 @@ extern void x_scroll_bar_configure (GdkEvent *);
 
 extern Lisp_Object x_dnd_begin_drag_and_drop (struct frame *, Time, Atom,
                                              bool, Atom *, const char **,
-                                             size_t);
+                                             size_t, bool);
 extern void x_set_dnd_targets (Atom *, int);
 
 INLINE int



reply via email to

[Prev in Thread] Current Thread [Next in Thread]