editeng/source/editeng/editview.cxx | 2 ++ editeng/source/outliner/outlvw.cxx | 2 ++ include/editeng/editview.hxx | 1 + include/editeng/outliner.hxx | 1 + svx/source/svdraw/svdedxv.cxx | 16 +++++++++++----- 5 files changed, 17 insertions(+), 5 deletions(-)
New commits: commit 75aeaab5ef36f819cdc11e88244f59efc4fbc5a6 Author: Jaume Pujantell <[email protected]> AuthorDate: Mon Jul 29 12:35:50 2024 +0200 Commit: Miklos Vajna <[email protected]> CommitDate: Thu Aug 1 13:54:28 2024 +0200 cool#9352 unassign cursor on SdrObjEditView to avoid crash On stress test with shapes and typing a segfault ocurred due to using a freed vcl::Cursor. On SdrObjEditView::SdrEndTextEdit, delete pOLV can delete the cursor remembered in pTECursorBuffer. But if it is set to the window before the deletion, it will be safely removed from the window. And on SdrObjEditView::ModelHasChanged a re-anchoring sets a cursor on the window that sholdn't be there and other SdrObjEditView can see, remeber, and use it even after this one died and freed the cursor. Change-Id: I3cfef3b68b77e6e6b49c3b68297a6a20e1f9394a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171184 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> (cherry picked from commit 3b5738ab1a646d089fa7cc59ffaeda7d011c1e07) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171288 Tested-by: Jenkins diff --git a/editeng/source/editeng/editview.cxx b/editeng/source/editeng/editview.cxx index a686ccb04111..d76f0a1c69c0 100644 --- a/editeng/source/editeng/editview.cxx +++ b/editeng/source/editeng/editview.cxx @@ -568,6 +568,8 @@ void EditView::HideCursor(bool bDeactivate) } } +bool EditView::IsCursorVisible() const { return getImpl().GetCursor()->IsVisible(); } + Pair EditView::Scroll( tools::Long ndX, tools::Long ndY, ScrollRangeCheck nRangeCheck ) { return getImpl().Scroll( ndX, ndY, nRangeCheck ); diff --git a/editeng/source/outliner/outlvw.cxx b/editeng/source/outliner/outlvw.cxx index 4bcd01905283..e4f06d4548a0 100644 --- a/editeng/source/outliner/outlvw.cxx +++ b/editeng/source/outliner/outlvw.cxx @@ -1255,6 +1255,8 @@ void OutlinerView::HideCursor(bool bDeactivate) pEditView->HideCursor(bDeactivate); } +bool OutlinerView::IsCursorVisible() const { return pEditView->IsCursorVisible(); } + void OutlinerView::SetWindow( vcl::Window* pWin ) { pEditView->SetWindow( pWin ); diff --git a/include/editeng/editview.hxx b/include/editeng/editview.hxx index f2c5f9c46d7d..a1cb4eb9603b 100644 --- a/include/editeng/editview.hxx +++ b/include/editeng/editview.hxx @@ -205,6 +205,7 @@ public: tools::Rectangle GetEditCursor() const; void ShowCursor( bool bGotoCursor = true, bool bForceVisCursor = true, bool bActivate = false ); void HideCursor( bool bDeactivate = false ); + bool IsCursorVisible() const; void SetSelectionMode( EESelectionMode eMode ); diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx index cd3acaf9452d..4b28af42ab00 100644 --- a/include/editeng/outliner.hxx +++ b/include/editeng/outliner.hxx @@ -221,6 +221,7 @@ public: void ShowCursor( bool bGotoCursor = true, bool bActivate = false ); void HideCursor( bool bDeactivate = false ); + bool IsCursorVisible() const; Outliner* GetOutliner() const { return pOwner; } diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx index fe647da817a1..ec938c51c320 100644 --- a/svx/source/svdraw/svdedxv.cxx +++ b/svx/source/svdraw/svdedxv.cxx @@ -434,8 +434,8 @@ void SdrObjEditView::ModelHasChanged() for (size_t nOV = 0; nOV < nOutlViewCnt; nOV++) { OutlinerView* pOLV = mpTextEditOutliner->GetView(nOV); + vcl::Window* pWin = pOLV->GetWindow(); { // invalidate old OutlinerView area - vcl::Window* pWin = pOLV->GetWindow(); tools::Rectangle aTmpRect(aOldArea); sal_uInt16 nPixSiz = pOLV->GetInvalidateMore() + 1; Size aMore(pWin->PixelToLogic(Size(nPixSiz, nPixSiz))); @@ -450,9 +450,15 @@ void SdrObjEditView::ModelHasChanged() if (bColorChg) pOLV->SetBackgroundColor(aNewColor); + bool bWasCoursorVisible = pOLV->IsCursorVisible(); + vcl::Cursor* pOldCursor = pWin->GetCursor(); pOLV->SetOutputArea( aTextEditArea); // because otherwise, we're not re-anchoring correctly ImpInvalidateOutlinerView(*pOLV); + // Undo SetOutputArea setting and showing the cursor + if (!bWasCoursorVisible) + pOLV->HideCursor(); + pWin->SetCursor(pOldCursor); } mpTextEditOutlinerView->ShowCursor(); } @@ -1853,6 +1859,10 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(bool bDontDeleteReally) // to call AdjustMarkHdl() always. AdjustMarkHdl(); } + if (pTEWin != nullptr) + { + pTEWin->SetCursor(pTECursorBuffer); + } // delete all OutlinerViews for (size_t i = pTEOutliner->GetViewCount(); i > 0;) { @@ -1884,10 +1894,6 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(bool bDontDeleteReally) delete pTEOutliner; else pTEOutliner->Clear(); - if (pTEWin != nullptr) - { - pTEWin->SetCursor(pTECursorBuffer); - } maHdlList.SetMoveOutside(false); if (eRet != SdrEndTextEditKind::Unchanged) {
