[Git][wxwidgets/wxwidgets][master] 2 commits: Guard against re-entering in wxOSX wxDropSource::DoDragDrop()

1 view
Skip to first unread message

Vadim Zeitlin (@_VZ_)

unread,
Dec 13, 2025, 7:37:15 PM (3 days ago) Dec 13
to wx-commi...@googlegroups.com

Vadim Zeitlin pushed to branch master at wxWidgets / wxWidgets

Commits:

  • 948b4f36
    by 徐扬斌 at 2025-12-14T00:56:41+01:00
    Guard against re-entering in wxOSX wxDropSource::DoDragDrop()
    
    At least when using CEF, repeatedly starting drag-and-drop operation may
    result in stack overflow.
    
    Messages processed by CEF are handled when wxEVT_IDLE is triggered and
    the problematic scenario is when:
    
    1. Cocoa calls OSXDefaultModeObserverCallBack()
    2. wxEVT_IDLE is triggered.
    3. wxWebViewChromium::OnIdle() is called.
    4. CefDoMessageLoopWork() performs various jobs for CEF.
    
    If DoDragDrop() is invoked during CefDoMessageLoopWork(), and there is a
    recursive call to it, then the previous DoDragDrop() can't return
    anymore, and will, in turn, prevent CefDoMessageLoopWork() from
    returning to the caller.
    
    Prevent recursively re-entering this function to avoid this.
    
    See #24520.
    
    Co-authored-by: Vadim Zeitlin <va...@wxwidgets.org>
    
  • 31966f7d
    by 徐扬斌 at 2025-12-14T01:03:27+01:00
    Allow wxDropSource::DoDragDrop() without mouse event in wxOSX
    
    DoDragDrop() may be called not only in response to a mouse event, but
    also, when using CEF, from external code.
    
    Synthesize an artificial event in this case instead of failing with an
    assert.
    
    See #24520.
    

1 changed file:

Changes:

  • src/osx/cocoa/dnd.mm
    ... ... @@ -18,6 +18,7 @@
    18 18
     #include "wx/dnd.h"
    
    19 19
     #include "wx/clipbrd.h"
    
    20 20
     #include "wx/filename.h"
    
    21
    +#include "wx/recguard.h"
    
    21 22
     
    
    22 23
     #ifndef WX_PRECOMP
    
    23 24
         #include "wx/app.h"
    
    ... ... @@ -483,17 +484,39 @@ typedef NSString* NSPasteboardType;
    483 484
     
    
    484 485
     wxDragResult wxDropSource::DoDragDrop(int flags)
    
    485 486
     {
    
    487
    +    static wxRecursionGuardFlag s_inDragDrop = 0;
    
    488
    +
    
    486 489
         wxASSERT_MSG( m_data, wxT("Drop source: no data") );
    
    487 490
     
    
    488 491
         wxDragResult result = wxDragNone;
    
    489 492
         if ((m_data == nullptr) || (m_data->GetFormatCount() == 0))
    
    490 493
             return result;
    
    491 494
     
    
    495
    +    wxRecursionGuard guard(s_inDragDrop);
    
    496
    +    if (guard.IsInside())
    
    497
    +        return wxDragNone;
    
    498
    +
    
    492 499
         NSView* view = m_window->GetPeer()->GetWXWidget();
    
    493 500
         if (view)
    
    494 501
         {
    
    495 502
             NSEvent* theEvent = (NSEvent*)wxTheApp->MacGetCurrentEvent();
    
    496
    -        wxASSERT_MSG(theEvent, "DoDragDrop must be called in response to a mouse down or drag event.");
    
    503
    +
    
    504
    +        // Drag and drop operation can be started from an external mouse event
    
    505
    +        // handler, this happens at least when using CEF, so synthesize the
    
    506
    +        // mouse event if we don't have one.
    
    507
    +        if (theEvent == nil)
    
    508
    +        {
    
    509
    +            NSPoint mouse_location = [NSEvent mouseLocation];
    
    510
    +            theEvent = [NSEvent mouseEventWithType:NSEventTypeLeftMouseDragged 
    
    511
    +                location:mouse_location
    
    512
    +                modifierFlags:0
    
    513
    +                timestamp: 0
    
    514
    +                windowNumber: [NSWindow windowNumberAtPoint:mouse_location belowWindowWithWindowNumber:0]
    
    515
    +                context:nil
    
    516
    +                eventNumber: 0
    
    517
    +                clickCount: 0
    
    518
    +                pressure: 1.0];
    
    519
    +        }
    
    497 520
     
    
    498 521
             gCurrentSource = this;
    
    499 522
     
    
    ... ... @@ -560,7 +583,6 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
    560 583
             gCurrentSource = nullptr;
    
    561 584
         }
    
    562 585
     
    
    563
    -
    
    564 586
         return result;
    
    565 587
     }
    
    566 588
     
    

Reply all
Reply to author
Forward
0 new messages