]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve safety of haiku-drag-message
authorPo Lu <luangruo@yahoo.com>
Wed, 6 Apr 2022 05:54:31 +0000 (05:54 +0000)
committerPo Lu <luangruo@yahoo.com>
Wed, 6 Apr 2022 05:54:31 +0000 (05:54 +0000)
* 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
src/frame.c
src/haiku_support.cc
src/haikuselect.c
src/haikuterm.h

index 6f8f9ac5196d8dff519650e53587ce41f345c915..955947fe6a21b5255ae65c539784b25a906d1889 100644 (file)
@@ -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)
index 05b22ac72ba3962bd5d6acbb864be06367708b00..93028aa89582e751f2bd1087de65aeb49cfa5967 100644 (file)
@@ -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);
 
index 830255d3f07573c2e3ed0894b0034dbbf9cf66cf..cb38a572f7c2f253dfca7af7e2db9be8e7b62f65 100644 (file)
@@ -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;
        }
index c3053688f5af283802f607d9b340c76cec2bf585..a186acc66ff484aaaaf35ac0eff5e150647141b4 100644 (file)
@@ -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;
 }
index 8f311b2ab12a780bdd569b45cbcc001d53d7033a..586df285751f34c0c8df7f0d8fa317c3cea35df1 100644 (file)
@@ -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
 {