// put the window to the end of the list if ( mpWindowImpl->mpPrev )
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; else
{ // coverity[copy_paste_error : FALSE] - this is correct mpFirstChild, not mpNext
mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
}
mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
mpWindowImpl->mpPrev = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild;
mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
mpWindowImpl->mpNext = nullptr;
}
void Window::ImplCalcToTop( ImplCalcToTopData* pPrevData )
{
SAL_WARN_IF( !ImplIsOverlapWindow(), "vcl", "Window::ImplCalcToTop(): Is not an OverlapWindow" );
if ( mpWindowImpl->mbFrame ) return;
if ( !IsReallyVisible() ) return;
// calculate region, where the window overlaps with other windows
vcl::Region aRegion( GetOutputRectPixel() );
vcl::Region aInvalidateRegion;
ImplCalcOverlapRegionOverlaps( aRegion, aInvalidateRegion );
if ( !aInvalidateRegion.IsEmpty() )
{
ImplCalcToTopData* pData = new ImplCalcToTopData;
pPrevData->mpNext.reset(pData);
pData->mpWindow = this;
pData->mpInvalidateRegion.reset(new vcl::Region(std::move(aInvalidateRegion)));
}
}
void Window::ImplToTop( ToTopFlags nFlags )
{
SAL_WARN_IF( !ImplIsOverlapWindow(), "vcl", "Window::ImplToTop(): Is not an OverlapWindow" );
if ( mpWindowImpl->mbFrame )
{ // on a mouse click in the external window, it is the latter's // responsibility to assure our frame is put in front if ( !mpWindowImpl->mpFrameData->mbHasFocus &&
!mpWindowImpl->mpFrameData->mbSysObjFocus &&
!mpWindowImpl->mpFrameData->mbInSysObjFocusHdl &&
!mpWindowImpl->mpFrameData->mbInSysObjToTopHdl )
{ // do not bring floating windows on the client to top if( !ImplGetClientWindow() || !(ImplGetClientWindow()->GetStyle() & WB_SYSTEMFLOATWIN) )
{
SalFrameToTop nSysFlags = SalFrameToTop::NONE; if ( nFlags & ToTopFlags::RestoreWhenMin )
nSysFlags |= SalFrameToTop::RestoreWhenMin; if ( nFlags & ToTopFlags::ForegroundTask )
nSysFlags |= SalFrameToTop::ForegroundTask; if ( nFlags & ToTopFlags::GrabFocusOnly )
nSysFlags |= SalFrameToTop::GrabFocusOnly;
mpWindowImpl->mpFrame->ToTop( nSysFlags );
}
}
} else
{ if ( mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap.get() != this )
{ // remove window from the list
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; if ( mpWindowImpl->mpNext )
mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; else
{ // coverity[copy_paste_error : FALSE] - this is correct mpLastOverlap, not mpPrev
mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
}
// take AlwaysOnTop into account bool bOnTop = IsAlwaysOnTopEnabled();
vcl::Window* pNextWin = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap; if ( !bOnTop )
{ while ( pNextWin )
{ if ( !pNextWin->IsAlwaysOnTopEnabled() ) break;
pNextWin = pNextWin->mpWindowImpl->mpNext;
}
}
// add the window to the list again
mpWindowImpl->mpNext = pNextWin; if ( pNextWin )
{
mpWindowImpl->mpPrev = pNextWin->mpWindowImpl->mpPrev;
pNextWin->mpWindowImpl->mpPrev = this;
} else
{
mpWindowImpl->mpPrev = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap;
mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this;
} if ( mpWindowImpl->mpPrev )
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; else
mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this;
// recalculate ClipRegion of this and all overlapping windows if ( IsReallyVisible() )
{
mpWindowImpl->mpOverlapWindow->ImplSetClipFlagOverlapWindows();
}
}
}
}
// first calculate paint areas
vcl::Window* pTempOverlapWindow = pOverlapWindow;
aStartData.mpNext = nullptr;
pCurData = &aStartData; do
{
pTempOverlapWindow->ImplCalcToTop( pCurData ); if ( pCurData->mpNext )
pCurData = pCurData->mpNext.get();
pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow;
} while ( !pTempOverlapWindow->mpWindowImpl->mbFrame ); // next calculate the paint areas of the ChildOverlap windows
pTempOverlapWindow = mpWindowImpl->mpFirstOverlap; while ( pTempOverlapWindow )
{
pTempOverlapWindow->ImplCalcToTop( pCurData ); if ( pCurData->mpNext )
pCurData = pCurData->mpNext.get();
pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpNext;
}
// and next change the windows list
pTempOverlapWindow = pOverlapWindow; do
{
pTempOverlapWindow->ImplToTop( nFlags );
pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow;
} while ( !pTempOverlapWindow->mpWindowImpl->mbFrame ); // as last step invalidate the invalid areas
pCurData = aStartData.mpNext.get(); while ( pCurData )
{
pCurData->mpWindow->ImplInvalidateFrameRegion( pCurData->mpInvalidateRegion.get(), InvalidateFlags::Children );
pCurData = pCurData->mpNext.get();
}
}
void Window::ImplFocusToTop( ToTopFlags nFlags, bool bReallyVisible )
{ // do we need to fetch the focus? if ( !(nFlags & ToTopFlags::NoGrabFocus) )
{ // first window with GrabFocus-Activate gets the focus
vcl::Window* pFocusWindow = this; while ( !pFocusWindow->ImplIsOverlapWindow() )
{ // if the window has no BorderWindow, we // should always find the belonging BorderWindow if ( !pFocusWindow->mpWindowImpl->mpBorderWindow )
{ if ( pFocusWindow->mpWindowImpl->mnActivateMode & ActivateModeFlags::GrabFocus ) break;
}
pFocusWindow = pFocusWindow->ImplGetParent();
} if ( (pFocusWindow->mpWindowImpl->mnActivateMode & ActivateModeFlags::GrabFocus) &&
!pFocusWindow->HasChildPathFocus( true ) )
pFocusWindow->GrabFocus();
}
// When ClipRegion was not initialised, assume // the window has not been sent, therefore do not // trigger any Invalidates. This is an optimization // for HTML documents with many controls. If this // check gives problems, a flag should be introduced // which tracks whether the window has already been // emitted after Show if ( bInitWinClipRegion ) return;
// Invalidate all windows which are next to each other // Is INCOMPLETE !!!
tools::Rectangle aWinRect = GetOutputRectPixel();
vcl::Window* pWindow = nullptr; if ( ImplIsOverlapWindow() )
{ if ( mpWindowImpl->mpOverlapWindow )
pWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
} else
pWindow = ImplGetParent()->mpWindowImpl->mpFirstChild; // Invalidate all windows in front of us and which are covered by us while ( pWindow )
{ if ( pWindow == this ) break;
tools::Rectangle aCompRect = pWindow->GetOutputRectPixel(); if ( aWinRect.Overlaps( aCompRect ) )
pWindow->Invalidate( InvalidateFlags::Children | InvalidateFlags::NoTransparent );
pWindow = pWindow->mpWindowImpl->mpNext;
}
// If we are covered by a window in the background // we should redraw it while ( pWindow )
{ if ( pWindow != this )
{
tools::Rectangle aCompRect = pWindow->GetOutputRectPixel(); if ( aWinRect.Overlaps( aCompRect ) )
{
Invalidate( InvalidateFlags::Children | InvalidateFlags::NoTransparent ); break;
}
}
pWindow = pWindow->mpWindowImpl->mpNext;
}
}
// topwindows must be frames or they must have a borderwindow which is a frame if( !mpWindowImpl->mbFrame && (!mpWindowImpl->mpBorderWindow || !mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame ) ) returnfalse;
// the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge. // For this, the data member of the event must not be NULL. // Previously, we did this in Window::Show, but there some events got lost in certain situations. if( bBecameReallyInvisible && ImplIsAccessibleCandidate() )
CallEventListeners( VclEventId::WindowHide, this ); // TODO. It's kind of a hack that we're re-using the VclEventId::WindowHide. Normally, we should // introduce another event which explicitly triggers the Accessibility implementations.
vcl::Window* pWindow = mpWindowImpl->mpFirstOverlap; while ( pWindow )
{ if ( pWindow->mpWindowImpl->mbReallyVisible )
pWindow->ImplResetReallyVisible();
pWindow = pWindow->mpWindowImpl->mpNext;
}
pWindow = mpWindowImpl->mpFirstChild; while ( pWindow )
{ if ( pWindow->mpWindowImpl->mbReallyVisible )
pWindow->ImplResetReallyVisible();
pWindow = pWindow->mpWindowImpl->mpNext;
}
}
// check if the overlap window changes
vcl::Window* pOldOverlapWindow;
vcl::Window* pNewOverlapWindow = nullptr; if ( ImplIsOverlapWindow() )
pOldOverlapWindow = nullptr; else
{
pNewOverlapWindow = pNewParent->ImplGetFirstOverlapWindow(); if ( mpWindowImpl->mpOverlapWindow.get() != pNewOverlapWindow )
pOldOverlapWindow = mpWindowImpl->mpOverlapWindow; else
pOldOverlapWindow = nullptr;
}
// convert windows in the hierarchy bool bFocusOverlapWin = HasChildPathFocus( true ); bool bFocusWin = HasChildPathFocus(); bool bNewFrame = pNewParent->mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow; if ( bNewFrame )
{ if ( mpWindowImpl->mpFrameData->mpFocusWin )
{ if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpFocusWin ) )
mpWindowImpl->mpFrameData->mpFocusWin = nullptr;
} if ( mpWindowImpl->mpFrameData->mpMouseMoveWin )
{ if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseMoveWin ) )
mpWindowImpl->mpFrameData->mpMouseMoveWin = nullptr;
} if ( mpWindowImpl->mpFrameData->mpMouseDownWin )
{ if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseDownWin ) )
mpWindowImpl->mpFrameData->mpMouseDownWin = nullptr;
}
}
ImplRemoveWindow( bNewFrame );
ImplInsertWindow( pNewParent ); if ( mpWindowImpl->mnParentClipMode & ParentClipMode::Clip )
pNewParent->mpWindowImpl->mbClipChildren = true;
ImplUpdateWindowPtr(); if ( ImplUpdatePos() )
ImplUpdateSysObjPos();
// If the Overlap-Window has changed, we need to test whether // OverlapWindows that had the Child window as their parent // need to be put into the window hierarchy. if ( ImplIsOverlapWindow() )
{ if ( bNewFrame )
{
vcl::Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap; while ( pOverlapWindow )
{
vcl::Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
pOverlapWindow = pNextOverlapWindow;
}
}
} elseif ( pOldOverlapWindow )
{ // reset Focus-Save if ( bFocusWin ||
(pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow &&
IsWindowOrChild( pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow )) )
pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow = nullptr;
// update activate-status at next overlap window if ( HasChildPathFocus( true ) )
ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow );
}
// also convert Activate-Status if ( bNewFrame )
{ if ( (GetType() == WindowType::BORDERWINDOW) &&
(ImplGetWindow()->GetType() == WindowType::FLOATINGWINDOW) ) static_cast<ImplBorderWindow*>(this)->SetDisplayActive( mpWindowImpl->mpFrameData->mbHasFocus );
}
// when required give focus to new frame if // FocusWindow is changed with SetParent() if ( bFocusOverlapWin )
{
mpWindowImpl->mpFrameData->mpFocusWin = Application::GetFocusWindow(); if ( !mpWindowImpl->mpFrameData->mbHasFocus )
{
mpWindowImpl->mpFrame->ToTop( SalFrameToTop::NONE );
}
}
// Assure DragSource and DropTarget members are created if ( bNewFrame )
{
GetDropTarget();
}
if( bChangeTaskPaneList )
pNewSysWin->GetTaskPaneList()->AddWindow( this );
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.