1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-12-03 08:30:09 +00:00

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.
This commit is contained in:
Po Lu 2022-03-25 21:24:03 +08:00
parent ab414c5661
commit 8ba0f19064
6 changed files with 26 additions and 15 deletions

View File

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

View File

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

View File

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

View File

@ -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 @@ Emacs. For that reason, they are not mentioned here. Consult
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;

View File

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

View File

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