Coverage Report

Created: 2026-05-16 09:25

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