emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 22b2250732: Handle display disconnects during DND


From: Po Lu
Subject: master 22b2250732: Handle display disconnects during DND
Date: Wed, 27 Apr 2022 21:31:51 -0400 (EDT)

branch: master
commit 22b2250732bcc1d8eecf11bb3cf490570d80497f
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Handle display disconnects during DND
    
    * src/xterm.c (handle_one_xevent): Keep track of the display the
    drop target is on during DND finish.
    (x_connection_closed, x_delete_terminal): Handle display
    disconnects during DND correctly.
---
 src/xterm.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/src/xterm.c b/src/xterm.c
index ff665acdf2..49e1ce1b84 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -875,6 +875,10 @@ struct frame *x_dnd_frame;
    important information.  */
 static bool x_dnd_waiting_for_finish;
 
+/* The display the drop target that is supposed to send information is
+   on.  */
+static Display *x_dnd_finish_display;
+
 /* State of the Motif drop operation.
 
    0 means nothing has happened, i.e. the event loop should not wait
@@ -16123,6 +16127,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                          = x_dnd_send_drop (x_dnd_frame, 
x_dnd_last_seen_window,
                                             x_dnd_selection_timestamp,
                                             x_dnd_last_protocol_version);
+                       x_dnd_finish_display = dpyinfo->display;
                      }
                    else if (x_dnd_last_seen_window != None)
                      {
@@ -16171,6 +16176,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                                x_dnd_waiting_for_finish = true;
                                x_dnd_waiting_for_motif_finish_display = 
dpyinfo;
                                x_dnd_waiting_for_motif_finish = 1;
+                               x_dnd_finish_display = dpyinfo->display;
                              }
                          }
                        else
@@ -17388,6 +17394,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                                = x_dnd_send_drop (x_dnd_frame, 
x_dnd_last_seen_window,
                                                   x_dnd_selection_timestamp,
                                                   x_dnd_last_protocol_version);
+                             x_dnd_finish_display = dpyinfo->display;
                            }
                          else if (x_dnd_last_seen_window != None)
                            {
@@ -17445,6 +17452,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                                      x_dnd_waiting_for_finish = true;
                                      x_dnd_waiting_for_motif_finish_display = 
dpyinfo;
                                      x_dnd_waiting_for_motif_finish = 1;
+                                     x_dnd_finish_display = dpyinfo->display;
                                    }
                                }
                              else
@@ -20026,6 +20034,30 @@ x_connection_closed (Display *dpy, const char 
*error_message, bool ioerror)
   /* Inhibit redisplay while frames are being deleted. */
   specbind (Qinhibit_redisplay, Qt);
 
+  /* If drag-and-drop is in progress and the DND frame's display is
+     DPY, cancel drag-and-drop.  Don't reset event masks or try to
+     send responses to other programs because the display is going
+     away.  */
+
+  if ((x_dnd_in_progress || x_dnd_waiting_for_finish)
+      && dpy == (x_dnd_waiting_for_finish
+                ? x_dnd_finish_display
+                : FRAME_X_DISPLAY (x_dnd_frame)))
+    {
+      x_dnd_last_seen_window = None;
+      x_dnd_last_seen_toplevel = None;
+      x_dnd_in_progress = false;
+      x_set_dnd_targets (NULL, 0);
+      x_dnd_waiting_for_finish = false;
+
+      if (x_dnd_use_toplevels)
+       x_dnd_free_toplevels ();
+
+      x_dnd_return_frame_object = NULL;
+      x_dnd_movement_frame = NULL;
+      x_dnd_frame = NULL;
+    }
+
   if (dpyinfo)
     {
       /* Protect display from being closed when we delete the last
@@ -23935,6 +23967,27 @@ x_delete_terminal (struct terminal *terminal)
       image_destroy_all_bitmaps (dpyinfo);
       XSetCloseDownMode (dpyinfo->display, DestroyAll);
 
+      /* Get rid of any drag-and-drop operation that might be in
+        progress as well.  */
+      if ((x_dnd_in_progress || x_dnd_waiting_for_finish)
+         && dpyinfo->display == (x_dnd_waiting_for_finish
+                                 ? x_dnd_finish_display
+                                 : FRAME_X_DISPLAY (x_dnd_frame)))
+       {
+         x_dnd_last_seen_window = None;
+         x_dnd_last_seen_toplevel = None;
+         x_dnd_in_progress = false;
+         x_set_dnd_targets (NULL, 0);
+         x_dnd_waiting_for_finish = false;
+
+         if (x_dnd_use_toplevels)
+           x_dnd_free_toplevels ();
+
+         x_dnd_return_frame_object = NULL;
+         x_dnd_movement_frame = NULL;
+         x_dnd_frame = NULL;
+       }
+
       /* Whether or not XCloseDisplay destroys the associated resource
         database depends on the version of libX11.  To avoid both
         crash and memory leak, we dissociate the database from the



reply via email to

[Prev in Thread] Current Thread [Next in Thread]