Fixes for dnd in wxOSX

Refactor pasteboard code for reuse in dnd.

Improve setting flags for file objects.

See #27047.

Closes #27117.

Co-authored-by: Stefan Csomor <csomor@advancedconcepts.ch>
This commit is contained in:
Alexey Shelaev
2026-09-28 23:08:13 +02:00
committed by Vadim Zeitlin
co-authored by Stefan Csomor
parent 14200bf215
commit dcce105995
2 changed files with 81 additions and 41 deletions
+23 -9
View File
@@ -76,11 +76,30 @@ public:
// create a new sink item
virtual wxOSXDataSinkItem* CreateItem() = 0;
// flush the created sink items into the system sink representation
virtual void Flush() = 0 ;
// flush the created sink items into the system sink representation (autoreleased)
virtual WX_NSArray Flush() = 0 ;
};
class WXDLLIMPEXP_CORE wxOSXPasteboard : public wxOSXDataSink, public wxOSXDataSource
class WXDLLIMPEXP_CORE wxOSXPasteboardSink : public wxOSXDataSink
{
public:
wxOSXPasteboardSink();
~wxOSXPasteboardSink();
virtual wxOSXDataSinkItem* CreateItem() override;
void Clear() override;
WX_NSArray Flush() override;
private:
virtual wxOSXDataSinkItem* DoCreateItem();
void DeleteSinkItems();
wxVector<wxOSXDataSinkItem*> m_sinkItems;
};
class WXDLLIMPEXP_CORE wxOSXPasteboard : public wxOSXPasteboardSink, public wxOSXDataSource
{
public:
wxOSXPasteboard(OSXPasteboard native);
@@ -88,11 +107,9 @@ public:
// sink methods
virtual wxOSXDataSinkItem* CreateItem() override;
void Clear() override;
void Flush() override;
WX_NSArray Flush() override;
// source methods
@@ -104,10 +121,7 @@ public:
static wxOSXPasteboard* GetGeneralClipboard();
private:
void DeleteSinkItems();
OSXPasteboard m_pasteboard;
wxVector<wxOSXDataSinkItem*> m_sinkItems;
};
#endif
+58 -32
View File
@@ -163,17 +163,16 @@ private:
NSPasteboard* m_pasteboard;
};
wxOSXPasteboard::wxOSXPasteboard(OSXPasteboard native)
wxOSXPasteboardSink::wxOSXPasteboardSink()
{
m_pasteboard = native;
}
wxOSXPasteboard::~wxOSXPasteboard()
wxOSXPasteboardSink::~wxOSXPasteboardSink()
{
DeleteSinkItems();
}
void wxOSXPasteboard::DeleteSinkItems()
void wxOSXPasteboardSink::DeleteSinkItems()
{
for ( wxVector<wxOSXDataSinkItem*>::iterator it = m_sinkItems.begin();
it != m_sinkItems.end();
@@ -184,15 +183,27 @@ void wxOSXPasteboard::DeleteSinkItems()
m_sinkItems.clear();
}
// data sink methods
void wxOSXPasteboard::Clear()
void wxOSXPasteboardSink::Clear()
{
[m_pasteboard clearContents];
DeleteSinkItems();
}
void wxOSXPasteboard::Flush()
wxOSXDataSinkItem* wxOSXPasteboardSink::CreateItem()
{
wxOSXDataSinkItem* item = DoCreateItem();
m_sinkItems.push_back(item);
return item;
}
wxOSXDataSinkItem* wxOSXPasteboardSink::DoCreateItem()
{
NSPasteboardItem* nsitem = [[NSPasteboardItem alloc] init];
return new wxOSXPasteboardSinkItem(nsitem);
}
WX_NSArray wxOSXPasteboardSink::Flush()
{
NSMutableArray* nsarray = [[NSMutableArray alloc] init];
for ( wxVector<wxOSXDataSinkItem*>::iterator it = m_sinkItems.begin();
@@ -204,17 +215,33 @@ void wxOSXPasteboard::Flush()
delete item;
}
m_sinkItems.clear();
[m_pasteboard writeObjects:nsarray];
[nsarray release];
return [nsarray autorelease];
}
wxOSXDataSinkItem* wxOSXPasteboard::CreateItem()
wxOSXPasteboard::wxOSXPasteboard(OSXPasteboard native)
{
NSPasteboardItem* nsitem = [[NSPasteboardItem alloc] init];
wxOSXPasteboardSinkItem* item = new wxOSXPasteboardSinkItem(nsitem);
m_sinkItems.push_back(item);
m_pasteboard = native;
}
return item;
wxOSXPasteboard::~wxOSXPasteboard()
{
}
// data sink methods
void wxOSXPasteboard::Clear()
{
[m_pasteboard clearContents];
wxOSXPasteboardSink::Clear();
}
WX_NSArray wxOSXPasteboard::Flush()
{
NSArray* nsarray = wxOSXPasteboardSink::Flush();
[m_pasteboard writeObjects:nsarray];
return nsarray;
}
// data source methods
@@ -321,17 +348,10 @@ wxDragResult NSDragOperationToWxDragResult(NSDragOperation code)
wxUnusedVar(session);
wxUnusedVar(context);
NSDragOperation allowedDragOperations = NSDragOperationEvery;
NSDragOperation allowedDragOperations = NSDragOperationCopy;
// NSDragOperationGeneric also makes a drag to the trash possible
// resulting in something we don't support (NSDragOperationDelete)
allowedDragOperations &= ~(NSDragOperationDelete | NSDragOperationGeneric);
if (m_dragFlags == wxDrag_CopyOnly)
{
allowedDragOperations &= ~NSDragOperationMove;
}
if ( m_dragFlags != wxDrag_CopyOnly )
allowedDragOperations |= NSDragOperationMove;
// we might adapt flags here in the future
// context can be NSDraggingContextOutsideApplication or NSDraggingContextWithinApplication
@@ -541,11 +561,19 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
NSPoint down = [theEvent locationInWindow];
NSPoint p = [view convertPoint:down fromView:nil];
wxPasteBoardWriter* writer = [[wxPasteBoardWriter alloc] initWithDataObject:m_data];
wxOSXPasteboardSink datasink;
m_data->WriteToSink(&datasink);
NSArray* dataitems = datasink.Flush();
wxCFMutableArrayRef<NSDraggingItem*> items;
NSDraggingItem* item = [[NSDraggingItem alloc] initWithPasteboardWriter:writer];
[item setDraggingFrame:NSMakeRect(p.x, p.y, 16, 16) contents:image];
items.push_back(item);
for (NSPasteboardItem* dataitem in dataitems )
{
NSDraggingItem* item = [[NSDraggingItem alloc] initWithPasteboardWriter:dataitem];
[item setDraggingFrame:NSMakeRect(p.x, p.y, 16, 16) contents:image];
items.push_back(item);
[item release];
}
[view beginDraggingSessionWithItems:items event:theEvent source:delegate];
wxEventLoopBase * const loop = wxEventLoop::GetActive();
@@ -555,8 +583,6 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
result = NSDragOperationToWxDragResult([delegate code]);
[delegate release];
[image release];
[writer clearDataObject];
[writer release];
wxWindow* mouseUpTarget = wxWindow::GetCapture();