diff options
author | Jaume Pujantell <jaume.pujantell@collabora.com> | 2024-07-29 12:35:50 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2024-07-31 12:03:12 +0200 |
commit | 3b5738ab1a646d089fa7cc59ffaeda7d011c1e07 (patch) | |
tree | 86a9cdb33845769e541ca0b835a62e1131003623 | |
parent | b24e920c6dc00ce39decee2596217e99f798a95c (diff) |
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 <vmiklos@collabora.com>
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
-rw-r--r-- | editeng/source/editeng/editview.cxx | 2 | ||||
-rw-r--r-- | editeng/source/outliner/outlvw.cxx | 2 | ||||
-rw-r--r-- | include/editeng/editview.hxx | 1 | ||||
-rw-r--r-- | include/editeng/outliner.hxx | 1 | ||||
-rw-r--r-- | svx/source/svdraw/svdedxv.cxx | 16 |
5 files changed, 17 insertions, 5 deletions
diff --git a/editeng/source/editeng/editview.cxx b/editeng/source/editeng/editview.cxx index e2f429bc7789..d4b60fecf415 100644 --- a/editeng/source/editeng/editview.cxx +++ b/editeng/source/editeng/editview.cxx @@ -566,6 +566,8 @@ void EditView::HideCursor(bool bDeactivate) } } +bool EditView::IsCursorVisible() const { return pImpEditView->GetCursor()->IsVisible(); } + Pair EditView::Scroll( tools::Long ndX, tools::Long ndY, ScrollRangeCheck nRangeCheck ) { return pImpEditView->Scroll( ndX, ndY, nRangeCheck ); diff --git a/editeng/source/outliner/outlvw.cxx b/editeng/source/outliner/outlvw.cxx index f3fd835ec1c9..fba3b099826a 100644 --- a/editeng/source/outliner/outlvw.cxx +++ b/editeng/source/outliner/outlvw.cxx @@ -1237,6 +1237,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 01a0e426c09a..0bafa99bb35f 100644 --- a/include/editeng/editview.hxx +++ b/include/editeng/editview.hxx @@ -207,6 +207,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 8733e4c4d429..79987a6b802a 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 48e28bc402a2..bc410669546c 100644 --- a/svx/source/svdraw/svdedxv.cxx +++ b/svx/source/svdraw/svdedxv.cxx @@ -359,8 +359,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))); @@ -375,9 +375,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(); } @@ -1766,6 +1772,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;) { @@ -1797,10 +1807,6 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(bool bDontDeleteReally) delete pTEOutliner; else pTEOutliner->Clear(); - if (pTEWin != nullptr) - { - pTEWin->SetCursor(pTECursorBuffer); - } maHdlList.SetMoveOutside(false); if (eRet != SdrEndTextEditKind::Unchanged) { |