aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-05-28 10:09:19 +0800
committerPo Lu2022-05-28 10:09:19 +0800
commit73237458ba305506d42293beb88d26054f8a353c (patch)
treeb1f54eb7cd0daaff2b0c3921837d0795ac11ca37 /src
parentac13957b86ad699a76a0b248063551f971c4cef9 (diff)
downloademacs-73237458ba305506d42293beb88d26054f8a353c.tar.gz
emacs-73237458ba305506d42293beb88d26054f8a353c.zip
Improve safety of various DND callbacks
* src/xterm.c (x_dnd_begin_drag_and_drop): Restore selection events if DND is no longer in progress and don't call x-dnd-movement-function.
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 94c996a11dc..5c591134692 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -10646,7 +10646,12 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
10646 /* FIXME: how come this can end up with movement frames 10646 /* FIXME: how come this can end up with movement frames
10647 from other displays on GTK builds? */ 10647 from other displays on GTK builds? */
10648 && (FRAME_X_DISPLAY (x_dnd_movement_frame) 10648 && (FRAME_X_DISPLAY (x_dnd_movement_frame)
10649 == FRAME_X_DISPLAY (f))) 10649 == FRAME_X_DISPLAY (f))
10650 /* If both those variables are false, then F is no
10651 longer protected from deletion by Lisp code. This
10652 can only happen during the final iteration of the DND
10653 event loop. */
10654 && (x_dnd_in_progress || x_dnd_waiting_for_finish))
10650 { 10655 {
10651 XSETFRAME (frame_object, x_dnd_movement_frame); 10656 XSETFRAME (frame_object, x_dnd_movement_frame);
10652 XSETINT (x, x_dnd_movement_x); 10657 XSETINT (x, x_dnd_movement_x);
@@ -10677,14 +10682,24 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
10677 { 10682 {
10678 if (hold_quit.kind == SELECTION_REQUEST_EVENT) 10683 if (hold_quit.kind == SELECTION_REQUEST_EVENT)
10679 { 10684 {
10680 x_dnd_old_window_attrs = root_window_attrs; 10685 /* It's not safe to run Lisp inside this function if
10681 x_dnd_unwind_flag = true; 10686 x_dnd_in_progress and x_dnd_waiting_for_finish
10687 are unset, so push it back into the event queue. */
10688
10689 if (!x_dnd_in_progress && !x_dnd_waiting_for_finish)
10690 kbd_buffer_store_event (&hold_quit);
10691 else
10692 {
10693 x_dnd_old_window_attrs = root_window_attrs;
10694 x_dnd_unwind_flag = true;
10695
10696 ref = SPECPDL_INDEX ();
10697 record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f);
10698 x_handle_selection_event ((struct selection_input_event *) &hold_quit);
10699 x_dnd_unwind_flag = false;
10700 unbind_to (ref, Qnil);
10701 }
10682 10702
10683 ref = SPECPDL_INDEX ();
10684 record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f);
10685 x_handle_selection_event ((struct selection_input_event *) &hold_quit);
10686 x_dnd_unwind_flag = false;
10687 unbind_to (ref, Qnil);
10688 continue; 10703 continue;
10689 } 10704 }
10690 10705