Merge branch 'auibook-drag-fix'

Fix crash when dragging in wxAuiNotebook and make the code more robust.

See #24039.
This commit is contained in:
Vadim Zeitlin 2023-11-07 15:09:56 +01:00
commit 6fbb504955
2 changed files with 31 additions and 19 deletions

View file

@ -236,14 +236,19 @@ protected:
protected:
wxPoint m_clickPt;
wxWindow* m_clickTab;
bool m_isDragging;
wxAuiTabContainerButton* m_hoverButton;
wxAuiTabContainerButton* m_pressedButton;
wxPoint m_clickPt = wxDefaultPosition;
wxWindow* m_clickTab = nullptr;
bool m_isDragging = false;
wxAuiTabContainerButton* m_hoverButton = nullptr;
wxAuiTabContainerButton* m_pressedButton = nullptr;
void SetHoverTab(wxWindow* wnd);
private:
// Reset dragging-related fields above to their initial values.
void DoEndDragging();
#ifndef SWIG
wxDECLARE_CLASS(wxAuiTabCtrl);
wxDECLARE_EVENT_TABLE();

View file

@ -1013,16 +1013,19 @@ wxAuiTabCtrl::wxAuiTabCtrl(wxWindow* parent,
long style) : wxControl(parent, id, pos, size, style)
{
SetName(wxT("wxAuiTabCtrl"));
m_clickPt = wxDefaultPosition;
m_isDragging = false;
m_hoverButton = nullptr;
m_pressedButton = nullptr;
}
wxAuiTabCtrl::~wxAuiTabCtrl()
{
}
void wxAuiTabCtrl::DoEndDragging()
{
m_clickPt = wxDefaultPosition;
m_isDragging = false;
m_clickTab = nullptr;
}
void wxAuiTabCtrl::OnPaint(wxPaintEvent&)
{
wxPaintDC dc(this);
@ -1057,9 +1060,9 @@ void wxAuiTabCtrl::OnSize(wxSizeEvent& evt)
void wxAuiTabCtrl::OnLeftDown(wxMouseEvent& evt)
{
CaptureMouse();
m_clickPt = wxDefaultPosition;
m_isDragging = false;
m_clickTab = nullptr;
// Reset any previous values first.
DoEndDragging();
m_pressedButton = nullptr;
@ -1099,10 +1102,12 @@ void wxAuiTabCtrl::OnCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event))
{
if (m_isDragging)
{
m_isDragging = false;
const auto clickTab = m_clickTab;
DoEndDragging();
wxAuiNotebookEvent evt(wxEVT_AUINOTEBOOK_CANCEL_DRAG, m_windowId);
evt.SetSelection(GetIdxFromWindow(m_clickTab));
evt.SetSelection(GetIdxFromWindow(clickTab));
evt.SetOldSelection(evt.GetSelection());
evt.SetEventObject(this);
GetEventHandler()->ProcessEvent(evt);
@ -1116,10 +1121,12 @@ void wxAuiTabCtrl::OnLeftUp(wxMouseEvent& evt)
if (m_isDragging)
{
m_isDragging = false;
const auto clickTab = m_clickTab;
DoEndDragging();
wxAuiNotebookEvent e(wxEVT_AUINOTEBOOK_END_DRAG, m_windowId);
e.SetSelection(GetIdxFromWindow(m_clickTab));
e.SetSelection(GetIdxFromWindow(clickTab));
e.SetOldSelection(e.GetSelection());
e.SetEventObject(this);
GetEventHandler()->ProcessEvent(e);
@ -1156,9 +1163,7 @@ void wxAuiTabCtrl::OnLeftUp(wxMouseEvent& evt)
m_pressedButton = nullptr;
}
m_clickPt = wxDefaultPosition;
m_isDragging = false;
m_clickTab = nullptr;
DoEndDragging();
}
void wxAuiTabCtrl::OnMiddleUp(wxMouseEvent& evt)
@ -2605,6 +2610,8 @@ void wxAuiNotebook::OnTabDragMotion(wxAuiNotebookEvent& evt)
if (dest_tabs->TabHitTest(pt.x, pt.y, &dest_location_tab))
{
int src_idx = evt.GetSelection();
wxCHECK_RET( src_idx != -1, "Invalid source tab?" );
int dest_idx = dest_tabs->GetIdxFromWindow(dest_location_tab);
// prevent jumpy drag