[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master aea799838b: Improve behavior of dragging text to windows on top o
From: |
Po Lu |
Subject: |
master aea799838b: Improve behavior of dragging text to windows on top of frames |
Date: |
Mon, 4 Apr 2022 01:10:32 -0400 (EDT) |
branch: master
commit aea799838b7ffd11f187c2511ecca250c8b99411
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Improve behavior of dragging text to windows on top of frames
* doc/lispref/frames.texi (Drag and Drop): Document new meaning
of `return-frame' in `x-begin-drag'.
* lisp/mouse.el (mouse-drag-and-drop-region): Use `now' when
calling `x-begin-drag'.
* src/xfns.c (Fx_begin_drag): Update doc string.
* src/xterm.c (x_dnd_begin_drag_and_drop): Accept return_frame
as a Lisp_Object and handle Qnow correctly.
(XTmouse_position): Ignore tooltip frames when processing
`drag-source'.
(syms_of_xterm): New defsym `now'.
* src/xterm.h: Update prototypes.
---
doc/lispref/frames.texi | 15 +++++++++------
lisp/mouse.el | 23 ++++++++++++++++++++---
src/xfns.c | 6 ++++--
src/xterm.c | 20 +++++++++++++++-----
src/xterm.h | 2 +-
5 files changed, 49 insertions(+), 17 deletions(-)
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index 057f070ccc..85f92d4f62 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -4075,12 +4075,15 @@ describing the available actions, and strings that the
drop target is
expected to present to the user to choose between the available
actions.
-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, but is not
-guaranteed to work on all systems and window managers.
+If @var{return-frame} is non-@code{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. If
+@var{return-frame} is the symbol @code{now}, then any frame underneath
+the mouse pointer will be returned and no further work will be done.
+@var{return-frame} useful when you want to treat dragging content from
+one frame to another specially, while also being able to drag content
+to other programs, but it 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/mouse.el b/lisp/mouse.el
index f42492bb5d..26a17365da 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -3061,7 +3061,8 @@ is copied instead of being cut."
value-selection ; This remains nil when event was "click".
text-tooltip
states
- window-exempt)
+ window-exempt
+ drag-again-mouse-position)
;; STATES stores for each window on this frame its start and point
;; positions so we can restore them on all windows but for the one
@@ -3171,7 +3172,14 @@ is copied instead of being cut."
(frame-pixel-width frame))
(> (cdr location)
(frame-pixel-height frame)))))
- (not (posn-window (event-end event)))))
+ (and (or (not drag-again-mouse-position)
+ (let ((mouse-position
(mouse-absolute-pixel-position)))
+ (or (< 5 (abs (- (car
drag-again-mouse-position)
+ (car
mouse-position))))
+ (< 5 (abs (- (cdr
drag-again-mouse-position)
+ (cdr
mouse-position)))))))
+ (not (posn-window (event-end event))))))
+ (setq drag-again-mouse-position nil)
(mouse-drag-and-drop-region-hide-tooltip)
(gui-set-selection 'XdndSelection value-selection)
(let ((drag-action-or-frame
@@ -3182,9 +3190,18 @@ is copied instead of being cut."
(if
mouse-drag-and-drop-region-cut-when-buffers-differ
'XdndActionMove
'XdndActionCopy)
- (posn-window (event-end event)) t)
+ (posn-window (event-end event)) 'now)
(quit nil))))
(when (framep drag-action-or-frame)
+ ;; With some window managers `x-begin-drag'
+ ;; returns a frame sooner than `mouse-position'
+ ;; will return one, due to over-wide frame windows
+ ;; being drawn by the window manager. To avoid
+ ;; that, we just require the mouse move a few
+ ;; pixels before beginning another cross-program
+ ;; drag.
+ (setq drag-again-mouse-position
+ (mouse-absolute-pixel-position))
(throw 'drag-again nil))
(let ((min-char (point)))
diff --git a/src/xfns.c b/src/xfns.c
index 4fa919f36a..5cf3eb4199 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -6712,7 +6712,9 @@ 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. (This is not guaranteed to work on some systems.)
+FRAME. (This is not guaranteed to work on some systems.) If
+RETURN-FRAME is the symbol `now', any frame underneath the mouse
+pointer will be returned immediately.
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
@@ -6828,7 +6830,7 @@ mouse buttons are released on top of FRAME. */)
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,
+ xaction, return_frame, action_list,
(const char **) &name_list, nnames,
!NILP (allow_current_frame));
diff --git a/src/xterm.c b/src/xterm.c
index e3935bacb9..c70b31c5ad 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -2295,6 +2295,7 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
static int x_dnd_get_window_proto (struct x_display_info *, Window);
static Window x_dnd_get_window_proxy (struct x_display_info *, Window);
+static void x_dnd_update_state (struct x_display_info *, Time);
#ifdef USE_XCB
static void
@@ -8933,9 +8934,9 @@ x_top_window_to_frame (struct x_display_info *dpyinfo,
int wdesc)
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, bool allow_current_frame)
+ Lisp_Object return_frame, Atom *ask_action_list,
+ const char **ask_action_names, size_t n_ask_actions,
+ bool allow_current_frame)
{
#ifndef USE_GTK
XEvent next_event;
@@ -9046,9 +9047,12 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time,
Atom xaction,
}
}
- if (return_frame_p)
+ if (!NILP (return_frame))
x_dnd_return_frame = 1;
+ if (EQ (return_frame, Qnow))
+ x_dnd_return_frame = 2;
+
#ifdef USE_GTK
current_count = 0;
#endif
@@ -9070,6 +9074,9 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time,
Atom xaction,
while (x_dnd_in_progress || x_dnd_waiting_for_finish)
{
+ if (EQ (return_frame, Qnow))
+ x_dnd_update_state (FRAME_DISPLAY_INFO (f), CurrentTime);
+
hold_quit.kind = NO_EVENT;
#ifdef USE_GTK
current_finish = X_EVENT_NORMAL;
@@ -9951,7 +9958,9 @@ XTmouse_position (struct frame **fp, int insist,
Lisp_Object *bar_window,
/* Child of win. */
&child);
- if (!EQ (track_mouse, Qdrag_source))
+ if (!EQ (track_mouse, Qdrag_source)
+ /* Don't let tooltips interfere. */
+ || (f1 && FRAME_TOOLTIP_P (f1)))
f1 = dpyinfo->last_mouse_frame;
else
{
@@ -22662,6 +22671,7 @@ syms_of_xterm (void)
DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
DEFSYM (Qlatin_1, "latin-1");
+ DEFSYM (Qnow, "now");
#ifdef USE_GTK
xg_default_icon_file = build_pure_c_string
("icons/hicolor/scalable/apps/emacs.svg");
diff --git a/src/xterm.h b/src/xterm.h
index 062b34b35c..57036af2bb 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1389,7 +1389,7 @@ extern void x_scroll_bar_configure (GdkEvent *);
#endif
extern Lisp_Object x_dnd_begin_drag_and_drop (struct frame *, Time, Atom,
- bool, Atom *, const char **,
+ Lisp_Object, Atom *, const char
**,
size_t, bool);
extern void x_set_dnd_targets (Atom *, int);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master aea799838b: Improve behavior of dragging text to windows on top of frames,
Po Lu <=