[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];
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 76850b26b9: Implement `allow-same-frame' for NS drag-and-drop,
Po Lu <=