From 3f94084e299eb48403f6e6b7692c03cfb9f70b2a Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Wed, 27 May 2015 20:09:34 +0400 Subject: [PATCH] Add DND move support on OS X The drag mask passed by Cocoa is conservative and doesn't include NSDragOperationMove which was added later. Override draggingSourceOperationMaskForLocal to include that flag if it's wanted. This also moving of text the default behaviour. Closes #13819. Closes #14726. --- src/osx/cocoa/dnd.mm | 39 +++++++++++++++++++++++++++++++++++---- src/osx/cocoa/window.mm | 5 +++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/osx/cocoa/dnd.mm b/src/osx/cocoa/dnd.mm index 47faae9b16..b63834a714 100644 --- a/src/osx/cocoa/dnd.mm +++ b/src/osx/cocoa/dnd.mm @@ -56,11 +56,15 @@ wxDragResult NSDragOperationToWxDragResult(NSDragOperation code) BOOL dragFinished; int resultCode; wxDropSource* impl; + + // Flags for drag and drop operations (wxDrag_* ). + int m_dragFlags; } -- (void)setImplementation: (wxDropSource *)dropSource; +- (void)setImplementation:(wxDropSource *)dropSource flags:(int)flags; - (BOOL)finished; - (NSDragOperation)code; +- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)forLocal; - (void)draggedImage:(NSImage *)anImage movedTo:(NSPoint)aPoint; - (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation; @end @@ -73,12 +77,14 @@ wxDragResult NSDragOperationToWxDragResult(NSDragOperation code) dragFinished = NO; resultCode = NSDragOperationNone; impl = 0; + m_dragFlags = wxDrag_CopyOnly; return self; } -- (void)setImplementation: (wxDropSource *)dropSource +- (void)setImplementation:(wxDropSource *)dropSource flags:(int)flags { impl = dropSource; + m_dragFlags = flags; } - (BOOL)finished @@ -91,6 +97,31 @@ wxDragResult NSDragOperationToWxDragResult(NSDragOperation code) return resultCode; } +- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)forLocal +{ + /* + By default drag targets receive a mask of NSDragOperationAll (0xf) + which, despite its name, does not include the later added + NSDragOperationMove (0x10) that sometimes is wanted. + Use NSDragOperationEvery instead because it includes all flags. + + Note that this, compared to the previous behaviour, adds + NSDragOperationDelete to the mask which seems harmless. + + We are also keeping NSDragOperationLink and NSDragOperationPrivate + in to preserve previous behaviour. + */ + + NSDragOperation allowedDragOperations = NSDragOperationEvery; + + if (m_dragFlags == wxDrag_CopyOnly) + { + allowedDragOperations &= ~NSDragOperationMove; + } + + return allowedDragOperations; +} + - (void)draggedImage:(NSImage *)anImage movedTo:(NSPoint)aPoint { wxUnusedVar( anImage ); @@ -186,7 +217,7 @@ wxDropSource* wxDropSource::GetCurrentDropSource() return gCurrentSource; } -wxDragResult wxDropSource::DoDragDrop(int WXUNUSED(flags)) +wxDragResult wxDropSource::DoDragDrop(int flags) { wxASSERT_MSG( m_data, wxT("Drop source: no data") ); @@ -240,7 +271,7 @@ wxDragResult wxDropSource::DoDragDrop(int WXUNUSED(flags)) DropSourceDelegate* delegate = [[DropSourceDelegate alloc] init]; - [delegate setImplementation: this]; + [delegate setImplementation:this flags:flags]; [view dragImage:image at:p offset:NSMakeSize(0.0,0.0) event: theEvent pasteboard: pboard source:delegate slideBack: NO]; diff --git a/src/osx/cocoa/window.mm b/src/osx/cocoa/window.mm index d98cd3a682..bad9a1446e 100644 --- a/src/osx/cocoa/window.mm +++ b/src/osx/cocoa/window.mm @@ -1210,6 +1210,11 @@ unsigned int wxOnDraggingEnteredOrUpdated(wxWidgetCocoaImpl* viewImpl, sourceDragMask contains copy, link, generic, and private flags. Formerly this would result in wxDragLink which is not what is expected for text. Give precedence to the move and copy flag instead. + + TODO: + In order to respect wxDrag_DefaultMove, access to dnd.mm's + DropSourceDelegate will be needed which contains the wxDrag value used. + (The draggingSource method of sender points to a DropSourceDelegate* ). */ wxDragResult result = wxDragNone;