[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 28f720e7c4: Make dragging stuff to a window above a frame work
From: |
Po Lu |
Subject: |
master 28f720e7c4: Make dragging stuff to a window above a frame work |
Date: |
Sun, 3 Apr 2022 06:59:57 -0400 (EDT) |
branch: master
commit 28f720e7c483c37a6c94f6b561e8f175b3af51a4
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Make dragging stuff to a window above a frame work
* doc/lispref/frames.texi (Mouse Tracking):
* etc/NEWS: Announce new `drag-source' value of `track-mouse'.
* lisp/mouse.el (mouse-drag-and-drop-region): Use new value of
`track-mouse' during interprogram drag and drop.
* src/keyboard.c (make_lispy_position): Handle nil values of f
correctly.
* src/xdisp.c (define_frame_cursor1): Ignore if `drag-source' as
well.
(syms_of_xdisp): New defsym `drag-source'.
* src/xterm.c (XTmouse_position): Implement `drag-source'.
(mouse_or_wdesc_frame): Likewise.
---
doc/lispref/frames.texi | 16 ++++++++++++----
etc/NEWS | 6 ++++++
lisp/mouse.el | 32 ++++++++++++++++++++++----------
src/keyboard.c | 38 ++++++++++++++++++++++++--------------
src/xdisp.c | 4 +++-
src/xterm.c | 29 +++++++++++++++++++++++------
6 files changed, 90 insertions(+), 35 deletions(-)
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index ebf426fe50..057f070ccc 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -3512,10 +3512,18 @@ enabled. Typically, @var{body} would use
@code{read-event} to read
the motion events and modify the display accordingly. @xref{Motion
Events}, for the format of mouse motion events.
-The value of @code{track-mouse} is that of the last form in @var{body}.
-You should design @var{body} to return when it sees the up-event that
-indicates the release of the button, or whatever kind of event means
-it is time to stop tracking.
+The value of @code{track-mouse} is that of the last form in
+@var{body}. You should design @var{body} to return when it sees the
+up-event that indicates the release of the button, or whatever kind of
+event means it is time to stop tracking. Its value also controls how
+mouse events are reported while a mouse button is held down: if it is
+@code{dropping} or @code{drag-source}, the motion events are reported
+relative to the frame underneath the pointer. If there is no such
+frame, the events will be reported relative to the frame the mouse
+buttons were first pressed on. In addition, the @code{posn-window} of
+the mouse position list will be @code{nil} if the value is
+@code{drag-source}. This is useful to determine if a frame is not
+directly visible underneath the mouse pointer.
The @code{track-mouse} form causes Emacs to generate mouse motion
events by binding the variable @code{track-mouse} to a
diff --git a/etc/NEWS b/etc/NEWS
index 037a9724d8..f81d194a2f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1331,6 +1331,12 @@ functions.
* Lisp Changes in Emacs 29.1
++++
+** 'track-mouse' can be a new value 'drag-source'.
+This means the same as 'dropping', but modifies the mouse position
+list in reported motion events if there is no frame underneath the
+mouse pointer.
+
+++
** New function 'x-begin-drag'.
This function initiates a drag-and-drop request with the contents of
diff --git a/lisp/mouse.el b/lisp/mouse.el
index 92e289b4ce..f42492bb5d 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -3085,7 +3085,18 @@ is copied instead of being cut."
(ignore-errors
(catch 'cross-program-drag
(track-mouse
- (setq track-mouse 'dropping)
+ (setq track-mouse (if mouse-drag-and-drop-region-cross-program
+ ;; When `track-mouse' is `drop', we
+ ;; get events with a posn-window of
+ ;; the grabbed frame even if some
+ ;; window is between that and the
+ ;; pointer. This makes dragging to a
+ ;; window on top of a frame
+ ;; impossible. With this value of
+ ;; `track-mouse', no frame is returned
+ ;; in that particular case.
+ 'drag-source
+ 'drop))
;; When event was "click" instead of "drag", skip loop.
(while (progn
(setq event (read-key)) ; read-event or read-key
@@ -3151,15 +3162,16 @@ is copied instead of being cut."
(when (and mouse-drag-and-drop-region-cross-program
(display-graphic-p)
(fboundp 'x-begin-drag)
- (framep (posn-window (event-end event)))
- (let ((location (posn-x-y (event-end event)))
- (frame (posn-window (event-end event))))
- (or (< (car location) 0)
- (< (cdr location) 0)
- (> (car location)
- (frame-pixel-width frame))
- (> (cdr location)
- (frame-pixel-height frame)))))
+ (or (and (framep (posn-window (event-end event)))
+ (let ((location (posn-x-y (event-end event)))
+ (frame (posn-window (event-end
event))))
+ (or (< (car location) 0)
+ (< (cdr location) 0)
+ (> (car location)
+ (frame-pixel-width frame))
+ (> (cdr location)
+ (frame-pixel-height frame)))))
+ (not (posn-window (event-end event)))))
(mouse-drag-and-drop-region-hide-tooltip)
(gui-set-selection 'XdndSelection value-selection)
(let ((drag-action-or-frame
diff --git a/src/keyboard.c b/src/keyboard.c
index 8b451d834d..d34bec48a6 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -5253,13 +5253,13 @@ make_lispy_position (struct frame *f, Lisp_Object x,
Lisp_Object y,
/* Report mouse events on the tab bar and (on GUI frames) on the
tool bar. */
- if ((WINDOWP (f->tab_bar_window)
- && EQ (window_or_frame, f->tab_bar_window))
+ if (f && ((WINDOWP (f->tab_bar_window)
+ && EQ (window_or_frame, f->tab_bar_window))
#ifndef HAVE_EXT_TOOL_BAR
- || (WINDOWP (f->tool_bar_window)
- && EQ (window_or_frame, f->tool_bar_window))
+ || (WINDOWP (f->tool_bar_window)
+ && EQ (window_or_frame, f->tool_bar_window))
#endif
- )
+ ))
{
/* While 'track-mouse' is neither nil nor t, do not report this
event as something that happened on the tool or tab bar since
@@ -5283,7 +5283,7 @@ make_lispy_position (struct frame *f, Lisp_Object x,
Lisp_Object y,
window_or_frame = Qnil;
}
- if (FRAME_TERMINAL (f)->toolkit_position_hook)
+ if (f && FRAME_TERMINAL (f)->toolkit_position_hook)
{
FRAME_TERMINAL (f)->toolkit_position_hook (f, mx, my, &menu_bar_p,
&tool_bar_p);
@@ -5524,9 +5524,16 @@ make_lispy_position (struct frame *f, Lisp_Object x,
Lisp_Object y,
}
#endif
}
-
else
- window_or_frame = Qnil;
+ {
+ if (EQ (track_mouse, Qdrag_source))
+ {
+ xret = mx;
+ yret = my;
+ }
+
+ window_or_frame = Qnil;
+ }
return Fcons (window_or_frame,
Fcons (posn,
@@ -12563,12 +12570,15 @@ and the minor mode maps regardless of
`overriding-local-map'. */);
doc: /* Non-nil means generate motion events for mouse motion.
The special values `dragging' and `dropping' assert that the mouse
cursor retains its appearance during mouse motion. Any non-nil value
-but `dropping' asserts that motion events always relate to the frame
-where the mouse movement started. The value `dropping' asserts
-that motion events relate to the frame where the mouse cursor is seen
-when generating the event. If there's no such frame, such motion
-events relate to the frame where the mouse movement started. */);
-
+but `dropping' or `drag-source' asserts that motion events always
+relate to the frame where the mouse movement started. The value
+`dropping' asserts that motion events relate to the frame where the
+mouse cursor is seen when generating the event. If there's no such
+frame, such motion events relate to the frame where the mouse movement
+started. The value `drag-source' is like `dropping', but the
+`posn-window' will be nil in mouse position lists inside mouse
+movement events if there is no frame directly visible underneath the
+mouse pointer. */);
DEFVAR_KBOARD ("system-key-alist", Vsystem_key_alist,
doc: /* Alist of system-specific X windows key symbols.
Each element should have the form (N . SYMBOL) where N is the
diff --git a/src/xdisp.c b/src/xdisp.c
index 62c8f9d4d9..d731308173 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -33856,7 +33856,8 @@ define_frame_cursor1 (struct frame *f, Emacs_Cursor
cursor, Lisp_Object pointer)
return;
/* Do not change cursor shape while dragging mouse. */
- if (EQ (track_mouse, Qdragging) || EQ (track_mouse, Qdropping))
+ if (EQ (track_mouse, Qdragging) || EQ (track_mouse, Qdropping)
+ || EQ (track_mouse, Qdrag_source))
return;
if (!NILP (pointer))
@@ -35678,6 +35679,7 @@ be let-bound around code that needs to disable messages
temporarily. */);
DEFSYM (Qdragging, "dragging");
DEFSYM (Qdropping, "dropping");
+ DEFSYM (Qdrag_source, "drag-source");
DEFSYM (Qdrag_with_mode_line, "drag-with-mode-line");
DEFSYM (Qdrag_with_header_line, "drag-with-header-line");
diff --git a/src/xterm.c b/src/xterm.c
index e7c671de74..aef3d2d840 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -9811,7 +9811,8 @@ XTmouse_position (struct frame **fp, int insist,
Lisp_Object *bar_window,
x_catch_errors (FRAME_X_DISPLAY (*fp));
- if (gui_mouse_grabbed (dpyinfo) && !EQ (track_mouse, Qdropping))
+ if (gui_mouse_grabbed (dpyinfo) && !EQ (track_mouse, Qdropping)
+ && !EQ (track_mouse, Qdrag_source))
{
/* If mouse was grabbed on a frame, give coords for that frame
even if the mouse is now outside it. */
@@ -9900,7 +9901,8 @@ XTmouse_position (struct frame **fp, int insist,
Lisp_Object *bar_window,
}
if ((!f1 || FRAME_TOOLTIP_P (f1))
- && EQ (track_mouse, Qdropping)
+ && (EQ (track_mouse, Qdropping)
+ || EQ (track_mouse, Qdrag_source))
&& gui_mouse_grabbed (dpyinfo))
{
/* When dropping then if we didn't get a frame or only a
@@ -9916,12 +9918,26 @@ XTmouse_position (struct frame **fp, int insist,
Lisp_Object *bar_window,
root_x, root_y, &win_x, &win_y,
/* Child of win. */
&child);
- f1 = dpyinfo->last_mouse_frame;
+
+ if (!EQ (track_mouse, Qdrag_source))
+ f1 = dpyinfo->last_mouse_frame;
+ else
+ {
+ /* Don't set FP but do set WIN_X and WIN_Y in this
+ case, so make_lispy_movement knows which
+ coordinates to report. */
+ *bar_window = Qnil;
+ *part = 0;
+ *fp = NULL;
+ XSETINT (*x, win_x);
+ XSETINT (*y, win_y);
+ *timestamp = dpyinfo->last_mouse_movement_time;
+ }
}
else if (f1 && FRAME_TOOLTIP_P (f1))
f1 = NULL;
- if (x_had_errors_p (FRAME_X_DISPLAY (*fp)))
+ if (x_had_errors_p (dpyinfo->display))
f1 = NULL;
x_uncatch_errors_after_check ();
@@ -9931,7 +9947,7 @@ XTmouse_position (struct frame **fp, int insist,
Lisp_Object *bar_window,
{
struct scroll_bar *bar;
- bar = x_window_to_scroll_bar (FRAME_X_DISPLAY (*fp), win, 2);
+ bar = x_window_to_scroll_bar (dpyinfo->display, win, 2);
if (bar)
{
@@ -12735,7 +12751,8 @@ mouse_or_wdesc_frame (struct x_display_info *dpyinfo,
int wdesc)
? dpyinfo->last_mouse_frame
: NULL);
- if (lm_f && !EQ (track_mouse, Qdropping))
+ if (lm_f && !EQ (track_mouse, Qdropping)
+ && !EQ (track_mouse, Qdrag_source))
return lm_f;
else
{
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 28f720e7c4: Make dragging stuff to a window above a frame work,
Po Lu <=