emacs-diffs
[Top][All Lists]
Advanced

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

master 78ecd67888: Improve safety of haiku-drag-message


From: Po Lu
Subject: master 78ecd67888: Improve safety of haiku-drag-message
Date: Wed, 6 Apr 2022 01:57:10 -0400 (EDT)

branch: master
commit 78ecd67888566167fb4c881d8350f611fa039649
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Improve safety of haiku-drag-message
    
    * lisp/term/haiku-win.el (haiku-drag-and-drop): Ignore
    placeholder message.
    * src/frame.c (delete_frame): Prevent deleting drop source frame
    on Haiku.
    * src/haiku_support.cc (RELEASE_NOW, CANCEL_DROP): New message
    types.
    (class EmacsView, MessageReceived): Handle new message types.
    (be_drag_message): Drag CANCEL_DROP message on quit; also send
    RELEASE_NOW to view if quitting.
    
    * src/haikuselect.c (syms_of_haikuselect)
    (haiku_unwind_drag_message): Clear new frame variable.
    (Fhaiku_drag_message): Set new frame variable.
    * src/haikuterm.h: Update prototypes.
---
 lisp/term/haiku-win.el |  7 +++++--
 src/frame.c            |  4 ++++
 src/haiku_support.cc   | 33 ++++++++++++++++++++++++++++++---
 src/haikuselect.c      | 10 ++++++++++
 src/haikuterm.h        |  1 +
 5 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el
index 6f8f9ac519..955947fe6a 100644
--- a/lisp/term/haiku-win.el
+++ b/lisp/term/haiku-win.el
@@ -264,8 +264,11 @@ VALUE will be encoded as UTF-8 and stored under the type
                              (if (multibyte-string-p text)
                                  text
                                (decode-coding-string text 'undecided))))))
-       (t (message "Don't know how to drop any of: %s"
-                   (mapcar #'car string)))))))
+       ((not (eq (cdr (assq 'type string))
+                 3003)) ; Type of the placeholder message Emacs uses
+                        ; to cancel a drop on C-g.
+        (message "Don't know how to drop any of: %s"
+                 (mapcar #'car string)))))))
 
 (define-key special-event-map [drag-n-drop]
             'haiku-drag-and-drop)
diff --git a/src/frame.c b/src/frame.c
index 05b22ac72b..93028aa895 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1991,6 +1991,10 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
   else if (x_dnd_in_progress && f == x_dnd_frame)
     error ("Attempt to delete the drop source frame");
 #endif
+#ifdef HAVE_HAIKU
+  else if (f == haiku_dnd_frame)
+    error ("Attempt to delete the drop source frame");
+#endif
 
   XSETFRAME (frame, f);
 
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 830255d3f0..cb38a572f7 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -81,8 +81,13 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 
 #include "haiku_support.h"
 
-#define SCROLL_BAR_UPDATE 3000
-#define WAIT_FOR_RELEASE 3001
+enum
+  {
+    SCROLL_BAR_UPDATE  = 3000,
+    WAIT_FOR_RELEASE   = 3001,
+    RELEASE_NOW                = 3002,
+    CANCEL_DROP                = 3003,
+  };
 
 static color_space dpy_color_space = B_NO_COLOR_SPACE;
 static key_map *key_map = NULL;
@@ -1272,7 +1277,10 @@ public:
   ~EmacsView ()
   {
     if (wait_for_release_message)
-      gui_abort ("Wait for release message still exists");
+      {
+       wait_for_release_message->SendReply (wait_for_release_message);
+       delete wait_for_release_message;
+      }
 
     TearDownDoubleBuffering ();
 
@@ -1307,6 +1315,14 @@ public:
        else
          wait_for_release_message = looper->DetachCurrentMessage ();
       }
+    else if (msg->what == RELEASE_NOW)
+      {
+       if (wait_for_release_message)
+         wait_for_release_message->SendReply (msg);
+
+       delete wait_for_release_message;
+       wait_for_release_message = NULL;
+      }
     else
       BView::MessageReceived (msg);
   }
@@ -4087,6 +4103,7 @@ be_drag_message (void *view, void *message, bool 
allow_same_view,
   BMessage *msg = (BMessage *) message;
   BMessage wait_for_release;
   BMessenger messenger (vw);
+  BMessage cancel_message (CANCEL_DROP);
   struct object_wait_info infos[2];
   ssize_t stat;
 
@@ -4142,6 +4159,16 @@ be_drag_message (void *view, void *message, bool 
allow_same_view,
 
       if (should_quit_function ())
        {
+         /* Do the best we can to prevent something from being
+            dropped, since Haiku doesn't provide a way to actually
+            cancel drag-and-drop.  */
+         if (vw->LockLooper ())
+           {
+             vw->DragMessage (&cancel_message, BRect (0, 0, 0, 0));
+             vw->UnlockLooper ();
+           }
+
+         messenger.SendMessage (CANCEL_DROP);
          drag_and_drop_in_progress = false;
          return true;
        }
diff --git a/src/haikuselect.c b/src/haikuselect.c
index c3053688f5..a186acc66f 100644
--- a/src/haikuselect.c
+++ b/src/haikuselect.c
@@ -27,6 +27,12 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 
 #include <stdlib.h>
 
+/* The frame that is currently the source of a drag-and-drop
+   operation, or NULL if none is in progress.  The reason for this
+   variable is to prevent it from being deleted, which really breaks
+   the nested event loop inside be_drag_message.  */
+struct frame *haiku_dnd_frame;
+
 static void haiku_lisp_to_message (Lisp_Object, void *);
 
 DEFUN ("haiku-selection-data", Fhaiku_selection_data, Shaiku_selection_data,
@@ -726,6 +732,7 @@ haiku_should_quit_drag (void)
 static void
 haiku_unwind_drag_message (void *message)
 {
+  haiku_dnd_frame = NULL;
   BMessage_delete (message);
 }
 
@@ -774,6 +781,7 @@ ignored if it is dropped on top of FRAME.  */)
   if (!FRAME_VISIBLE_P (f))
     error ("Frame is invisible");
 
+  haiku_dnd_frame = f;
   be_message = be_create_simple_message ();
 
   record_unwind_protect_ptr (haiku_unwind_drag_message, be_message);
@@ -852,4 +860,6 @@ used to retrieve the current position of the mouse.  */);
   defsubr (&Shaiku_selection_put);
   defsubr (&Shaiku_selection_owner_p);
   defsubr (&Shaiku_drag_message);
+
+  haiku_dnd_frame = NULL;
 }
diff --git a/src/haikuterm.h b/src/haikuterm.h
index 8f311b2ab1..586df28575 100644
--- a/src/haikuterm.h
+++ b/src/haikuterm.h
@@ -192,6 +192,7 @@ extern struct haiku_display_info *x_display_list;
 extern struct font_driver const haikufont_driver;
 
 extern Lisp_Object tip_frame;
+extern struct frame *haiku_dnd_frame;
 
 struct scroll_bar
 {



reply via email to

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