macOS: Don't interfere with native views' drag and drop

wxWidgetCocoaImpl injects implementation of several
NSDraggingDestination protocol methods, but never called their base
implementations, presumably on the assumption that drag and drop is
explicitly supported and not builtin into native NSView-derived
controls.

This prevented native builtin d'n'd in e.g. NSTextView (text can be
copied and inserted by dragging it to the insertion point) from
working. Fixed by always calling base implementation.

Closes https://github.com/wxWidgets/wxWidgets/pull/2320
This commit is contained in:
Václav Slavík 2021-04-12 13:40:41 +02:00 committed by Vadim Zeitlin
parent dc5f1711f2
commit db3e54b3dc
2 changed files with 39 additions and 21 deletions

View File

@ -372,7 +372,9 @@ public:
typedef void (*wxOSX_EventHandlerPtr)(NSView* self, SEL _cmd, NSEvent *event);
typedef BOOL (*wxOSX_PerformKeyEventHandlerPtr)(NSView* self, SEL _cmd, NSEvent *event);
typedef BOOL (*wxOSX_FocusHandlerPtr)(NSView* self, SEL _cmd);
typedef NSDragOperation (*wxOSX_DraggingEnteredOrUpdatedHandlerPtr)(NSView *self, SEL _cmd, void *sender);
typedef void (*wxOSX_DraggingExitedHandlerPtr)(NSView *self, SEL _cmd, void *sender);
typedef BOOL (*wxOSX_PerformDragOperationHandlerPtr)(NSView *self, SEL _cmd, void *sender);
WXDLLIMPEXP_CORE NSScreen* wxOSXGetMenuScreen();
WXDLLIMPEXP_CORE NSRect wxToNSRect( NSView* parent, const wxRect& r );

View File

@ -1246,15 +1246,21 @@ namespace
{
unsigned int wxOnDraggingEnteredOrUpdated(wxWidgetCocoaImpl* viewImpl,
void *s, bool entered)
WXWidget slf, void *_cmd,
void *s, bool entered)
{
wxWindow* wxpeer = viewImpl->GetWXPeer();
if ( wxpeer == NULL )
return NSDragOperationNone;
wxDropTarget* target = wxpeer->GetDropTarget();
wxDropTarget* target = wxpeer ? wxpeer->GetDropTarget() : NULL;
if ( target == NULL )
return NSDragOperationNone;
{
if ([[slf superclass] instancesRespondToSelector:(SEL)_cmd])
{
auto superimpl = (wxOSX_DraggingEnteredOrUpdatedHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
return superimpl(slf, (SEL)_cmd, s);
}
else
return NSDragOperationNone;
}
id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
wxOSXPasteboard pb([sender draggingPasteboard]);
@ -1338,20 +1344,24 @@ unsigned int wxOnDraggingEnteredOrUpdated(wxWidgetCocoaImpl* viewImpl,
} // anonymous namespace
unsigned int wxWidgetCocoaImpl::draggingEntered(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
unsigned int wxWidgetCocoaImpl::draggingEntered(void* s, WXWidget slf, void *_cmd)
{
return wxOnDraggingEnteredOrUpdated(this, s, true /*entered*/);
return wxOnDraggingEnteredOrUpdated(this, slf, _cmd, s, true /*entered*/);
}
void wxWidgetCocoaImpl::draggingExited(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
void wxWidgetCocoaImpl::draggingExited(void* s, WXWidget slf, void *_cmd)
{
wxWindow* wxpeer = GetWXPeer();
if ( wxpeer == NULL )
return;
wxDropTarget* target = wxpeer->GetDropTarget();
wxDropTarget* target = wxpeer ? wxpeer->GetDropTarget() : NULL;
if ( target == NULL )
{
if ([[slf superclass] instancesRespondToSelector:(SEL)_cmd])
{
auto superimpl = (wxOSX_DraggingExitedHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
superimpl(slf, (SEL)_cmd, s);
}
return;
}
id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
wxOSXPasteboard pb([sender draggingPasteboard]);
@ -1360,19 +1370,25 @@ void wxWidgetCocoaImpl::draggingExited(void* s, WXWidget WXUNUSED(slf), void *WX
target->OnLeave();
}
unsigned int wxWidgetCocoaImpl::draggingUpdated(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
unsigned int wxWidgetCocoaImpl::draggingUpdated(void* s, WXWidget slf, void *_cmd)
{
return wxOnDraggingEnteredOrUpdated(this, s, false /*updated*/);
return wxOnDraggingEnteredOrUpdated(this, slf, _cmd, s, false /*updated*/);
}
bool wxWidgetCocoaImpl::performDragOperation(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
bool wxWidgetCocoaImpl::performDragOperation(void* s, WXWidget slf, void *_cmd)
{
wxWindow* wxpeer = GetWXPeer();
if ( wxpeer == NULL )
return false;
wxDropTarget* target = wxpeer->GetDropTarget();
wxDropTarget* target = wxpeer ? wxpeer->GetDropTarget() : NULL;
if ( target == NULL )
return false;
{
if ([[slf superclass] instancesRespondToSelector:(SEL)_cmd])
{
auto superimpl = (wxOSX_PerformDragOperationHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
return superimpl(slf, (SEL)_cmd, s);
}
else
return false;
}
id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
wxOSXPasteboard pb([sender draggingPasteboard]);