1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <vcl/syswin.hxx>
21 #include <vcl/window.hxx>
22 #include <vcl/taskpanelist.hxx>
23 #include <sal/log.hxx>
24 
25 #include <salframe.hxx>
26 #include <svdata.hxx>
27 #include <window.h>
28 #include <brdwin.hxx>
29 
30 #include <com/sun/star/awt/XTopWindow.hpp>
31 
32 using namespace ::com::sun::star::uno;
33 using namespace ::com::sun::star::lang;
34 using namespace ::com::sun::star::datatransfer::clipboard;
35 using namespace ::com::sun::star::datatransfer::dnd;
36 using namespace ::com::sun::star;
37 
38 using ::com::sun::star::awt::XTopWindow;
39 
40 struct ImplCalcToTopData
41 {
42     std::unique_ptr<ImplCalcToTopData> mpNext;
43     VclPtr<vcl::Window>                mpWindow;
44     std::unique_ptr<vcl::Region>       mpInvalidateRegion;
45 };
46 
47 namespace vcl {
48 
ImplGetTopmostFrameWindow()49 vcl::Window* Window::ImplGetTopmostFrameWindow()
50 {
51     vcl::Window *pTopmostParent = this;
52     while( pTopmostParent->ImplGetParent() )
53         pTopmostParent = pTopmostParent->ImplGetParent();
54     return pTopmostParent->mpWindowImpl->mpFrameWindow;
55 }
56 
ImplInsertWindow(vcl::Window * pParent)57 void Window::ImplInsertWindow( vcl::Window* pParent )
58 {
59     mpWindowImpl->mpParent            = pParent;
60     mpWindowImpl->mpRealParent        = pParent;
61 
62     if ( pParent && !mpWindowImpl->mbFrame )
63     {
64         // search frame window and set window frame data
65         vcl::Window* pFrameParent = pParent->mpWindowImpl->mpFrameWindow;
66         mpWindowImpl->mpFrameData     = pFrameParent->mpWindowImpl->mpFrameData;
67         mpWindowImpl->mpFrame         = pFrameParent->mpWindowImpl->mpFrame;
68         mpWindowImpl->mpFrameWindow   = pFrameParent;
69         mpWindowImpl->mbFrame         = false;
70 
71         // search overlap window and insert window in list
72         if ( ImplIsOverlapWindow() )
73         {
74             vcl::Window* pFirstOverlapParent = pParent;
75             while ( !pFirstOverlapParent->ImplIsOverlapWindow() )
76                 pFirstOverlapParent = pFirstOverlapParent->ImplGetParent();
77             mpWindowImpl->mpOverlapWindow = pFirstOverlapParent;
78 
79             mpWindowImpl->mpNextOverlap = mpWindowImpl->mpFrameData->mpFirstOverlap;
80             mpWindowImpl->mpFrameData->mpFirstOverlap = this;
81 
82             // Overlap-Windows are by default the uppermost
83             mpWindowImpl->mpNext = pFirstOverlapParent->mpWindowImpl->mpFirstOverlap;
84             pFirstOverlapParent->mpWindowImpl->mpFirstOverlap = this;
85             if ( !pFirstOverlapParent->mpWindowImpl->mpLastOverlap )
86                 pFirstOverlapParent->mpWindowImpl->mpLastOverlap = this;
87             else
88                 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
89         }
90         else
91         {
92             if ( pParent->ImplIsOverlapWindow() )
93                 mpWindowImpl->mpOverlapWindow = pParent;
94             else
95                 mpWindowImpl->mpOverlapWindow = pParent->mpWindowImpl->mpOverlapWindow;
96             mpWindowImpl->mpPrev = pParent->mpWindowImpl->mpLastChild;
97             pParent->mpWindowImpl->mpLastChild = this;
98             if ( !pParent->mpWindowImpl->mpFirstChild )
99                 pParent->mpWindowImpl->mpFirstChild = this;
100             else
101                 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
102         }
103     }
104 }
105 
ImplRemoveWindow(bool bRemoveFrameData)106 void Window::ImplRemoveWindow( bool bRemoveFrameData )
107 {
108     // remove window from the lists
109     if ( !mpWindowImpl->mbFrame )
110     {
111         if ( ImplIsOverlapWindow() )
112         {
113             if ( mpWindowImpl->mpFrameData->mpFirstOverlap.get() == this )
114                 mpWindowImpl->mpFrameData->mpFirstOverlap = mpWindowImpl->mpNextOverlap;
115             else
116             {
117                 vcl::Window* pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap;
118                 while ( pTempWin->mpWindowImpl->mpNextOverlap.get() != this )
119                     pTempWin = pTempWin->mpWindowImpl->mpNextOverlap;
120                 pTempWin->mpWindowImpl->mpNextOverlap = mpWindowImpl->mpNextOverlap;
121             }
122 
123             if ( mpWindowImpl->mpPrev )
124                 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
125             else
126                 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
127             if ( mpWindowImpl->mpNext )
128                 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
129             else
130                 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
131         }
132         else
133         {
134             if ( mpWindowImpl->mpPrev )
135                 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
136             else if ( mpWindowImpl->mpParent )
137                 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
138             if ( mpWindowImpl->mpNext )
139                 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
140             else if ( mpWindowImpl->mpParent )
141                 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
142         }
143 
144         mpWindowImpl->mpPrev = nullptr;
145         mpWindowImpl->mpNext = nullptr;
146     }
147 
148     if ( bRemoveFrameData )
149     {
150         // release the graphic
151         OutputDevice *pOutDev = GetOutDev();
152         pOutDev->ReleaseGraphics();
153     }
154 }
155 
reorderWithinParent(sal_uInt16 nNewPosition)156 void Window::reorderWithinParent(sal_uInt16 nNewPosition)
157 {
158     sal_uInt16 nChildCount = 0;
159     vcl::Window *pSource = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild;
160     while (pSource)
161     {
162         if (nChildCount == nNewPosition)
163             break;
164         pSource = pSource->mpWindowImpl->mpNext;
165         nChildCount++;
166     }
167 
168     if (pSource == this) //already at the right place
169         return;
170 
171     ImplRemoveWindow(false);
172 
173     if (pSource)
174     {
175         mpWindowImpl->mpNext = pSource;
176         mpWindowImpl->mpPrev = pSource->mpWindowImpl->mpPrev;
177         pSource->mpWindowImpl->mpPrev = this;
178     }
179     else
180         mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
181 
182     if (mpWindowImpl->mpPrev)
183         mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
184     else
185         mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = this;
186 }
187 
ImplToBottomChild()188 void Window::ImplToBottomChild()
189 {
190     if ( !ImplIsOverlapWindow() && !mpWindowImpl->mbReallyVisible && (mpWindowImpl->mpParent->mpWindowImpl->mpLastChild.get() != this) )
191     {
192         // put the window to the end of the list
193         if ( mpWindowImpl->mpPrev )
194             mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
195         else
196             mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
197         mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
198         mpWindowImpl->mpPrev = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild;
199         mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
200         mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
201         mpWindowImpl->mpNext = nullptr;
202     }
203 }
204 
ImplCalcToTop(ImplCalcToTopData * pPrevData)205 void Window::ImplCalcToTop( ImplCalcToTopData* pPrevData )
206 {
207     SAL_WARN_IF( !ImplIsOverlapWindow(), "vcl", "Window::ImplCalcToTop(): Is not an OverlapWindow" );
208 
209     if ( !mpWindowImpl->mbFrame )
210     {
211         if ( IsReallyVisible() )
212         {
213             // calculate region, where the window overlaps with other windows
214             Point aPoint( mnOutOffX, mnOutOffY );
215             vcl::Region  aRegion( tools::Rectangle( aPoint,
216                                         Size( mnOutWidth, mnOutHeight ) ) );
217             vcl::Region  aInvalidateRegion;
218             ImplCalcOverlapRegionOverlaps( aRegion, aInvalidateRegion );
219 
220             if ( !aInvalidateRegion.IsEmpty() )
221             {
222                 ImplCalcToTopData* pData    = new ImplCalcToTopData;
223                 pPrevData->mpNext.reset(pData);
224                 pData->mpWindow             = this;
225                 pData->mpInvalidateRegion.reset(new vcl::Region( aInvalidateRegion ));
226             }
227         }
228     }
229 }
230 
ImplToTop(ToTopFlags nFlags)231 void Window::ImplToTop( ToTopFlags nFlags )
232 {
233     SAL_WARN_IF( !ImplIsOverlapWindow(), "vcl", "Window::ImplToTop(): Is not an OverlapWindow" );
234 
235     if ( mpWindowImpl->mbFrame )
236     {
237         // on a mouse click in the external window, it is the latter's
238         // responsibility to assure our frame is put in front
239         if ( !mpWindowImpl->mpFrameData->mbHasFocus &&
240              !mpWindowImpl->mpFrameData->mbSysObjFocus &&
241              !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl &&
242              !mpWindowImpl->mpFrameData->mbInSysObjToTopHdl )
243         {
244             // do not bring floating windows on the client to top
245             if( !ImplGetClientWindow() || !(ImplGetClientWindow()->GetStyle() & WB_SYSTEMFLOATWIN) )
246             {
247                 SalFrameToTop nSysFlags = SalFrameToTop::NONE;
248                 if ( nFlags & ToTopFlags::RestoreWhenMin )
249                     nSysFlags |= SalFrameToTop::RestoreWhenMin;
250                 if ( nFlags & ToTopFlags::ForegroundTask )
251                     nSysFlags |= SalFrameToTop::ForegroundTask;
252                 if ( nFlags & ToTopFlags::GrabFocusOnly )
253                     nSysFlags |= SalFrameToTop::GrabFocusOnly;
254                 mpWindowImpl->mpFrame->ToTop( nSysFlags );
255             }
256         }
257     }
258     else
259     {
260         if ( mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap.get() != this )
261         {
262             // remove window from the list
263             mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
264             if ( mpWindowImpl->mpNext )
265                 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
266             else
267                 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
268 
269             // take AlwaysOnTop into account
270             bool    bOnTop = IsAlwaysOnTopEnabled();
271             vcl::Window* pNextWin = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
272             if ( !bOnTop )
273             {
274                 while ( pNextWin )
275                 {
276                     if ( !pNextWin->IsAlwaysOnTopEnabled() )
277                         break;
278                     pNextWin = pNextWin->mpWindowImpl->mpNext;
279                 }
280             }
281 
282             // add the window to the list again
283             mpWindowImpl->mpNext = pNextWin;
284             if ( pNextWin )
285             {
286                 mpWindowImpl->mpPrev = pNextWin->mpWindowImpl->mpPrev;
287                 pNextWin->mpWindowImpl->mpPrev = this;
288             }
289             else
290             {
291                 mpWindowImpl->mpPrev = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap;
292                 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this;
293             }
294             if ( mpWindowImpl->mpPrev )
295                 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
296             else
297                 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this;
298 
299             // recalculate ClipRegion of this and all overlapping windows
300             if ( IsReallyVisible() )
301             {
302                 mpWindowImpl->mpOverlapWindow->ImplSetClipFlagOverlapWindows();
303             }
304         }
305     }
306 }
307 
ImplStartToTop(ToTopFlags nFlags)308 void Window::ImplStartToTop( ToTopFlags nFlags )
309 {
310     ImplCalcToTopData   aStartData;
311     ImplCalcToTopData*  pCurData;
312     vcl::Window* pOverlapWindow;
313     if ( ImplIsOverlapWindow() )
314         pOverlapWindow = this;
315     else
316         pOverlapWindow = mpWindowImpl->mpOverlapWindow;
317 
318     // first calculate paint areas
319     vcl::Window* pTempOverlapWindow = pOverlapWindow;
320     aStartData.mpNext = nullptr;
321     pCurData = &aStartData;
322     do
323     {
324         pTempOverlapWindow->ImplCalcToTop( pCurData );
325         if ( pCurData->mpNext )
326             pCurData = pCurData->mpNext.get();
327         pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow;
328     }
329     while ( !pTempOverlapWindow->mpWindowImpl->mbFrame );
330     // next calculate the paint areas of the ChildOverlap windows
331     pTempOverlapWindow = mpWindowImpl->mpFirstOverlap;
332     while ( pTempOverlapWindow )
333     {
334         pTempOverlapWindow->ImplCalcToTop( pCurData );
335         if ( pCurData->mpNext )
336             pCurData = pCurData->mpNext.get();
337         pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpNext;
338     }
339 
340     // and next change the windows list
341     pTempOverlapWindow = pOverlapWindow;
342     do
343     {
344         pTempOverlapWindow->ImplToTop( nFlags );
345         pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow;
346     }
347     while ( !pTempOverlapWindow->mpWindowImpl->mbFrame );
348     // as last step invalidate the invalid areas
349     pCurData = aStartData.mpNext.get();
350     while ( pCurData )
351     {
352         pCurData->mpWindow->ImplInvalidateFrameRegion( pCurData->mpInvalidateRegion.get(), InvalidateFlags::Children );
353         pCurData = pCurData->mpNext.get();
354     }
355 }
356 
ImplFocusToTop(ToTopFlags nFlags,bool bReallyVisible)357 void Window::ImplFocusToTop( ToTopFlags nFlags, bool bReallyVisible )
358 {
359     // do we need to fetch the focus?
360     if ( !(nFlags & ToTopFlags::NoGrabFocus) )
361     {
362         // first window with GrabFocus-Activate gets the focus
363         vcl::Window* pFocusWindow = this;
364         while ( !pFocusWindow->ImplIsOverlapWindow() )
365         {
366             // if the window has no BorderWindow, we
367             // should always find the belonging BorderWindow
368             if ( !pFocusWindow->mpWindowImpl->mpBorderWindow )
369             {
370                 if ( pFocusWindow->mpWindowImpl->mnActivateMode & ActivateModeFlags::GrabFocus )
371                     break;
372             }
373             pFocusWindow = pFocusWindow->ImplGetParent();
374         }
375         if ( (pFocusWindow->mpWindowImpl->mnActivateMode & ActivateModeFlags::GrabFocus) &&
376              !pFocusWindow->HasChildPathFocus( true ) )
377             pFocusWindow->GrabFocus();
378     }
379 
380     if ( bReallyVisible )
381         ImplGenerateMouseMove();
382 }
383 
ImplShowAllOverlaps()384 void Window::ImplShowAllOverlaps()
385 {
386     vcl::Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
387     while ( pOverlapWindow )
388     {
389         if ( pOverlapWindow->mpWindowImpl->mbOverlapVisible )
390         {
391             pOverlapWindow->Show( true, ShowFlags::NoActivate );
392             pOverlapWindow->mpWindowImpl->mbOverlapVisible = false;
393         }
394 
395         pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
396     }
397 }
398 
ImplHideAllOverlaps()399 void Window::ImplHideAllOverlaps()
400 {
401     vcl::Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
402     while ( pOverlapWindow )
403     {
404         if ( pOverlapWindow->IsVisible() )
405         {
406             pOverlapWindow->mpWindowImpl->mbOverlapVisible = true;
407             pOverlapWindow->Show( false );
408         }
409 
410         pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
411     }
412 }
413 
ToTop(ToTopFlags nFlags)414 void Window::ToTop( ToTopFlags nFlags )
415 {
416     if (!mpWindowImpl)
417         return;
418 
419     ImplStartToTop( nFlags );
420     ImplFocusToTop( nFlags, IsReallyVisible() );
421 }
422 
SetZOrder(vcl::Window * pRefWindow,ZOrderFlags nFlags)423 void Window::SetZOrder( vcl::Window* pRefWindow, ZOrderFlags nFlags )
424 {
425 
426     if ( mpWindowImpl->mpBorderWindow )
427     {
428         mpWindowImpl->mpBorderWindow->SetZOrder( pRefWindow, nFlags );
429         return;
430     }
431 
432     if ( nFlags & ZOrderFlags::First )
433     {
434         if ( ImplIsOverlapWindow() )
435             pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
436         else
437             pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild;
438         nFlags |= ZOrderFlags::Before;
439     }
440     else if ( nFlags & ZOrderFlags::Last )
441     {
442         if ( ImplIsOverlapWindow() )
443             pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap;
444         else
445             pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild;
446         nFlags |= ZOrderFlags::Behind;
447     }
448 
449     while ( pRefWindow && pRefWindow->mpWindowImpl->mpBorderWindow )
450         pRefWindow = pRefWindow->mpWindowImpl->mpBorderWindow;
451     if (!pRefWindow || pRefWindow == this || mpWindowImpl->mbFrame)
452         return;
453 
454     SAL_WARN_IF( pRefWindow->mpWindowImpl->mpParent != mpWindowImpl->mpParent, "vcl", "Window::SetZOrder() - pRefWindow has other parent" );
455     if ( nFlags & ZOrderFlags::Before )
456     {
457         if ( pRefWindow->mpWindowImpl->mpPrev.get() == this )
458             return;
459 
460         if ( ImplIsOverlapWindow() )
461         {
462             if ( mpWindowImpl->mpPrev )
463                 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
464             else
465                 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
466             if ( mpWindowImpl->mpNext )
467                 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
468             else
469                 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
470             if ( !pRefWindow->mpWindowImpl->mpPrev )
471                 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this;
472         }
473         else
474         {
475             if ( mpWindowImpl->mpPrev )
476                 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
477             else
478                 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
479             if ( mpWindowImpl->mpNext )
480                 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
481             else
482                 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
483             if ( !pRefWindow->mpWindowImpl->mpPrev )
484                 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = this;
485         }
486 
487         mpWindowImpl->mpPrev = pRefWindow->mpWindowImpl->mpPrev;
488         mpWindowImpl->mpNext = pRefWindow;
489         if ( mpWindowImpl->mpPrev )
490             mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
491         mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
492     }
493     else if ( nFlags & ZOrderFlags::Behind )
494     {
495         if ( pRefWindow->mpWindowImpl->mpNext.get() == this )
496             return;
497 
498         if ( ImplIsOverlapWindow() )
499         {
500             if ( mpWindowImpl->mpPrev )
501                 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
502             else
503                 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
504             if ( mpWindowImpl->mpNext )
505                 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
506             else
507                 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
508             if ( !pRefWindow->mpWindowImpl->mpNext )
509                 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this;
510         }
511         else
512         {
513             if ( mpWindowImpl->mpPrev )
514                 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
515             else
516                 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
517             if ( mpWindowImpl->mpNext )
518                 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
519             else
520                 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
521             if ( !pRefWindow->mpWindowImpl->mpNext )
522                 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
523         }
524 
525         mpWindowImpl->mpPrev = pRefWindow;
526         mpWindowImpl->mpNext = pRefWindow->mpWindowImpl->mpNext;
527         if ( mpWindowImpl->mpNext )
528             mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
529         mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
530     }
531 
532     if ( IsReallyVisible() )
533     {
534         if ( mpWindowImpl->mbInitWinClipRegion || !mpWindowImpl->maWinClipRegion.IsEmpty() )
535         {
536             bool bInitWinClipRegion = mpWindowImpl->mbInitWinClipRegion;
537             ImplSetClipFlag();
538 
539             // When ClipRegion was not initialised, assume
540             // the window has not been sent, therefore do not
541             // trigger any Invalidates. This is an optimization
542             // for HTML documents with many controls. If this
543             // check gives problems, a flag should be introduced
544             // which tracks whether the window has already been
545             // emitted after Show
546             if ( !bInitWinClipRegion )
547             {
548                 // Invalidate all windows which are next to each other
549                 // Is INCOMPLETE !!!
550                 tools::Rectangle   aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
551                 vcl::Window*     pWindow = nullptr;
552                 if ( ImplIsOverlapWindow() )
553                 {
554                     if ( mpWindowImpl->mpOverlapWindow )
555                         pWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
556                 }
557                 else
558                     pWindow = ImplGetParent()->mpWindowImpl->mpFirstChild;
559                 // Invalidate all windows in front of us and which are covered by us
560                 while ( pWindow )
561                 {
562                     if ( pWindow == this )
563                         break;
564                     tools::Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ),
565                                          Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) );
566                     if ( aWinRect.IsOver( aCompRect ) )
567                         pWindow->Invalidate( InvalidateFlags::Children | InvalidateFlags::NoTransparent );
568                     pWindow = pWindow->mpWindowImpl->mpNext;
569                 }
570 
571                 // If we are covered by a window in the background
572                 // we should redraw it
573                 while ( pWindow )
574                 {
575                     if ( pWindow != this )
576                     {
577                         tools::Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ),
578                                              Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) );
579                         if ( aWinRect.IsOver( aCompRect ) )
580                         {
581                             Invalidate( InvalidateFlags::Children | InvalidateFlags::NoTransparent );
582                             break;
583                         }
584                     }
585                     pWindow = pWindow->mpWindowImpl->mpNext;
586                 }
587             }
588         }
589     }
590 }
591 
EnableAlwaysOnTop(bool bEnable)592 void Window::EnableAlwaysOnTop( bool bEnable )
593 {
594 
595     mpWindowImpl->mbAlwaysOnTop = bEnable;
596 
597     if ( mpWindowImpl->mpBorderWindow )
598         mpWindowImpl->mpBorderWindow->EnableAlwaysOnTop( bEnable );
599     else if ( bEnable && IsReallyVisible() )
600         ToTop();
601 
602     if ( mpWindowImpl->mbFrame )
603         mpWindowImpl->mpFrame->SetAlwaysOnTop( bEnable );
604 }
605 
IsTopWindow() const606 bool Window::IsTopWindow() const
607 {
608     if ( !mpWindowImpl || mpWindowImpl->mbInDispose )
609         return false;
610 
611     // topwindows must be frames or they must have a borderwindow which is a frame
612     if( !mpWindowImpl->mbFrame && (!mpWindowImpl->mpBorderWindow || !mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame ) )
613         return false;
614 
615     ImplGetWinData();
616     if( mpWindowImpl->mpWinData->mnIsTopWindow == sal_uInt16(~0))    // still uninitialized
617     {
618         // #113722#, cache result of expensive queryInterface call
619         vcl::Window *pThisWin = const_cast<vcl::Window*>(this);
620         uno::Reference< XTopWindow > xTopWindow( pThisWin->GetComponentInterface(), UNO_QUERY );
621         pThisWin->mpWindowImpl->mpWinData->mnIsTopWindow = xTopWindow.is() ? 1 : 0;
622     }
623     return mpWindowImpl->mpWinData->mnIsTopWindow == 1;
624 }
625 
FindWindow(const Point & rPos) const626 vcl::Window* Window::FindWindow( const Point& rPos ) const
627 {
628 
629     Point aPos = OutputToScreenPixel( rPos );
630     return const_cast<vcl::Window*>(this)->ImplFindWindow( aPos );
631 }
632 
ImplFindWindow(const Point & rFramePos)633 vcl::Window* Window::ImplFindWindow( const Point& rFramePos )
634 {
635     vcl::Window* pTempWindow;
636     vcl::Window* pFindWindow;
637 
638     // first check all overlapping windows
639     pTempWindow = mpWindowImpl->mpFirstOverlap;
640     while ( pTempWindow )
641     {
642         pFindWindow = pTempWindow->ImplFindWindow( rFramePos );
643         if ( pFindWindow )
644             return pFindWindow;
645         pTempWindow = pTempWindow->mpWindowImpl->mpNext;
646     }
647 
648     // then we check our window
649     if ( !mpWindowImpl->mbVisible )
650         return nullptr;
651 
652     WindowHitTest nHitTest = ImplHitTest( rFramePos );
653     if ( nHitTest & WindowHitTest::Inside )
654     {
655         // and then we check all child windows
656         pTempWindow = mpWindowImpl->mpFirstChild;
657         while ( pTempWindow )
658         {
659             pFindWindow = pTempWindow->ImplFindWindow( rFramePos );
660             if ( pFindWindow )
661                 return pFindWindow;
662             pTempWindow = pTempWindow->mpWindowImpl->mpNext;
663         }
664 
665         if ( nHitTest & WindowHitTest::Transparent )
666             return nullptr;
667         else
668             return this;
669     }
670 
671     return nullptr;
672 }
673 
ImplIsRealParentPath(const vcl::Window * pWindow) const674 bool Window::ImplIsRealParentPath( const vcl::Window* pWindow ) const
675 {
676     pWindow = pWindow->GetParent();
677     while ( pWindow )
678     {
679         if ( pWindow == this )
680             return true;
681         pWindow = pWindow->GetParent();
682     }
683 
684     return false;
685 }
686 
ImplIsChild(const vcl::Window * pWindow,bool bSystemWindow) const687 bool Window::ImplIsChild( const vcl::Window* pWindow, bool bSystemWindow ) const
688 {
689     do
690     {
691         if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() )
692             break;
693 
694         pWindow = pWindow->ImplGetParent();
695 
696         if ( pWindow == this )
697             return true;
698     }
699     while ( pWindow );
700 
701     return false;
702 }
703 
ImplIsWindowOrChild(const vcl::Window * pWindow,bool bSystemWindow) const704 bool Window::ImplIsWindowOrChild( const vcl::Window* pWindow, bool bSystemWindow ) const
705 {
706     if ( this == pWindow )
707         return true;
708     return ImplIsChild( pWindow, bSystemWindow );
709 }
710 
ImplResetReallyVisible()711 void Window::ImplResetReallyVisible()
712 {
713     bool bBecameReallyInvisible = mpWindowImpl->mbReallyVisible;
714 
715     mbDevOutput     = false;
716     mpWindowImpl->mbReallyVisible = false;
717     mpWindowImpl->mbReallyShown   = false;
718 
719     // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
720     // For this, the data member of the event must not be NULL.
721     // Previously, we did this in Window::Show, but there some events got lost in certain situations.
722     if( bBecameReallyInvisible && ImplIsAccessibleCandidate() )
723         CallEventListeners( VclEventId::WindowHide, this );
724         // TODO. It's kind of a hack that we're re-using the VclEventId::WindowHide. Normally, we should
725         // introduce another event which explicitly triggers the Accessibility implementations.
726 
727     vcl::Window* pWindow = mpWindowImpl->mpFirstOverlap;
728     while ( pWindow )
729     {
730         if ( pWindow->mpWindowImpl->mbReallyVisible )
731             pWindow->ImplResetReallyVisible();
732         pWindow = pWindow->mpWindowImpl->mpNext;
733     }
734 
735     pWindow = mpWindowImpl->mpFirstChild;
736     while ( pWindow )
737     {
738         if ( pWindow->mpWindowImpl->mbReallyVisible )
739             pWindow->ImplResetReallyVisible();
740         pWindow = pWindow->mpWindowImpl->mpNext;
741     }
742 }
743 
ImplUpdateWindowPtr(vcl::Window * pWindow)744 void Window::ImplUpdateWindowPtr( vcl::Window* pWindow )
745 {
746     if ( mpWindowImpl->mpFrameWindow != pWindow->mpWindowImpl->mpFrameWindow )
747     {
748         // release graphic
749         OutputDevice *pOutDev = GetOutDev();
750         pOutDev->ReleaseGraphics();
751     }
752 
753     mpWindowImpl->mpFrameData     = pWindow->mpWindowImpl->mpFrameData;
754     mpWindowImpl->mpFrame         = pWindow->mpWindowImpl->mpFrame;
755     mpWindowImpl->mpFrameWindow   = pWindow->mpWindowImpl->mpFrameWindow;
756     if ( pWindow->ImplIsOverlapWindow() )
757         mpWindowImpl->mpOverlapWindow = pWindow;
758     else
759         mpWindowImpl->mpOverlapWindow = pWindow->mpWindowImpl->mpOverlapWindow;
760 
761     vcl::Window* pChild = mpWindowImpl->mpFirstChild;
762     while ( pChild )
763     {
764         pChild->ImplUpdateWindowPtr( pWindow );
765         pChild = pChild->mpWindowImpl->mpNext;
766     }
767 }
768 
ImplUpdateWindowPtr()769 void Window::ImplUpdateWindowPtr()
770 {
771     vcl::Window* pChild = mpWindowImpl->mpFirstChild;
772     while ( pChild )
773     {
774         pChild->ImplUpdateWindowPtr( this );
775         pChild = pChild->mpWindowImpl->mpNext;
776     }
777 }
778 
ImplUpdateOverlapWindowPtr(bool bNewFrame)779 void Window::ImplUpdateOverlapWindowPtr( bool bNewFrame )
780 {
781     bool bVisible = IsVisible();
782     Show( false );
783     ImplRemoveWindow( bNewFrame );
784     vcl::Window* pRealParent = mpWindowImpl->mpRealParent;
785     ImplInsertWindow( ImplGetParent() );
786     mpWindowImpl->mpRealParent = pRealParent;
787     ImplUpdateWindowPtr();
788     if ( ImplUpdatePos() )
789         ImplUpdateSysObjPos();
790 
791     if ( bNewFrame )
792     {
793         vcl::Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
794         while ( pOverlapWindow )
795         {
796             vcl::Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
797             pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
798             pOverlapWindow = pNextOverlapWindow;
799         }
800     }
801 
802     if ( bVisible )
803         Show();
804 }
805 
GetSystemWindow() const806 SystemWindow* Window::GetSystemWindow() const
807 {
808 
809     const vcl::Window* pWin = this;
810     while ( pWin && !pWin->IsSystemWindow() )
811         pWin  = pWin->GetParent();
812     return static_cast<SystemWindow*>(const_cast<Window*>(pWin));
813 }
814 
ImplGetLastSystemWindow(vcl::Window * pWin)815 static SystemWindow *ImplGetLastSystemWindow( vcl::Window *pWin )
816 {
817     // get the most top-level system window, the one that contains the taskpanelist
818     SystemWindow *pSysWin = nullptr;
819     if( !pWin )
820         return pSysWin;
821     vcl::Window *pMyParent = pWin;
822     while ( pMyParent )
823     {
824         if ( pMyParent->IsSystemWindow() )
825             pSysWin = static_cast<SystemWindow*>(pMyParent);
826         pMyParent = pMyParent->GetParent();
827     }
828     return pSysWin;
829 }
830 
SetParent(vcl::Window * pNewParent)831 void Window::SetParent( vcl::Window* pNewParent )
832 {
833     SAL_INFO_IF( !pNewParent, "vcl", "Window::SetParent(): pParent == NULL" );
834     SAL_WARN_IF( pNewParent == this, "vcl", "someone tried to reparent a window to itself" );
835 
836     if( !pNewParent || pNewParent == this )
837         return;
838 
839     // check if the taskpanelist would change and move the window pointer accordingly
840     SystemWindow *pSysWin = ImplGetLastSystemWindow(this);
841     SystemWindow *pNewSysWin = nullptr;
842     bool bChangeTaskPaneList = false;
843     if( pSysWin && pSysWin->ImplIsInTaskPaneList( this ) )
844     {
845         pNewSysWin = ImplGetLastSystemWindow( pNewParent );
846         if( pNewSysWin && pNewSysWin != pSysWin )
847         {
848             bChangeTaskPaneList = true;
849             pSysWin->GetTaskPaneList()->RemoveWindow( this );
850         }
851     }
852     // remove ownerdraw decorated windows from list in the top-most frame window
853     if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
854     {
855         ::std::vector< VclPtr<vcl::Window> >& rList = ImplGetOwnerDrawList();
856         auto p = ::std::find( rList.begin(), rList.end(), VclPtr<vcl::Window>(this) );
857         if( p != rList.end() )
858             rList.erase( p );
859     }
860 
861     ImplSetFrameParent( pNewParent );
862 
863     if ( mpWindowImpl->mpBorderWindow )
864     {
865         mpWindowImpl->mpRealParent = pNewParent;
866         mpWindowImpl->mpBorderWindow->SetParent( pNewParent );
867         return;
868     }
869 
870     if ( mpWindowImpl->mpParent.get() == pNewParent )
871         return;
872 
873     if ( mpWindowImpl->mbFrame )
874         mpWindowImpl->mpFrame->SetParent( pNewParent->mpWindowImpl->mpFrame );
875 
876     bool bVisible = IsVisible();
877     Show( false, ShowFlags::NoFocusChange );
878 
879     // check if the overlap window changes
880     vcl::Window* pOldOverlapWindow;
881     vcl::Window* pNewOverlapWindow = nullptr;
882     if ( ImplIsOverlapWindow() )
883         pOldOverlapWindow = nullptr;
884     else
885     {
886         pNewOverlapWindow = pNewParent->ImplGetFirstOverlapWindow();
887         if ( mpWindowImpl->mpOverlapWindow.get() != pNewOverlapWindow )
888             pOldOverlapWindow = mpWindowImpl->mpOverlapWindow;
889         else
890             pOldOverlapWindow = nullptr;
891     }
892 
893     // convert windows in the hierarchy
894     bool bFocusOverlapWin = HasChildPathFocus( true );
895     bool bFocusWin = HasChildPathFocus();
896     bool bNewFrame = pNewParent->mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow;
897     if ( bNewFrame )
898     {
899         if ( mpWindowImpl->mpFrameData->mpFocusWin )
900         {
901             if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpFocusWin ) )
902                 mpWindowImpl->mpFrameData->mpFocusWin = nullptr;
903         }
904         if ( mpWindowImpl->mpFrameData->mpMouseMoveWin )
905         {
906             if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseMoveWin ) )
907                 mpWindowImpl->mpFrameData->mpMouseMoveWin = nullptr;
908         }
909         if ( mpWindowImpl->mpFrameData->mpMouseDownWin )
910         {
911             if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseDownWin ) )
912                 mpWindowImpl->mpFrameData->mpMouseDownWin = nullptr;
913         }
914     }
915     ImplRemoveWindow( bNewFrame );
916     ImplInsertWindow( pNewParent );
917     if ( mpWindowImpl->mnParentClipMode & ParentClipMode::Clip )
918         pNewParent->mpWindowImpl->mbClipChildren = true;
919     ImplUpdateWindowPtr();
920     if ( ImplUpdatePos() )
921         ImplUpdateSysObjPos();
922 
923     // If the Overlap-Window has changed, we need to test whether
924     // OverlapWindows that had the Child window as their parent
925     // need to be put into the window hierarchy.
926     if ( ImplIsOverlapWindow() )
927     {
928         if ( bNewFrame )
929         {
930             vcl::Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
931             while ( pOverlapWindow )
932             {
933                 vcl::Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
934                 pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
935                 pOverlapWindow = pNextOverlapWindow;
936             }
937         }
938     }
939     else if ( pOldOverlapWindow )
940     {
941         // reset Focus-Save
942         if ( bFocusWin ||
943              (pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow &&
944               IsWindowOrChild( pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow )) )
945             pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow = nullptr;
946 
947         vcl::Window* pOverlapWindow = pOldOverlapWindow->mpWindowImpl->mpFirstOverlap;
948         while ( pOverlapWindow )
949         {
950             vcl::Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
951             if ( ImplIsRealParentPath( pOverlapWindow->ImplGetWindow() ) )
952                 pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
953             pOverlapWindow = pNextOverlapWindow;
954         }
955 
956         // update activate-status at next overlap window
957         if ( HasChildPathFocus( true ) )
958             ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow );
959     }
960 
961     // also convert Activate-Status
962     if ( bNewFrame )
963     {
964         if ( (GetType() == WindowType::BORDERWINDOW) &&
965              (ImplGetWindow()->GetType() == WindowType::FLOATINGWINDOW) )
966             static_cast<ImplBorderWindow*>(this)->SetDisplayActive( mpWindowImpl->mpFrameData->mbHasFocus );
967     }
968 
969     // when required give focus to new frame if
970     // FocusWindow is changed with SetParent()
971     if ( bFocusOverlapWin )
972     {
973         mpWindowImpl->mpFrameData->mpFocusWin = Application::GetFocusWindow();
974         if ( !mpWindowImpl->mpFrameData->mbHasFocus )
975         {
976             mpWindowImpl->mpFrame->ToTop( SalFrameToTop::NONE );
977         }
978     }
979 
980     // Assure DragSource and DropTarget members are created
981     if ( bNewFrame )
982     {
983             GetDropTarget();
984     }
985 
986     if( bChangeTaskPaneList )
987         pNewSysWin->GetTaskPaneList()->AddWindow( this );
988 
989     if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
990         ImplGetOwnerDrawList().emplace_back(this );
991 
992     if ( bVisible )
993         Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate );
994 }
995 
IsAncestorOf(const vcl::Window & rWindow) const996 bool Window::IsAncestorOf( const vcl::Window& rWindow ) const
997 {
998     return ImplIsRealParentPath(&rWindow);
999 }
1000 
GetChildCount() const1001 sal_uInt16 Window::GetChildCount() const
1002 {
1003     if (!mpWindowImpl)
1004         return 0;
1005 
1006     sal_uInt16  nChildCount = 0;
1007     vcl::Window* pChild = mpWindowImpl->mpFirstChild;
1008     while ( pChild )
1009     {
1010         nChildCount++;
1011         pChild = pChild->mpWindowImpl->mpNext;
1012     }
1013 
1014     return nChildCount;
1015 }
1016 
GetChild(sal_uInt16 nChild) const1017 vcl::Window* Window::GetChild( sal_uInt16 nChild ) const
1018 {
1019     if (!mpWindowImpl)
1020         return nullptr;
1021 
1022     sal_uInt16  nChildCount = 0;
1023     vcl::Window* pChild = mpWindowImpl->mpFirstChild;
1024     while ( pChild )
1025     {
1026         if ( nChild == nChildCount )
1027             return pChild;
1028         pChild = pChild->mpWindowImpl->mpNext;
1029         nChildCount++;
1030     }
1031 
1032     return nullptr;
1033 }
1034 
GetWindow(GetWindowType nType) const1035 vcl::Window* Window::GetWindow( GetWindowType nType ) const
1036 {
1037     if (!mpWindowImpl)
1038         return nullptr;
1039 
1040     switch ( nType )
1041     {
1042         case GetWindowType::Parent:
1043             return mpWindowImpl->mpRealParent;
1044 
1045         case GetWindowType::FirstChild:
1046             return mpWindowImpl->mpFirstChild;
1047 
1048         case GetWindowType::LastChild:
1049             return mpWindowImpl->mpLastChild;
1050 
1051         case GetWindowType::Prev:
1052             return mpWindowImpl->mpPrev;
1053 
1054         case GetWindowType::Next:
1055             return mpWindowImpl->mpNext;
1056 
1057         case GetWindowType::FirstOverlap:
1058             return mpWindowImpl->mpFirstOverlap;
1059 
1060         case GetWindowType::Overlap:
1061             if ( ImplIsOverlapWindow() )
1062                 return const_cast<vcl::Window*>(this);
1063             else
1064                 return mpWindowImpl->mpOverlapWindow;
1065 
1066         case GetWindowType::ParentOverlap:
1067             if ( ImplIsOverlapWindow() )
1068                 return mpWindowImpl->mpOverlapWindow;
1069             else
1070                 return mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpOverlapWindow;
1071 
1072         case GetWindowType::Client:
1073             return this->ImplGetWindow();
1074 
1075         case GetWindowType::RealParent:
1076             return ImplGetParent();
1077 
1078         case GetWindowType::Frame:
1079             return mpWindowImpl->mpFrameWindow;
1080 
1081         case GetWindowType::Border:
1082             if ( mpWindowImpl->mpBorderWindow )
1083                 return mpWindowImpl->mpBorderWindow->GetWindow( GetWindowType::Border );
1084             return const_cast<vcl::Window*>(this);
1085 
1086         case GetWindowType::FirstTopWindowChild:
1087             return ImplGetWinData()->maTopWindowChildren.empty() ? nullptr : (*ImplGetWinData()->maTopWindowChildren.begin()).get();
1088 
1089         case GetWindowType::NextTopWindowSibling:
1090         {
1091             if ( !mpWindowImpl->mpRealParent )
1092                 return nullptr;
1093             const ::std::list< VclPtr<vcl::Window> >& rTopWindows( mpWindowImpl->mpRealParent->ImplGetWinData()->maTopWindowChildren );
1094             ::std::list< VclPtr<vcl::Window> >::const_iterator myPos =
1095                 ::std::find( rTopWindows.begin(), rTopWindows.end(), this );
1096             if ( ( myPos == rTopWindows.end() ) || ( ++myPos == rTopWindows.end() ) )
1097                 return nullptr;
1098             return *myPos;
1099         }
1100 
1101     }
1102 
1103     return nullptr;
1104 }
1105 
IsChild(const vcl::Window * pWindow) const1106 bool Window::IsChild( const vcl::Window* pWindow ) const
1107 {
1108     do
1109     {
1110         if ( pWindow->ImplIsOverlapWindow() )
1111             break;
1112 
1113         pWindow = pWindow->ImplGetParent();
1114 
1115         if ( pWindow == this )
1116             return true;
1117     }
1118     while ( pWindow );
1119 
1120     return false;
1121 }
1122 
IsWindowOrChild(const vcl::Window * pWindow,bool bSystemWindow) const1123 bool Window::IsWindowOrChild( const vcl::Window* pWindow, bool bSystemWindow ) const
1124 {
1125 
1126     if ( this == pWindow )
1127         return true;
1128     return ImplIsChild( pWindow, bSystemWindow );
1129 }
1130 
ImplSetFrameParent(const vcl::Window * pParent)1131 void Window::ImplSetFrameParent( const vcl::Window* pParent )
1132 {
1133     vcl::Window* pFrameWindow = ImplGetSVData()->maWinData.mpFirstFrame;
1134     while( pFrameWindow )
1135     {
1136         // search all frames that are children of this window
1137         // and reparent them
1138         if( ImplIsRealParentPath( pFrameWindow ) )
1139         {
1140             SAL_WARN_IF( mpWindowImpl->mpFrame == pFrameWindow->mpWindowImpl->mpFrame, "vcl", "SetFrameParent to own" );
1141             SAL_WARN_IF( !mpWindowImpl->mpFrame, "vcl", "no frame" );
1142             SalFrame* pParentFrame = pParent ? pParent->mpWindowImpl->mpFrame : nullptr;
1143             pFrameWindow->mpWindowImpl->mpFrame->SetParent( pParentFrame );
1144         }
1145         pFrameWindow = pFrameWindow->mpWindowImpl->mpFrameData->mpNextFrame;
1146     }
1147 }
1148 
1149 } /* namespace vcl */
1150 
1151 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1152