Coverage Report

Created: 2025-12-31 10:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/vcl/source/window/window.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 <sal/config.h>
21
22
#include <rtl/strbuf.hxx>
23
#include <sal/log.hxx>
24
25
#include <sal/types.h>
26
#include <comphelper/diagnose_ex.hxx>
27
#include <comphelper/OAccessible.hxx>
28
#include <vcl/dndlistenercontainer.hxx>
29
#include <vcl/salgtype.hxx>
30
#include <vcl/event.hxx>
31
#include <vcl/cursor.hxx>
32
#include <vcl/svapp.hxx>
33
#include <vcl/transfer.hxx>
34
#include <vcl/vclevent.hxx>
35
#include <vcl/window.hxx>
36
#include <vcl/syswin.hxx>
37
#include <vcl/dockwin.hxx>
38
#include <vcl/wall.hxx>
39
#include <vcl/toolkit/fixed.hxx>
40
#include <vcl/toolkit/button.hxx>
41
#include <vcl/taskpanelist.hxx>
42
#include <vcl/toolkit/unowrap.hxx>
43
#include <tools/lazydelete.hxx>
44
#include <vcl/virdev.hxx>
45
#include <vcl/settings.hxx>
46
#include <vcl/sysdata.hxx>
47
#include <vcl/ptrstyle.hxx>
48
#include <vcl/IDialogRenderable.hxx>
49
50
#include <vcl/uitest/uiobject.hxx>
51
52
#include <ImplOutDevData.hxx>
53
#include <impfontcache.hxx>
54
#include <salframe.hxx>
55
#include <salobj.hxx>
56
#include <salinst.hxx>
57
#include <salgdi.hxx>
58
#include <svdata.hxx>
59
#include <window.h>
60
#include <toolbox.h>
61
#include <brdwin.hxx>
62
#include <helpwin.hxx>
63
#include <dndeventdispatcher.hxx>
64
65
#include <com/sun/star/accessibility/AccessibleRelation.hpp>
66
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
67
#include <com/sun/star/accessibility/XAccessible.hpp>
68
#include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
69
#include <com/sun/star/awt/XVclWindowPeer.hpp>
70
#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
71
#include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
72
#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
73
#include <com/sun/star/rendering/CanvasFactory.hpp>
74
#include <com/sun/star/rendering/XSpriteCanvas.hpp>
75
#include <comphelper/configuration.hxx>
76
#include <comphelper/lok.hxx>
77
#include <comphelper/processfactory.hxx>
78
#include <osl/diagnose.h>
79
#include <tools/debug.hxx>
80
#include <tools/json_writer.hxx>
81
#include <boost/property_tree/ptree.hpp>
82
83
#include <cassert>
84
#include <typeinfo>
85
86
#ifdef _WIN32 // see #140456#
87
#include <win/salframe.h>
88
#endif
89
90
#include "impldockingwrapper.hxx"
91
92
using namespace ::com::sun::star::uno;
93
using namespace ::com::sun::star::lang;
94
using namespace ::com::sun::star::datatransfer::clipboard;
95
using namespace ::com::sun::star::datatransfer::dnd;
96
97
namespace vcl {
98
99
Window::Window( WindowType eType )
100
117k
    : mpWindowImpl(new WindowImpl( *this, eType ))
101
117k
{
102
    // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
103
117k
    mpWindowImpl->mxOutDev->mbEnableRTL = AllSettings::GetLayoutRTL();
104
117k
}
vcl::Window::Window(WindowType)
Line
Count
Source
100
117k
    : mpWindowImpl(new WindowImpl( *this, eType ))
101
117k
{
102
    // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
103
117k
    mpWindowImpl->mxOutDev->mbEnableRTL = AllSettings::GetLayoutRTL();
104
117k
}
Unexecuted instantiation: vcl::Window::Window(WindowType)
105
106
Window::Window( vcl::Window* pParent, WinBits nStyle )
107
22.8k
    : mpWindowImpl(new WindowImpl( *this, WindowType::WINDOW ))
108
22.8k
{
109
    // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
110
22.8k
    mpWindowImpl->mxOutDev->mbEnableRTL = AllSettings::GetLayoutRTL();
111
112
22.8k
    ImplInit( pParent, nStyle, nullptr );
113
22.8k
}
vcl::Window::Window(vcl::Window*, long)
Line
Count
Source
107
22.8k
    : mpWindowImpl(new WindowImpl( *this, WindowType::WINDOW ))
108
22.8k
{
109
    // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
110
22.8k
    mpWindowImpl->mxOutDev->mbEnableRTL = AllSettings::GetLayoutRTL();
111
112
22.8k
    ImplInit( pParent, nStyle, nullptr );
113
22.8k
}
Unexecuted instantiation: vcl::Window::Window(vcl::Window*, long)
114
115
#if OSL_DEBUG_LEVEL > 0
116
namespace
117
{
118
     OString lcl_createWindowInfo(const vcl::Window* pWindow)
119
     {
120
         // skip border windows, they do not carry information that
121
         // would help with diagnosing the problem
122
         const vcl::Window* pTempWin( pWindow );
123
         while ( pTempWin && pTempWin->GetType() == WindowType::BORDERWINDOW ) {
124
             pTempWin = pTempWin->GetWindow( GetWindowType::FirstChild );
125
         }
126
         // check if pTempWin is not null, otherwise use the
127
         // original address
128
         if ( pTempWin ) {
129
             pWindow = pTempWin;
130
         }
131
132
         return OString::Concat(" ") +
133
            typeid( *pWindow ).name() +
134
            "(" +
135
             OUStringToOString(
136
                 pWindow->GetText(),
137
                 RTL_TEXTENCODING_UTF8
138
                 ) +
139
            ")";
140
     }
141
}
142
#endif
143
144
void Window::dispose()
145
114k
{
146
114k
    assert( mpWindowImpl );
147
114k
    assert( !mpWindowImpl->mbInDispose ); // should only be called from disposeOnce()
148
114k
    assert( (!mpWindowImpl->mpParent ||
149
114k
             mpWindowImpl->mpParent->mpWindowImpl) &&
150
114k
            "vcl::Window child should have its parent disposed first" );
151
152
    // remove Key and Mouse events issued by Application::PostKey/MouseEvent
153
114k
    Application::RemoveMouseAndKeyEvents( this );
154
155
    // Dispose of the canvas implementation (which, currently, has an
156
    // own wrapper window as a child to this one.
157
114k
    GetOutDev()->ImplDisposeCanvas();
158
159
114k
    mpWindowImpl->mbInDispose = true;
160
161
114k
    CallEventListeners( VclEventId::ObjectDying );
162
163
    // do not send child events for frames that were registered as native frames
164
114k
    if( !IsNativeFrame() && mpWindowImpl->mbReallyVisible )
165
0
        if ( ImplIsAccessibleCandidate() && GetAccessibleParentWindow() )
166
0
            GetAccessibleParentWindow()->CallEventListeners( VclEventId::WindowChildDestroyed, this );
167
168
    // remove associated data structures from dockingmanager
169
114k
    ImplGetDockingManager()->RemoveWindow( this );
170
171
    // remove ownerdraw decorated windows from list in the top-most frame window
172
114k
    if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
173
0
    {
174
0
        ::std::vector< VclPtr<vcl::Window> >& rList = ImplGetOwnerDrawList();
175
0
        auto p = ::std::find( rList.begin(), rList.end(), VclPtr<vcl::Window>(this) );
176
0
        if( p != rList.end() )
177
0
            rList.erase( p );
178
0
    }
179
180
    // shutdown drag and drop
181
114k
    if( mpWindowImpl->mxDNDListenerContainer.is() )
182
9.15k
        mpWindowImpl->mxDNDListenerContainer->dispose();
183
184
114k
    if( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData )
185
4.57k
    {
186
4.57k
        try
187
4.57k
        {
188
            // deregister drop target listener
189
4.57k
            if( mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
190
0
            {
191
0
                Reference< XDragGestureRecognizer > xDragGestureRecognizer(mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY);
192
0
                if( xDragGestureRecognizer.is() )
193
0
                {
194
0
                    xDragGestureRecognizer->removeDragGestureListener(mpWindowImpl->mpFrameData->mxDropTargetListener);
195
0
                }
196
197
0
                mpWindowImpl->mpFrameData->mxDropTarget->removeDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener );
198
0
                mpWindowImpl->mpFrameData->mxDropTargetListener.clear();
199
0
            }
200
201
            // shutdown drag and drop for this frame window
202
4.57k
            Reference< XComponent > xComponent( mpWindowImpl->mpFrameData->mxDropTarget, UNO_QUERY );
203
204
            // DNDEventDispatcher does not hold a reference of the DropTarget,
205
            // so it's ok if it does not support XComponent
206
4.57k
            if( xComponent.is() )
207
0
                xComponent->dispose();
208
4.57k
        }
209
4.57k
        catch (const Exception&)
210
4.57k
        {
211
            // can be safely ignored here.
212
0
        }
213
4.57k
    }
214
215
114k
    UnoWrapperBase* pWrapper = UnoWrapperBase::GetUnoWrapper( false );
216
114k
    if ( pWrapper )
217
114k
        pWrapper->WindowDestroyed( this );
218
219
114k
    if (mpWindowImpl->mpAccessible.is())
220
0
    {
221
0
        mpWindowImpl->mpAccessible->dispose();
222
0
        mpWindowImpl->mpAccessible.clear();
223
0
    }
224
225
114k
    if (mpWindowImpl->mpAccessibleInfos)
226
0
        mpWindowImpl->mpAccessibleInfos->pAccessibleParent.clear();
227
228
114k
    ImplSVData* pSVData = ImplGetSVData();
229
230
114k
    if ( ImplGetSVHelpData().mpHelpWin && (ImplGetSVHelpData().mpHelpWin->GetParent() == this) )
231
0
        ImplDestroyHelpWindow( true );
232
233
114k
    SAL_WARN_IF(pSVData->mpWinData->mpTrackWin.get() == this, "vcl.window",
234
114k
                "Window::~Window(): Window is in TrackingMode");
235
114k
    SAL_WARN_IF(IsMouseCaptured(), "vcl.window",
236
114k
                "Window::~Window(): Window has the mouse captured");
237
238
    // due to old compatibility
239
114k
    if (pSVData->mpWinData->mpTrackWin == this)
240
0
        EndTracking();
241
114k
    if (IsMouseCaptured())
242
0
        ReleaseMouse();
243
244
#if OSL_DEBUG_LEVEL > 0
245
    // always perform these tests in debug builds
246
    {
247
        OStringBuffer aErrorStr;
248
        bool        bError = false;
249
        vcl::Window*     pTempWin;
250
251
        if ( mpWindowImpl->mpFirstChild )
252
        {
253
            OStringBuffer aTempStr = "Window (" +
254
                lcl_createWindowInfo(this) +
255
                ") with live children destroyed: ";
256
            pTempWin = mpWindowImpl->mpFirstChild;
257
            while ( pTempWin )
258
            {
259
                aTempStr.append(lcl_createWindowInfo(pTempWin));
260
                pTempWin = pTempWin->mpWindowImpl->mpNext;
261
            }
262
            OSL_FAIL( aTempStr.getStr() );
263
            Application::Abort(OStringToOUString(aTempStr, RTL_TEXTENCODING_UTF8));
264
        }
265
266
        if (mpWindowImpl->mpFrameData != nullptr)
267
        {
268
            pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap;
269
            while ( pTempWin )
270
            {
271
                if ( ImplIsRealParentPath( pTempWin ) )
272
                {
273
                    bError = true;
274
                    aErrorStr.append(lcl_createWindowInfo(pTempWin));
275
                }
276
                pTempWin = pTempWin->mpWindowImpl->mpNextOverlap;
277
            }
278
            if ( bError )
279
            {
280
                OString aTempStr =
281
                    "Window (" +
282
                    lcl_createWindowInfo(this) +
283
                    ") with live SystemWindows destroyed: " +
284
                    aErrorStr;
285
                OSL_FAIL(aTempStr.getStr());
286
                Application::Abort(OStringToOUString(aTempStr, RTL_TEXTENCODING_UTF8));
287
            }
288
        }
289
290
        bError = false;
291
        pTempWin = pSVData->maFrameData.mpFirstFrame;
292
        while ( pTempWin )
293
        {
294
            if ( ImplIsRealParentPath( pTempWin ) )
295
            {
296
                bError = true;
297
                aErrorStr.append(lcl_createWindowInfo(pTempWin));
298
            }
299
            pTempWin = pTempWin->mpWindowImpl->mpFrameData->mpNextFrame;
300
        }
301
        if ( bError )
302
        {
303
            OString aTempStr =  "Window (" +
304
                lcl_createWindowInfo(this) +
305
                ") with live SystemWindows destroyed: " +
306
                aErrorStr;
307
            OSL_FAIL( aTempStr.getStr() );
308
            Application::Abort(OStringToOUString(aTempStr, RTL_TEXTENCODING_UTF8));
309
        }
310
311
        if ( mpWindowImpl->mpFirstOverlap )
312
        {
313
            OStringBuffer aTempStr = "Window (" +
314
                lcl_createWindowInfo(this) +
315
                ") with live SystemWindows destroyed: ";
316
            pTempWin = mpWindowImpl->mpFirstOverlap;
317
            while ( pTempWin )
318
            {
319
                aTempStr.append(lcl_createWindowInfo(pTempWin));
320
                pTempWin = pTempWin->mpWindowImpl->mpNext;
321
            }
322
            OSL_FAIL( aTempStr.getStr() );
323
            Application::Abort(OStringToOUString(aTempStr, RTL_TEXTENCODING_UTF8));
324
        }
325
326
        vcl::Window* pMyParent = GetParent();
327
        SystemWindow* pMySysWin = nullptr;
328
329
        while ( pMyParent )
330
        {
331
            if ( pMyParent->IsSystemWindow() )
332
            {
333
                pMySysWin = dynamic_cast<SystemWindow *>(pMyParent);
334
            }
335
            pMyParent = pMyParent->GetParent();
336
        }
337
        if ( pMySysWin && pMySysWin->ImplIsInTaskPaneList( this ) )
338
        {
339
            OString aTempStr = "Window (" +
340
                lcl_createWindowInfo(this) +
341
                ") still in TaskPanelList!";
342
            OSL_FAIL( aTempStr.getStr() );
343
            Application::Abort(OStringToOUString(aTempStr, RTL_TEXTENCODING_UTF8));
344
        }
345
    }
346
#endif
347
348
114k
    if( mpWindowImpl->mbIsInTaskPaneList )
349
0
    {
350
0
        vcl::Window* pMyParent = GetParent();
351
0
        SystemWindow* pMySysWin = nullptr;
352
353
0
        while ( pMyParent )
354
0
        {
355
0
            if ( pMyParent->IsSystemWindow() )
356
0
            {
357
0
                pMySysWin = dynamic_cast<SystemWindow *>(pMyParent);
358
0
            }
359
0
            pMyParent = pMyParent->GetParent();
360
0
        }
361
0
        if ( pMySysWin && pMySysWin->ImplIsInTaskPaneList( this ) )
362
0
        {
363
0
            pMySysWin->GetTaskPaneList()->RemoveWindow( this );
364
0
        }
365
0
        else
366
0
        {
367
0
            SAL_WARN( "vcl", "Window (" << GetText() << ") not found in TaskPanelList");
368
0
        }
369
0
    }
370
371
    // remove from size-group if necessary
372
114k
    remove_from_all_size_groups();
373
374
    // clear mnemonic labels
375
114k
    std::vector<VclPtr<FixedText> > aMnemonicLabels(list_mnemonic_labels());
376
114k
    for (auto const& mnemonicLabel : aMnemonicLabels)
377
0
    {
378
0
        remove_mnemonic_label(mnemonicLabel);
379
0
    }
380
381
    // hide window in order to trigger the Paint-Handling
382
114k
    Hide();
383
384
    // EndExtTextInputMode
385
114k
    if (pSVData->mpWinData->mpExtTextInputWin == this)
386
0
    {
387
0
        EndExtTextInput();
388
0
        if (pSVData->mpWinData->mpExtTextInputWin == this)
389
0
            pSVData->mpWinData->mpExtTextInputWin = nullptr;
390
0
    }
391
392
    // check if the focus window is our child
393
114k
    bool bHasFocusedChild = false;
394
114k
    if (pSVData->mpWinData->mpFocusWin && ImplIsRealParentPath(pSVData->mpWinData->mpFocusWin))
395
0
    {
396
        // #122232#, this must not happen and is an application bug ! but we try some cleanup to hopefully avoid crashes, see below
397
0
        bHasFocusedChild = true;
398
#if OSL_DEBUG_LEVEL > 0
399
        OUString aTempStr = "Window (" + GetText() +
400
                ") with focused child window destroyed ! THIS WILL LEAD TO CRASHES AND MUST BE FIXED !";
401
        SAL_WARN( "vcl", aTempStr );
402
        Application::Abort(aTempStr);
403
#endif
404
0
    }
405
406
    // if we get focus pass focus to another window
407
114k
    vcl::Window* pOverlapWindow = ImplGetFirstOverlapWindow();
408
114k
    if (pSVData->mpWinData->mpFocusWin == this
409
114k
        || bHasFocusedChild) // #122232#, see above, try some cleanup
410
0
    {
411
0
        if ( mpWindowImpl->mbFrame )
412
0
        {
413
0
            pSVData->mpWinData->mpFocusWin = nullptr;
414
0
            pOverlapWindow->mpWindowImpl->mpLastFocusWindow = nullptr;
415
0
        }
416
0
        else
417
0
        {
418
0
            vcl::Window* pParent = GetParent();
419
0
            vcl::Window* pBorderWindow = mpWindowImpl->mpBorderWindow;
420
        // when windows overlap, give focus to the parent
421
        // of the next FrameWindow
422
0
            if ( pBorderWindow )
423
0
            {
424
0
                if ( pBorderWindow->ImplIsOverlapWindow() )
425
0
                    pParent = pBorderWindow->mpWindowImpl->mpOverlapWindow;
426
0
            }
427
0
            else if ( ImplIsOverlapWindow() )
428
0
                pParent = mpWindowImpl->mpOverlapWindow;
429
430
0
            if ( pParent && pParent->IsEnabled() && pParent->IsInputEnabled() && ! pParent->IsInModalMode() )
431
0
                pParent->GrabFocus();
432
0
            else
433
0
                mpWindowImpl->mpFrameWindow->GrabFocus();
434
435
            // If the focus was set back to 'this' set it to nothing
436
0
            if (pSVData->mpWinData->mpFocusWin == this)
437
0
            {
438
0
                pSVData->mpWinData->mpFocusWin = nullptr;
439
0
                pOverlapWindow->mpWindowImpl->mpLastFocusWindow = nullptr;
440
0
            }
441
0
        }
442
0
    }
443
444
114k
    if ( pOverlapWindow != nullptr &&
445
114k
         pOverlapWindow->mpWindowImpl->mpLastFocusWindow == this )
446
0
        pOverlapWindow->mpWindowImpl->mpLastFocusWindow = nullptr;
447
448
    // reset hint for DefModalDialogParent
449
114k
    if( pSVData->maFrameData.mpActiveApplicationFrame == this )
450
0
        pSVData->maFrameData.mpActiveApplicationFrame = nullptr;
451
452
    // reset hint of what was the last wheeled window
453
114k
    if (pSVData->mpWinData->mpLastWheelWindow == this)
454
0
        pSVData->mpWinData->mpLastWheelWindow = nullptr;
455
456
    // reset marked windows
457
114k
    if ( mpWindowImpl->mpFrameData != nullptr )
458
114k
    {
459
114k
        if ( mpWindowImpl->mpFrameData->mpFocusWin == this )
460
0
            mpWindowImpl->mpFrameData->mpFocusWin = nullptr;
461
114k
        if ( mpWindowImpl->mpFrameData->mpMouseMoveWin == this )
462
0
            mpWindowImpl->mpFrameData->mpMouseMoveWin = nullptr;
463
114k
        if ( mpWindowImpl->mpFrameData->mpMouseDownWin == this )
464
0
            mpWindowImpl->mpFrameData->mpMouseDownWin = nullptr;
465
114k
    }
466
467
    // reset Deactivate-Window
468
114k
    if (pSVData->mpWinData->mpLastDeacWin == this)
469
0
        pSVData->mpWinData->mpLastDeacWin = nullptr;
470
471
114k
    if ( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData )
472
4.57k
    {
473
4.57k
        if ( mpWindowImpl->mpFrameData->mnFocusId )
474
0
            Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnFocusId );
475
4.57k
        mpWindowImpl->mpFrameData->mnFocusId = nullptr;
476
4.57k
        if ( mpWindowImpl->mpFrameData->mnMouseMoveId )
477
0
            Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnMouseMoveId );
478
4.57k
        mpWindowImpl->mpFrameData->mnMouseMoveId = nullptr;
479
4.57k
    }
480
481
    // release SalGraphics
482
114k
    VclPtr<OutputDevice> pOutDev = GetOutDev();
483
114k
    pOutDev->ReleaseGraphics();
484
485
    // remove window from the lists
486
114k
    ImplRemoveWindow( true );
487
488
    // de-register as "top window child" at our parent, if necessary
489
114k
    if ( mpWindowImpl->mbFrame )
490
4.57k
    {
491
4.57k
        bool bIsTopWindow
492
4.57k
            = mpWindowImpl->mpWinData && (mpWindowImpl->mpWinData->mnIsTopWindow == 1);
493
4.57k
        if ( mpWindowImpl->mpRealParent && bIsTopWindow )
494
0
        {
495
0
            ImplWinData* pParentWinData = mpWindowImpl->mpRealParent->ImplGetWinData();
496
497
0
            auto myPos = ::std::find( pParentWinData->maTopWindowChildren.begin(),
498
0
                pParentWinData->maTopWindowChildren.end(), VclPtr<vcl::Window>(this) );
499
0
            SAL_WARN_IF( myPos == pParentWinData->maTopWindowChildren.end(), "vcl.window", "Window::~Window: inconsistency in top window chain!" );
500
0
            if ( myPos != pParentWinData->maTopWindowChildren.end() )
501
0
                pParentWinData->maTopWindowChildren.erase( myPos );
502
0
        }
503
4.57k
    }
504
505
114k
    mpWindowImpl->mpWinData.reset();
506
507
    // remove BorderWindow or Frame window data
508
114k
    mpWindowImpl->mpBorderWindow.disposeAndClear();
509
114k
    if ( mpWindowImpl->mbFrame )
510
4.57k
    {
511
4.57k
        if ( pSVData->maFrameData.mpFirstFrame == this )
512
4.57k
            pSVData->maFrameData.mpFirstFrame = mpWindowImpl->mpFrameData->mpNextFrame;
513
1
        else
514
1
        {
515
1
            sal_Int32 nWindows = 0;
516
1
            vcl::Window* pSysWin = pSVData->maFrameData.mpFirstFrame;
517
1
            while ( pSysWin && pSysWin->mpWindowImpl->mpFrameData->mpNextFrame.get() != this )
518
0
            {
519
0
                pSysWin = pSysWin->mpWindowImpl->mpFrameData->mpNextFrame;
520
0
                nWindows++;
521
0
            }
522
523
1
            if ( pSysWin )
524
1
            {
525
1
                assert (mpWindowImpl->mpFrameData->mpNextFrame.get() != pSysWin);
526
1
                pSysWin->mpWindowImpl->mpFrameData->mpNextFrame = mpWindowImpl->mpFrameData->mpNextFrame;
527
1
            }
528
0
            else // if it is not in the list, we can't remove it.
529
1
                SAL_WARN("vcl.window", "Window " << this << " marked as frame window, "
530
1
                         "is missing from list of " << nWindows << " frames");
531
1
        }
532
4.57k
        if (mpWindowImpl->mpFrame) // otherwise exception during init
533
4.57k
        {
534
4.57k
            mpWindowImpl->mpFrame->SetCallback( nullptr, nullptr );
535
4.57k
            pSVData->mpDefInst->DestroyFrame( mpWindowImpl->mpFrame );
536
4.57k
        }
537
4.57k
        assert (mpWindowImpl->mpFrameData->mnFocusId == nullptr);
538
4.57k
        assert (mpWindowImpl->mpFrameData->mnMouseMoveId == nullptr);
539
540
4.57k
        mpWindowImpl->mpFrameData->mpBuffer.disposeAndClear();
541
4.57k
        delete mpWindowImpl->mpFrameData;
542
4.57k
        mpWindowImpl->mpFrameData = nullptr;
543
4.57k
    }
544
545
114k
    if (mpWindowImpl->mxWindowPeer)
546
9.16k
        mpWindowImpl->mxWindowPeer->dispose();
547
548
    // should be the last statements
549
114k
    mpWindowImpl.reset();
550
551
114k
    pOutDev.disposeAndClear();
552
    // just to make loplugin:vclwidgets happy
553
114k
    VclReferenceBase::dispose();
554
114k
}
555
556
Window::~Window()
557
114k
{
558
114k
    disposeOnce();
559
114k
}
560
561
// We will eventually being removing the inheritance of OutputDevice
562
// from Window. It will be replaced with a transient relationship such
563
// that the OutputDevice is only live for the scope of the Paint method.
564
// In the meantime this can help move us towards a Window use an
565
// OutputDevice, not being one.
566
567
::OutputDevice const* Window::GetOutDev() const
568
591k
{
569
591k
    return mpWindowImpl ? mpWindowImpl->mxOutDev.get() : nullptr;
570
591k
}
571
572
::OutputDevice* Window::GetOutDev()
573
4.80M
{
574
4.80M
    return mpWindowImpl ? mpWindowImpl->mxOutDev.get() : nullptr;
575
4.80M
}
576
577
Color WindowOutputDevice::GetBackgroundColor() const
578
0
{
579
0
    return mxOwnerWindow->GetDisplayBackground().GetColor();
580
0
}
581
582
bool WindowOutputDevice::CanEnableNativeWidget() const
583
34.8k
{
584
34.8k
    return mxOwnerWindow->IsNativeWidgetEnabled();
585
34.8k
}
586
587
} /* namespace vcl */
588
589
WindowImpl::WindowImpl( vcl::Window& rWindow, WindowType eType )
590
140k
{
591
140k
    mxOutDev = VclPtr<vcl::WindowOutputDevice>::Create(rWindow);
592
140k
    maZoom                              = Fraction( 1, 1 );
593
140k
    mfPartialScrollX                    = 0.0;
594
140k
    mfPartialScrollY                    = 0.0;
595
140k
    maWinRegion                         = vcl::Region(true);
596
140k
    maWinClipRegion                     = vcl::Region(true);
597
140k
    mpWinData                           = nullptr;                      // Extra Window Data, that we don't need for all windows
598
140k
    mpFrameData                         = nullptr;                      // Frame Data
599
140k
    mpFrame                             = nullptr;                      // Pointer to frame window
600
140k
    mpSysObj                            = nullptr;
601
140k
    mpFrameWindow                       = nullptr;                      // window to top level parent (same as frame window)
602
140k
    mpOverlapWindow                     = nullptr;                      // first overlap parent
603
140k
    mpBorderWindow                      = nullptr;                      // Border-Window
604
140k
    mpClientWindow                      = nullptr;                      // Client-Window of a FrameWindow
605
140k
    mpParent                            = nullptr;                      // parent (incl. BorderWindow)
606
140k
    mpRealParent                        = nullptr;                      // real parent (excl. BorderWindow)
607
140k
    mpFirstChild                        = nullptr;                      // first child window
608
140k
    mpLastChild                         = nullptr;                      // last child window
609
140k
    mpFirstOverlap                      = nullptr;                      // first overlap window (only set in overlap windows)
610
140k
    mpLastOverlap                       = nullptr;                      // last overlap window (only set in overlap windows)
611
140k
    mpPrev                              = nullptr;                      // prev window
612
140k
    mpNext                              = nullptr;                      // next window
613
140k
    mpNextOverlap                       = nullptr;                      // next overlap window of frame
614
140k
    mpLastFocusWindow                   = nullptr;                      // window for focus restore
615
140k
    mpDlgCtrlDownWindow                 = nullptr;                      // window for dialog control
616
140k
    mnEventListenersIteratingCount = 0;
617
140k
    mnChildEventListenersIteratingCount = 0;
618
140k
    mpCursor                            = nullptr;                      // cursor
619
140k
    maPointer                           = PointerStyle::Arrow;
620
140k
    mpVCLXWindow                        = nullptr;
621
140k
    mpAccessibleInfos                   = nullptr;
622
140k
    maControlForeground                 = COL_TRANSPARENT;  // no foreground set
623
140k
    maControlBackground                 = COL_TRANSPARENT;  // no background set
624
140k
    mnLeftBorder                        = 0;                         // width of left border
625
140k
    mnTopBorder                         = 0;                         // width of top border
626
140k
    mnRightBorder                       = 0;                         // width of right border
627
140k
    mnBottomBorder                      = 0;                         // width of bottom border
628
140k
    mnWidthRequest                      = -1;                        // width request
629
140k
    mnHeightRequest                     = -1;                        // height request
630
140k
    mnOptimalWidthCache                 = -1;                        // optimal width cache
631
140k
    mnOptimalHeightCache                = -1;                        // optimal height cache
632
140k
    mnX                                 = 0;                         // X-Position to Parent
633
140k
    mnY                                 = 0;                         // Y-Position to Parent
634
140k
    mnAbsScreenX                        = 0;                         // absolute X-position on screen, used for RTL window positioning
635
140k
    mpChildClipRegion                   = nullptr;                      // Child-Clip-Region when ClipChildren
636
140k
    mpPaintRegion                       = nullptr;                      // Paint-ClipRegion
637
140k
    mnStyle                             = 0;                         // style (init in ImplInitWindow)
638
140k
    mnPrevStyle                         = 0;                         // prevstyle (set in SetStyle)
639
140k
    mnExtendedStyle                     = WindowExtendedStyle::NONE; // extended style (init in ImplInitWindow)
640
140k
    meType                              = eType;                     // type
641
140k
    mnGetFocusFlags                     = GetFocusFlags::NONE;       // Flags for GetFocus()-Call
642
140k
    mnWaitCount                         = 0;                         // Wait-Count (>1 == "wait" mouse pointer)
643
140k
    mnPaintFlags                        = ImplPaintFlags::NONE;      // Flags for ImplCallPaint
644
140k
    mnParentClipMode                    = ParentClipMode::NONE;      // Flags for Parent-ClipChildren-Mode
645
140k
    mnActivateMode                      = ActivateModeFlags::NONE;   // Will be converted in System/Overlap-Windows
646
140k
    mnDlgCtrlFlags                      = DialogControlFlags::NONE;  // DialogControl-Flags
647
140k
    meAlwaysInputMode                   = AlwaysInputNone;           // AlwaysEnableInput not called
648
140k
    meHalign                            = VclAlign::Fill;
649
140k
    meValign                            = VclAlign::Fill;
650
140k
    mePackType                          = VclPackType::Start;
651
140k
    mnPadding                           = 0;
652
140k
    mnGridHeight                        = 1;
653
140k
    mnGridLeftAttach                    = -1;
654
140k
    mnGridTopAttach                     = -1;
655
140k
    mnGridWidth                         = 1;
656
140k
    mnBorderWidth                       = 0;
657
140k
    mnMarginLeft                        = 0;
658
140k
    mnMarginRight                       = 0;
659
140k
    mnMarginTop                         = 0;
660
140k
    mnMarginBottom                      = 0;
661
140k
    mbFrame                             = false;                     // true: Window is a frame window
662
140k
    mbBorderWin                         = false;                     // true: Window is a border window
663
140k
    mbOverlapWin                        = false;                     // true: Window is an overlap window
664
140k
    mbSysWin                            = false;                     // true: SystemWindow is the base class
665
140k
    mbDialog                            = false;                     // true: Dialog is the base class
666
140k
    mbDockWin                           = false;                     // true: DockingWindow is the base class
667
140k
    mbFloatWin                          = false;                     // true: FloatingWindow is the base class
668
140k
    mbPushButton                        = false;                     // true: PushButton is the base class
669
140k
    mbToolBox                           = false;                     // true: ToolBox is the base class
670
140k
    mbMenuFloatingWindow                = false;                     // true: MenuFloatingWindow is the base class
671
140k
    mbSplitter                          = false;                     // true: Splitter is the base class
672
140k
    mbVisible                           = false;                     // true: Show( true ) called
673
140k
    mbOverlapVisible                    = false;                     // true: Hide called for visible window from ImplHideAllOverlapWindow()
674
140k
    mbDisabled                          = false;                     // true: Enable( false ) called
675
140k
    mbInputDisabled                     = false;                     // true: EnableInput( false ) called
676
140k
    mbNoUpdate                          = false;                     // true: SetUpdateMode( false ) called
677
140k
    mbNoParentUpdate                    = false;                     // true: SetParentUpdateMode( false ) called
678
140k
    mbActive                            = false;                     // true: Window Active
679
140k
    mbReallyVisible                     = false;                     // true: this and all parents to an overlapped window are visible
680
140k
    mbReallyShown                       = false;                     // true: this and all parents to an overlapped window are shown
681
140k
    mbInInitShow                        = false;                     // true: we are in InitShow
682
140k
    mbChildPtrOverwrite                 = false;                     // true: PointerStyle overwrites Child-Pointer
683
140k
    mbNoPtrVisible                      = false;                     // true: ShowPointer( false ) called
684
140k
    mbPaintFrame                        = false;                     // true: Paint is visible, but not painted
685
140k
    mbInPaint                           = false;                     // true: Inside PaintHdl
686
140k
    mbMouseButtonDown                   = false;                     // true: BaseMouseButtonDown called
687
140k
    mbMouseButtonUp                     = false;                     // true: BaseMouseButtonUp called
688
140k
    mbKeyInput                          = false;                     // true: BaseKeyInput called
689
140k
    mbKeyUp                             = false;                     // true: BaseKeyUp called
690
140k
    mbCommand                           = false;                     // true: BaseCommand called
691
140k
    mbDefPos                            = true;                      // true: Position is not Set
692
140k
    mbDefSize                           = true;                      // true: Size is not Set
693
140k
    mbCallMove                          = true;                      // true: Move must be called by Show
694
140k
    mbCallResize                        = true;                      // true: Resize must be called by Show
695
140k
    mbWaitSystemResize                  = true;                      // true: Wait for System-Resize
696
140k
    mbInitWinClipRegion                 = true;                      // true: Calc Window Clip Region
697
140k
    mbInitChildRegion                   = false;                     // true: InitChildClipRegion
698
140k
    mbWinRegion                         = false;                     // true: Window Region
699
140k
    mbClipChildren                      = false;                     // true: Child-window should be clipped
700
140k
    mbClipSiblings                      = false;                     // true: Adjacent Child-window should be clipped
701
140k
    mbChildTransparent                  = false;                     // true: Child-windows are allowed to switch to transparent (incl. Parent-CLIPCHILDREN)
702
140k
    mbPaintTransparent                  = false;                     // true: Paints should be executed on the Parent
703
140k
    mbMouseTransparent                  = false;                     // true: Window is transparent for Mouse
704
140k
    mbDlgCtrlStart                      = false;                     // true: From here on own Dialog-Control
705
140k
    mbFocusVisible                      = false;                     // true: Focus Visible
706
140k
    mbUseNativeFocus                    = false;
707
140k
    mbNativeFocusVisible                = false;                     // true: native Focus Visible
708
140k
    mbInShowFocus                       = false;                     // prevent recursion
709
140k
    mbInHideFocus                       = false;                     // prevent recursion
710
140k
    mbTrackVisible                      = false;                     // true: Tracking Visible
711
140k
    mbControlForeground                 = false;                     // true: Foreground-Property set
712
140k
    mbControlBackground                 = false;                     // true: Background-Property set
713
140k
    mbAlwaysOnTop                       = false;                     // true: always visible for all others windows
714
140k
    mbCompoundControl                   = false;                     // true: Composite Control => Listener...
715
140k
    mbCompoundControlHasFocus           = false;                     // true: Composite Control has focus somewhere
716
140k
    mbPaintDisabled                     = false;                     // true: Paint should not be executed
717
140k
    mbAllResize                         = false;                     // true: Also sent ResizeEvents with 0,0
718
140k
    mbInDispose                         = false;                     // true: We're still in Window::dispose()
719
140k
    mbExtTextInput                      = false;                     // true: ExtTextInput-Mode is active
720
140k
    mbInFocusHdl                        = false;                     // true: Within GetFocus-Handler
721
140k
    mbCreatedWithToolkit                = false;
722
140k
    mbSuppressAccessibilityEvents       = false;                     // true: do not send any accessibility events
723
140k
    mbDrawSelectionBackground           = false;                     // true: draws transparent window background to indicate (toolbox) selection
724
140k
    mbIsInTaskPaneList                  = false;                     // true: window was added to the taskpanelist in the topmost system window
725
140k
    mnNativeBackground                  = ControlPart::NONE;         // initialize later, depends on type
726
140k
    mbHelpTextDynamic                   = false;                     // true: append help id in HELP_DEBUG case
727
140k
    mbFakeFocusSet                      = false;                     // true: pretend as if the window has focus.
728
140k
    mbHexpand                           = false;
729
140k
    mbVexpand                           = false;
730
140k
    mbExpand                            = false;
731
140k
    mbFill                              = true;
732
140k
    mbSecondary                         = false;
733
140k
    mbNonHomogeneous                    = false;
734
140k
    static bool bDoubleBuffer = getenv("VCL_DOUBLEBUFFERING_FORCE_ENABLE");
735
140k
    mbDoubleBufferingRequested = bDoubleBuffer; // when we are not sure, assume it cannot do double-buffering via RenderContext
736
140k
    mpLOKNotifier                       = nullptr;
737
140k
    mnLOKWindowId                       = 0;
738
140k
    mbUseFrameData                      = false;
739
140k
}
740
741
WindowImpl::~WindowImpl()
742
114k
{
743
114k
    mpChildClipRegion.reset();
744
114k
    mpAccessibleInfos.reset();
745
114k
}
746
747
ImplWinData::ImplWinData() :
748
118k
    mnCursorExtWidth(0),
749
118k
    mbVertical(false),
750
118k
    mnCompositionCharRects(0),
751
118k
    mnTrackFlags(ShowTrackFlags::NONE),
752
118k
    mnIsTopWindow(sal_uInt16(~0)), // not initialized yet, 0/1 will indicate TopWindow (see IsTopWindow())
753
118k
    mbMouseOver(false),
754
118k
    mbEnableNativeWidget(false)
755
118k
{
756
118k
}
757
758
ImplWinData::~ImplWinData()
759
114k
{
760
114k
    mpCompositionCharRects.reset();
761
114k
}
762
763
ImplFrameData::ImplFrameData( vcl::Window *pWindow )
764
8.34k
    : maPaintIdle( "vcl::Window maPaintIdle" ),
765
8.34k
      maResizeIdle( "vcl::Window maResizeIdle" )
766
8.34k
{
767
8.34k
    ImplSVData* pSVData = ImplGetSVData();
768
8.34k
    assert (pSVData->maFrameData.mpFirstFrame.get() != pWindow);
769
8.34k
    mpNextFrame        = pSVData->maFrameData.mpFirstFrame;
770
8.34k
    pSVData->maFrameData.mpFirstFrame = pWindow;
771
8.34k
    mpFirstOverlap     = nullptr;
772
8.34k
    mpFocusWin         = nullptr;
773
8.34k
    mpMouseMoveWin     = nullptr;
774
8.34k
    mpMouseDownWin     = nullptr;
775
8.34k
    mpTrackWin         = nullptr;
776
8.34k
    mxFontCollection   = pSVData->maGDIData.mxScreenFontList;
777
8.34k
    mxFontCache        = pSVData->maGDIData.mxScreenFontCache;
778
8.34k
    mnFocusId          = nullptr;
779
8.34k
    mnMouseMoveId      = nullptr;
780
8.34k
    mnLastMouseX       = -32767;
781
8.34k
    mnLastMouseY       = -32767;
782
8.34k
    mnBeforeLastMouseX = -32767;
783
8.34k
    mnBeforeLastMouseY = -32767;
784
8.34k
    mnFirstMouseX      = -32767;
785
8.34k
    mnFirstMouseY      = -32767;
786
8.34k
    mnLastMouseWinX    = -32767;
787
8.34k
    mnLastMouseWinY    = -32767;
788
8.34k
    mnModalMode        = 0;
789
8.34k
    mnMouseDownTime    = 0;
790
8.34k
    mnClickCount       = 0;
791
8.34k
    mnFirstMouseCode   = 0;
792
8.34k
    mnMouseCode        = 0;
793
8.34k
    mnMouseMode        = MouseEventModifiers::NONE;
794
8.34k
    mbHasFocus         = false;
795
8.34k
    mbInMouseMove      = false;
796
8.34k
    mbMouseIn          = false;
797
8.34k
    mbStartDragCalled  = false;
798
8.34k
    mbNeedSysWindow    = false;
799
8.34k
    mbMinimized        = false;
800
8.34k
    mbStartFocusState  = false;
801
8.34k
    mbInSysObjFocusHdl = false;
802
8.34k
    mbInSysObjToTopHdl = false;
803
8.34k
    mbSysObjFocus      = false;
804
8.34k
    maPaintIdle.SetPriority( TaskPriority::REPAINT );
805
8.34k
    maPaintIdle.SetInvokeHandler( LINK( pWindow, vcl::Window, ImplHandlePaintHdl ) );
806
8.34k
    maResizeIdle.SetPriority( TaskPriority::RESIZE );
807
8.34k
    maResizeIdle.SetInvokeHandler( LINK( pWindow, vcl::Window, ImplHandleResizeTimerHdl ) );
808
8.34k
    mbInternalDragGestureRecognizer = false;
809
8.34k
    mbDragging = false;
810
8.34k
    mbInBufferedPaint = false;
811
8.34k
    mnDPIX = 96;
812
8.34k
    mnDPIY = 96;
813
8.34k
    mnTouchPanPositionX = -1;
814
8.34k
    mnTouchPanPositionY = -1;
815
8.34k
}
816
817
namespace vcl {
818
819
bool WindowOutputDevice::AcquireGraphics() const
820
171k
{
821
171k
    DBG_TESTSOLARMUTEX();
822
823
171k
    if (isDisposed())
824
0
        return false;
825
826
171k
    if (mpGraphics)
827
86.4k
        return true;
828
829
85.3k
    mbInitLineColor     = true;
830
85.3k
    mbInitFillColor     = true;
831
85.3k
    mbInitFont          = true;
832
85.3k
    mbInitTextColor     = true;
833
85.3k
    mbInitClipRegion    = true;
834
835
85.3k
    ImplSVData* pSVData = ImplGetSVData();
836
837
85.3k
    mpGraphics = mxOwnerWindow->mpWindowImpl->mpFrame->AcquireGraphics();
838
    // try harder if no wingraphics was available directly
839
85.3k
    if ( !mpGraphics )
840
0
    {
841
        // find another output device in the same frame
842
0
        vcl::WindowOutputDevice* pReleaseOutDev = pSVData->maGDIData.mpLastWinGraphics.get();
843
0
        while ( pReleaseOutDev )
844
0
        {
845
0
            if ( pReleaseOutDev->mxOwnerWindow && pReleaseOutDev->mxOwnerWindow->mpWindowImpl->mpFrame == mxOwnerWindow->mpWindowImpl->mpFrame )
846
0
                break;
847
0
            pReleaseOutDev = static_cast<vcl::WindowOutputDevice*>(pReleaseOutDev->mpPrevGraphics.get());
848
0
        }
849
850
0
        if ( pReleaseOutDev )
851
0
        {
852
            // steal the wingraphics from the other outdev
853
0
            mpGraphics = pReleaseOutDev->mpGraphics;
854
0
            pReleaseOutDev->ReleaseGraphics( false );
855
0
        }
856
0
        else
857
0
        {
858
            // if needed retry after releasing least recently used wingraphics
859
0
            while ( !mpGraphics )
860
0
            {
861
0
                if ( !pSVData->maGDIData.mpLastWinGraphics )
862
0
                    break;
863
0
                pSVData->maGDIData.mpLastWinGraphics->ReleaseGraphics();
864
0
                mpGraphics = mxOwnerWindow->mpWindowImpl->mpFrame->AcquireGraphics();
865
0
            }
866
0
        }
867
0
    }
868
869
85.3k
    if ( mpGraphics )
870
85.3k
    {
871
        // update global LRU list of wingraphics
872
85.3k
        mpNextGraphics = pSVData->maGDIData.mpFirstWinGraphics.get();
873
85.3k
        pSVData->maGDIData.mpFirstWinGraphics = const_cast<vcl::WindowOutputDevice*>(this);
874
85.3k
        if ( mpNextGraphics )
875
85.3k
            mpNextGraphics->mpPrevGraphics = const_cast<vcl::WindowOutputDevice*>(this);
876
85.3k
        if ( !pSVData->maGDIData.mpLastWinGraphics )
877
31
            pSVData->maGDIData.mpLastWinGraphics = const_cast<vcl::WindowOutputDevice*>(this);
878
879
85.3k
        mpGraphics->SetXORMode( (RasterOp::Invert == meRasterOp) || (RasterOp::Xor == meRasterOp), RasterOp::Invert == meRasterOp );
880
85.3k
        mpGraphics->setAntiAlias(bool(mnAntialiasing & AntialiasingFlags::Enable));
881
85.3k
    }
882
883
85.3k
    return mpGraphics != nullptr;
884
171k
}
885
886
void WindowOutputDevice::ReleaseGraphics( bool bRelease )
887
228k
{
888
228k
    DBG_TESTSOLARMUTEX();
889
890
228k
    if ( !mpGraphics )
891
151k
        return;
892
893
    // release the fonts of the physically released graphics device
894
77.8k
    if( bRelease )
895
77.8k
        ImplReleaseFonts();
896
897
77.8k
    ImplSVData* pSVData = ImplGetSVData();
898
899
77.8k
    vcl::Window* pWindow = mxOwnerWindow.get();
900
77.8k
    if (!pWindow)
901
0
        return;
902
903
77.8k
    if ( bRelease )
904
77.8k
        pWindow->mpWindowImpl->mpFrame->ReleaseGraphics( mpGraphics );
905
    // remove from global LRU list of window graphics
906
77.8k
    if ( mpPrevGraphics )
907
64.0k
        mpPrevGraphics->mpNextGraphics = mpNextGraphics;
908
13.7k
    else
909
13.7k
        pSVData->maGDIData.mpFirstWinGraphics = static_cast<vcl::WindowOutputDevice*>(mpNextGraphics.get());
910
77.8k
    if ( mpNextGraphics )
911
77.8k
        mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
912
1
    else
913
1
        pSVData->maGDIData.mpLastWinGraphics = static_cast<vcl::WindowOutputDevice*>(mpPrevGraphics.get());
914
915
77.8k
    mpGraphics      = nullptr;
916
77.8k
    mpPrevGraphics  = nullptr;
917
77.8k
    mpNextGraphics  = nullptr;
918
77.8k
}
919
920
static sal_Int32 CountDPIScaleFactor(sal_Int32 nDPI)
921
140k
{
922
140k
#ifndef MACOSX
923
    // Setting of HiDPI is unfortunately all only a heuristic; and to add
924
    // insult to an injury, the system is constantly lying to us about
925
    // the DPI and whatnot
926
    // eg. fdo#77059 - set the value from which we do consider the
927
    // screen HiDPI to greater than 168
928
140k
    if (nDPI > 216)      // 96 * 2   + 96 / 4
929
0
        return 250;
930
140k
    else if (nDPI > 168) // 96 * 2   - 96 / 4
931
0
        return 200;
932
140k
    else if (nDPI > 120) // 96 * 1.5 - 96 / 4
933
0
        return 150;
934
#else
935
    (void)nDPI;
936
#endif
937
938
140k
    return 100;
939
140k
}
940
941
void Window::ImplInit( vcl::Window* pParent, WinBits nStyle, SystemParentData* pSystemParentData )
942
140k
{
943
140k
    SAL_WARN_IF( !mpWindowImpl->mbFrame && !pParent && GetType() != WindowType::FIXEDIMAGE, "vcl.window",
944
140k
        "Window::Window(): pParent == NULL" );
945
946
140k
    ImplSVData* pSVData = ImplGetSVData();
947
140k
    vcl::Window*     pRealParent = pParent;
948
949
    // inherit 3D look
950
140k
    if ( !mpWindowImpl->mbOverlapWin && pParent && (pParent->GetStyle() & WB_3DLOOK) )
951
54.9k
        nStyle |= WB_3DLOOK;
952
953
    // create border window if necessary
954
140k
    if ( !mpWindowImpl->mbFrame && !mpWindowImpl->mbBorderWin && !mpWindowImpl->mpBorderWindow
955
127k
         && (nStyle & (WB_BORDER | WB_SYSTEMCHILDWINDOW) ) )
956
4.57k
    {
957
4.57k
        BorderWindowStyle nBorderTypeStyle = BorderWindowStyle::NONE;
958
4.57k
        if( nStyle & WB_SYSTEMCHILDWINDOW )
959
0
        {
960
            // handle WB_SYSTEMCHILDWINDOW
961
            // these should be analogous to a top level frame; meaning they
962
            // should have a border window with style BorderWindowStyle::Frame
963
            // which controls their size
964
0
            nBorderTypeStyle |= BorderWindowStyle::Frame;
965
0
            nStyle |= WB_BORDER;
966
0
        }
967
4.57k
        VclPtrInstance<ImplBorderWindow> pBorderWin( pParent, nStyle & (WB_BORDER | WB_DIALOGCONTROL | WB_NODIALOGCONTROL), nBorderTypeStyle );
968
4.57k
        static_cast<vcl::Window*>(pBorderWin)->mpWindowImpl->mpClientWindow = this;
969
4.57k
        pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
970
4.57k
        mpWindowImpl->mpBorderWindow  = pBorderWin;
971
4.57k
        pParent = mpWindowImpl->mpBorderWindow;
972
4.57k
    }
973
136k
    else if( !mpWindowImpl->mbFrame && ! pParent )
974
0
    {
975
0
        mpWindowImpl->mbOverlapWin  = true;
976
0
        mpWindowImpl->mbFrame = true;
977
0
    }
978
979
    // insert window in list
980
140k
    ImplInsertWindow( pParent );
981
140k
    mpWindowImpl->mnStyle = nStyle;
982
983
140k
    if( pParent && ! mpWindowImpl->mbFrame )
984
132k
        mpWindowImpl->mxOutDev->mbEnableRTL = AllSettings::GetLayoutRTL();
985
986
    // test for frame creation
987
140k
    if ( mpWindowImpl->mbFrame )
988
8.34k
    {
989
        // create frame
990
8.34k
        SalFrameStyleFlags nFrameStyle = SalFrameStyleFlags::NONE;
991
992
8.34k
        if ( nStyle & WB_MOVEABLE )
993
8.31k
            nFrameStyle |= SalFrameStyleFlags::MOVEABLE;
994
8.34k
        if ( nStyle & WB_SIZEABLE )
995
8.31k
            nFrameStyle |= SalFrameStyleFlags::SIZEABLE;
996
8.34k
        if ( nStyle & WB_CLOSEABLE )
997
8.31k
            nFrameStyle |= SalFrameStyleFlags::CLOSEABLE;
998
8.34k
        if ( nStyle & WB_APP )
999
0
            nFrameStyle |= SalFrameStyleFlags::DEFAULT;
1000
        // check for undecorated floating window
1001
8.34k
        if( // 1. floating windows that are not moveable/sizeable (only closeable allowed)
1002
8.34k
            ( !(nFrameStyle & ~SalFrameStyleFlags::CLOSEABLE) &&
1003
31
            ( mpWindowImpl->mbFloatWin || ((GetType() == WindowType::BORDERWINDOW) && static_cast<ImplBorderWindow*>(this)->mbFloatWindow) || (nStyle & WB_SYSTEMFLOATWIN) ) ) ||
1004
            // 2. borderwindows of floaters with ownerdraw decoration
1005
8.34k
            ((GetType() == WindowType::BORDERWINDOW) && static_cast<ImplBorderWindow*>(this)->mbFloatWindow && (nStyle & WB_OWNERDRAWDECORATION) ) )
1006
0
        {
1007
0
            nFrameStyle = SalFrameStyleFlags::FLOAT;
1008
0
            if( nStyle & WB_OWNERDRAWDECORATION )
1009
0
                nFrameStyle |= SalFrameStyleFlags::OWNERDRAWDECORATION | SalFrameStyleFlags::NOSHADOW;
1010
0
        }
1011
8.34k
        else if( mpWindowImpl->mbFloatWin )
1012
0
            nFrameStyle |= SalFrameStyleFlags::TOOLWINDOW;
1013
1014
8.34k
        if( nStyle & WB_INTROWIN )
1015
0
            nFrameStyle |= SalFrameStyleFlags::INTRO;
1016
8.34k
        if( nStyle & WB_TOOLTIPWIN )
1017
0
            nFrameStyle |= SalFrameStyleFlags::TOOLTIP;
1018
1019
8.34k
        if( nStyle & WB_NOSHADOW )
1020
0
            nFrameStyle |= SalFrameStyleFlags::NOSHADOW;
1021
1022
8.34k
        if( nStyle & WB_SYSTEMCHILDWINDOW )
1023
0
            nFrameStyle |= SalFrameStyleFlags::SYSTEMCHILD;
1024
1025
8.34k
        switch (mpWindowImpl->meType)
1026
8.34k
        {
1027
0
            case WindowType::DIALOG:
1028
0
            case WindowType::TABDIALOG:
1029
0
            case WindowType::MODELESSDIALOG:
1030
0
            case WindowType::MESSBOX:
1031
0
            case WindowType::INFOBOX:
1032
0
            case WindowType::WARNINGBOX:
1033
0
            case WindowType::ERRORBOX:
1034
0
            case WindowType::QUERYBOX:
1035
0
                nFrameStyle |= SalFrameStyleFlags::DIALOG;
1036
0
                break;
1037
8.34k
            default:
1038
8.34k
                break;
1039
8.34k
        }
1040
1041
        // tdf#144624 for the DefaultWindow, which is never visible, don't
1042
        // create an icon for it so construction of a DefaultWindow cannot
1043
        // trigger creation of a VirtualDevice which itself requires a
1044
        // DefaultWindow to exist
1045
8.34k
        if( nStyle & WB_DEFAULTWIN )
1046
31
            nFrameStyle |= SalFrameStyleFlags::NOICON;
1047
1048
8.34k
        SalFrame* pParentFrame = nullptr;
1049
8.34k
        if ( pParent )
1050
0
            pParentFrame = pParent->mpWindowImpl->mpFrame;
1051
8.34k
        SalFrame* pFrame;
1052
8.34k
        if ( pSystemParentData )
1053
0
            pFrame = pSVData->mpDefInst->CreateChildFrame( pSystemParentData, nFrameStyle | SalFrameStyleFlags::PLUG );
1054
8.34k
        else
1055
8.34k
            pFrame = pSVData->mpDefInst->CreateFrame( pParentFrame, nFrameStyle );
1056
8.34k
        if ( !pFrame )
1057
0
        {
1058
            // do not abort but throw an exception, may be the current thread terminates anyway (plugin-scenario)
1059
0
            throw RuntimeException(
1060
0
                u"Could not create system window!"_ustr,
1061
0
                Reference< XInterface >() );
1062
0
        }
1063
1064
8.34k
        pFrame->SetCallback( this, ImplWindowFrameProc );
1065
1066
        // set window frame data
1067
8.34k
        mpWindowImpl->mpFrameData     = new ImplFrameData( this );
1068
8.34k
        mpWindowImpl->mpFrame         = pFrame;
1069
8.34k
        mpWindowImpl->mpFrameWindow   = this;
1070
8.34k
        mpWindowImpl->mpOverlapWindow = this;
1071
1072
8.34k
        if (!(nStyle & WB_DEFAULTWIN) && mpWindowImpl->mbDoubleBufferingRequested)
1073
0
            RequestDoubleBuffering(true);
1074
1075
8.34k
        if ( pRealParent && IsTopWindow() )
1076
0
        {
1077
0
            ImplWinData* pParentWinData = pRealParent->ImplGetWinData();
1078
0
            pParentWinData->maTopWindowChildren.emplace_back(this );
1079
0
        }
1080
8.34k
    }
1081
1082
    // init data
1083
140k
    mpWindowImpl->mpRealParent = pRealParent;
1084
1085
    // #99318: make sure fontcache and list is available before call to SetSettings
1086
140k
    mpWindowImpl->mxOutDev->mxFontCollection = mpWindowImpl->mpFrameData->mxFontCollection;
1087
140k
    mpWindowImpl->mxOutDev->mxFontCache = mpWindowImpl->mpFrameData->mxFontCache;
1088
1089
140k
    if ( mpWindowImpl->mbFrame )
1090
8.34k
    {
1091
8.34k
        if ( pParent )
1092
0
        {
1093
0
            mpWindowImpl->mpFrameData->mnDPIX     = pParent->mpWindowImpl->mpFrameData->mnDPIX;
1094
0
            mpWindowImpl->mpFrameData->mnDPIY     = pParent->mpWindowImpl->mpFrameData->mnDPIY;
1095
0
        }
1096
8.34k
        else
1097
8.34k
        {
1098
8.34k
            if (auto* pGraphics = GetOutDev()->GetGraphics())
1099
8.34k
            {
1100
8.34k
                pGraphics->GetResolution(mpWindowImpl->mpFrameData->mnDPIX,
1101
8.34k
                                         mpWindowImpl->mpFrameData->mnDPIY);
1102
8.34k
            }
1103
8.34k
        }
1104
1105
        // add ownerdraw decorated frame windows to list in the top-most frame window
1106
        // so they can be hidden on lose focus
1107
8.34k
        if( nStyle & WB_OWNERDRAWDECORATION )
1108
0
            ImplGetOwnerDrawList().emplace_back(this );
1109
1110
        // delay settings initialization until first "real" frame
1111
        // this relies on the IntroWindow not needing any system settings
1112
8.34k
        if ( !pSVData->maAppData.mbSettingsInit &&
1113
31
             ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN))
1114
8.34k
             )
1115
2
        {
1116
            // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings
1117
2
            ImplUpdateGlobalSettings( *pSVData->maAppData.mxSettings );
1118
2
            mpWindowImpl->mxOutDev->SetSettings( *pSVData->maAppData.mxSettings );
1119
2
            pSVData->maAppData.mbSettingsInit = true;
1120
2
        }
1121
1122
        // If we create a Window with default size, query this
1123
        // size directly, because we want resize all Controls to
1124
        // the correct size before we display the window
1125
8.34k
        if ( nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_APP) )
1126
8.31k
            mpWindowImpl->mpFrame->GetClientSize( mpWindowImpl->mxOutDev->mnOutWidth, mpWindowImpl->mxOutDev->mnOutHeight );
1127
8.34k
    }
1128
132k
    else
1129
132k
    {
1130
132k
        if ( pParent )
1131
132k
        {
1132
132k
            if ( !ImplIsOverlapWindow() )
1133
132k
            {
1134
132k
                mpWindowImpl->mbDisabled          = pParent->mpWindowImpl->mbDisabled;
1135
132k
                mpWindowImpl->mbInputDisabled     = pParent->mpWindowImpl->mbInputDisabled;
1136
132k
                mpWindowImpl->meAlwaysInputMode   = pParent->mpWindowImpl->meAlwaysInputMode;
1137
132k
            }
1138
1139
132k
            if (!comphelper::IsFuzzing())
1140
0
            {
1141
                // we don't want to call the WindowOutputDevice override of this because
1142
                // it calls back into us.
1143
0
                mpWindowImpl->mxOutDev->OutputDevice::SetSettings( pParent->GetSettings() );
1144
0
            }
1145
132k
        }
1146
1147
132k
    }
1148
1149
    // setup the scale factor for HiDPI displays
1150
140k
    mpWindowImpl->mxOutDev->mnDPIScalePercentage = CountDPIScaleFactor(mpWindowImpl->mpFrameData->mnDPIY);
1151
140k
    mpWindowImpl->mxOutDev->mnDPIX = mpWindowImpl->mpFrameData->mnDPIX;
1152
140k
    mpWindowImpl->mxOutDev->mnDPIY = mpWindowImpl->mpFrameData->mnDPIY;
1153
1154
140k
    if (!comphelper::IsFuzzing())
1155
0
    {
1156
0
        const StyleSettings& rStyleSettings = mpWindowImpl->mxOutDev->moSettings->GetStyleSettings();
1157
0
        mpWindowImpl->mxOutDev->maFont = rStyleSettings.GetAppFont();
1158
1159
0
        if ( nStyle & WB_3DLOOK )
1160
0
        {
1161
0
            SetTextColor( rStyleSettings.GetButtonTextColor() );
1162
0
            SetBackground( Wallpaper( rStyleSettings.GetFaceColor() ) );
1163
0
        }
1164
0
        else
1165
0
        {
1166
0
            SetTextColor( rStyleSettings.GetWindowTextColor() );
1167
0
            SetBackground( Wallpaper( rStyleSettings.GetWindowColor() ) );
1168
0
        }
1169
0
    }
1170
140k
    else
1171
140k
    {
1172
140k
        mpWindowImpl->mxOutDev->maFont = OutputDevice::GetDefaultFont( DefaultFontType::FIXED, LANGUAGE_ENGLISH_US, GetDefaultFontFlags::NONE );
1173
140k
    }
1174
1175
140k
    ImplPointToLogic(*GetOutDev(), mpWindowImpl->mxOutDev->maFont);
1176
1177
140k
    (void)ImplUpdatePos();
1178
1179
    // calculate app font res (except for the Intro Window or the default window)
1180
140k
    if ( mpWindowImpl->mbFrame && !pSVData->maGDIData.mnAppFontX && ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN)) )
1181
2
        ImplInitAppFontData( this );
1182
140k
}
1183
1184
void Window::ImplInitAppFontData( vcl::Window const * pWindow )
1185
3
{
1186
3
    ImplSVData* pSVData = ImplGetSVData();
1187
3
    tools::Long nTextHeight = pWindow->GetTextHeight();
1188
3
    tools::Long nTextWidth = pWindow->approximate_char_width() * 8;
1189
3
    tools::Long nSymHeight = nTextHeight*4;
1190
    // Make the basis wider if the font is too narrow
1191
    // such that the dialog looks symmetrical and does not become too narrow.
1192
    // Add some extra space when the dialog has the same width,
1193
    // as a little more space is better.
1194
3
    if ( nSymHeight > nTextWidth )
1195
0
        nTextWidth = nSymHeight;
1196
3
    else if ( nSymHeight+5 > nTextWidth )
1197
0
        nTextWidth = nSymHeight+5;
1198
3
    pSVData->maGDIData.mnAppFontX = nTextWidth * 10 / 8;
1199
3
    pSVData->maGDIData.mnAppFontY = nTextHeight * 10;
1200
1201
#ifdef MACOSX
1202
    // FIXME: this is currently only on macOS, check with other
1203
    // platforms
1204
    if( pSVData->maNWFData.mbNoFocusRects )
1205
    {
1206
        // try to find out whether there is a large correction
1207
        // of control sizes, if yes, make app font scalings larger
1208
        // so dialog positioning is not completely off
1209
        ImplControlValue aControlValue;
1210
        tools::Rectangle aCtrlRegion( Point(), Size( nTextWidth < 10 ? 10 : nTextWidth, nTextHeight < 10 ? 10 : nTextHeight ) );
1211
        tools::Rectangle aBoundingRgn( aCtrlRegion );
1212
        tools::Rectangle aContentRgn( aCtrlRegion );
1213
        if( pWindow->GetNativeControlRegion( ControlType::Editbox, ControlPart::Entire, aCtrlRegion,
1214
                                             ControlState::ENABLED, aControlValue,
1215
                                             aBoundingRgn, aContentRgn ) )
1216
        {
1217
            // comment: the magical +6 is for the extra border in bordered
1218
            // (which is the standard) edit fields
1219
            if( aContentRgn.GetHeight() - nTextHeight > (nTextHeight+4)/4 )
1220
                pSVData->maGDIData.mnAppFontY = (aContentRgn.GetHeight()-4) * 10;
1221
        }
1222
    }
1223
#endif
1224
3
}
1225
1226
ImplWinData* Window::ImplGetWinData() const
1227
163k
{
1228
163k
    if (!mpWindowImpl->mpWinData)
1229
118k
    {
1230
118k
        static const char* pNoNWF = getenv( "SAL_NO_NWF" );
1231
1232
118k
        const_cast<vcl::Window*>(this)->mpWindowImpl->mpWinData.reset(new ImplWinData);
1233
118k
        mpWindowImpl->mpWinData->mbEnableNativeWidget = !(pNoNWF && *pNoNWF); // true: try to draw this control with native theme API
1234
118k
    }
1235
1236
163k
    return mpWindowImpl->mpWinData.get();
1237
163k
}
1238
1239
1240
void WindowOutputDevice::CopyDeviceArea( SalTwoRect& aPosAry, bool bWindowInvalidate )
1241
0
{
1242
0
    if (aPosAry.mnSrcWidth == 0 || aPosAry.mnSrcHeight == 0 || aPosAry.mnDestWidth == 0 || aPosAry.mnDestHeight == 0)
1243
0
        return;
1244
1245
0
    if (bWindowInvalidate)
1246
0
    {
1247
0
        const tools::Rectangle aSrcRect(Point(aPosAry.mnSrcX, aPosAry.mnSrcY),
1248
0
                Size(aPosAry.mnSrcWidth, aPosAry.mnSrcHeight));
1249
1250
0
        mxOwnerWindow->ImplMoveAllInvalidateRegions(aSrcRect,
1251
0
                aPosAry.mnDestX-aPosAry.mnSrcX,
1252
0
                aPosAry.mnDestY-aPosAry.mnSrcY,
1253
0
                false);
1254
1255
0
        mpGraphics->CopyArea(aPosAry.mnDestX, aPosAry.mnDestY,
1256
0
                aPosAry.mnSrcX, aPosAry.mnSrcY,
1257
0
                aPosAry.mnSrcWidth, aPosAry.mnSrcHeight,
1258
0
                *this);
1259
1260
0
        return;
1261
0
    }
1262
1263
0
    OutputDevice::CopyDeviceArea(aPosAry, bWindowInvalidate);
1264
0
}
1265
1266
const OutputDevice* WindowOutputDevice::DrawOutDevDirectCheck(const OutputDevice& rSrcDev) const
1267
0
{
1268
0
    const OutputDevice* pSrcDevChecked;
1269
0
    if ( this == &rSrcDev )
1270
0
        pSrcDevChecked = nullptr;
1271
0
    else if (GetOutDevType() != rSrcDev.GetOutDevType())
1272
0
        pSrcDevChecked = &rSrcDev;
1273
0
    else if (mxOwnerWindow->mpWindowImpl->mpFrameWindow == static_cast<const vcl::WindowOutputDevice&>(rSrcDev).mxOwnerWindow->mpWindowImpl->mpFrameWindow)
1274
0
        pSrcDevChecked = nullptr;
1275
0
    else
1276
0
        pSrcDevChecked = &rSrcDev;
1277
1278
0
    return pSrcDevChecked;
1279
0
}
1280
1281
void WindowOutputDevice::DrawOutDevDirectProcess( const OutputDevice& rSrcDev, SalTwoRect& rPosAry, SalGraphics* pSrcGraphics )
1282
0
{
1283
0
    if (pSrcGraphics)
1284
0
        mpGraphics->CopyBits(rPosAry, *pSrcGraphics, *this, rSrcDev);
1285
0
    else
1286
0
        mpGraphics->CopyBits(rPosAry, *this);
1287
0
}
1288
1289
SalGraphics* Window::ImplGetFrameGraphics() const
1290
0
{
1291
0
    if ( mpWindowImpl->mpFrameWindow->GetOutDev()->mpGraphics )
1292
0
    {
1293
0
        mpWindowImpl->mpFrameWindow->GetOutDev()->mbInitClipRegion = true;
1294
0
    }
1295
0
    else
1296
0
    {
1297
0
        OutputDevice* pFrameWinOutDev = mpWindowImpl->mpFrameWindow->GetOutDev();
1298
0
        if ( ! pFrameWinOutDev->AcquireGraphics() )
1299
0
        {
1300
0
            return nullptr;
1301
0
        }
1302
0
    }
1303
0
    mpWindowImpl->mpFrameWindow->GetOutDev()->mpGraphics->ResetClipRegion();
1304
0
    return mpWindowImpl->mpFrameWindow->GetOutDev()->mpGraphics;
1305
0
}
1306
1307
void Window::ImplSetReallyVisible()
1308
0
{
1309
    // #i43594# it is possible that INITSHOW was never send, because the visibility state changed between
1310
    // ImplCallInitShow() and ImplSetReallyVisible() when called from Show()
1311
    // mbReallyShown is a useful indicator
1312
0
    if( !mpWindowImpl->mbReallyShown )
1313
0
        ImplCallInitShow();
1314
1315
0
    bool bBecameReallyVisible = !mpWindowImpl->mbReallyVisible;
1316
1317
0
    GetOutDev()->mbDevOutput     = true;
1318
0
    mpWindowImpl->mbReallyVisible = true;
1319
0
    mpWindowImpl->mbReallyShown   = true;
1320
1321
    // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
1322
    // For this, the data member of the event must not be NULL.
1323
    // Previously, we did this in Window::Show, but there some events got lost in certain situations. Now
1324
    // we're doing it when the visibility really changes
1325
0
    if( bBecameReallyVisible && ImplIsAccessibleCandidate() )
1326
0
        CallEventListeners( VclEventId::WindowShow, this );
1327
        // TODO. It's kind of a hack that we're re-using the VclEventId::WindowShow. Normally, we should
1328
        // introduce another event which explicitly triggers the Accessibility implementations.
1329
1330
0
    vcl::Window* pWindow = mpWindowImpl->mpFirstOverlap;
1331
0
    while ( pWindow )
1332
0
    {
1333
0
        if ( pWindow->mpWindowImpl->mbVisible )
1334
0
            pWindow->ImplSetReallyVisible();
1335
0
        pWindow = pWindow->mpWindowImpl->mpNext;
1336
0
    }
1337
1338
0
    pWindow = mpWindowImpl->mpFirstChild;
1339
0
    while ( pWindow )
1340
0
    {
1341
0
        if ( pWindow->mpWindowImpl->mbVisible )
1342
0
            pWindow->ImplSetReallyVisible();
1343
0
        pWindow = pWindow->mpWindowImpl->mpNext;
1344
0
    }
1345
0
}
1346
1347
void Window::ImplInitResolutionSettings()
1348
43.3k
{
1349
    // recalculate AppFont-resolution and DPI-resolution
1350
43.3k
    if (mpWindowImpl->mbFrame)
1351
2
    {
1352
2
        GetOutDev()->mnDPIX = mpWindowImpl->mpFrameData->mnDPIX;
1353
2
        GetOutDev()->mnDPIY = mpWindowImpl->mpFrameData->mnDPIY;
1354
1355
        // setup the scale factor for HiDPI displays
1356
2
        GetOutDev()->mnDPIScalePercentage = CountDPIScaleFactor(mpWindowImpl->mpFrameData->mnDPIY);
1357
2
        const StyleSettings& rStyleSettings = GetOutDev()->moSettings->GetStyleSettings();
1358
2
        SetPointFont(*GetOutDev(), rStyleSettings.GetAppFont());
1359
2
    }
1360
43.3k
    else if ( mpWindowImpl->mpParent )
1361
43.3k
    {
1362
43.3k
        GetOutDev()->mnDPIX  = mpWindowImpl->mpParent->GetOutDev()->mnDPIX;
1363
43.3k
        GetOutDev()->mnDPIY  = mpWindowImpl->mpParent->GetOutDev()->mnDPIY;
1364
43.3k
        GetOutDev()->mnDPIScalePercentage = mpWindowImpl->mpParent->GetOutDev()->mnDPIScalePercentage;
1365
43.3k
    }
1366
1367
    // update the recalculated values for logical units
1368
    // and also tools belonging to the values
1369
43.3k
    if (IsMapModeEnabled())
1370
43.3k
    {
1371
43.3k
        MapMode aMapMode = GetMapMode();
1372
43.3k
        SetMapMode();
1373
43.3k
        SetMapMode( aMapMode );
1374
43.3k
    }
1375
43.3k
}
1376
1377
void Window::ImplPointToLogic(vcl::RenderContext const & rRenderContext, vcl::Font& rFont,
1378
                            bool bUseRenderContextDPI) const
1379
158k
{
1380
158k
    Size aSize = rFont.GetFontSize();
1381
1382
158k
    if (aSize.Width())
1383
0
    {
1384
0
        aSize.setWidth( aSize.Width() *
1385
0
            ( bUseRenderContextDPI ? rRenderContext.GetDPIX() : mpWindowImpl->mpFrameData->mnDPIX) );
1386
0
        aSize.AdjustWidth(72 / 2 );
1387
0
        aSize.setWidth( aSize.Width() / 72 );
1388
0
    }
1389
158k
    aSize.setHeight( aSize.Height()
1390
158k
        * ( bUseRenderContextDPI ? rRenderContext.GetDPIY() : mpWindowImpl->mpFrameData->mnDPIY) );
1391
158k
    aSize.AdjustHeight(72/2 );
1392
158k
    aSize.setHeight( aSize.Height() / 72 );
1393
1394
158k
    aSize = rRenderContext.PixelToLogic(aSize);
1395
1396
158k
    rFont.SetFontSize(aSize);
1397
158k
}
1398
1399
void Window::ImplLogicToPoint(vcl::RenderContext const & rRenderContext, vcl::Font& rFont) const
1400
0
{
1401
0
    Size aSize = rFont.GetFontSize();
1402
0
    aSize = rRenderContext.LogicToPixel(aSize);
1403
1404
0
    if (aSize.Width())
1405
0
    {
1406
0
        aSize.setWidth( aSize.Width() * 72 );
1407
0
        aSize.AdjustWidth(mpWindowImpl->mpFrameData->mnDPIX / 2 );
1408
0
        aSize.setWidth( aSize.Width() / ( mpWindowImpl->mpFrameData->mnDPIX) );
1409
0
    }
1410
0
    aSize.setHeight( aSize.Height() * 72 );
1411
0
    aSize.AdjustHeight(mpWindowImpl->mpFrameData->mnDPIY / 2 );
1412
0
    aSize.setHeight( aSize.Height() / ( mpWindowImpl->mpFrameData->mnDPIY) );
1413
1414
0
    rFont.SetFontSize(aSize);
1415
0
}
1416
1417
bool Window::ImplUpdatePos()
1418
177k
{
1419
177k
    bool bSysChild = false;
1420
1421
177k
    if ( ImplIsOverlapWindow() )
1422
8.34k
    {
1423
8.34k
        GetOutDev()->mnOutOffX  = mpWindowImpl->mnX;
1424
8.34k
        GetOutDev()->mnOutOffY  = mpWindowImpl->mnY;
1425
8.34k
    }
1426
168k
    else
1427
168k
    {
1428
168k
        vcl::Window* pParent = ImplGetParent();
1429
1430
168k
        GetOutDev()->mnOutOffX  = mpWindowImpl->mnX + pParent->GetOutDev()->mnOutOffX;
1431
168k
        GetOutDev()->mnOutOffY  = mpWindowImpl->mnY + pParent->GetOutDev()->mnOutOffY;
1432
168k
    }
1433
1434
177k
    VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
1435
177k
    while ( pChild )
1436
0
    {
1437
0
        if ( pChild->ImplUpdatePos() )
1438
0
            bSysChild = true;
1439
0
        pChild = pChild->mpWindowImpl->mpNext;
1440
0
    }
1441
1442
177k
    if ( mpWindowImpl->mpSysObj )
1443
0
        bSysChild = true;
1444
1445
177k
    return bSysChild;
1446
177k
}
1447
1448
void Window::ImplUpdateSysObjPos()
1449
0
{
1450
0
    if ( mpWindowImpl->mpSysObj )
1451
0
        mpWindowImpl->mpSysObj->SetPosSize( GetOutDev()->mnOutOffX, GetOutDev()->mnOutOffY, GetOutDev()->mnOutWidth, GetOutDev()->mnOutHeight );
1452
1453
0
    VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
1454
0
    while ( pChild )
1455
0
    {
1456
0
        pChild->ImplUpdateSysObjPos();
1457
0
        pChild = pChild->mpWindowImpl->mpNext;
1458
0
    }
1459
0
}
1460
1461
void Window::ImplPosSizeWindow( tools::Long nX, tools::Long nY,
1462
                                tools::Long nWidth, tools::Long nHeight, PosSizeFlags nFlags )
1463
81.5k
{
1464
81.5k
    bool    bNewPos         = false;
1465
81.5k
    bool    bNewSize        = false;
1466
81.5k
    bool    bCopyBits       = false;
1467
81.5k
    tools::Long    nOldOutOffX     = GetOutDev()->mnOutOffX;
1468
81.5k
    tools::Long    nOldOutOffY     = GetOutDev()->mnOutOffY;
1469
81.5k
    tools::Long    nOldOutWidth    = GetOutDev()->mnOutWidth;
1470
81.5k
    tools::Long    nOldOutHeight   = GetOutDev()->mnOutHeight;
1471
81.5k
    std::unique_ptr<vcl::Region> pOverlapRegion;
1472
81.5k
    std::unique_ptr<vcl::Region> pOldRegion;
1473
1474
81.5k
    if ( IsReallyVisible() )
1475
0
    {
1476
0
        tools::Rectangle aOldWinRect( Point( nOldOutOffX, nOldOutOffY ),
1477
0
                               Size( nOldOutWidth, nOldOutHeight ) );
1478
0
        pOldRegion.reset( new vcl::Region( aOldWinRect ) );
1479
0
        if ( mpWindowImpl->mbWinRegion )
1480
0
            pOldRegion->Intersect( GetOutDev()->ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
1481
1482
0
        if ( GetOutDev()->mnOutWidth && GetOutDev()->mnOutHeight && !mpWindowImpl->mbPaintTransparent &&
1483
0
             !mpWindowImpl->mbInitWinClipRegion && !mpWindowImpl->maWinClipRegion.IsEmpty() &&
1484
0
             !HasPaintEvent() )
1485
0
            bCopyBits = true;
1486
0
    }
1487
1488
81.5k
    bool bnXRecycled = false; // avoid duplicate mirroring in RTL case
1489
81.5k
    if ( nFlags & PosSizeFlags::Width )
1490
81.5k
    {
1491
81.5k
        if(!( nFlags & PosSizeFlags::X ))
1492
40.3k
        {
1493
40.3k
            nX = mpWindowImpl->mnX;
1494
40.3k
            nFlags |= PosSizeFlags::X;
1495
40.3k
            bnXRecycled = true; // we're using a mnX which was already mirrored in RTL case
1496
40.3k
        }
1497
1498
81.5k
        if ( nWidth < 0 )
1499
4.57k
            nWidth = 0;
1500
81.5k
        if ( nWidth != GetOutDev()->mnOutWidth )
1501
22.0k
        {
1502
22.0k
            GetOutDev()->mnOutWidth = nWidth;
1503
22.0k
            bNewSize = true;
1504
22.0k
            bCopyBits = false;
1505
22.0k
        }
1506
81.5k
    }
1507
81.5k
    if ( nFlags & PosSizeFlags::Height )
1508
81.5k
    {
1509
81.5k
        if ( nHeight < 0 )
1510
4.57k
            nHeight = 0;
1511
81.5k
        if ( nHeight != GetOutDev()->mnOutHeight )
1512
22.0k
        {
1513
22.0k
            GetOutDev()->mnOutHeight = nHeight;
1514
22.0k
            bNewSize = true;
1515
22.0k
            bCopyBits = false;
1516
22.0k
        }
1517
81.5k
    }
1518
1519
81.5k
    if ( nFlags & PosSizeFlags::X )
1520
81.5k
    {
1521
81.5k
        tools::Long nOrgX = nX;
1522
81.5k
        Point aPtDev( nX+GetOutDev()->mnOutOffX, 0 );
1523
81.5k
        OutputDevice *pOutDev = GetOutDev();
1524
81.5k
        if( pOutDev->HasMirroredGraphics() )
1525
0
        {
1526
0
            aPtDev.setX( GetOutDev()->mpGraphics->mirror2( aPtDev.X(), *GetOutDev() ) );
1527
1528
            // #106948# always mirror our pos if our parent is not mirroring, even
1529
            // if we are also not mirroring
1530
            // RTL: check if parent is in different coordinates
1531
0
            if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->GetOutDev()->ImplIsAntiparallel() )
1532
0
            {
1533
0
                nX = mpWindowImpl->mpParent->GetOutDev()->mnOutWidth - GetOutDev()->mnOutWidth - nX;
1534
0
            }
1535
            /* #i99166# An LTR window in RTL UI that gets sized only would be
1536
               expected to not moved its upper left point
1537
            */
1538
0
            if( bnXRecycled )
1539
0
            {
1540
0
                if( GetOutDev()->ImplIsAntiparallel() )
1541
0
                {
1542
0
                    aPtDev.setX( mpWindowImpl->mnAbsScreenX );
1543
0
                    nOrgX = mpWindowImpl->maPos.X();
1544
0
                }
1545
0
            }
1546
0
        }
1547
81.5k
        else if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->GetOutDev()->ImplIsAntiparallel() )
1548
0
        {
1549
            // mirrored window in LTR UI
1550
0
            nX = mpWindowImpl->mpParent->GetOutDev()->mnOutWidth - GetOutDev()->mnOutWidth - nX;
1551
0
        }
1552
1553
        // check maPos as well, as it could have been changed for client windows (ImplCallMove())
1554
81.5k
        if ( mpWindowImpl->mnAbsScreenX != aPtDev.X() || nX != mpWindowImpl->mnX || nOrgX != mpWindowImpl->maPos.X() )
1555
36.6k
        {
1556
36.6k
            if ( bCopyBits && !pOverlapRegion )
1557
0
            {
1558
0
                pOverlapRegion.reset( new vcl::Region() );
1559
0
                ImplCalcOverlapRegion( GetOutputRectPixel(),
1560
0
                                       *pOverlapRegion, false, true );
1561
0
            }
1562
36.6k
            mpWindowImpl->mnX = nX;
1563
36.6k
            mpWindowImpl->maPos.setX( nOrgX );
1564
36.6k
            mpWindowImpl->mnAbsScreenX = aPtDev.X();
1565
36.6k
            bNewPos = true;
1566
36.6k
        }
1567
81.5k
    }
1568
81.5k
    if ( nFlags & PosSizeFlags::Y )
1569
41.2k
    {
1570
        // check maPos as well, as it could have been changed for client windows (ImplCallMove())
1571
41.2k
        if ( nY != mpWindowImpl->mnY || nY != mpWindowImpl->maPos.Y() )
1572
4.57k
        {
1573
4.57k
            if ( bCopyBits && !pOverlapRegion )
1574
0
            {
1575
0
                pOverlapRegion.reset( new vcl::Region() );
1576
0
                ImplCalcOverlapRegion( GetOutputRectPixel(),
1577
0
                                       *pOverlapRegion, false, true );
1578
0
            }
1579
4.57k
            mpWindowImpl->mnY = nY;
1580
4.57k
            mpWindowImpl->maPos.setY( nY );
1581
4.57k
            bNewPos = true;
1582
4.57k
        }
1583
41.2k
    }
1584
1585
81.5k
    if ( !(bNewPos || bNewSize) )
1586
36.6k
        return;
1587
1588
44.9k
    bool bUpdateSysObjPos = false;
1589
44.9k
    if ( bNewPos )
1590
36.6k
        bUpdateSysObjPos = ImplUpdatePos();
1591
1592
    // the borderwindow always specifies the position for its client window
1593
44.9k
    if ( mpWindowImpl->mpBorderWindow )
1594
4.57k
        mpWindowImpl->maPos = mpWindowImpl->mpBorderWindow->mpWindowImpl->maPos;
1595
1596
44.9k
    if ( mpWindowImpl->mpClientWindow )
1597
0
    {
1598
0
        mpWindowImpl->mpClientWindow->ImplPosSizeWindow( mpWindowImpl->mpClientWindow->mpWindowImpl->mnLeftBorder,
1599
0
                                           mpWindowImpl->mpClientWindow->mpWindowImpl->mnTopBorder,
1600
0
                                           GetOutDev()->mnOutWidth - mpWindowImpl->mpClientWindow->mpWindowImpl->mnLeftBorder-mpWindowImpl->mpClientWindow->mpWindowImpl->mnRightBorder,
1601
0
                                           GetOutDev()->mnOutHeight - mpWindowImpl->mpClientWindow->mpWindowImpl->mnTopBorder-mpWindowImpl->mpClientWindow->mpWindowImpl->mnBottomBorder,
1602
0
                                           PosSizeFlags::X | PosSizeFlags::Y |
1603
0
                                           PosSizeFlags::Width | PosSizeFlags::Height );
1604
        // If we have a client window, then this is the position
1605
        // of the Application's floating windows
1606
0
        mpWindowImpl->mpClientWindow->mpWindowImpl->maPos = mpWindowImpl->maPos;
1607
0
        if ( bNewPos )
1608
0
        {
1609
0
            if ( mpWindowImpl->mpClientWindow->IsVisible() )
1610
0
            {
1611
0
                mpWindowImpl->mpClientWindow->ImplCallMove();
1612
0
            }
1613
0
            else
1614
0
            {
1615
0
                mpWindowImpl->mpClientWindow->mpWindowImpl->mbCallMove = true;
1616
0
            }
1617
0
        }
1618
0
    }
1619
1620
    // Move()/Resize() will be called only for Show(), such that
1621
    // at least one is called before Show()
1622
44.9k
    if ( IsVisible() )
1623
4.57k
    {
1624
4.57k
        if ( bNewPos )
1625
4.57k
        {
1626
4.57k
            ImplCallMove();
1627
4.57k
        }
1628
4.57k
        if ( bNewSize )
1629
0
        {
1630
0
            ImplCallResize();
1631
0
        }
1632
4.57k
    }
1633
40.3k
    else
1634
40.3k
    {
1635
40.3k
        if ( bNewPos )
1636
32.0k
            mpWindowImpl->mbCallMove = true;
1637
40.3k
        if ( bNewSize )
1638
35.7k
            mpWindowImpl->mbCallResize = true;
1639
40.3k
    }
1640
1641
44.9k
    bool bUpdateSysObjClip = false;
1642
44.9k
    if ( IsReallyVisible() )
1643
0
    {
1644
0
        if ( bNewPos || bNewSize )
1645
0
        {
1646
            // set Clip-Flag
1647
0
            bUpdateSysObjClip = !ImplSetClipFlag( true );
1648
0
        }
1649
1650
        // invalidate window content ?
1651
0
        if ( bNewPos || (GetOutDev()->mnOutWidth > nOldOutWidth) || (GetOutDev()->mnOutHeight > nOldOutHeight) )
1652
0
        {
1653
0
            if ( bNewPos )
1654
0
            {
1655
0
                bool bInvalidate = false;
1656
0
                bool bParentPaint = true;
1657
0
                if ( !ImplIsOverlapWindow() )
1658
0
                    bParentPaint = mpWindowImpl->mpParent->IsPaintEnabled();
1659
0
                if ( bCopyBits && bParentPaint && !HasPaintEvent() )
1660
0
                {
1661
0
                    vcl::Region aRegion( GetOutputRectPixel() );
1662
0
                    if ( mpWindowImpl->mbWinRegion )
1663
0
                        aRegion.Intersect( GetOutDev()->ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
1664
0
                    ImplClipBoundaries( aRegion, false, true );
1665
0
                    if ( !pOverlapRegion->IsEmpty() )
1666
0
                    {
1667
0
                        pOverlapRegion->Move( GetOutDev()->mnOutOffX - nOldOutOffX, GetOutDev()->mnOutOffY - nOldOutOffY );
1668
0
                        aRegion.Exclude( *pOverlapRegion );
1669
0
                    }
1670
0
                    if ( !aRegion.IsEmpty() )
1671
0
                    {
1672
                        // adapt Paint areas
1673
0
                        ImplMoveAllInvalidateRegions( tools::Rectangle( Point( nOldOutOffX, nOldOutOffY ),
1674
0
                                                                 Size( nOldOutWidth, nOldOutHeight ) ),
1675
0
                                                      GetOutDev()->mnOutOffX - nOldOutOffX, GetOutDev()->mnOutOffY - nOldOutOffY,
1676
0
                                                      true );
1677
0
                        SalGraphics* pGraphics = ImplGetFrameGraphics();
1678
0
                        if ( pGraphics )
1679
0
                        {
1680
1681
0
                            OutputDevice *pOutDev = GetOutDev();
1682
0
                            const bool bSelectClipRegion = pOutDev->SelectClipRegion( aRegion, pGraphics );
1683
0
                            if ( bSelectClipRegion )
1684
0
                            {
1685
0
                                pGraphics->CopyArea( GetOutDev()->mnOutOffX, GetOutDev()->mnOutOffY,
1686
0
                                                     nOldOutOffX, nOldOutOffY,
1687
0
                                                     nOldOutWidth, nOldOutHeight,
1688
0
                                                     *GetOutDev() );
1689
0
                            }
1690
0
                            else
1691
0
                                bInvalidate = true;
1692
0
                        }
1693
0
                        else
1694
0
                            bInvalidate = true;
1695
0
                        if ( !bInvalidate )
1696
0
                        {
1697
0
                            if ( !pOverlapRegion->IsEmpty() )
1698
0
                                ImplInvalidateFrameRegion( pOverlapRegion.get(), InvalidateFlags::Children );
1699
0
                        }
1700
0
                    }
1701
0
                    else
1702
0
                        bInvalidate = true;
1703
0
                }
1704
0
                else
1705
0
                    bInvalidate = true;
1706
0
                if ( bInvalidate )
1707
0
                    ImplInvalidateFrameRegion( nullptr, InvalidateFlags::Children );
1708
0
            }
1709
0
            else
1710
0
            {
1711
0
                vcl::Region aRegion( GetOutputRectPixel() );
1712
0
                aRegion.Exclude( *pOldRegion );
1713
0
                if ( mpWindowImpl->mbWinRegion )
1714
0
                    aRegion.Intersect( GetOutDev()->ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
1715
0
                ImplClipBoundaries( aRegion, false, true );
1716
0
                if ( !aRegion.IsEmpty() )
1717
0
                    ImplInvalidateFrameRegion( &aRegion, InvalidateFlags::Children );
1718
0
            }
1719
0
        }
1720
1721
        // invalidate Parent or Overlaps
1722
0
        if ( bNewPos ||
1723
0
             (GetOutDev()->mnOutWidth < nOldOutWidth) || (GetOutDev()->mnOutHeight < nOldOutHeight) )
1724
0
        {
1725
0
            vcl::Region aRegion( *pOldRegion );
1726
0
            if ( !mpWindowImpl->mbPaintTransparent )
1727
0
                ImplExcludeWindowRegion( aRegion );
1728
0
            ImplClipBoundaries( aRegion, false, true );
1729
0
            if ( !aRegion.IsEmpty() && !mpWindowImpl->mpBorderWindow )
1730
0
                ImplInvalidateParentFrameRegion( aRegion );
1731
0
        }
1732
0
    }
1733
1734
    // adapt system objects
1735
44.9k
    if ( bUpdateSysObjClip )
1736
0
        ImplUpdateSysObjClip();
1737
44.9k
    if ( bUpdateSysObjPos )
1738
0
        ImplUpdateSysObjPos();
1739
44.9k
    if ( bNewSize && mpWindowImpl->mpSysObj )
1740
0
        mpWindowImpl->mpSysObj->SetPosSize( GetOutDev()->mnOutOffX, GetOutDev()->mnOutOffY, GetOutDev()->mnOutWidth, GetOutDev()->mnOutHeight );
1741
44.9k
}
1742
1743
void Window::ImplNewInputContext()
1744
0
{
1745
0
    ImplSVData* pSVData = ImplGetSVData();
1746
0
    vcl::Window* pFocusWin = pSVData->mpWinData->mpFocusWin;
1747
0
    if ( !pFocusWin || !pFocusWin->mpWindowImpl || pFocusWin->isDisposed() )
1748
0
        return;
1749
1750
    // Is InputContext changed?
1751
0
    const InputContext& rInputContext = pFocusWin->GetInputContext();
1752
0
    if ( rInputContext == pFocusWin->mpWindowImpl->mpFrameData->maOldInputContext )
1753
0
        return;
1754
1755
0
    pFocusWin->mpWindowImpl->mpFrameData->maOldInputContext = rInputContext;
1756
1757
0
    SalInputContext         aNewContext;
1758
0
    const vcl::Font&        rFont = rInputContext.GetFont();
1759
0
    const OUString&         rFontName = rFont.GetFamilyName();
1760
0
    if (!rFontName.isEmpty())
1761
0
    {
1762
0
        OutputDevice *pFocusWinOutDev = pFocusWin->GetOutDev();
1763
0
        Size aSize = pFocusWinOutDev->ImplLogicToDevicePixel( rFont.GetFontSize() );
1764
0
        if ( !aSize.Height() )
1765
0
        {
1766
            // only set default sizes if the font height in logical
1767
            // coordinates equals 0
1768
0
            if ( rFont.GetFontSize().Height() )
1769
0
                aSize.setHeight( 1 );
1770
0
            else
1771
0
                aSize.setHeight( (12*pFocusWin->GetOutDev()->mnDPIY)/72 );
1772
0
        }
1773
0
        aNewContext.mpFont =
1774
0
                        pFocusWin->GetOutDev()->mxFontCache->GetFontInstance(
1775
0
                            pFocusWin->GetOutDev()->mxFontCollection.get(),
1776
0
                            rFont, aSize, static_cast<float>(aSize.Height()) );
1777
0
    }
1778
0
    aNewContext.mnOptions   = rInputContext.GetOptions();
1779
0
    pFocusWin->ImplGetFrame()->SetInputContext( &aNewContext );
1780
0
}
1781
1782
void Window::SetDumpAsPropertyTreeHdl(const Link<tools::JsonWriter&, void>& rLink)
1783
0
{
1784
0
    if (mpWindowImpl) // may be called after dispose
1785
0
    {
1786
0
        mpWindowImpl->maDumpAsPropertyTreeHdl = rLink;
1787
0
    }
1788
0
}
1789
1790
void Window::SetModalHierarchyHdl(const Link<bool, void>& rLink)
1791
9.15k
{
1792
9.15k
    ImplGetFrame()->SetModalHierarchyHdl(rLink);
1793
9.15k
}
1794
1795
KeyIndicatorState Window::GetIndicatorState() const
1796
0
{
1797
0
    return mpWindowImpl->mpFrame->GetIndicatorState();
1798
0
}
1799
1800
void Window::SimulateKeyPress( sal_uInt16 nKeyCode ) const
1801
0
{
1802
0
    mpWindowImpl->mpFrame->SimulateKeyPress(nKeyCode);
1803
0
}
1804
1805
void Window::KeyInput( const KeyEvent& rKEvt )
1806
0
{
1807
0
#ifndef _WIN32 // On Windows, dialogs react to accelerators  without Alt (tdf#157649)
1808
0
    KeyCode cod = rKEvt.GetKeyCode ();
1809
1810
    // do not respond to accelerators unless Alt or Ctrl is held
1811
0
    if (cod.GetCode () >= 0x200 && cod.GetCode () <= 0x219)
1812
0
    {
1813
0
        bool autoacc = ImplGetSVData()->maNWFData.mbAutoAccel;
1814
0
        if (autoacc && cod.GetModifier () != KEY_MOD2 && !(cod.GetModifier() & KEY_MOD1))
1815
0
            return;
1816
0
    }
1817
0
#endif
1818
1819
0
    NotifyEvent aNEvt( NotifyEventType::KEYINPUT, this, &rKEvt );
1820
0
    if ( !CompatNotify( aNEvt ) )
1821
0
        mpWindowImpl->mbKeyInput = true;
1822
0
}
1823
1824
void Window::KeyUp( const KeyEvent& rKEvt )
1825
0
{
1826
0
    NotifyEvent aNEvt( NotifyEventType::KEYUP, this, &rKEvt );
1827
0
    if ( !CompatNotify( aNEvt ) )
1828
0
        mpWindowImpl->mbKeyUp = true;
1829
0
}
1830
1831
void Window::Draw( OutputDevice*, const Point&, SystemTextColorFlags )
1832
0
{
1833
0
}
1834
1835
27.4k
void Window::Move() {}
1836
1837
9.15k
void Window::Resize() {}
1838
1839
0
void Window::Activate() {}
1840
1841
8.34k
void Window::Deactivate() {}
1842
1843
void Window::GetFocus()
1844
0
{
1845
0
    if ( HasFocus() && mpWindowImpl->mpLastFocusWindow && !(mpWindowImpl->mnDlgCtrlFlags & DialogControlFlags::WantFocus) )
1846
0
    {
1847
0
        VclPtr<vcl::Window> xWindow(this);
1848
0
        mpWindowImpl->mpLastFocusWindow->GrabFocus();
1849
0
        if( xWindow->isDisposed() )
1850
0
            return;
1851
0
    }
1852
1853
0
    NotifyEvent aNEvt( NotifyEventType::GETFOCUS, this );
1854
0
    CompatNotify( aNEvt );
1855
0
}
1856
1857
void Window::LoseFocus()
1858
0
{
1859
0
    NotifyEvent aNEvt( NotifyEventType::LOSEFOCUS, this );
1860
0
    CompatNotify( aNEvt );
1861
0
}
1862
1863
void Window::SetCommandHdl(const Link<const CommandEvent&, bool>& rLink)
1864
164
{
1865
164
    if (mpWindowImpl)
1866
164
        mpWindowImpl->maCommandHdl = rLink;
1867
164
}
1868
1869
void Window::SetHelpHdl(const Link<vcl::Window&, bool>& rLink)
1870
0
{
1871
0
    if (mpWindowImpl) // may be called after dispose
1872
0
    {
1873
0
        mpWindowImpl->maHelpRequestHdl = rLink;
1874
0
    }
1875
0
}
1876
1877
void Window::RequestHelp( const HelpEvent& rHEvt )
1878
0
{
1879
    // if Balloon-Help is requested, show the balloon
1880
    // with help text set
1881
0
    if ( rHEvt.GetMode() & HelpEventMode::BALLOON )
1882
0
    {
1883
0
        OUString rStr = GetHelpText();
1884
0
        if ( rStr.isEmpty() )
1885
0
            rStr = GetQuickHelpText();
1886
0
        if ( rStr.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() )
1887
0
            ImplGetParent()->RequestHelp( rHEvt );
1888
0
        else
1889
0
        {
1890
0
            Point aPos = GetPosPixel();
1891
0
            if ( ImplGetParent() && !ImplIsOverlapWindow() )
1892
0
                aPos = OutputToScreenPixel(Point(0, 0));
1893
0
            tools::Rectangle   aRect( aPos, GetSizePixel() );
1894
1895
0
            Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), aRect, rStr );
1896
0
        }
1897
0
    }
1898
0
    else if ( rHEvt.GetMode() & HelpEventMode::QUICK )
1899
0
    {
1900
0
        const OUString& rStr = GetQuickHelpText();
1901
0
        if ( rStr.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() )
1902
0
            ImplGetParent()->RequestHelp( rHEvt );
1903
0
        else
1904
0
        {
1905
0
            Point aPos = GetPosPixel();
1906
0
            if ( ImplGetParent() && !ImplIsOverlapWindow() )
1907
0
                aPos = OutputToScreenPixel(Point(0, 0));
1908
0
            tools::Rectangle   aRect( aPos, GetSizePixel() );
1909
0
            Help::ShowQuickHelp( this, aRect, rStr, QuickHelpFlags::CtrlText );
1910
0
        }
1911
0
    }
1912
0
    else if (!mpWindowImpl->maHelpRequestHdl.IsSet() || mpWindowImpl->maHelpRequestHdl.Call(*this))
1913
0
    {
1914
0
        OUString aStrHelpId( GetHelpId() );
1915
0
        if ( aStrHelpId.isEmpty() && ImplGetParent() )
1916
0
            ImplGetParent()->RequestHelp( rHEvt );
1917
0
        else
1918
0
        {
1919
0
            Help* pHelp = Application::GetHelp();
1920
0
            if ( pHelp )
1921
0
            {
1922
0
                if( !aStrHelpId.isEmpty() )
1923
0
                    pHelp->Start( aStrHelpId, this );
1924
0
                else
1925
0
                    pHelp->Start( u"" OOO_HELP_INDEX ""_ustr, this );
1926
0
            }
1927
0
        }
1928
0
    }
1929
0
}
1930
1931
void Window::Command( const CommandEvent& rCEvt )
1932
0
{
1933
0
    if (mpWindowImpl && mpWindowImpl->maCommandHdl.Call(rCEvt))
1934
0
        return;
1935
1936
0
    CallEventListeners( VclEventId::WindowCommand, const_cast<CommandEvent *>(&rCEvt) );
1937
1938
0
    NotifyEvent aNEvt( NotifyEventType::COMMAND, this, &rCEvt );
1939
0
    if ( !CompatNotify( aNEvt ) )
1940
0
        mpWindowImpl->mbCommand = true;
1941
0
}
1942
1943
void Window::Tracking( const TrackingEvent& rTEvt )
1944
0
{
1945
1946
0
    ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1947
0
    if( pWrapper )
1948
0
        pWrapper->Tracking( rTEvt );
1949
0
}
1950
1951
void Window::StateChanged(StateChangedType eType)
1952
72.2k
{
1953
72.2k
    switch (eType)
1954
72.2k
    {
1955
        //stuff that doesn't invalidate the layout
1956
0
        case StateChangedType::ControlForeground:
1957
8.31k
        case StateChangedType::ControlBackground:
1958
17.3k
        case StateChangedType::UpdateMode:
1959
17.3k
        case StateChangedType::ReadOnly:
1960
17.3k
        case StateChangedType::Enable:
1961
17.3k
        case StateChangedType::State:
1962
17.3k
        case StateChangedType::Data:
1963
17.3k
        case StateChangedType::InitShow:
1964
17.3k
        case StateChangedType::ControlFocus:
1965
17.3k
            break;
1966
        //stuff that does invalidate the layout
1967
54.9k
        default:
1968
54.9k
            queue_resize(eType);
1969
54.9k
            break;
1970
72.2k
    }
1971
72.2k
}
1972
1973
void Window::SetStyle( WinBits nStyle )
1974
0
{
1975
0
    if ( mpWindowImpl && mpWindowImpl->mnStyle != nStyle )
1976
0
    {
1977
0
        mpWindowImpl->mnPrevStyle = mpWindowImpl->mnStyle;
1978
0
        mpWindowImpl->mnStyle = nStyle;
1979
0
        CompatStateChanged( StateChangedType::Style );
1980
0
    }
1981
0
}
1982
1983
void Window::SetExtendedStyle( WindowExtendedStyle nExtendedStyle )
1984
107k
{
1985
1986
107k
    if ( mpWindowImpl->mnExtendedStyle == nExtendedStyle )
1987
98.2k
        return;
1988
1989
9.43k
    vcl::Window* pWindow = ImplGetBorderWindow();
1990
9.43k
    if( ! pWindow )
1991
0
        pWindow = this;
1992
9.43k
    if( pWindow->mpWindowImpl->mbFrame )
1993
9.43k
    {
1994
9.43k
        SalExtStyle nExt = 0;
1995
9.43k
        if( nExtendedStyle & WindowExtendedStyle::Document )
1996
8.31k
            nExt |= SAL_FRAME_EXT_STYLE_DOCUMENT;
1997
9.43k
        if( nExtendedStyle & WindowExtendedStyle::DocModified )
1998
0
            nExt |= SAL_FRAME_EXT_STYLE_DOCMODIFIED;
1999
2000
9.43k
        pWindow->ImplGetFrame()->SetExtendedFrameStyle( nExt );
2001
9.43k
    }
2002
9.43k
    mpWindowImpl->mnExtendedStyle = nExtendedStyle;
2003
9.43k
}
2004
2005
void Window::SetBorderStyle( WindowBorderStyle nBorderStyle )
2006
4.57k
{
2007
2008
4.57k
    if ( !mpWindowImpl->mpBorderWindow )
2009
0
        return;
2010
2011
4.57k
    if( nBorderStyle == WindowBorderStyle::REMOVEBORDER &&
2012
0
        ! mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame &&
2013
0
        mpWindowImpl->mpBorderWindow->mpWindowImpl->mpParent
2014
4.57k
        )
2015
0
    {
2016
        // this is a little awkward: some controls (e.g. svtools ProgressBar)
2017
        // cannot avoid getting constructed with WB_BORDER but want to disable
2018
        // borders in case of NWF drawing. So they need a method to remove their border window
2019
0
        VclPtr<vcl::Window> pBorderWin = mpWindowImpl->mpBorderWindow;
2020
        // remove us as border window's client
2021
0
        pBorderWin->mpWindowImpl->mpClientWindow = nullptr;
2022
0
        mpWindowImpl->mpBorderWindow = nullptr;
2023
0
        mpWindowImpl->mpRealParent = pBorderWin->mpWindowImpl->mpParent;
2024
        // reparent us above the border window
2025
0
        SetParent( pBorderWin->mpWindowImpl->mpParent );
2026
        // set us to the position and size of our previous border
2027
0
        Point aBorderPos( pBorderWin->GetPosPixel() );
2028
0
        Size aBorderSize( pBorderWin->GetSizePixel() );
2029
0
        setPosSizePixel( aBorderPos.X(), aBorderPos.Y(), aBorderSize.Width(), aBorderSize.Height() );
2030
        // release border window
2031
0
        pBorderWin.disposeAndClear();
2032
2033
        // set new style bits
2034
0
        SetStyle( GetStyle() & (~WB_BORDER) );
2035
0
    }
2036
4.57k
    else
2037
4.57k
    {
2038
4.57k
        if ( mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW )
2039
4.57k
            static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetBorderStyle( nBorderStyle );
2040
0
        else
2041
0
            mpWindowImpl->mpBorderWindow->SetBorderStyle( nBorderStyle );
2042
4.57k
    }
2043
4.57k
}
2044
2045
WindowBorderStyle Window::GetBorderStyle() const
2046
0
{
2047
2048
0
    if ( mpWindowImpl->mpBorderWindow )
2049
0
    {
2050
0
        if ( mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW )
2051
0
            return static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->GetBorderStyle();
2052
0
        else
2053
0
            return mpWindowImpl->mpBorderWindow->GetBorderStyle();
2054
0
    }
2055
2056
0
    return WindowBorderStyle::NONE;
2057
0
}
2058
2059
tools::Long Window::CalcTitleWidth() const
2060
0
{
2061
2062
0
    if ( mpWindowImpl->mpBorderWindow )
2063
0
    {
2064
0
        if ( mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW )
2065
0
            return static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->CalcTitleWidth();
2066
0
        else
2067
0
            return mpWindowImpl->mpBorderWindow->CalcTitleWidth();
2068
0
    }
2069
0
    else if ( mpWindowImpl->mbFrame && (mpWindowImpl->mnStyle & WB_MOVEABLE) )
2070
0
    {
2071
        // we guess the width for frame windows as we do not know the
2072
        // border of external dialogs
2073
0
        const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
2074
0
        vcl::Font aFont = GetFont();
2075
0
        const_cast<vcl::Window*>(this)->SetPointFont(const_cast<::OutputDevice&>(*GetOutDev()), rStyleSettings.GetTitleFont());
2076
0
        tools::Long nTitleWidth = GetTextWidth( GetText() );
2077
0
        const_cast<vcl::Window*>(this)->SetFont( aFont );
2078
0
        nTitleWidth += rStyleSettings.GetTitleHeight() * 3;
2079
0
        nTitleWidth += StyleSettings::GetBorderSize() * 2;
2080
0
        nTitleWidth += 10;
2081
0
        return nTitleWidth;
2082
0
    }
2083
2084
0
    return 0;
2085
0
}
2086
2087
void Window::SetInputContext( const InputContext& rInputContext )
2088
9.16k
{
2089
2090
9.16k
    mpWindowImpl->maInputContext = rInputContext;
2091
9.16k
    if ( !mpWindowImpl->mbInFocusHdl && HasFocus() )
2092
0
        ImplNewInputContext();
2093
9.16k
}
2094
2095
void Window::PostExtTextInputEvent(VclEventId nType, const OUString& rText)
2096
0
{
2097
0
    switch (nType)
2098
0
    {
2099
0
    case VclEventId::ExtTextInput:
2100
0
    {
2101
0
        std::unique_ptr<ExtTextInputAttr[]> pAttr(new ExtTextInputAttr[rText.getLength()]);
2102
0
        for (int i = 0; i < rText.getLength(); ++i) {
2103
0
            pAttr[i] = ExtTextInputAttr::Underline;
2104
0
        }
2105
0
        SalExtTextInputEvent aEvent { rText, pAttr.get(), rText.getLength(), EXTTEXTINPUT_CURSOR_OVERWRITE };
2106
0
        ImplWindowFrameProc(this, SalEvent::ExtTextInput, &aEvent);
2107
0
    }
2108
0
    break;
2109
0
    case VclEventId::EndExtTextInput:
2110
0
        ImplWindowFrameProc(this, SalEvent::EndExtTextInput, nullptr);
2111
0
        break;
2112
0
    default:
2113
0
        assert(false);
2114
0
    }
2115
0
}
2116
2117
void Window::EndExtTextInput()
2118
0
{
2119
0
    if ( mpWindowImpl->mbExtTextInput )
2120
0
        ImplGetFrame()->EndExtTextInput( EndExtTextInputFlags::Complete );
2121
0
}
2122
2123
void Window::SetCursorRect( const tools::Rectangle* pRect, tools::Long nExtTextInputWidth )
2124
0
{
2125
2126
0
    ImplWinData* pWinData = ImplGetWinData();
2127
0
    if ( pWinData->mpCursorRect )
2128
0
    {
2129
0
        if ( pRect )
2130
0
            pWinData->mpCursorRect = *pRect;
2131
0
        else
2132
0
            pWinData->mpCursorRect.reset();
2133
0
    }
2134
0
    else
2135
0
    {
2136
0
        if ( pRect )
2137
0
            pWinData->mpCursorRect = *pRect;
2138
0
    }
2139
2140
0
    pWinData->mnCursorExtWidth = nExtTextInputWidth;
2141
2142
0
}
2143
2144
const tools::Rectangle* Window::GetCursorRect() const
2145
0
{
2146
2147
0
    ImplWinData* pWinData = ImplGetWinData();
2148
0
    return pWinData->mpCursorRect ? &*pWinData->mpCursorRect : nullptr;
2149
0
}
2150
2151
tools::Long Window::GetCursorExtTextInputWidth() const
2152
0
{
2153
2154
0
    ImplWinData* pWinData = ImplGetWinData();
2155
0
    return pWinData->mnCursorExtWidth;
2156
0
}
2157
2158
0
void Window::SetCompositionCharRect( const tools::Rectangle* pRect, tools::Long nCompositionLength, bool bVertical ) {
2159
2160
0
    ImplWinData* pWinData = ImplGetWinData();
2161
0
    pWinData->mpCompositionCharRects.reset();
2162
0
    pWinData->mbVertical = bVertical;
2163
0
    pWinData->mnCompositionCharRects = nCompositionLength;
2164
0
    if ( pRect && (nCompositionLength > 0) )
2165
0
    {
2166
0
        pWinData->mpCompositionCharRects.reset( new tools::Rectangle[nCompositionLength] );
2167
0
        for (tools::Long i = 0; i < nCompositionLength; ++i)
2168
0
            pWinData->mpCompositionCharRects[i] = pRect[i];
2169
0
    }
2170
0
}
2171
2172
void Window::CollectChildren(::std::vector<vcl::Window *>& rAllChildren )
2173
0
{
2174
0
    rAllChildren.push_back( this );
2175
2176
0
    VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
2177
0
    while ( pChild )
2178
0
    {
2179
0
        pChild->CollectChildren( rAllChildren );
2180
0
        pChild = pChild->mpWindowImpl->mpNext;
2181
0
    }
2182
0
}
2183
2184
void Window::SetPointFont(vcl::RenderContext& rRenderContext, const vcl::Font& rFont,
2185
                          bool bUseRenderContextDPI)
2186
17.4k
{
2187
17.4k
    vcl::Font aFont = rFont;
2188
17.4k
    ImplPointToLogic(rRenderContext, aFont, bUseRenderContextDPI);
2189
17.4k
    rRenderContext.SetFont(aFont);
2190
17.4k
}
2191
2192
vcl::Font Window::GetPointFont(vcl::RenderContext const & rRenderContext) const
2193
0
{
2194
0
    vcl::Font aFont = rRenderContext.GetFont();
2195
0
    ImplLogicToPoint(rRenderContext, aFont);
2196
0
    return aFont;
2197
0
}
2198
2199
void Window::Show(bool bVisible, ShowFlags nFlags)
2200
169k
{
2201
169k
    if ( !mpWindowImpl || mpWindowImpl->mbVisible == bVisible )
2202
123k
        return;
2203
2204
45.6k
    VclPtr<vcl::Window> xWindow(this);
2205
2206
45.6k
    bool bRealVisibilityChanged = false;
2207
45.6k
    mpWindowImpl->mbVisible = bVisible;
2208
2209
45.6k
    if ( !bVisible )
2210
22.8k
    {
2211
22.8k
        ImplHideAllOverlaps();
2212
22.8k
        if( !xWindow->mpWindowImpl )
2213
0
            return;
2214
2215
22.8k
        if ( mpWindowImpl->mpBorderWindow )
2216
4.57k
        {
2217
4.57k
            bool bOldUpdate = mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate;
2218
4.57k
            if ( mpWindowImpl->mbNoParentUpdate )
2219
0
                mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = true;
2220
4.57k
            mpWindowImpl->mpBorderWindow->Show( false, nFlags );
2221
4.57k
            mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = bOldUpdate;
2222
4.57k
        }
2223
18.2k
        else if ( mpWindowImpl->mbFrame )
2224
0
        {
2225
0
            mpWindowImpl->mbSuppressAccessibilityEvents = true;
2226
0
            mpWindowImpl->mpFrame->Show( false );
2227
0
        }
2228
2229
22.8k
        CompatStateChanged( StateChangedType::Visible );
2230
2231
22.8k
        if ( mpWindowImpl->mbReallyVisible )
2232
0
        {
2233
0
            if ( mpWindowImpl->mbInitWinClipRegion )
2234
0
                ImplInitWinClipRegion();
2235
2236
0
            vcl::Region aInvRegion = mpWindowImpl->maWinClipRegion;
2237
2238
0
            if( !xWindow->mpWindowImpl )
2239
0
                return;
2240
2241
0
            bRealVisibilityChanged = mpWindowImpl->mbReallyVisible;
2242
0
            ImplResetReallyVisible();
2243
0
            ImplSetClipFlag();
2244
2245
0
            if ( ImplIsOverlapWindow() && !mpWindowImpl->mbFrame )
2246
0
            {
2247
                // convert focus
2248
0
                if ( !(nFlags & ShowFlags::NoFocusChange) && HasChildPathFocus() )
2249
0
                {
2250
0
                    if ( mpWindowImpl->mpOverlapWindow->IsEnabled() &&
2251
0
                         mpWindowImpl->mpOverlapWindow->IsInputEnabled() &&
2252
0
                         ! mpWindowImpl->mpOverlapWindow->IsInModalMode()
2253
0
                         )
2254
0
                        mpWindowImpl->mpOverlapWindow->GrabFocus();
2255
0
                }
2256
0
            }
2257
2258
0
            if ( !mpWindowImpl->mbFrame )
2259
0
            {
2260
0
                if (mpWindowImpl->mpWinData && mpWindowImpl->mpWinData->mbEnableNativeWidget)
2261
0
                {
2262
                    /*
2263
                    * #i48371# native theming: some themes draw outside the control
2264
                    * area we tell them to (bad thing, but we cannot do much about it ).
2265
                    * On hiding these controls they get invalidated with their window rectangle
2266
                    * which leads to the parts outside the control area being left and not
2267
                    * invalidated. Workaround: invalidate an area on the parent, too
2268
                    */
2269
0
                    const int workaround_border = 5;
2270
0
                    tools::Rectangle aBounds( aInvRegion.GetBoundRect() );
2271
0
                    aBounds.AdjustLeft( -workaround_border );
2272
0
                    aBounds.AdjustTop( -workaround_border );
2273
0
                    aBounds.AdjustRight(workaround_border );
2274
0
                    aBounds.AdjustBottom(workaround_border );
2275
0
                    aInvRegion = aBounds;
2276
0
                }
2277
0
                if ( !mpWindowImpl->mbNoParentUpdate )
2278
0
                {
2279
0
                    if ( !aInvRegion.IsEmpty() )
2280
0
                        ImplInvalidateParentFrameRegion( aInvRegion );
2281
0
                }
2282
0
                ImplGenerateMouseMove();
2283
0
            }
2284
0
        }
2285
22.8k
    }
2286
22.8k
    else
2287
22.8k
    {
2288
        // inherit native widget flag for form controls
2289
        // required here, because frames never show up in the child hierarchy - which should be fixed...
2290
        // eg, the drop down of a combobox which is a system floating window
2291
22.8k
        if( mpWindowImpl->mbFrame && GetParent() && !GetParent()->isDisposed() &&
2292
0
            GetParent()->IsCompoundControl() &&
2293
0
            GetParent()->IsNativeWidgetEnabled() != IsNativeWidgetEnabled() &&
2294
0
            !(GetStyle() & WB_TOOLTIPWIN) )
2295
0
        {
2296
0
            EnableNativeWidget( GetParent()->IsNativeWidgetEnabled() );
2297
0
        }
2298
2299
22.8k
        if ( mpWindowImpl->mbCallMove )
2300
22.8k
        {
2301
22.8k
            ImplCallMove();
2302
22.8k
        }
2303
22.8k
        if ( mpWindowImpl->mbCallResize )
2304
22.8k
        {
2305
22.8k
            ImplCallResize();
2306
22.8k
        }
2307
2308
22.8k
        CompatStateChanged( StateChangedType::Visible );
2309
2310
22.8k
        vcl::Window* pTestParent;
2311
22.8k
        if ( ImplIsOverlapWindow() )
2312
0
            pTestParent = mpWindowImpl->mpOverlapWindow;
2313
22.8k
        else
2314
22.8k
            pTestParent = ImplGetParent();
2315
22.8k
        if ( mpWindowImpl->mbFrame || pTestParent->mpWindowImpl->mbReallyVisible )
2316
0
        {
2317
            // if a window becomes visible, send all child windows a StateChange,
2318
            // such that these can initialise themselves
2319
0
            ImplCallInitShow();
2320
2321
            // If it is a SystemWindow it automatically pops up on top of
2322
            // all other windows if needed.
2323
0
            if (ImplIsOverlapWindow())
2324
0
            {
2325
0
                if (!(nFlags & ShowFlags::NoActivate))
2326
0
                {
2327
0
                    ImplStartToTop((nFlags & ShowFlags::ForegroundTask) ? ToTopFlags::ForegroundTask
2328
0
                                                                        : ToTopFlags::NONE);
2329
0
                    ImplFocusToTop(ToTopFlags::NONE, false);
2330
2331
0
                    if (!(nFlags & ShowFlags::ForegroundTask))
2332
0
                    {
2333
                        // Inform user about window if we did not popup it at foreground
2334
0
                        FlashWindow();
2335
0
                    }
2336
0
                }
2337
0
            }
2338
2339
            // adjust mpWindowImpl->mbReallyVisible
2340
0
            bRealVisibilityChanged = !mpWindowImpl->mbReallyVisible;
2341
0
            ImplSetReallyVisible();
2342
2343
            // assure clip rectangles will be recalculated
2344
0
            ImplSetClipFlag();
2345
2346
0
            if ( !mpWindowImpl->mbFrame )
2347
0
            {
2348
0
                InvalidateFlags nInvalidateFlags = InvalidateFlags::Children;
2349
0
                if( ! IsPaintTransparent() )
2350
0
                    nInvalidateFlags |= InvalidateFlags::NoTransparent;
2351
0
                ImplInvalidate( nullptr, nInvalidateFlags );
2352
0
                ImplGenerateMouseMove();
2353
0
            }
2354
0
        }
2355
2356
22.8k
        if ( mpWindowImpl->mpBorderWindow )
2357
4.57k
            mpWindowImpl->mpBorderWindow->Show( true, nFlags );
2358
18.2k
        else if ( mpWindowImpl->mbFrame )
2359
0
        {
2360
            // #106431#, hide SplashScreen
2361
0
            ImplSVData* pSVData = ImplGetSVData();
2362
0
            if ( !pSVData->mpIntroWindow )
2363
0
            {
2364
                // The right way would be just to call this (not even in the 'if')
2365
0
                auto pApp = GetpApp();
2366
0
                if ( pApp )
2367
0
                    pApp->InitFinished();
2368
0
            }
2369
0
            else if ( !ImplIsWindowOrChild( pSVData->mpIntroWindow ) )
2370
0
            {
2371
                // ... but the VCL splash is broken, and it needs this
2372
                // (for ./soffice .uno:NewDoc)
2373
0
                pSVData->mpIntroWindow->Hide();
2374
0
            }
2375
2376
            //SAL_WARN_IF( mpWindowImpl->mbSuppressAccessibilityEvents, "vcl", "Window::Show() - Frame reactivated");
2377
0
            mpWindowImpl->mbSuppressAccessibilityEvents = false;
2378
2379
0
            mpWindowImpl->mbPaintFrame = true;
2380
0
            if (!Application::IsHeadlessModeEnabled())
2381
0
            {
2382
0
                bool bNoActivate(nFlags & (ShowFlags::NoActivate|ShowFlags::NoFocusChange));
2383
0
                mpWindowImpl->mpFrame->Show( true, bNoActivate );
2384
0
            }
2385
0
            if( !xWindow->mpWindowImpl )
2386
0
                return;
2387
2388
            // Query the correct size of the window, if we are waiting for
2389
            // a system resize
2390
0
            if ( mpWindowImpl->mbWaitSystemResize )
2391
0
            {
2392
0
                tools::Long nOutWidth;
2393
0
                tools::Long nOutHeight;
2394
0
                mpWindowImpl->mpFrame->GetClientSize( nOutWidth, nOutHeight );
2395
0
                ImplHandleResize( this, nOutWidth, nOutHeight );
2396
0
            }
2397
2398
0
            if (mpWindowImpl->mpFrameData->mpBuffer && mpWindowImpl->mpFrameData->mpBuffer->GetOutputSizePixel() != GetOutputSizePixel())
2399
                // Make sure that the buffer size matches the window size, even if no resize was needed.
2400
0
                mpWindowImpl->mpFrameData->mpBuffer->SetOutputSizePixel(GetOutputSizePixel());
2401
0
        }
2402
2403
22.8k
        if( !xWindow->mpWindowImpl )
2404
0
            return;
2405
2406
22.8k
        ImplShowAllOverlaps();
2407
22.8k
    }
2408
2409
45.6k
    if( !xWindow->mpWindowImpl )
2410
0
        return;
2411
2412
    // the SHOW/HIDE events also serve as indicators to send child creation/destroy events to the access bridge
2413
    // However, the access bridge only uses this event if the data member is not NULL (it's kind of a hack that
2414
    // we re-use the SHOW/HIDE events this way, with this particular semantics).
2415
    // Since #104887#, the notifications for the access bridge are done in Impl(Set|Reset)ReallyVisible. Here, we
2416
    // now only notify with a NULL data pointer, for all other clients except the access bridge.
2417
45.6k
    if ( !bRealVisibilityChanged )
2418
45.6k
        CallEventListeners( mpWindowImpl->mbVisible ? VclEventId::WindowShow : VclEventId::WindowHide );
2419
45.6k
}
2420
2421
Size Window::GetSizePixel() const
2422
63.5k
{
2423
63.5k
    if (!mpWindowImpl)
2424
0
    {
2425
0
        SAL_WARN("vcl.layout", "WTF no windowimpl");
2426
0
        return Size(0,0);
2427
0
    }
2428
2429
    // #i43257# trigger pending resize handler to assure correct window sizes
2430
63.5k
    if( mpWindowImpl->mpFrameData->maResizeIdle.IsActive() )
2431
0
    {
2432
0
        VclPtr<vcl::Window> xWindow( const_cast<Window*>(this) );
2433
0
        mpWindowImpl->mpFrameData->maResizeIdle.Stop();
2434
0
        mpWindowImpl->mpFrameData->maResizeIdle.Invoke( nullptr );
2435
0
        if( xWindow->isDisposed() )
2436
0
            return Size(0,0);
2437
0
    }
2438
2439
63.5k
    return Size( GetOutDev()->mnOutWidth + mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
2440
63.5k
                 GetOutDev()->mnOutHeight + mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder );
2441
63.5k
}
2442
2443
void Window::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
2444
                               sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
2445
36.1k
{
2446
36.1k
    rLeftBorder     = mpWindowImpl->mnLeftBorder;
2447
36.1k
    rTopBorder      = mpWindowImpl->mnTopBorder;
2448
36.1k
    rRightBorder    = mpWindowImpl->mnRightBorder;
2449
36.1k
    rBottomBorder   = mpWindowImpl->mnBottomBorder;
2450
36.1k
}
2451
2452
void Window::Enable( bool bEnable, bool bChild )
2453
0
{
2454
0
    if ( isDisposed() )
2455
0
        return;
2456
2457
0
    if ( !bEnable )
2458
0
    {
2459
        // the tracking mode will be stopped or the capture will be stolen
2460
        // when a window is disabled,
2461
0
        if ( IsTracking() )
2462
0
            EndTracking( TrackingEventFlags::Cancel );
2463
0
        if ( IsMouseCaptured() )
2464
0
            ReleaseMouse();
2465
        // try to pass focus to the next control
2466
        // if the window has focus and is contained in the dialog control
2467
        // mpWindowImpl->mbDisabled should only be set after a call of ImplDlgCtrlNextWindow().
2468
        // Otherwise ImplDlgCtrlNextWindow() should be used
2469
0
        if ( HasFocus() )
2470
0
            ImplDlgCtrlNextWindow();
2471
0
    }
2472
2473
0
    if ( mpWindowImpl->mpBorderWindow )
2474
0
    {
2475
0
        mpWindowImpl->mpBorderWindow->Enable( bEnable, false );
2476
0
        if ( (mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW) &&
2477
0
             static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->mpMenuBarWindow )
2478
0
            static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->mpMenuBarWindow->Enable( bEnable );
2479
0
    }
2480
2481
    // #i56102# restore app focus win in case the
2482
    // window was disabled when the frame focus changed
2483
0
    ImplSVData* pSVData = ImplGetSVData();
2484
0
    if (bEnable && pSVData->mpWinData->mpFocusWin == nullptr
2485
0
        && mpWindowImpl->mpFrameData->mbHasFocus && mpWindowImpl->mpFrameData->mpFocusWin == this)
2486
0
        pSVData->mpWinData->mpFocusWin = this;
2487
2488
0
    if ( mpWindowImpl->mbDisabled != !bEnable )
2489
0
    {
2490
0
        mpWindowImpl->mbDisabled = !bEnable;
2491
0
        if ( mpWindowImpl->mpSysObj )
2492
0
            mpWindowImpl->mpSysObj->Enable( bEnable && !mpWindowImpl->mbInputDisabled );
2493
0
        CompatStateChanged( StateChangedType::Enable );
2494
2495
0
        CallEventListeners( bEnable ? VclEventId::WindowEnabled : VclEventId::WindowDisabled );
2496
0
    }
2497
2498
0
    if ( bChild )
2499
0
    {
2500
0
        VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
2501
0
        while ( pChild )
2502
0
        {
2503
0
            pChild->Enable( bEnable, bChild );
2504
0
            pChild = pChild->mpWindowImpl->mpNext;
2505
0
        }
2506
0
    }
2507
2508
0
    if ( IsReallyVisible() )
2509
0
        ImplGenerateMouseMove();
2510
0
}
2511
2512
void Window::EnableInput( bool bEnable, bool bChild )
2513
0
{
2514
0
    if (!mpWindowImpl)
2515
0
        return;
2516
2517
0
    if ( mpWindowImpl->mpBorderWindow )
2518
0
    {
2519
0
        mpWindowImpl->mpBorderWindow->EnableInput( bEnable, false );
2520
0
        if ( (mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW) &&
2521
0
             static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->mpMenuBarWindow )
2522
0
            static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->mpMenuBarWindow->EnableInput( bEnable );
2523
0
    }
2524
2525
0
    if ( (!bEnable && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled) || bEnable )
2526
0
    {
2527
        // automatically stop the tracking mode or steal capture
2528
        // if the window is disabled
2529
0
        if ( !bEnable )
2530
0
        {
2531
0
            if ( IsTracking() )
2532
0
                EndTracking( TrackingEventFlags::Cancel );
2533
0
            if ( IsMouseCaptured() )
2534
0
                ReleaseMouse();
2535
0
        }
2536
2537
0
        if ( mpWindowImpl->mbInputDisabled != !bEnable )
2538
0
        {
2539
0
            mpWindowImpl->mbInputDisabled = !bEnable;
2540
0
            if ( mpWindowImpl->mpSysObj )
2541
0
                mpWindowImpl->mpSysObj->Enable( !mpWindowImpl->mbDisabled && bEnable );
2542
0
        }
2543
0
    }
2544
2545
    // #i56102# restore app focus win in case the
2546
    // window was disabled when the frame focus changed
2547
0
    ImplSVData* pSVData = ImplGetSVData();
2548
0
    if (bEnable && pSVData->mpWinData->mpFocusWin == nullptr
2549
0
        && mpWindowImpl->mpFrameData->mbHasFocus && mpWindowImpl->mpFrameData->mpFocusWin == this)
2550
0
        pSVData->mpWinData->mpFocusWin = this;
2551
2552
0
    if ( bChild )
2553
0
    {
2554
0
        VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
2555
0
        while ( pChild )
2556
0
        {
2557
0
            pChild->EnableInput( bEnable, bChild );
2558
0
            pChild = pChild->mpWindowImpl->mpNext;
2559
0
        }
2560
0
    }
2561
2562
0
    if ( IsReallyVisible() )
2563
0
        ImplGenerateMouseMove();
2564
0
}
2565
2566
void Window::EnableInput( bool bEnable, const vcl::Window* pExcludeWindow )
2567
0
{
2568
0
    if (!mpWindowImpl)
2569
0
        return;
2570
2571
0
    EnableInput( bEnable );
2572
2573
    // pExecuteWindow is the first Overlap-Frame --> if this
2574
    // shouldn't be the case, then this must be changed in dialog.cxx
2575
0
    if( pExcludeWindow )
2576
0
        pExcludeWindow = pExcludeWindow->ImplGetFirstOverlapWindow();
2577
0
    vcl::Window* pSysWin = mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mpFirstOverlap;
2578
0
    while ( pSysWin )
2579
0
    {
2580
        // Is Window in the path from this window
2581
0
        if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pSysWin, true ) )
2582
0
        {
2583
            // Is Window not in the exclude window path or not the
2584
            // exclude window, then change the status
2585
0
            if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( pSysWin, true ) )
2586
0
                pSysWin->EnableInput( bEnable );
2587
0
        }
2588
0
        pSysWin = pSysWin->mpWindowImpl->mpNextOverlap;
2589
0
    }
2590
2591
    // enable/disable floating system windows as well
2592
0
    vcl::Window* pFrameWin = ImplGetSVData()->maFrameData.mpFirstFrame;
2593
0
    while ( pFrameWin )
2594
0
    {
2595
0
        if( pFrameWin->ImplIsFloatingWindow() )
2596
0
        {
2597
            // Is Window in the path from this window
2598
0
            if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pFrameWin, true ) )
2599
0
            {
2600
                // Is Window not in the exclude window path or not the
2601
                // exclude window, then change the status
2602
0
                if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( pFrameWin, true ) )
2603
0
                    pFrameWin->EnableInput( bEnable );
2604
0
            }
2605
0
        }
2606
0
        pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame;
2607
0
    }
2608
2609
    // the same for ownerdraw floating windows
2610
0
    if( !mpWindowImpl->mbFrame )
2611
0
        return;
2612
2613
0
    ::std::vector< VclPtr<vcl::Window> >& rList = mpWindowImpl->mpFrameData->maOwnerDrawList;
2614
0
    for (auto const& elem : rList)
2615
0
    {
2616
        // Is Window in the path from this window
2617
0
        if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( elem, true ) )
2618
0
        {
2619
            // Is Window not in the exclude window path or not the
2620
            // exclude window, then change the status
2621
0
            if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( elem, true ) )
2622
0
                elem->EnableInput( bEnable );
2623
0
        }
2624
0
    }
2625
0
}
2626
2627
void Window::AlwaysEnableInput( bool bAlways, bool bChild )
2628
0
{
2629
2630
0
    if ( mpWindowImpl->mpBorderWindow )
2631
0
        mpWindowImpl->mpBorderWindow->AlwaysEnableInput( bAlways, false );
2632
2633
0
    if( bAlways && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled )
2634
0
    {
2635
0
        mpWindowImpl->meAlwaysInputMode = AlwaysInputEnabled;
2636
0
        EnableInput(true, false);
2637
0
    }
2638
0
    else if( ! bAlways && mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled )
2639
0
    {
2640
0
        mpWindowImpl->meAlwaysInputMode = AlwaysInputNone;
2641
0
    }
2642
2643
0
    if ( bChild )
2644
0
    {
2645
0
        VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
2646
0
        while ( pChild )
2647
0
        {
2648
0
            pChild->AlwaysEnableInput( bAlways, bChild );
2649
0
            pChild = pChild->mpWindowImpl->mpNext;
2650
0
        }
2651
0
    }
2652
0
}
2653
2654
void Window::SetActivateMode( ActivateModeFlags nMode )
2655
16.6k
{
2656
2657
16.6k
    if ( mpWindowImpl->mpBorderWindow )
2658
8.34k
        mpWindowImpl->mpBorderWindow->SetActivateMode( nMode );
2659
2660
16.6k
    if ( mpWindowImpl->mnActivateMode == nMode )
2661
8.34k
        return;
2662
2663
8.34k
    mpWindowImpl->mnActivateMode = nMode;
2664
2665
    // possibly trigger Deactivate/Activate
2666
8.34k
    if ( mpWindowImpl->mnActivateMode != ActivateModeFlags::NONE )
2667
8.34k
    {
2668
8.34k
        if ( (mpWindowImpl->mbActive || (GetType() == WindowType::BORDERWINDOW)) &&
2669
8.34k
             !HasChildPathFocus( true ) )
2670
8.34k
        {
2671
8.34k
            mpWindowImpl->mbActive = false;
2672
8.34k
            Deactivate();
2673
8.34k
        }
2674
8.34k
    }
2675
0
    else
2676
0
    {
2677
0
        if ( !mpWindowImpl->mbActive || (GetType() == WindowType::BORDERWINDOW) )
2678
0
        {
2679
0
            mpWindowImpl->mbActive = true;
2680
0
            Activate();
2681
0
        }
2682
0
    }
2683
8.34k
}
2684
2685
void Window::setPosSizePixel( tools::Long nX, tools::Long nY,
2686
                              tools::Long nWidth, tools::Long nHeight, PosSizeFlags nFlags )
2687
76.9k
{
2688
76.9k
    bool bHasValidSize = !mpWindowImpl->mbDefSize;
2689
2690
76.9k
    if ( nFlags & PosSizeFlags::Pos )
2691
36.6k
        mpWindowImpl->mbDefPos = false;
2692
76.9k
    if ( nFlags & PosSizeFlags::Size )
2693
76.9k
        mpWindowImpl->mbDefSize = false;
2694
2695
    // The top BorderWindow is the window which is to be positioned
2696
76.9k
    VclPtr<vcl::Window> pWindow = this;
2697
76.9k
    while ( pWindow->mpWindowImpl->mpBorderWindow )
2698
0
        pWindow = pWindow->mpWindowImpl->mpBorderWindow;
2699
2700
76.9k
    if ( pWindow->mpWindowImpl->mbFrame )
2701
0
    {
2702
        // Note: if we're positioning a frame, the coordinates are interpreted
2703
        // as being the top-left corner of the window's client area and NOT
2704
        // as the position of the border ! (due to limitations of several UNIX window managers)
2705
0
        tools::Long nOldWidth  = pWindow->GetOutDev()->mnOutWidth;
2706
2707
0
        if ( !(nFlags & PosSizeFlags::Width) )
2708
0
            nWidth = pWindow->GetOutDev()->mnOutWidth;
2709
0
        if ( !(nFlags & PosSizeFlags::Height) )
2710
0
            nHeight = pWindow->GetOutDev()->mnOutHeight;
2711
2712
0
        sal_uInt16 nSysFlags=0;
2713
0
        VclPtr<vcl::Window> pParent = GetParent();
2714
0
        VclPtr<vcl::Window> pWinParent = pWindow->GetParent();
2715
2716
0
        if( nFlags & PosSizeFlags::Width )
2717
0
            nSysFlags |= SAL_FRAME_POSSIZE_WIDTH;
2718
0
        if( nFlags & PosSizeFlags::Height )
2719
0
            nSysFlags |= SAL_FRAME_POSSIZE_HEIGHT;
2720
0
        if( nFlags & PosSizeFlags::X )
2721
0
        {
2722
0
            nSysFlags |= SAL_FRAME_POSSIZE_X;
2723
0
            if( pWinParent && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) )
2724
0
            {
2725
0
                nX += pWinParent->GetOutDev()->mnOutOffX;
2726
0
            }
2727
0
            if( pParent && pParent->GetOutDev()->ImplIsAntiparallel() )
2728
0
            {
2729
0
                tools::Rectangle aRect( Point ( nX, nY ), Size( nWidth, nHeight ) );
2730
0
                const OutputDevice *pParentOutDev = pParent->GetOutDev();
2731
0
                if (!comphelper::LibreOfficeKit::isActive())
2732
0
                    pParentOutDev->ReMirror( aRect );
2733
0
                nX = aRect.Left();
2734
0
            }
2735
0
        }
2736
0
        if( !comphelper::LibreOfficeKit::isActive() &&
2737
0
            !(nFlags & PosSizeFlags::X) && bHasValidSize &&
2738
0
            pWindow->mpWindowImpl->mpFrame->GetWidth())
2739
0
        {
2740
            // RTL: make sure the old right aligned position is not changed
2741
            // system windows will always grow to the right
2742
0
            if ( pWinParent )
2743
0
            {
2744
0
                OutputDevice *pParentOutDev = pWinParent->GetOutDev();
2745
0
                if( pParentOutDev->HasMirroredGraphics() )
2746
0
                {
2747
0
                    const SalFrameGeometry aSysGeometry = mpWindowImpl->mpFrame->GetUnmirroredGeometry();
2748
0
                    const SalFrameGeometry aParentSysGeometry =
2749
0
                        pWinParent->mpWindowImpl->mpFrame->GetUnmirroredGeometry();
2750
0
                    tools::Long myWidth = nOldWidth;
2751
0
                    if( !myWidth )
2752
0
                        myWidth = aSysGeometry.width();
2753
0
                    if( !myWidth )
2754
0
                        myWidth = nWidth;
2755
0
                    nFlags |= PosSizeFlags::X;
2756
0
                    nSysFlags |= SAL_FRAME_POSSIZE_X;
2757
0
                    nX = aParentSysGeometry.x() - aSysGeometry.leftDecoration() + aParentSysGeometry.width()
2758
0
                        - myWidth - 1 - aSysGeometry.x();
2759
0
                }
2760
0
            }
2761
0
        }
2762
0
        if( nFlags & PosSizeFlags::Y )
2763
0
        {
2764
0
            nSysFlags |= SAL_FRAME_POSSIZE_Y;
2765
0
            if( pWinParent && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) )
2766
0
            {
2767
0
                nY += pWinParent->GetOutDev()->mnOutOffY;
2768
0
            }
2769
0
        }
2770
2771
0
        if( nSysFlags & (SAL_FRAME_POSSIZE_WIDTH|SAL_FRAME_POSSIZE_HEIGHT) )
2772
0
        {
2773
            // check for min/max client size and adjust size accordingly
2774
            // otherwise it may happen that the resize event is ignored, i.e. the old size remains
2775
            // unchanged but ImplHandleResize() is called with the wrong size
2776
0
            SystemWindow *pSystemWindow = dynamic_cast< SystemWindow* >( pWindow.get() );
2777
0
            if( pSystemWindow )
2778
0
            {
2779
0
                Size aMinSize = pSystemWindow->GetMinOutputSizePixel();
2780
0
                Size aMaxSize = pSystemWindow->GetMaxOutputSizePixel();
2781
0
                if( nWidth < aMinSize.Width() )
2782
0
                    nWidth = aMinSize.Width();
2783
0
                if( nHeight < aMinSize.Height() )
2784
0
                    nHeight = aMinSize.Height();
2785
2786
0
                if( nWidth > aMaxSize.Width() )
2787
0
                    nWidth = aMaxSize.Width();
2788
0
                if( nHeight > aMaxSize.Height() )
2789
0
                    nHeight = aMaxSize.Height();
2790
0
            }
2791
0
        }
2792
2793
0
        pWindow->mpWindowImpl->mpFrame->SetPosSize( nX, nY, nWidth, nHeight, nSysFlags );
2794
2795
        // Adjust resize with the hack of different client size and frame geometries to fix
2796
        // native menu bars. Eventually this should be replaced by proper mnTopBorder usage.
2797
0
        pWindow->mpWindowImpl->mpFrame->GetClientSize(nWidth, nHeight);
2798
2799
        // Resize should be called directly. If we haven't
2800
        // set the correct size, we get a second resize from
2801
        // the system with the correct size. This can be happened
2802
        // if the size is too small or too large.
2803
0
        ImplHandleResize( pWindow, nWidth, nHeight );
2804
0
    }
2805
76.9k
    else
2806
76.9k
    {
2807
76.9k
        pWindow->ImplPosSizeWindow( nX, nY, nWidth, nHeight, nFlags );
2808
76.9k
        if ( IsReallyVisible() )
2809
0
            ImplGenerateMouseMove();
2810
76.9k
    }
2811
76.9k
}
2812
2813
Point Window::GetPosPixel() const
2814
2.13k
{
2815
2.13k
    return mpWindowImpl->maPos;
2816
2.13k
}
2817
2818
AbsoluteScreenPixelRectangle Window::GetDesktopRectPixel() const
2819
0
{
2820
0
    AbsoluteScreenPixelRectangle rRect;
2821
0
    mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrame->GetWorkArea( rRect );
2822
0
    return rRect;
2823
0
}
2824
2825
Point Window::OutputToScreenPixel( const Point& rPos ) const
2826
4.58k
{
2827
    // relative to top level parent
2828
4.58k
    return Point( rPos.X() + GetOutDev()->mnOutOffX, rPos.Y() + GetOutDev()->mnOutOffY );
2829
4.58k
}
2830
2831
Point Window::ScreenToOutputPixel( const Point& rPos ) const
2832
18.6k
{
2833
    // relative to top level parent
2834
18.6k
    return Point( rPos.X() - GetOutDev()->mnOutOffX, rPos.Y() - GetOutDev()->mnOutOffY );
2835
18.6k
}
2836
2837
tools::Long Window::ImplGetUnmirroredOutOffX() const
2838
0
{
2839
    // revert mnOutOffX changes that were potentially made in ImplPosSizeWindow
2840
0
    tools::Long offx = GetOutDev()->mnOutOffX;
2841
0
    const OutputDevice *pOutDev = GetOutDev();
2842
0
    if( pOutDev->HasMirroredGraphics() )
2843
0
    {
2844
0
        if( mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->GetOutDev()->ImplIsAntiparallel() )
2845
0
        {
2846
0
            if ( !ImplIsOverlapWindow() )
2847
0
                offx -= mpWindowImpl->mpParent->GetOutDev()->mnOutOffX;
2848
2849
0
            offx = mpWindowImpl->mpParent->GetOutDev()->mnOutWidth - GetOutDev()->mnOutWidth - offx;
2850
2851
0
            if ( !ImplIsOverlapWindow() )
2852
0
                offx += mpWindowImpl->mpParent->GetOutDev()->mnOutOffX;
2853
2854
0
        }
2855
0
    }
2856
0
    return offx;
2857
0
}
2858
2859
// normalized screen pixel are independent of mirroring
2860
Point Window::OutputToNormalizedScreenPixel( const Point& rPos ) const
2861
0
{
2862
    // relative to top level parent
2863
0
    tools::Long offx = ImplGetUnmirroredOutOffX();
2864
0
    return Point( rPos.X()+offx, rPos.Y() + GetOutDev()->mnOutOffY );
2865
0
}
2866
2867
Point Window::NormalizedScreenToOutputPixel( const Point& rPos ) const
2868
0
{
2869
    // relative to top level parent
2870
0
    tools::Long offx = ImplGetUnmirroredOutOffX();
2871
0
    return Point( rPos.X()-offx, rPos.Y() - GetOutDev()->mnOutOffY );
2872
0
}
2873
2874
AbsoluteScreenPixelPoint Window::OutputToAbsoluteScreenPixel( const Point& rPos ) const
2875
0
{
2876
    // relative to the screen
2877
0
    Point p = OutputToScreenPixel( rPos );
2878
0
    SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
2879
0
    p.AdjustX(g.x() );
2880
0
    p.AdjustY(g.y() );
2881
0
    return AbsoluteScreenPixelPoint(p);
2882
0
}
2883
2884
Point Window::AbsoluteScreenToOutputPixel( const AbsoluteScreenPixelPoint& rPos ) const
2885
0
{
2886
    // relative to the screen
2887
0
    Point p = ScreenToOutputPixel( Point(rPos) );
2888
0
    SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
2889
0
    p.AdjustX( -(g.x()) );
2890
0
    p.AdjustY( -(g.y()) );
2891
0
    return p;
2892
0
}
2893
2894
AbsoluteScreenPixelRectangle Window::ImplOutputToUnmirroredAbsoluteScreenPixel( const tools::Rectangle &rRect ) const
2895
0
{
2896
    // this method creates unmirrored screen coordinates to be compared with the desktop
2897
    // and is used for positioning of RTL popup windows correctly on the screen
2898
0
    SalFrameGeometry g = mpWindowImpl->mpFrame->GetUnmirroredGeometry();
2899
2900
0
    Point p1 = rRect.TopRight();
2901
0
    p1 = OutputToScreenPixel(p1);
2902
0
    p1.setX( g.x()+g.width()-p1.X() );
2903
0
    p1.AdjustY(g.y() );
2904
2905
0
    Point p2 = rRect.BottomLeft();
2906
0
    p2 = OutputToScreenPixel(p2);
2907
0
    p2.setX( g.x()+g.width()-p2.X() );
2908
0
    p2.AdjustY(g.y() );
2909
2910
0
    return AbsoluteScreenPixelRectangle( AbsoluteScreenPixelPoint(p1), AbsoluteScreenPixelPoint(p2) );
2911
0
}
2912
2913
tools::Rectangle Window::ImplUnmirroredAbsoluteScreenToOutputPixel( const AbsoluteScreenPixelRectangle &rRect ) const
2914
0
{
2915
    // undo ImplOutputToUnmirroredAbsoluteScreenPixel
2916
0
    SalFrameGeometry g = mpWindowImpl->mpFrame->GetUnmirroredGeometry();
2917
2918
0
    Point p1( rRect.TopRight() );
2919
0
    p1.AdjustY(-g.y() );
2920
0
    p1.setX( g.x()+g.width()-p1.X() );
2921
0
    p1 = ScreenToOutputPixel(p1);
2922
2923
0
    Point p2( rRect.BottomLeft() );
2924
0
    p2.AdjustY(-g.y());
2925
0
    p2.setX( g.x()+g.width()-p2.X() );
2926
0
    p2 = ScreenToOutputPixel(p2);
2927
2928
0
    return tools::Rectangle( p1, p2 );
2929
0
}
2930
2931
2932
// with decoration
2933
tools::Rectangle Window::GetWindowExtentsRelative(const vcl::Window & rRelativeWindow) const
2934
0
{
2935
0
    AbsoluteScreenPixelRectangle aRect = GetWindowExtentsAbsolute();
2936
    // #106399# express coordinates relative to borderwindow
2937
0
    const vcl::Window *pRelWin = rRelativeWindow.mpWindowImpl->mpBorderWindow ? rRelativeWindow.mpWindowImpl->mpBorderWindow.get() : &rRelativeWindow;
2938
0
    return tools::Rectangle(
2939
0
        pRelWin->AbsoluteScreenToOutputPixel( aRect.GetPos() ),
2940
0
        aRect.GetSize() );
2941
0
}
2942
2943
// with decoration
2944
AbsoluteScreenPixelRectangle Window::GetWindowExtentsAbsolute() const
2945
0
{
2946
    // make sure we use the extent of our border window,
2947
    // otherwise we miss a few pixels
2948
0
    const vcl::Window *pWin = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow : this;
2949
2950
0
    AbsoluteScreenPixelPoint aPos( pWin->OutputToAbsoluteScreenPixel( Point(0,0) ) );
2951
0
    Size aSize ( pWin->GetSizePixel() );
2952
    // #104088# do not add decoration to the workwindow to be compatible to java accessibility api
2953
0
    if( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame && GetType() != WindowType::WORKWINDOW) )
2954
0
    {
2955
0
        SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
2956
0
        aPos.AdjustX( -sal_Int32(g.leftDecoration()) );
2957
0
        aPos.AdjustY( -sal_Int32(g.topDecoration()) );
2958
0
        aSize.AdjustWidth(g.leftDecoration() + g.rightDecoration() );
2959
0
        aSize.AdjustHeight(g.topDecoration() + g.bottomDecoration() );
2960
0
    }
2961
0
    return AbsoluteScreenPixelRectangle( aPos, aSize );
2962
0
}
2963
2964
void Window::Scroll( tools::Long nHorzScroll, tools::Long nVertScroll, ScrollFlags nFlags )
2965
0
{
2966
2967
0
    ImplScroll( GetOutputRectPixel(),
2968
0
                nHorzScroll, nVertScroll, nFlags & ~ScrollFlags::Clip );
2969
0
}
2970
2971
void Window::Scroll( tools::Long nHorzScroll, tools::Long nVertScroll,
2972
                     const tools::Rectangle& rRect, ScrollFlags nFlags )
2973
0
{
2974
0
    OutputDevice *pOutDev = GetOutDev();
2975
0
    tools::Rectangle aRect = pOutDev->ImplLogicToDevicePixel( rRect );
2976
0
    aRect.Intersection( GetOutputRectPixel() );
2977
0
    if ( !aRect.IsEmpty() )
2978
0
        ImplScroll( aRect, nHorzScroll, nVertScroll, nFlags );
2979
0
}
2980
2981
void WindowOutputDevice::Flush()
2982
0
{
2983
0
    if (mxOwnerWindow->mpWindowImpl)
2984
0
        mxOwnerWindow->mpWindowImpl->mpFrame->Flush( GetOutputRectPixel() );
2985
0
}
2986
2987
void Window::SetUpdateMode( bool bUpdate )
2988
9.06k
{
2989
9.06k
    if (mpWindowImpl)
2990
9.06k
    {
2991
9.06k
        mpWindowImpl->mbNoUpdate = !bUpdate;
2992
9.06k
        CompatStateChanged( StateChangedType::UpdateMode );
2993
9.06k
    }
2994
9.06k
}
2995
2996
void Window::GrabFocus()
2997
0
{
2998
0
    ImplGrabFocus( GetFocusFlags::NONE );
2999
0
}
3000
3001
bool Window::HasFocus() const
3002
9.16k
{
3003
9.16k
    return (this == ImplGetSVData()->mpWinData->mpFocusWin);
3004
9.16k
}
3005
3006
void Window::GrabFocusToDocument()
3007
0
{
3008
0
    ImplGrabFocusToDocument(GetFocusFlags::NONE);
3009
0
}
3010
3011
VclPtr<vcl::Window> Window::GetFocusedWindow() const
3012
0
{
3013
0
    if (mpWindowImpl && mpWindowImpl->mpFrameData)
3014
0
        return mpWindowImpl->mpFrameData->mpFocusWin;
3015
0
    else
3016
0
        return VclPtr<vcl::Window>();
3017
0
}
3018
3019
void Window::SetFakeFocus( bool bFocus )
3020
0
{
3021
0
    ImplGetWindowImpl()->mbFakeFocusSet = bFocus;
3022
0
}
3023
3024
bool Window::HasChildPathFocus( bool bSystemWindow ) const
3025
31.2k
{
3026
3027
31.2k
    vcl::Window* pFocusWin = ImplGetSVData()->mpWinData->mpFocusWin;
3028
31.2k
    if ( pFocusWin )
3029
0
        return ImplIsWindowOrChild( pFocusWin, bSystemWindow );
3030
31.2k
    return false;
3031
31.2k
}
3032
3033
void Window::SetCursor( vcl::Cursor* pCursor )
3034
9.15k
{
3035
3036
9.15k
    if ( mpWindowImpl->mpCursor != pCursor )
3037
9.15k
    {
3038
9.15k
        if ( mpWindowImpl->mpCursor )
3039
4.57k
            mpWindowImpl->mpCursor->ImplHide();
3040
9.15k
        mpWindowImpl->mpCursor = pCursor;
3041
9.15k
        if ( pCursor )
3042
4.57k
            pCursor->ImplShow();
3043
9.15k
    }
3044
9.15k
}
3045
3046
void Window::SetText( const OUString& rStr )
3047
13.7k
{
3048
13.7k
    if (!mpWindowImpl || rStr == mpWindowImpl->maText)
3049
4.57k
        return;
3050
3051
9.21k
    OUString oldTitle( mpWindowImpl->maText );
3052
9.21k
    mpWindowImpl->maText = rStr;
3053
3054
9.21k
    if ( mpWindowImpl->mpBorderWindow )
3055
4.60k
        mpWindowImpl->mpBorderWindow->SetText( rStr );
3056
4.60k
    else if ( mpWindowImpl->mbFrame )
3057
4.60k
        mpWindowImpl->mpFrame->SetTitle( rStr );
3058
3059
9.21k
    CallEventListeners( VclEventId::WindowFrameTitleChanged, &oldTitle );
3060
3061
    // #107247# needed for accessibility
3062
    // The VclEventId::WindowFrameTitleChanged is (mis)used to notify accessible name changes.
3063
    // Therefore a window, which is labeled by this window, must also notify an accessible
3064
    // name change.
3065
9.21k
    if ( IsReallyVisible() )
3066
0
    {
3067
0
        vcl::Window* pWindow = GetAccessibleRelationLabelFor();
3068
0
        if ( pWindow && pWindow != this )
3069
0
            pWindow->CallEventListeners( VclEventId::WindowFrameTitleChanged, &oldTitle );
3070
0
    }
3071
3072
9.21k
    CompatStateChanged( StateChangedType::Text );
3073
9.21k
}
3074
3075
OUString Window::GetText() const
3076
0
{
3077
3078
0
    return mpWindowImpl->maText;
3079
0
}
3080
3081
OUString Window::GetDisplayText() const
3082
0
{
3083
3084
0
    return GetText();
3085
0
}
3086
3087
const Wallpaper& Window::GetDisplayBackground() const
3088
0
{
3089
    // FIXME: fix issue 52349, need to fix this really in
3090
    // all NWF enabled controls
3091
0
    const ToolBox* pTB = dynamic_cast<const ToolBox*>(this);
3092
0
    if( pTB && IsNativeWidgetEnabled() )
3093
0
        return pTB->ImplGetToolBoxPrivateData()->maDisplayBackground;
3094
3095
0
    if( !IsBackground() )
3096
0
    {
3097
0
        if( mpWindowImpl->mpParent )
3098
0
            return mpWindowImpl->mpParent->GetDisplayBackground();
3099
0
    }
3100
3101
0
    const Wallpaper& rBack = GetBackground();
3102
0
    if( ! rBack.IsBitmap() &&
3103
0
        ! rBack.IsGradient() &&
3104
0
        rBack.GetColor()== COL_TRANSPARENT &&
3105
0
        mpWindowImpl->mpParent )
3106
0
            return mpWindowImpl->mpParent->GetDisplayBackground();
3107
0
    return rBack;
3108
0
}
3109
3110
const OUString& Window::GetHelpText() const
3111
0
{
3112
0
    const OUString& rStrHelpId(GetHelpId());
3113
0
    const bool bStrHelpId = !rStrHelpId.isEmpty();
3114
3115
0
    if (mpWindowImpl->mbHelpTextDynamic && bStrHelpId)
3116
0
    {
3117
0
        static const char* pEnv = getenv( "HELP_DEBUG" );
3118
0
        if( pEnv && *pEnv )
3119
0
        {
3120
0
            mpWindowImpl->maHelpText = mpWindowImpl->maHelpText + "\n------------------\n" + rStrHelpId;
3121
0
        }
3122
0
        mpWindowImpl->mbHelpTextDynamic = false;
3123
0
    }
3124
3125
    //Fallback to Window::GetAccessibleDescription without reentry to GetHelpText()
3126
0
    if (mpWindowImpl->maHelpText.isEmpty() && mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleDescription)
3127
0
        return *mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
3128
0
    return mpWindowImpl->maHelpText;
3129
0
}
3130
3131
void Window::SetWindowPeer( Reference< css::awt::XVclWindowPeer > const & xPeer, VCLXWindow* pVCLXWindow  )
3132
132k
{
3133
132k
    if (!mpWindowImpl || mpWindowImpl->mbInDispose)
3134
9.16k
        return;
3135
3136
    // be safe against re-entrance: first clear the old ref, then assign the new one
3137
123k
    if (mpWindowImpl->mxWindowPeer)
3138
45.7k
    {
3139
        // first, disconnect the peer from ourself, otherwise disposing it, will dispose us
3140
45.7k
        UnoWrapperBase* pWrapper = UnoWrapperBase::GetUnoWrapper();
3141
45.7k
        SAL_WARN_IF( !pWrapper, "vcl.window", "SetComponentInterface: No Wrapper!" );
3142
45.7k
        if ( pWrapper )
3143
45.7k
            pWrapper->SetWindowInterface( nullptr, mpWindowImpl->mxWindowPeer );
3144
45.7k
        mpWindowImpl->mxWindowPeer->dispose();
3145
45.7k
        mpWindowImpl->mxWindowPeer.clear();
3146
45.7k
    }
3147
123k
    mpWindowImpl->mxWindowPeer = xPeer;
3148
3149
123k
    mpWindowImpl->mpVCLXWindow = pVCLXWindow;
3150
123k
}
3151
3152
Reference< css::awt::XVclWindowPeer > Window::GetComponentInterface( bool bCreate )
3153
220k
{
3154
220k
    if ( !mpWindowImpl->mxWindowPeer.is() && bCreate )
3155
69.1k
    {
3156
69.1k
        UnoWrapperBase* pWrapper = UnoWrapperBase::GetUnoWrapper();
3157
69.1k
        if ( pWrapper )
3158
69.1k
            mpWindowImpl->mxWindowPeer = pWrapper->GetWindowInterface( this );
3159
69.1k
    }
3160
220k
    return mpWindowImpl->mxWindowPeer;
3161
220k
}
3162
3163
void Window::SetComponentInterface( Reference< css::awt::XVclWindowPeer > const & xIFace )
3164
8.31k
{
3165
8.31k
    UnoWrapperBase* pWrapper = UnoWrapperBase::GetUnoWrapper();
3166
8.31k
    SAL_WARN_IF( !pWrapper, "vcl.window", "SetComponentInterface: No Wrapper!" );
3167
8.31k
    if ( pWrapper )
3168
8.31k
        pWrapper->SetWindowInterface( this, xIFace );
3169
8.31k
}
3170
3171
typedef std::map<vcl::LOKWindowId, VclPtr<vcl::Window>> LOKWindowsMap;
3172
3173
namespace {
3174
3175
LOKWindowsMap& GetLOKWindowsMap()
3176
0
{
3177
    // Map to remember the LOKWindowId <-> Window binding.
3178
0
    static LOKWindowsMap s_aLOKWindowsMap;
3179
3180
0
    return s_aLOKWindowsMap;
3181
0
}
3182
3183
}
3184
3185
void Window::SetLOKNotifier(const vcl::ILibreOfficeKitNotifier* pNotifier, bool bParent)
3186
0
{
3187
    // don't allow setting this twice
3188
0
    assert(mpWindowImpl->mpLOKNotifier == nullptr);
3189
0
    assert(pNotifier);
3190
    // never use this in the desktop case
3191
0
    assert(comphelper::LibreOfficeKit::isActive());
3192
3193
0
    if (!bParent)
3194
0
    {
3195
        // Counter to be able to have unique id's for each window.
3196
0
        static vcl::LOKWindowId sLastLOKWindowId = 1;
3197
3198
        // assign the LOK window id
3199
0
        assert(mpWindowImpl->mnLOKWindowId == 0);
3200
0
        mpWindowImpl->mnLOKWindowId = sLastLOKWindowId++;
3201
0
        GetLOKWindowsMap().emplace(mpWindowImpl->mnLOKWindowId, this);
3202
0
    }
3203
3204
0
    mpWindowImpl->mpLOKNotifier = pNotifier;
3205
0
}
3206
3207
VclPtr<Window> Window::FindLOKWindow(vcl::LOKWindowId nWindowId)
3208
0
{
3209
0
    const auto it = GetLOKWindowsMap().find(nWindowId);
3210
0
    if (it != GetLOKWindowsMap().end())
3211
0
        return it->second;
3212
3213
0
    return VclPtr<Window>();
3214
0
}
3215
3216
bool Window::IsLOKWindowsEmpty()
3217
0
{
3218
0
    return GetLOKWindowsMap().empty();
3219
0
}
3220
3221
void Window::ReleaseLOKNotifier()
3222
0
{
3223
    // unregister the LOK window binding
3224
0
    if (mpWindowImpl->mnLOKWindowId > 0)
3225
0
        GetLOKWindowsMap().erase(mpWindowImpl->mnLOKWindowId);
3226
3227
0
    mpWindowImpl->mpLOKNotifier = nullptr;
3228
0
    mpWindowImpl->mnLOKWindowId = 0;
3229
0
}
3230
3231
ILibreOfficeKitNotifier::~ILibreOfficeKitNotifier()
3232
4.57k
{
3233
4.57k
    if (!comphelper::LibreOfficeKit::isActive())
3234
4.57k
    {
3235
4.57k
        return;
3236
4.57k
    }
3237
3238
0
    for (auto it = GetLOKWindowsMap().begin(); it != GetLOKWindowsMap().end();)
3239
0
    {
3240
0
        WindowImpl* pWindowImpl = it->second->ImplGetWindowImpl();
3241
0
        if (pWindowImpl && pWindowImpl->mpLOKNotifier == this)
3242
0
        {
3243
0
            pWindowImpl->mpLOKNotifier = nullptr;
3244
0
            pWindowImpl->mnLOKWindowId = 0;
3245
0
            it = GetLOKWindowsMap().erase(it);
3246
0
            continue;
3247
0
        }
3248
3249
0
        ++it;
3250
0
    }
3251
0
}
3252
3253
const vcl::ILibreOfficeKitNotifier* Window::GetLOKNotifier() const
3254
269k
{
3255
269k
    return mpWindowImpl ? mpWindowImpl->mpLOKNotifier : nullptr;
3256
269k
}
3257
3258
vcl::LOKWindowId Window::GetLOKWindowId() const
3259
0
{
3260
0
    return mpWindowImpl ? mpWindowImpl->mnLOKWindowId : 0;
3261
0
}
3262
3263
VclPtr<vcl::Window> Window::GetParentWithLOKNotifier()
3264
73.2k
{
3265
73.2k
    VclPtr<vcl::Window> pWindow(this);
3266
3267
324k
    while (pWindow && !pWindow->GetLOKNotifier())
3268
251k
        pWindow = pWindow->GetParent();
3269
3270
73.2k
    return pWindow;
3271
73.2k
}
3272
3273
namespace
3274
{
3275
3276
std::string_view windowTypeName(WindowType nWindowType)
3277
0
{
3278
0
    switch (nWindowType)
3279
0
    {
3280
0
        case WindowType::NONE:                      return "none";
3281
0
        case WindowType::MESSBOX:                   return "messagebox";
3282
0
        case WindowType::INFOBOX:                   return "infobox";
3283
0
        case WindowType::WARNINGBOX:                return "warningbox";
3284
0
        case WindowType::ERRORBOX:                  return "errorbox";
3285
0
        case WindowType::QUERYBOX:                  return "querybox";
3286
0
        case WindowType::WINDOW:                    return "window";
3287
0
        case WindowType::WORKWINDOW:                return "workwindow";
3288
0
        case WindowType::CONTAINER:                 return "container";
3289
0
        case WindowType::FLOATINGWINDOW:            return "floatingwindow";
3290
0
        case WindowType::DIALOG:                    return "dialog";
3291
0
        case WindowType::MODELESSDIALOG:            return "modelessdialog";
3292
0
        case WindowType::CONTROL:                   return "control";
3293
0
        case WindowType::PUSHBUTTON:                return "pushbutton";
3294
0
        case WindowType::OKBUTTON:                  return "okbutton";
3295
0
        case WindowType::CANCELBUTTON:              return "cancelbutton";
3296
0
        case WindowType::HELPBUTTON:                return "helpbutton";
3297
0
        case WindowType::IMAGEBUTTON:               return "imagebutton";
3298
0
        case WindowType::MENUBUTTON:                return "menubutton";
3299
0
        case WindowType::MOREBUTTON:                return "morebutton";
3300
0
        case WindowType::SPINBUTTON:                return "spinbutton";
3301
0
        case WindowType::RADIOBUTTON:               return "radiobutton";
3302
0
        case WindowType::CHECKBOX:                  return "checkbox";
3303
0
        case WindowType::TRISTATEBOX:               return "tristatebox";
3304
0
        case WindowType::EDIT:                      return "edit";
3305
0
        case WindowType::MULTILINEEDIT:             return "multilineedit";
3306
0
        case WindowType::COMBOBOX:                  return "combobox";
3307
0
        case WindowType::LISTBOX:                   return "listbox";
3308
0
        case WindowType::MULTILISTBOX:              return "multilistbox";
3309
0
        case WindowType::FIXEDTEXT:                 return "fixedtext";
3310
0
        case WindowType::FIXEDLINE:                 return "fixedline";
3311
0
        case WindowType::FIXEDBITMAP:               return "fixedbitmap";
3312
0
        case WindowType::FIXEDIMAGE:                return "fixedimage";
3313
0
        case WindowType::GROUPBOX:                  return "groupbox";
3314
0
        case WindowType::SCROLLBAR:                 return "scrollbar";
3315
0
        case WindowType::SCROLLBARBOX:              return "scrollbarbox";
3316
0
        case WindowType::SPLITTER:                  return "splitter";
3317
0
        case WindowType::SPLITWINDOW:               return "splitwindow";
3318
0
        case WindowType::SPINFIELD:                 return "spinfield";
3319
0
        case WindowType::PATTERNFIELD:              return "patternfield";
3320
0
        case WindowType::METRICFIELD:               return "metricfield";
3321
0
        case WindowType::FORMATTEDFIELD:            return "formattedfield";
3322
0
        case WindowType::CURRENCYFIELD:             return "currencyfield";
3323
0
        case WindowType::DATEFIELD:                 return "datefield";
3324
0
        case WindowType::TIMEFIELD:                 return "timefield";
3325
0
        case WindowType::PATTERNBOX:                return "patternbox";
3326
0
        case WindowType::NUMERICBOX:                return "numericbox";
3327
0
        case WindowType::METRICBOX:                 return "metricbox";
3328
0
        case WindowType::CURRENCYBOX:               return "currencybox";
3329
0
        case WindowType::DATEBOX:                   return "datebox";
3330
0
        case WindowType::TIMEBOX:                   return "timebox";
3331
0
        case WindowType::LONGCURRENCYBOX:           return "longcurrencybox";
3332
0
        case WindowType::SCROLLWINDOW:              return "scrollwindow";
3333
0
        case WindowType::TOOLBOX:                   return "toolbox";
3334
0
        case WindowType::DOCKINGWINDOW:             return "dockingwindow";
3335
0
        case WindowType::STATUSBAR:                 return "statusbar";
3336
0
        case WindowType::TABPAGE:                   return "tabpage";
3337
0
        case WindowType::TABCONTROL:                return "tabcontrol";
3338
0
        case WindowType::TABDIALOG:                 return "tabdialog";
3339
0
        case WindowType::BORDERWINDOW:              return "borderwindow";
3340
0
        case WindowType::BUTTONDIALOG:              return "buttondialog";
3341
0
        case WindowType::SYSTEMCHILDWINDOW:         return "systemchildwindow";
3342
0
        case WindowType::SLIDER:                    return "slider";
3343
0
        case WindowType::MENUBARWINDOW:             return "menubarwindow";
3344
0
        case WindowType::TREELISTBOX:               return "treelistbox";
3345
0
        case WindowType::HELPTEXTWINDOW:            return "helptextwindow";
3346
0
        case WindowType::INTROWINDOW:               return "introwindow";
3347
0
        case WindowType::LISTBOXWINDOW:             return "listboxwindow";
3348
0
        case WindowType::DOCKINGAREA:               return "dockingarea";
3349
0
        case WindowType::RULER:                     return "ruler";
3350
0
        case WindowType::HEADERBAR:                 return "headerbar";
3351
0
        case WindowType::VERTICALTABCONTROL:        return "verticaltabcontrol";
3352
0
        case WindowType::PROGRESSBAR:               return "progressbar";
3353
0
        case WindowType::LINK_BUTTON:               return "linkbutton";
3354
3355
        // nothing to do here, but for completeness
3356
0
        case WindowType::TOOLKIT_FRAMEWINDOW:       return "toolkit_framewindow";
3357
0
        case WindowType::TOOLKIT_SYSTEMCHILDWINDOW: return "toolkit_systemchildwindow";
3358
0
    }
3359
3360
0
    return "none";
3361
0
}
3362
3363
}
3364
3365
std::string_view Window::GetTypeName() const
3366
0
{
3367
0
    return windowTypeName(GetType());
3368
0
}
3369
void Window::DumpAsPropertyTree(tools::JsonWriter& rJsonWriter)
3370
0
{
3371
0
    if (!mpWindowImpl)
3372
0
        return;
3373
3374
0
    rJsonWriter.put("id", get_id());  // TODO could be missing - sort out
3375
0
    rJsonWriter.put("type", GetTypeName());
3376
0
    rJsonWriter.put("text", GetText());
3377
0
    rJsonWriter.put("enabled", IsEnabled());
3378
0
    rJsonWriter.put("canFocus", bool(GetStyle() & WB_TABSTOP));
3379
0
    if (!IsVisible())
3380
0
        rJsonWriter.put("visible", false);
3381
3382
0
    if (vcl::Window* pChild = mpWindowImpl->mpFirstChild)
3383
0
    {
3384
0
        auto childrenNode = rJsonWriter.startArray("children");
3385
0
        while (pChild)
3386
0
        {
3387
0
            {
3388
0
                auto childNode = rJsonWriter.startStruct();
3389
0
                pChild->DumpAsPropertyTree(rJsonWriter);
3390
0
                sal_Int32 nLeft = pChild->get_grid_left_attach();
3391
0
                sal_Int32 nTop = pChild->get_grid_top_attach();
3392
0
                if (nLeft != -1 && nTop != -1)
3393
0
                {
3394
0
                    rJsonWriter.put("left", nLeft);
3395
0
                    rJsonWriter.put("top", nTop);
3396
0
                }
3397
3398
0
                sal_Int32 nWidth = pChild->get_grid_width();
3399
0
                if (nWidth > 1)
3400
0
                    rJsonWriter.put("width", nWidth);
3401
0
                sal_Int32 nHeight = pChild->get_grid_height();
3402
0
                if (nHeight > 1)
3403
0
                    rJsonWriter.put("height", nHeight);
3404
0
            }
3405
0
            pChild = pChild->mpWindowImpl->mpNext;
3406
0
        }
3407
0
    }
3408
3409
0
    vcl::Window* pAccLabelFor = getAccessibleRelationLabelFor();
3410
0
    if (pAccLabelFor)
3411
0
        rJsonWriter.put("labelFor", pAccLabelFor->get_id());
3412
3413
0
    vcl::Window* pAccLabelledBy = GetAccessibleRelationLabeledBy();
3414
0
    if (pAccLabelledBy)
3415
0
        rJsonWriter.put("labelledBy", pAccLabelledBy->get_id());
3416
3417
0
    if(!pAccLabelFor && !pAccLabelledBy)
3418
0
    {
3419
0
        OUString sAccName = GetAccessibleName();
3420
0
        OUString sAccDesc = GetAccessibleDescription();
3421
3422
0
        if (!sAccName.isEmpty() || !sAccDesc.isEmpty())
3423
0
        {
3424
0
            auto aAria = rJsonWriter.startNode("aria");
3425
0
            if (!sAccName.isEmpty())
3426
0
                rJsonWriter.put("label", sAccName);
3427
0
            if (!sAccDesc.isEmpty())
3428
0
                rJsonWriter.put("description", sAccDesc);
3429
0
        }
3430
0
    }
3431
3432
0
    mpWindowImpl->maDumpAsPropertyTreeHdl.Call(rJsonWriter);
3433
0
}
3434
3435
void Window::ImplCallDeactivateListeners( vcl::Window *pNew )
3436
0
{
3437
    // no deactivation if the newly activated window is my child
3438
0
    if ( !pNew || !ImplIsChild( pNew ) )
3439
0
    {
3440
0
        VclPtr<vcl::Window> xWindow(this);
3441
0
        CallEventListeners( VclEventId::WindowDeactivate, pNew );
3442
0
        if( !xWindow->mpWindowImpl )
3443
0
            return;
3444
3445
        // #100759#, avoid walking the wrong frame's hierarchy
3446
        //           eg, undocked docking windows (ImplDockFloatWin)
3447
0
        if ( ImplGetParent() && ImplGetParent()->mpWindowImpl &&
3448
0
             mpWindowImpl->mpFrameWindow == ImplGetParent()->mpWindowImpl->mpFrameWindow )
3449
0
            ImplGetParent()->ImplCallDeactivateListeners( pNew );
3450
0
    }
3451
0
}
3452
3453
void Window::ImplCallActivateListeners( vcl::Window *pOld )
3454
0
{
3455
    // no activation if the old active window is my child
3456
0
    if ( pOld && ImplIsChild( pOld ))
3457
0
        return;
3458
3459
0
    VclPtr<vcl::Window> xWindow(this);
3460
0
    CallEventListeners( VclEventId::WindowActivate, pOld );
3461
0
    if( !xWindow->mpWindowImpl )
3462
0
        return;
3463
3464
0
    if ( ImplGetParent() )
3465
0
        ImplGetParent()->ImplCallActivateListeners( pOld );
3466
0
    else if( (mpWindowImpl->mnStyle & WB_INTROWIN) == 0 )
3467
0
    {
3468
        // top level frame reached: store hint for DefModalDialogParent
3469
0
        ImplGetSVData()->maFrameData.mpActiveApplicationFrame = mpWindowImpl->mpFrameWindow;
3470
0
    }
3471
0
}
3472
3473
void Window::SetClipboard(Reference<XClipboard> const & xClipboard)
3474
0
{
3475
0
    if (mpWindowImpl->mpFrameData)
3476
0
        mpWindowImpl->mpFrameData->mxClipboard = xClipboard;
3477
0
}
3478
3479
Reference< XClipboard > Window::GetClipboard()
3480
4.57k
{
3481
4.57k
    if (!mpWindowImpl->mpFrameData)
3482
0
        return static_cast<XClipboard*>(nullptr);
3483
4.57k
    if (!mpWindowImpl->mpFrameData->mxClipboard.is())
3484
4.57k
        mpWindowImpl->mpFrameData->mxClipboard = GetSystemClipboard();
3485
4.57k
    return mpWindowImpl->mpFrameData->mxClipboard;
3486
4.57k
}
3487
3488
void Window::RecordLayoutData( vcl::ControlLayoutData* pLayout, const tools::Rectangle& rRect )
3489
0
{
3490
0
    assert(GetOutDev()->mpOutDevData);
3491
0
    GetOutDev()->mpOutDevData->mpRecordLayout = pLayout;
3492
0
    GetOutDev()->mpOutDevData->maRecordRect = rRect;
3493
0
    Paint(*GetOutDev(), rRect);
3494
0
    GetOutDev()->mpOutDevData->mpRecordLayout = nullptr;
3495
0
}
3496
3497
void Window::DrawSelectionBackground( const tools::Rectangle& rRect,
3498
                                      sal_uInt16 highlight,
3499
                                      bool bChecked,
3500
                                      bool bDrawBorder
3501
                                      )
3502
0
{
3503
0
    if( rRect.IsEmpty() )
3504
0
        return;
3505
3506
0
    const StyleSettings& rStyles = GetSettings().GetStyleSettings();
3507
3508
    // colors used for item highlighting
3509
0
    Color aSelectionBorderCol( rStyles.GetHighlightColor() );
3510
0
    Color aSelectionFillCol( aSelectionBorderCol );
3511
3512
0
    bool bDark = rStyles.GetFaceColor().IsDark();
3513
0
    bool bBright = ( rStyles.GetFaceColor() == COL_WHITE );
3514
3515
0
    int c1 = aSelectionBorderCol.GetLuminance();
3516
0
    int c2 = GetBackgroundColor().GetLuminance();
3517
3518
0
    if( !bDark && !bBright && abs( c2-c1 ) < 75 )
3519
0
    {
3520
        // contrast too low
3521
0
        sal_uInt16 h,s,b;
3522
0
        aSelectionFillCol.RGBtoHSB( h, s, b );
3523
0
        if( b > 50 )    b -= 40;
3524
0
        else            b += 40;
3525
0
        aSelectionFillCol = Color::HSBtoRGB( h, s, b );
3526
0
        aSelectionBorderCol = aSelectionFillCol;
3527
0
    }
3528
3529
0
    tools::Rectangle aRect( rRect );
3530
0
    auto popIt = GetOutDev()->ScopedPush(vcl::PushFlags::FILLCOLOR | vcl::PushFlags::LINECOLOR);
3531
3532
0
    if( bDrawBorder )
3533
0
        GetOutDev()->SetLineColor( bDark ? COL_WHITE : ( bBright ? COL_BLACK : aSelectionBorderCol ) );
3534
0
    else
3535
0
        GetOutDev()->SetLineColor();
3536
3537
0
    sal_uInt16 nPercent = 0;
3538
0
    if( !highlight )
3539
0
    {
3540
0
        if( bDark )
3541
0
            aSelectionFillCol = COL_BLACK;
3542
0
        else
3543
0
            nPercent = 80;  // just checked (light)
3544
0
    }
3545
0
    else
3546
0
    {
3547
0
        if( bChecked && highlight == 2 )
3548
0
        {
3549
0
            if( bDark )
3550
0
                aSelectionFillCol = COL_LIGHTGRAY;
3551
0
            else if ( bBright )
3552
0
            {
3553
0
                aSelectionFillCol = COL_BLACK;
3554
0
                GetOutDev()->SetLineColor( COL_BLACK );
3555
0
                nPercent = 0;
3556
0
            }
3557
0
            else
3558
0
                nPercent = 20;          // selected, pressed or checked ( very dark )
3559
0
        }
3560
0
        else if( bChecked || highlight == 1 )
3561
0
        {
3562
0
            if( bDark )
3563
0
                aSelectionFillCol = COL_GRAY;
3564
0
            else if ( bBright )
3565
0
            {
3566
0
                aSelectionFillCol = COL_BLACK;
3567
0
                GetOutDev()->SetLineColor( COL_BLACK );
3568
0
                nPercent = 0;
3569
0
            }
3570
0
            else
3571
0
                nPercent = 35;          // selected, pressed or checked ( very dark )
3572
0
        }
3573
0
        else
3574
0
        {
3575
0
            if( bDark )
3576
0
                aSelectionFillCol = COL_LIGHTGRAY;
3577
0
            else if ( bBright )
3578
0
            {
3579
0
                aSelectionFillCol = COL_BLACK;
3580
0
                GetOutDev()->SetLineColor( COL_BLACK );
3581
0
                if( highlight == 3 )
3582
0
                    nPercent = 80;
3583
0
                else
3584
0
                    nPercent = 0;
3585
0
            }
3586
0
            else
3587
0
                nPercent = 70;          // selected ( dark )
3588
0
        }
3589
0
    }
3590
3591
0
    GetOutDev()->SetFillColor( aSelectionFillCol );
3592
3593
0
    if( bDark )
3594
0
    {
3595
0
        GetOutDev()->DrawRect( aRect );
3596
0
    }
3597
0
    else
3598
0
    {
3599
0
        tools::Polygon aPoly( aRect );
3600
0
        tools::PolyPolygon aPolyPoly( aPoly );
3601
0
        GetOutDev()->DrawTransparent( aPolyPoly, nPercent );
3602
0
    }
3603
0
}
3604
3605
bool Window::IsScrollable() const
3606
0
{
3607
    // check for scrollbars
3608
0
    VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
3609
0
    while( pChild )
3610
0
    {
3611
0
        if( pChild->GetType() == WindowType::SCROLLBAR )
3612
0
            return true;
3613
0
        else
3614
0
            pChild = pChild->mpWindowImpl->mpNext;
3615
0
    }
3616
0
    return false;
3617
0
}
3618
3619
void Window::ImplMirrorFramePos( Point &pt ) const
3620
0
{
3621
0
    pt.setX(mpWindowImpl->mpFrame->GetWidth() - 1 - pt.X());
3622
0
}
3623
3624
// frame based modal counter (dialogs are not modal to the whole application anymore)
3625
bool Window::IsInModalMode() const
3626
9.15k
{
3627
9.15k
    return (mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mnModalMode != 0);
3628
9.15k
}
3629
3630
void Window::IncModalCount()
3631
0
{
3632
0
    vcl::Window* pFrameWindow = mpWindowImpl->mpFrameWindow;
3633
0
    vcl::Window* pParent = pFrameWindow;
3634
0
    while( pFrameWindow )
3635
0
    {
3636
0
        pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode++;
3637
0
        while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow )
3638
0
        {
3639
0
            pParent = pParent->GetParent();
3640
0
        }
3641
0
        pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow.get() : nullptr;
3642
0
    }
3643
0
}
3644
void Window::DecModalCount()
3645
0
{
3646
0
    vcl::Window* pFrameWindow = mpWindowImpl->mpFrameWindow;
3647
0
    vcl::Window* pParent = pFrameWindow;
3648
0
    while( pFrameWindow )
3649
0
    {
3650
0
        pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode--;
3651
0
        while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow )
3652
0
        {
3653
0
            pParent = pParent->GetParent();
3654
0
        }
3655
0
        pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow.get() : nullptr;
3656
0
    }
3657
0
}
3658
3659
void Window::ImplIsInTaskPaneList( bool mbIsInTaskList )
3660
0
{
3661
0
    mpWindowImpl->mbIsInTaskPaneList = mbIsInTaskList;
3662
0
}
3663
3664
void Window::ImplNotifyIconifiedState( bool bIconified )
3665
0
{
3666
0
    mpWindowImpl->mpFrameWindow->CallEventListeners( bIconified ? VclEventId::WindowMinimize : VclEventId::WindowNormalize );
3667
    // #109206# notify client window as well to have toolkit topwindow listeners notified
3668
0
    if( mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow && mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow )
3669
0
        mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow->CallEventListeners( bIconified ? VclEventId::WindowMinimize : VclEventId::WindowNormalize );
3670
0
}
3671
3672
bool Window::HasActiveChildFrame() const
3673
0
{
3674
0
    bool bRet = false;
3675
0
    vcl::Window *pFrameWin = ImplGetSVData()->maFrameData.mpFirstFrame;
3676
0
    while( pFrameWin )
3677
0
    {
3678
0
        if( pFrameWin != mpWindowImpl->mpFrameWindow )
3679
0
        {
3680
0
            bool bDecorated = false;
3681
0
            VclPtr< vcl::Window > pChildFrame = pFrameWin->ImplGetWindow();
3682
            // #i15285# unfortunately WB_MOVEABLE is the same as WB_TABSTOP which can
3683
            // be removed for ToolBoxes to influence the keyboard accessibility
3684
            // thus WB_MOVEABLE is no indicator for decoration anymore
3685
            // but FloatingWindows carry this information in their TitleType...
3686
            // TODO: avoid duplicate WinBits !!!
3687
0
            if( pChildFrame && pChildFrame->ImplIsFloatingWindow() )
3688
0
                bDecorated = static_cast<FloatingWindow*>(pChildFrame.get())->GetTitleType() != FloatWinTitleType::NONE;
3689
0
            if( bDecorated || (pFrameWin->mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE) ) )
3690
0
                if( pChildFrame && pChildFrame->IsVisible() && pChildFrame->IsActive() )
3691
0
                {
3692
0
                    if( ImplIsChild( pChildFrame, true ) )
3693
0
                    {
3694
0
                        bRet = true;
3695
0
                        break;
3696
0
                    }
3697
0
                }
3698
0
        }
3699
0
        pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame;
3700
0
    }
3701
0
    return bRet;
3702
0
}
3703
3704
LanguageType Window::GetInputLanguage() const
3705
0
{
3706
0
    return mpWindowImpl->mpFrame->GetInputLanguage();
3707
0
}
3708
3709
void Window::EnableNativeWidget( bool bEnable )
3710
0
{
3711
0
    static const char* pNoNWF = getenv( "SAL_NO_NWF" );
3712
0
    if( pNoNWF && *pNoNWF )
3713
0
        bEnable = false;
3714
3715
0
    if( bEnable != ImplGetWinData()->mbEnableNativeWidget )
3716
0
    {
3717
0
        ImplGetWinData()->mbEnableNativeWidget = bEnable;
3718
3719
        // send datachanged event to allow for internal changes required for NWF
3720
        // like clipmode, transparency, etc.
3721
0
        DataChangedEvent aDCEvt( DataChangedEventType::SETTINGS, &*GetOutDev()->moSettings, AllSettingsFlags::STYLE );
3722
0
        CompatDataChanged( aDCEvt );
3723
3724
        // sometimes the borderwindow is queried, so keep it in sync
3725
0
        if( mpWindowImpl->mpBorderWindow )
3726
0
            mpWindowImpl->mpBorderWindow->ImplGetWinData()->mbEnableNativeWidget = bEnable;
3727
0
    }
3728
3729
    // push down, useful for compound controls
3730
0
    VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
3731
0
    while( pChild )
3732
0
    {
3733
0
        pChild->EnableNativeWidget( bEnable );
3734
0
        pChild = pChild->mpWindowImpl->mpNext;
3735
0
    }
3736
0
}
3737
3738
bool Window::IsNativeWidgetEnabled() const
3739
34.8k
{
3740
34.8k
    return mpWindowImpl && ImplGetWinData()->mbEnableNativeWidget;
3741
34.8k
}
3742
3743
Reference< css::rendering::XCanvas > WindowOutputDevice::ImplGetCanvas( bool bSpriteCanvas ) const
3744
6
{
3745
    // Feed any with operating system's window handle
3746
3747
    // common: first any is VCL pointer to window (for VCL canvas)
3748
6
    Sequence< Any > aArg{
3749
6
        Any(reinterpret_cast<sal_Int64>(this)),
3750
6
        Any(css::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight )),
3751
6
        Any(mxOwnerWindow->mpWindowImpl->mbAlwaysOnTop),
3752
6
        Any(Reference< css::awt::XWindow >(
3753
6
                             mxOwnerWindow->GetComponentInterface(),
3754
6
                             UNO_QUERY )),
3755
6
        GetSystemGfxDataAny()
3756
6
    };
3757
3758
6
    const Reference< XComponentContext >& xContext = comphelper::getProcessComponentContext();
3759
3760
    // Create canvas instance with window handle
3761
3762
6
    static tools::DeleteUnoReferenceOnDeinit<XMultiComponentFactory> xStaticCanvasFactory(
3763
6
        css::rendering::CanvasFactory::create( xContext ) );
3764
6
    Reference<XMultiComponentFactory> xCanvasFactory(xStaticCanvasFactory.get());
3765
6
    Reference< css::rendering::XCanvas > xCanvas;
3766
3767
6
    if(xCanvasFactory.is())
3768
6
    {
3769
#ifdef _WIN32
3770
        // see #140456# - if we're running on a multiscreen setup,
3771
        // request special, multi-screen safe sprite canvas
3772
        // implementation (not DX5 canvas, as it cannot cope with
3773
        // surfaces spanning multiple displays). Note: canvas
3774
        // (without sprite) stays the same)
3775
        const sal_uInt32 nDisplay = static_cast< WinSalFrame* >( mxOwnerWindow->mpWindowImpl->mpFrame )->mnDisplay;
3776
        if( nDisplay >= Application::GetScreenCount() )
3777
        {
3778
            xCanvas.set( xCanvasFactory->createInstanceWithArgumentsAndContext(
3779
                                 bSpriteCanvas ?
3780
                                 OUString( "com.sun.star.rendering.SpriteCanvas.MultiScreen" ) :
3781
                                 OUString( "com.sun.star.rendering.Canvas.MultiScreen" ),
3782
                                 aArg,
3783
                                 xContext ),
3784
                             UNO_QUERY );
3785
3786
        }
3787
        else
3788
#endif
3789
6
        {
3790
6
            xCanvas.set( xCanvasFactory->createInstanceWithArgumentsAndContext(
3791
6
                             bSpriteCanvas ?
3792
0
                             u"com.sun.star.rendering.SpriteCanvas"_ustr :
3793
6
                             u"com.sun.star.rendering.Canvas"_ustr,
3794
6
                             aArg,
3795
6
                             xContext ),
3796
6
                         UNO_QUERY );
3797
3798
6
        }
3799
6
    }
3800
3801
    // no factory??? Empty reference, then.
3802
6
    return xCanvas;
3803
6
}
3804
3805
OUString Window::GetSurroundingText() const
3806
0
{
3807
0
  return OUString();
3808
0
}
3809
3810
Selection Window::GetSurroundingTextSelection() const
3811
0
{
3812
0
  return Selection( 0, 0 );
3813
0
}
3814
3815
namespace
3816
{
3817
    using namespace com::sun::star;
3818
3819
    uno::Reference<accessibility::XAccessibleEditableText>
3820
    lcl_FindFocusedEditableText(uno::Reference<accessibility::XAccessibleContext> const& xContext)
3821
0
    {
3822
0
        if (!xContext.is())
3823
0
            return uno::Reference<accessibility::XAccessibleEditableText>();
3824
3825
0
        sal_Int64 nState = xContext->getAccessibleStateSet();
3826
0
        if (nState & accessibility::AccessibleStateType::FOCUSED)
3827
0
        {
3828
0
            uno::Reference<accessibility::XAccessibleEditableText> xText(xContext, uno::UNO_QUERY);
3829
0
            if (xText.is())
3830
0
                return xText;
3831
0
            if (nState & accessibility::AccessibleStateType::MANAGES_DESCENDANTS)
3832
0
                return uno::Reference<accessibility::XAccessibleEditableText>();
3833
0
        }
3834
3835
0
        bool bSafeToIterate = true;
3836
0
        sal_Int64 nCount = xContext->getAccessibleChildCount();
3837
0
        if (nCount < 0 || nCount > SAL_MAX_UINT16 /* slow enough for anyone */)
3838
0
            bSafeToIterate = false;
3839
0
        if (!bSafeToIterate)
3840
0
            return uno::Reference<accessibility::XAccessibleEditableText>();
3841
3842
0
        for (sal_Int64 i = 0; i < xContext->getAccessibleChildCount(); ++i)
3843
0
        {
3844
0
            uno::Reference<accessibility::XAccessible> xChild = xContext->getAccessibleChild(i);
3845
0
            if (!xChild.is())
3846
0
                continue;
3847
0
            uno::Reference<accessibility::XAccessibleContext> xChildContext
3848
0
                = xChild->getAccessibleContext();
3849
0
            if (!xChildContext.is())
3850
0
                continue;
3851
0
            uno::Reference<accessibility::XAccessibleEditableText> xText
3852
0
                = lcl_FindFocusedEditableText(xChildContext);
3853
0
            if (xText.is())
3854
0
                return xText;
3855
0
        }
3856
0
        return uno::Reference<accessibility::XAccessibleEditableText>();
3857
0
    }
3858
3859
    uno::Reference<accessibility::XAccessibleEditableText> lcl_GetxText(vcl::Window *pFocusWin)
3860
0
    {
3861
0
        uno::Reference<accessibility::XAccessibleEditableText> xText;
3862
0
        try
3863
0
        {
3864
0
            rtl::Reference<comphelper::OAccessible> pAccessible = pFocusWin->GetAccessible();
3865
0
            if (pAccessible.is())
3866
0
                xText = lcl_FindFocusedEditableText(pAccessible);
3867
0
        }
3868
0
        catch(const uno::Exception&)
3869
0
        {
3870
0
            TOOLS_WARN_EXCEPTION( "vcl.gtk3", "Exception in getting input method surrounding text");
3871
0
        }
3872
0
        return xText;
3873
0
    }
3874
}
3875
3876
// this is a rubbish implementation using a11y, ideally all subclasses implementing
3877
// GetSurroundingText/GetSurroundingTextSelection should implement this and then this
3878
// should be removed in favor of a stub that returns false
3879
bool Window::DeleteSurroundingText(const Selection& rSelection)
3880
0
{
3881
0
    uno::Reference<accessibility::XAccessibleEditableText> xText = lcl_GetxText(this);
3882
0
    if (xText.is())
3883
0
    {
3884
0
        sal_Int32 nPosition = xText->getCaretPosition();
3885
        // #i111768# range checking
3886
0
        sal_Int32 nDeletePos = rSelection.Min();
3887
0
        sal_Int32 nDeleteEnd = rSelection.Max();
3888
0
        if (nDeletePos < 0)
3889
0
            nDeletePos = 0;
3890
0
        if (nDeleteEnd < 0)
3891
0
            nDeleteEnd = 0;
3892
0
        if (nDeleteEnd > xText->getCharacterCount())
3893
0
            nDeleteEnd = xText->getCharacterCount();
3894
3895
0
        xText->deleteText(nDeletePos, nDeleteEnd);
3896
        //tdf91641 adjust cursor if deleted chars shift it forward (normal case)
3897
0
        if (nDeletePos < nPosition)
3898
0
        {
3899
0
            if (nDeleteEnd <= nPosition)
3900
0
                nPosition = nPosition - (nDeleteEnd - nDeletePos);
3901
0
            else
3902
0
                nPosition = nDeletePos;
3903
3904
0
            if (xText->getCharacterCount() >= nPosition)
3905
0
                xText->setCaretPosition( nPosition );
3906
0
        }
3907
0
        return true;
3908
0
    }
3909
3910
0
    return false;
3911
0
}
3912
3913
bool WindowOutputDevice::UsePolyPolygonForComplexGradient()
3914
0
{
3915
0
    return meRasterOp != RasterOp::OverPaint;
3916
0
}
3917
3918
void Window::ApplySettings(vcl::RenderContext& /*rRenderContext*/)
3919
0
{
3920
0
}
3921
3922
const SystemEnvData* Window::GetSystemData() const
3923
0
{
3924
3925
0
    return mpWindowImpl->mpFrame ? &mpWindowImpl->mpFrame->GetSystemData() : nullptr;
3926
0
}
3927
3928
bool Window::SupportsDoubleBuffering() const
3929
3
{
3930
3
    return mpWindowImpl->mpFrameData->mpBuffer;
3931
3
}
3932
3933
void Window::RequestDoubleBuffering(bool bRequest)
3934
0
{
3935
0
    if (bRequest)
3936
0
    {
3937
0
        mpWindowImpl->mpFrameData->mpBuffer = VclPtrInstance<VirtualDevice>();
3938
        // Make sure that the buffer size matches the frame size.
3939
0
        mpWindowImpl->mpFrameData->mpBuffer->SetOutputSizePixel(mpWindowImpl->mpFrameWindow->GetOutputSizePixel());
3940
0
    }
3941
0
    else
3942
0
        mpWindowImpl->mpFrameData->mpBuffer.reset();
3943
0
}
3944
3945
/*
3946
 * The rationale here is that we moved destructors to
3947
 * dispose and this altered a lot of code paths, that
3948
 * are better left unchanged for now.
3949
 */
3950
void Window::CompatGetFocus()
3951
0
{
3952
0
    if (!mpWindowImpl || mpWindowImpl->mbInDispose)
3953
0
        Window::GetFocus();
3954
0
    else
3955
0
        GetFocus();
3956
0
}
3957
3958
void Window::CompatLoseFocus()
3959
0
{
3960
0
    if (!mpWindowImpl || mpWindowImpl->mbInDispose)
3961
0
        Window::LoseFocus();
3962
0
    else
3963
0
        LoseFocus();
3964
0
}
3965
3966
void Window::CompatStateChanged( StateChangedType nStateChange )
3967
72.2k
{
3968
72.2k
    if (!mpWindowImpl || mpWindowImpl->mbInDispose)
3969
13.6k
        Window::StateChanged(nStateChange);
3970
58.6k
    else
3971
58.6k
        StateChanged(nStateChange);
3972
72.2k
}
3973
3974
void Window::CompatDataChanged( const DataChangedEvent& rDCEvt )
3975
0
{
3976
0
    if (!mpWindowImpl || mpWindowImpl->mbInDispose)
3977
0
        Window::DataChanged(rDCEvt);
3978
0
    else
3979
0
        DataChanged(rDCEvt);
3980
0
}
3981
3982
bool Window::CompatPreNotify( NotifyEvent& rNEvt )
3983
0
{
3984
0
    if (!mpWindowImpl || mpWindowImpl->mbInDispose)
3985
0
        return Window::PreNotify( rNEvt );
3986
0
    else
3987
0
        return PreNotify( rNEvt );
3988
0
}
3989
3990
bool Window::CompatNotify( NotifyEvent& rNEvt )
3991
0
{
3992
0
    if (!mpWindowImpl || mpWindowImpl->mbInDispose)
3993
0
        return Window::EventNotify( rNEvt );
3994
0
    else
3995
0
        return EventNotify( rNEvt );
3996
0
}
3997
3998
void Window::set_id(const OUString& rID)
3999
4.57k
{
4000
4.57k
    mpWindowImpl->maID = rID;
4001
4.57k
}
4002
4003
const OUString& Window::get_id() const
4004
0
{
4005
0
    static OUString empty;
4006
0
    return mpWindowImpl ? mpWindowImpl->maID : empty;
4007
0
}
4008
4009
FactoryFunction Window::GetUITestFactory() const
4010
0
{
4011
0
    return WindowUIObject::create;
4012
0
}
4013
4014
WindowOutputDevice::WindowOutputDevice(vcl::Window& rOwnerWindow) :
4015
140k
    ::OutputDevice(OUTDEV_WINDOW),
4016
140k
    mxOwnerWindow(&rOwnerWindow)
4017
140k
{
4018
140k
    assert(mxOwnerWindow);
4019
140k
}
Unexecuted instantiation: vcl::WindowOutputDevice::WindowOutputDevice(vcl::Window&)
vcl::WindowOutputDevice::WindowOutputDevice(vcl::Window&)
Line
Count
Source
4015
140k
    ::OutputDevice(OUTDEV_WINDOW),
4016
140k
    mxOwnerWindow(&rOwnerWindow)
4017
140k
{
4018
    assert(mxOwnerWindow);
4019
140k
}
4020
4021
WindowOutputDevice::~WindowOutputDevice()
4022
114k
{
4023
114k
    disposeOnce();
4024
114k
}
4025
4026
void WindowOutputDevice::dispose()
4027
114k
{
4028
114k
    assert((!mxOwnerWindow || mxOwnerWindow->isDisposed()) && "This belongs to the associated window and must be disposed after it");
4029
114k
    ::OutputDevice::dispose();
4030
    // need to do this after OutputDevice::dispose so that the call to WindowOutputDevice::ReleaseGraphics
4031
    // can release the graphics properly
4032
114k
    mxOwnerWindow.reset();
4033
114k
}
4034
4035
css::awt::DeviceInfo WindowOutputDevice::GetDeviceInfo() const
4036
36.1k
{
4037
36.1k
    css::awt::DeviceInfo aInfo = GetCommonDeviceInfo(mxOwnerWindow->GetSizePixel());
4038
36.1k
    mxOwnerWindow->GetBorder(aInfo.LeftInset, aInfo.TopInset, aInfo.RightInset, aInfo.BottomInset);
4039
36.1k
    return aInfo;
4040
36.1k
}
4041
4042
4043
} /* namespace vcl */
4044
4045
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */