emacs-diffs
[Top][All Lists]
Advanced

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

master 76850b26b9: Implement `allow-same-frame' for NS drag-and-drop


From: Po Lu
Subject: master 76850b26b9: Implement `allow-same-frame' for NS drag-and-drop
Date: Wed, 1 Jun 2022 01:51:05 -0400 (EDT)

branch: master
commit 76850b26b92ab0f23d56180d000063d4ad6e08ca
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Implement `allow-same-frame' for NS drag-and-drop
    
    * lisp/term/ns-win.el (x-begin-drag): Implement
    `allow-same-frame'.
    * src/nsselect.m (Fns_begin_drag): New parameter
    `allow-same-frame'.
    * src/nsterm.h (@interface EmacsWindow): Update prototypes.
    * src/nsterm.m ([EmacsView draggingEntered:]):
    ([EmacsView prepareForDragOperation:]):
    ([EmacsView performDragOperation:]): Respect new parameter.
    ([EmacsWindow beginDrag:forPasteboard:withMode:returnFrameTo:]):
    Likewise.
---
 lisp/term/ns-win.el |  4 ++--
 src/nsselect.m      | 14 +++++++----
 src/nsterm.h        |  5 +++-
 src/nsterm.m        | 68 +++++++++++++++++++++++++++++++++++------------------
 4 files changed, 60 insertions(+), 31 deletions(-)

diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el
index 65abdcf0fb..a36d5d11e7 100644
--- a/lisp/term/ns-win.el
+++ b/lisp/term/ns-win.el
@@ -895,7 +895,7 @@ See the documentation of `create-fontset-from-fontset-spec' 
for the format.")
                                          &context (window-system ns))
   (ns-get-selection selection-symbol target-type))
 
-(defun x-begin-drag (targets &optional action frame return-frame 
_allow-current-frame)
+(defun x-begin-drag (targets &optional action frame return-frame 
allow-current-frame)
   "SKIP: real doc in xfns.c."
   (unless ns-dnd-selection-value
     (error "No local value for XdndSelection"))
@@ -910,7 +910,7 @@ See the documentation of `create-fontset-from-fontset-spec' 
for the format.")
                                           (expand-file-name
                                            ns-dnd-selection-value))))
             pasteboard))
-    (ns-begin-drag frame pasteboard action return-frame)))
+    (ns-begin-drag frame pasteboard action return-frame allow-current-frame)))
 
 (defun ns-handle-drag-motion (frame x y)
   "Handle mouse movement on FRAME at X and Y during drag-and-drop.
diff --git a/src/nsselect.m b/src/nsselect.m
index 63cea365e2..a4129b12f0 100644
--- a/src/nsselect.m
+++ b/src/nsselect.m
@@ -662,7 +662,7 @@ ns_dnd_action_from_operation (NSDragOperation operation)
     }
 }
 
-DEFUN ("ns-begin-drag", Fns_begin_drag, Sns_begin_drag, 3, 4, 0,
+DEFUN ("ns-begin-drag", Fns_begin_drag, Sns_begin_drag, 3, 5, 0,
        doc: /* Begin a drag-and-drop operation on FRAME.
 
 FRAME must be a window system frame.  PBOARD is an alist of (TYPE
@@ -680,13 +680,16 @@ data inside PBOARD.
 
 Return the action that the drop target actually chose to perform, or
 nil if no action was performed (either because there was no drop
-target, or the drop was rejected).  If RETURN_FRAME is the symbol
+target, or the drop was rejected).  If RETURN-FRAME is the symbol
 `now', also return any frame that mouse moves into during the
 drag-and-drop operation, whilst simultaneously cancelling it.  Any
 other non-nil value means to do the same, but to wait for the mouse to
-leave FRAME first.  */)
+leave FRAME first.
+
+If ALLOW-SAME-FRAME is nil, dropping on FRAME will result in the drop
+being ignored.  */)
   (Lisp_Object frame, Lisp_Object pboard, Lisp_Object action,
-   Lisp_Object return_frame)
+   Lisp_Object return_frame, Lisp_Object allow_same_frame)
 {
   struct frame *f, *return_to;
   NSPasteboard *pasteboard;
@@ -715,7 +718,8 @@ leave FRAME first.  */)
   operation = [window beginDrag: operation
                  forPasteboard: pasteboard
                       withMode: mode
-                 returnFrameTo: &return_to];
+                 returnFrameTo: &return_to
+                  prohibitSame: (BOOL) NILP (allow_same_frame)];
 
   if (return_to)
     {
diff --git a/src/nsterm.h b/src/nsterm.h
index c39b66534f..37bff6260a 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -425,6 +425,7 @@ enum ns_return_frame_mode
 
   struct frame *dnd_return_frame;
   enum ns_return_frame_mode dnd_mode;
+  BOOL dnd_allow_same_frame;
 }
 
 #ifdef NS_IMPL_GNUSTEP
@@ -444,7 +445,9 @@ enum ns_return_frame_mode
 - (NSDragOperation) beginDrag: (NSDragOperation) op
                forPasteboard: (NSPasteboard *) pasteboard
                     withMode: (enum ns_return_frame_mode) mode
-               returnFrameTo: (struct frame **) frame_return;
+               returnFrameTo: (struct frame **) frame_return
+           prohibitSame: (BOOL) prohibit_same_frame;
+- (BOOL) mustNotDropOn: (NSView *) receiver;
 @end
 
 
diff --git a/src/nsterm.m b/src/nsterm.m
index f4fde9bd12..46ce2cc5e4 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -8608,13 +8608,30 @@ ns_create_font_panel_buttons (id target, SEL select, 
SEL cancel_action)
 
 -(NSDragOperation) draggingEntered: (id <NSDraggingInfo>) sender
 {
+  id source;
+
   NSTRACE ("[EmacsView draggingEntered:]");
+
+  source = [sender draggingSource];
+
+  if (source && [source respondsToSelector: @selector(mustNotDropOn:)]
+      && [source mustNotDropOn: self])
+    return NSDragOperationNone;
+
   return NSDragOperationGeneric;
 }
 
 
--(BOOL)prepareForDragOperation: (id <NSDraggingInfo>) sender
+-(BOOL) prepareForDragOperation: (id <NSDraggingInfo>) sender
 {
+  id source;
+
+  source = [sender draggingSource];
+
+  if (source && [source respondsToSelector: @selector(mustNotDropOn:)]
+      && [source mustNotDropOn: self])
+    return NO;
+
   return YES;
 }
 
@@ -8675,25 +8692,29 @@ ns_create_font_panel_buttons (id target, SEL select, 
SEL cancel_action)
   return NSDragOperationGeneric;
 }
 
--(BOOL)performDragOperation: (id <NSDraggingInfo>) sender
+- (BOOL) performDragOperation: (id <NSDraggingInfo>) sender
 {
-  id pb;
+  id pb, source;
   int x, y;
   NSString *type;
-  NSEvent *theEvent = [[self window] currentEvent];
   NSPoint position;
   NSDragOperation op = [sender draggingSourceOperationMask];
   Lisp_Object operations = Qnil;
   Lisp_Object strings = Qnil;
   Lisp_Object type_sym;
+  struct input_event ie;
 
   NSTRACE ("[EmacsView performDragOperation:]");
 
-  if (!emacs_event)
+  source = [sender draggingSource];
+
+  if (source && [source respondsToSelector: @selector(mustNotDropOn:)]
+      && [source mustNotDropOn: self])
     return NO;
 
   position = [self convertPoint: [sender draggingLocation] fromView: nil];
-  x = lrint (position.x);  y = lrint (position.y);
+  x = lrint (position.x);
+  y = lrint (position.y);
 
   pb = [sender draggingPasteboard];
   type = [pb availableTypeFromArray: ns_drag_types];
@@ -8709,10 +8730,8 @@ ns_create_font_panel_buttons (id target, SEL select, SEL 
cancel_action)
   if (op & NSDragOperationGeneric || NILP (operations))
     operations = Fcons (Qns_drag_operation_generic, operations);
 
-  if (type == 0)
-    {
-      return NO;
-    }
+  if (!type)
+    return NO;
 #if NS_USE_NSPasteboardTypeFileURL != 0
   else if ([type isEqualToString: NSPasteboardTypeFileURL])
     {
@@ -8764,21 +8783,16 @@ ns_create_font_panel_buttons (id target, SEL select, 
SEL cancel_action)
       strings = list1 ([data lispString]);
     }
   else
-    {
-      fputs ("Invalid data type in dragging pasteboard\n", stderr);
-      return NO;
-    }
-
-  emacs_event->kind = DRAG_N_DROP_EVENT;
-  XSETINT (emacs_event->x, x);
-  XSETINT (emacs_event->y, y);
-  emacs_event->modifiers = 0;
+    return NO;
 
-  emacs_event->arg = Fcons (type_sym,
-                            Fcons (operations,
-                                   strings));
-  EV_TRAILER (theEvent);
+  EVENT_INIT (ie);
+  ie.kind = DRAG_N_DROP_EVENT;
+  ie.arg = Fcons (type_sym, Fcons (operations, strings));
+  XSETINT (ie.x, x);
+  XSETINT (ie.y, y);
+  XSETFRAME (ie.frame_or_window, emacsframe);
 
+  kbd_buffer_store_event (&ie);
   return YES;
 }
 
@@ -9611,10 +9625,17 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c)
 }
 #endif
 
+- (BOOL) mustNotDropOn: (NSView *) receiver
+{
+  return ([receiver window] == self
+         ? !dnd_allow_same_frame : NO);
+}
+
 - (NSDragOperation) beginDrag: (NSDragOperation) op
                forPasteboard: (NSPasteboard *) pasteboard
                     withMode: (enum ns_return_frame_mode) mode
                returnFrameTo: (struct frame **) frame_return
+                prohibitSame: (BOOL) prohibit_same_frame
 {
   NSImage *image;
 #ifdef NS_IMPL_COCOA
@@ -9627,6 +9648,7 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c)
   image = [[NSImage alloc] initWithSize: NSMakeSize (1.0, 1.0)];
   dnd_mode = mode;
   dnd_return_frame = NULL;
+  dnd_allow_same_frame = !prohibit_same_frame;
 
   /* Now draw transparency onto the image.  */
   [image lockFocus];



reply via email to

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