vcl/source/window/dialog.cxx | 25 ++++++++++++++----------- vcl/source/window/mouse.cxx | 3 ++- vcl/source/window/paint.cxx | 17 +++++++++++++++-- vcl/source/window/window2.cxx | 5 +++++ vcl/source/window/winproc.cxx | 34 ++++++++++++++++++++++------------ 5 files changed, 58 insertions(+), 26 deletions(-)
New commits: commit 16aac413015beac2b5bfc4024810534cbd035452 Author: Gabriel Masei <gabriel.ma...@1and1.ro> AuthorDate: Wed Jun 16 09:41:12 2021 +0300 Commit: Aron Budea <aron.bu...@collabora.com> CommitDate: Thu Aug 26 09:23:05 2021 +0200 vcl: check mpWindowImpl for nullptr Change-Id: I492c7d5c1846df7507b1f043b80de4e61ff8ca86 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117282 Tested-by: Jenkins Reviewed-by: Michael Meeks <michael.me...@collabora.com> (cherry picked from commit bf6dabe0ebad3cc5bc0edc04ae74fba0190b6203) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121049 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Aron Budea <aron.bu...@collabora.com> diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx index a30aa19f71b4..74462fc1c7c5 100644 --- a/vcl/source/window/dialog.cxx +++ b/vcl/source/window/dialog.cxx @@ -418,7 +418,8 @@ vcl::Window* Dialog::GetDefaultParent(WinBits nStyle) auto& rExecuteDialogs = pSVData->mpWinData->mpExecuteDialogs; auto it = std::find_if(rExecuteDialogs.rbegin(), rExecuteDialogs.rend(), [&pParent](VclPtr<Dialog>& rDialogPtr) { - return pParent->ImplGetFirstOverlapWindow()->IsWindowOrChild(rDialogPtr, true) && + return pParent->ImplGetFirstOverlapWindow() && + pParent->ImplGetFirstOverlapWindow()->IsWindowOrChild(rDialogPtr, true) && rDialogPtr->IsReallyVisible() && rDialogPtr->IsEnabled() && rDialogPtr->IsInputEnabled() && !rDialogPtr->IsInModalMode(); }); if (it != rExecuteDialogs.rend()) @@ -964,12 +965,15 @@ bool Dialog::ImplStartExecute() if ( pParent ) { pParent = pParent->ImplGetFirstOverlapWindow(); - SAL_WARN_IF( !pParent->IsReallyVisible(), "vcl", - "Dialog::StartExecuteModal() - Parent not visible" ); - SAL_WARN_IF( !pParent->IsInputEnabled(), "vcl", - "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ); - SAL_WARN_IF( pParent->IsInModalMode(), "vcl", - "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ); + if (pParent) + { + SAL_WARN_IF( !pParent->IsReallyVisible(), "vcl", + "Dialog::StartExecuteModal() - Parent not visible" ); + SAL_WARN_IF( !pParent->IsInputEnabled(), "vcl", + "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ); + SAL_WARN_IF( pParent->IsInModalMode(), "vcl", + "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ); + } } #endif @@ -1287,12 +1291,11 @@ void Dialog::ImplSetModalInputMode( bool bModal ) void Dialog::GrabFocusToFirstControl() { - vcl::Window* pFocusControl; + vcl::Window* pFocusControl = nullptr; + vcl::Window* pFirstOverlapWindow = ImplGetFirstOverlapWindow(); // find focus control, even if the dialog has focus - if ( HasFocus() ) - pFocusControl = nullptr; - else + if (!HasFocus() && pFirstOverlapWindow && pFirstOverlapWindow->mpWindowImpl) { // prefer a child window which had focus before pFocusControl = ImplGetFirstOverlapWindow()->mpWindowImpl->mpLastFocusWindow; diff --git a/vcl/source/window/mouse.cxx b/vcl/source/window/mouse.cxx index c1a59bc0dc90..6517ad2d90c1 100644 --- a/vcl/source/window/mouse.cxx +++ b/vcl/source/window/mouse.cxx @@ -292,7 +292,8 @@ void Window::ImplGrabFocus( GetFocusFlags nFlags ) // mark this windows as the last FocusWindow vcl::Window* pOverlapWindow = ImplGetFirstOverlapWindow(); - pOverlapWindow->mpWindowImpl->mpLastFocusWindow = this; + if (pOverlapWindow->mpWindowImpl) + pOverlapWindow->mpWindowImpl->mpLastFocusWindow = this; mpWindowImpl->mpFrameData->mpFocusWin = this; if( !bHasFocus ) diff --git a/vcl/source/window/paint.cxx b/vcl/source/window/paint.cxx index 034eef555d6a..95640db261bb 100644 --- a/vcl/source/window/paint.cxx +++ b/vcl/source/window/paint.cxx @@ -622,6 +622,9 @@ void Window::ImplCallPaint(const vcl::Region* pRegion, ImplPaintFlags nPaintFlag void Window::ImplCallOverlapPaint() { + if (!mpWindowImpl) + return; + // emit overlapping windows first vcl::Window* pTempWindow = mpWindowImpl->mpFirstOverlap; while ( pTempWindow ) @@ -988,7 +991,7 @@ void Window::ImplValidate() void Window::ImplUpdateAll() { - if ( !mpWindowImpl->mbReallyVisible ) + if ( !mpWindowImpl || !mpWindowImpl->mbReallyVisible ) return; bool bFlush = false; @@ -1287,6 +1290,9 @@ bool Window::HasPaintEvent() const void Window::PaintImmediately() { + if (!mpWindowImpl) + return; + if ( mpWindowImpl->mpBorderWindow ) { mpWindowImpl->mpBorderWindow->PaintImmediately(); @@ -1338,7 +1344,11 @@ void Window::PaintImmediately() // trigger an update also for system windows on top of us, // otherwise holes would remain - vcl::Window* pUpdateOverlapWindow = ImplGetFirstOverlapWindow()->mpWindowImpl->mpFirstOverlap; + vcl::Window* pUpdateOverlapWindow = ImplGetFirstOverlapWindow(); + if (pUpdateOverlapWindow->mpWindowImpl) + pUpdateOverlapWindow = pUpdateOverlapWindow->mpWindowImpl->mpFirstOverlap; + else + pUpdateOverlapWindow = nullptr; while ( pUpdateOverlapWindow ) { pUpdateOverlapWindow->PaintImmediately(); @@ -1568,6 +1578,9 @@ void Window::ImplPaintToDevice( OutputDevice* i_pTargetOutDev, const Point& i_rP void Window::PaintToDevice(OutputDevice* pDev, const Point& rPos) { + if( !mpWindowImpl ) + return; + SAL_WARN_IF( pDev->HasMirroredGraphics(), "vcl.window", "PaintToDevice to mirroring graphics" ); SAL_WARN_IF( pDev->IsRTLEnabled(), "vcl.window", "PaintToDevice to mirroring device" ); diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx index 8b8348079887..d1f5ec5e2f95 100644 --- a/vcl/source/window/window2.cxx +++ b/vcl/source/window/window2.cxx @@ -892,6 +892,11 @@ vcl::Window* Window::ImplGetFirstOverlapWindow() const vcl::Window* Window::ImplGetFirstOverlapWindow() const { + if (!mpWindowImpl) + { + return nullptr; + } + if ( mpWindowImpl->mbOverlapWin ) return this; else diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx index 4e1f4f5117d3..2096b7cf3da1 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -1865,6 +1865,9 @@ IMPL_LINK_NOARG(vcl::Window, ImplAsyncFocusHdl, void*, void) static void ImplHandleGetFocus( vcl::Window* pWindow ) { + if (!pWindow || !pWindow->ImplGetWindowImpl() || !pWindow->ImplGetWindowImpl()->mpFrameData) + return; + pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = true; // execute Focus-Events after a delay, such that SystemChildWindows @@ -1881,6 +1884,9 @@ static void ImplHandleGetFocus( vcl::Window* pWindow ) static void ImplHandleLoseFocus( vcl::Window* pWindow ) { + if (!pWindow) + return; + ImplSVData* pSVData = ImplGetSVData(); // Abort the autoscroll if the frame loses focus @@ -1890,23 +1896,27 @@ static void ImplHandleLoseFocus( vcl::Window* pWindow ) // Abort tracking if the frame loses focus if (pSVData->mpWinData->mpTrackWin) { - if (pSVData->mpWinData->mpTrackWin->ImplGetWindowImpl()->mpFrameWindow == pWindow) + if (pSVData->mpWinData->mpTrackWin->ImplGetWindowImpl() && + pSVData->mpWinData->mpTrackWin->ImplGetWindowImpl()->mpFrameWindow == pWindow) pSVData->mpWinData->mpTrackWin->EndTracking(TrackingEventFlags::Cancel); } - pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = false; - - // execute Focus-Events after a delay, such that SystemChildWindows - // do not flicker when they receive focus - if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId ) + if (pWindow->ImplGetWindowImpl() && pWindow->ImplGetWindowImpl()->mpFrameData) { - pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus; - pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId = Application::PostUserEvent( LINK( pWindow, vcl::Window, ImplAsyncFocusHdl ), nullptr, true ); - } + pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = false; + + // execute Focus-Events after a delay, such that SystemChildWindows + // do not flicker when they receive focus + if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId ) + { + pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus; + pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId = Application::PostUserEvent( LINK( pWindow, vcl::Window, ImplAsyncFocusHdl ), nullptr, true ); + } - vcl::Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin; - if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor ) - pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide(); + vcl::Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin; + if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor ) + pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide(); + } // Make sure that no menu is visible when a toplevel window loses focus. VclPtr<FloatingWindow> pFirstFloat = pSVData->mpWinData->mpFirstFloat;