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