From: Po Lu Date: Tue, 5 Apr 2022 12:03:48 +0000 (+0800) Subject: Mark some data during drag-and-drop X-Git-Tag: emacs-29.0.90~1931^2~765 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=7d504c9acc0c8d75d11c3a2b5e016f39e6156bf8;p=emacs.git Mark some data during drag-and-drop It doesn't make sense to prevent the return frame or movement frame from being deleted, but we should at least protect them from garbage collection. * src/alloc.c (garbage_collect): Call mark_xterm. * src/xterm.c (x_dnd_begin_drag_and_drop) (x_dnd_cleanup_drag_and_drop): Clear movement and return frames upon DND completion. (mark_xterm): Mark those frames. * src/xterm.h: Update prototypes. --- diff --git a/src/alloc.c b/src/alloc.c index 6d91ec33585..733f7733fa9 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -6196,6 +6196,10 @@ garbage_collect (void) mark_fringe_data (); #endif +#ifdef HAVE_X_WINDOWS + mark_xterm (); +#endif + /* Everything is now marked, except for the data in font caches, undo lists, and finalizers. The first two are compacted by removing an items which aren't reachable otherwise. */ diff --git a/src/xterm.c b/src/xterm.c index 922aafbbdf1..b9a5355b415 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -3497,6 +3497,8 @@ x_dnd_cleanup_drag_and_drop (void *frame) #ifdef USE_GTK current_hold_quit = NULL; #endif + x_dnd_return_frame_object = NULL; + x_dnd_movement_frame = NULL; block_input (); /* Restore the old event mask. */ @@ -9528,6 +9530,9 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, if (x_dnd_use_toplevels) x_dnd_free_toplevels (); + x_dnd_return_frame_object = NULL; + x_dnd_movement_frame = NULL; + FRAME_DISPLAY_INFO (f)->grabbed = 0; #ifdef USE_GTK current_hold_quit = NULL; @@ -9546,6 +9551,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, #ifdef USE_GTK current_hold_quit = NULL; #endif + x_dnd_movement_frame = NULL; /* Restore the old event mask. */ XSelectInput (FRAME_X_DISPLAY (f), @@ -9554,14 +9560,18 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, unblock_input (); - if (x_dnd_return_frame == 3) + if (x_dnd_return_frame == 3 + && FRAME_LIVE_P (x_dnd_return_frame_object)) { x_dnd_return_frame_object->mouse_moved = true; XSETFRAME (action, x_dnd_return_frame_object); + x_dnd_return_frame_object = NULL; return action; } + x_dnd_return_frame_object = NULL; + if (x_dnd_use_toplevels) x_dnd_free_toplevels (); FRAME_DISPLAY_INFO (f)->grabbed = 0; @@ -23015,6 +23025,24 @@ init_xterm (void) } #endif +void +mark_xterm (void) +{ + Lisp_Object val; + + if (x_dnd_return_frame_object) + { + XSETFRAME (val, x_dnd_return_frame_object); + mark_object (val); + } + + if (x_dnd_movement_frame) + { + XSETFRAME (val, x_dnd_movement_frame); + mark_object (val); + } +} + void syms_of_xterm (void) { diff --git a/src/xterm.h b/src/xterm.h index 79dee6a569c..4eb16d0c142 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1557,6 +1557,8 @@ extern struct frame *x_dnd_frame; struct xi_device_t *xi_device_from_id (struct x_display_info *, int); #endif +extern void mark_xterm (void); + /* Is the frame embedded into another application? */ #define FRAME_X_EMBEDDED_P(f) (FRAME_X_OUTPUT(f)->explicit_parent != 0)