From cf30850d2e04737ca1c646eef6668f110d7ab883 Mon Sep 17 00:00:00 2001 From: Gabriel Masei Date: Wed, 16 Jun 2021 09:41:12 +0300 Subject: vcl: check mpWindowImpl for nullptr Change-Id: I492c7d5c1846df7507b1f043b80de4e61ff8ca86 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117282 Tested-by: Jenkins Reviewed-by: Michael Meeks (cherry picked from commit bf6dabe0ebad3cc5bc0edc04ae74fba0190b6203) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117292 Tested-by: Jenkins CollaboraOffice Reviewed-by: Andras Timar --- 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(-) diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx index 3cbffb41da66..a68a6a8e4249 100644 --- a/vcl/source/window/dialog.cxx +++ b/vcl/source/window/dialog.cxx @@ -416,7 +416,8 @@ vcl::Window* Dialog::GetDefaultParent(WinBits nStyle) auto& rExecuteDialogs = pSVData->mpWinData->mpExecuteDialogs; auto it = std::find_if(rExecuteDialogs.rbegin(), rExecuteDialogs.rend(), [&pParent](VclPtr& 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()) @@ -962,12 +963,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 @@ -1264,12 +1268,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 e2f0458bf0fe..513b186b2dc7 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 218cdd3216ed..f361e49d392b 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::Update() { + if (!mpWindowImpl) + return; + if ( mpWindowImpl->mpBorderWindow ) { mpWindowImpl->mpBorderWindow->Update(); @@ -1338,7 +1344,11 @@ void Window::Update() // 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->Update(); @@ -1601,6 +1611,9 @@ void Window::ImplPaintToDevice( OutputDevice* i_pTargetOutDev, const Point& i_rP void Window::PaintToDevice( OutputDevice* pDev, const Point& rPos, const Size& /*rSize*/ ) { + 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 b4c69e49d0ff..32150d1474fc 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 fe3b8bee916d..096dd683c894 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -1843,6 +1843,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 @@ -1859,6 +1862,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 @@ -1868,23 +1874,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 pFirstFloat = pSVData->mpWinData->mpFirstFloat; -- cgit