Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/vcl/source/window/window.cxx
Line
Count
Source (jump to first uncovered line)
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 <vcl/salgtype.hxx>
28
#include <vcl/event.hxx>
29
#include <vcl/cursor.hxx>
30
#include <vcl/svapp.hxx>
31
#include <vcl/transfer.hxx>
32
#include <vcl/vclevent.hxx>
33
#include <vcl/window.hxx>
34
#include <vcl/syswin.hxx>
35
#include <vcl/dockwin.hxx>
36
#include <vcl/wall.hxx>
37
#include <vcl/toolkit/fixed.hxx>
38
#include <vcl/toolkit/button.hxx>
39
#include <vcl/taskpanelist.hxx>
40
#include <vcl/toolkit/unowrap.hxx>
41
#include <tools/lazydelete.hxx>
42
#include <vcl/virdev.hxx>
43
#include <vcl/settings.hxx>
44
#include <vcl/sysdata.hxx>
45
#include <vcl/ptrstyle.hxx>
46
#include <vcl/IDialogRenderable.hxx>
47
48
#include <vcl/uitest/uiobject.hxx>
49
50
#include <ImplOutDevData.hxx>
51
#include <impfontcache.hxx>
52
#include <salframe.hxx>
53
#include <salobj.hxx>
54
#include <salinst.hxx>
55
#include <salgdi.hxx>
56
#include <svdata.hxx>
57
#include <window.h>
58
#include <toolbox.h>
59
#include <brdwin.hxx>
60
#include <helpwin.hxx>
61
#include <dndlistenercontainer.hxx>
62
#include <dndeventdispatcher.hxx>
63
64
#include <com/sun/star/accessibility/AccessibleRelation.hpp>
65
#include <com/sun/star/accessibility/XAccessible.hpp>
66
#include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
67
#include <com/sun/star/awt/XVclWindowPeer.hpp>
68
#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
69
#include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
70
#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
71
#include <com/sun/star/rendering/CanvasFactory.hpp>
72
#include <com/sun/star/rendering/XSpriteCanvas.hpp>
73
#include <comphelper/configuration.hxx>
74
#include <comphelper/lok.hxx>
75
#include <comphelper/processfactory.hxx>
76
#include <osl/diagnose.h>
77
#include <tools/debug.hxx>
78
#include <tools/json_writer.hxx>
79
#include <boost/property_tree/ptree.hpp>
80
81
#include <cassert>
82
#include <typeinfo>
83
84
#ifdef _WIN32 // see #140456#
85
#include <win/salframe.h>
86
#endif
87
88
#include "impldockingwrapper.hxx"
89
90
using namespace ::com::sun::star::uno;
91
using namespace ::com::sun::star::lang;
92
using namespace ::com::sun::star::datatransfer::clipboard;
93
using namespace ::com::sun::star::datatransfer::dnd;
94
95
namespace vcl {
96
97
Window::Window( WindowType eType )
98
199k
    : mpWindowImpl(new WindowImpl( *this, eType ))
99
199k
{
100
    // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
101
199k
    mpWindowImpl->mxOutDev->mbEnableRTL = AllSettings::GetLayoutRTL();
102
199k
}
vcl::Window::Window(WindowType)
Line
Count
Source
98
199k
    : mpWindowImpl(new WindowImpl( *this, eType ))
99
199k
{
100
    // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
101
199k
    mpWindowImpl->mxOutDev->mbEnableRTL = AllSettings::GetLayoutRTL();
102
199k
}
Unexecuted instantiation: vcl::Window::Window(WindowType)
103
104
Window::Window( vcl::Window* pParent, WinBits nStyle )
105
42.3k
    : mpWindowImpl(new WindowImpl( *this, WindowType::WINDOW ))
106
42.3k
{
107
    // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
108
42.3k
    mpWindowImpl->mxOutDev->mbEnableRTL = AllSettings::GetLayoutRTL();
109
110
42.3k
    ImplInit( pParent, nStyle, nullptr );
111
42.3k
}
vcl::Window::Window(vcl::Window*, long)
Line
Count
Source
105
42.3k
    : mpWindowImpl(new WindowImpl( *this, WindowType::WINDOW ))
106
42.3k
{
107
    // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
108
42.3k
    mpWindowImpl->mxOutDev->mbEnableRTL = AllSettings::GetLayoutRTL();
109
110
42.3k
    ImplInit( pParent, nStyle, nullptr );
111
42.3k
}
Unexecuted instantiation: vcl::Window::Window(vcl::Window*, long)
112
113
#if OSL_DEBUG_LEVEL > 0
114
namespace
115
{
116
     OString lcl_createWindowInfo(const vcl::Window* pWindow)
117
     {
118
         // skip border windows, they do not carry information that
119
         // would help with diagnosing the problem
120
         const vcl::Window* pTempWin( pWindow );
121
         while ( pTempWin && pTempWin->GetType() == WindowType::BORDERWINDOW ) {
122
             pTempWin = pTempWin->GetWindow( GetWindowType::FirstChild );
123
         }
124
         // check if pTempWin is not null, otherwise use the
125
         // original address
126
         if ( pTempWin ) {
127
             pWindow = pTempWin;
128
         }
129
130
         return OString::Concat(" ") +
131
            typeid( *pWindow ).name() +
132
            "(" +
133
             OUStringToOString(
134
                 pWindow->GetText(),
135
                 RTL_TEXTENCODING_UTF8
136
                 ) +
137
            ")";
138
     }
139
}
140
#endif
141
142
void Window::dispose()
143
211k
{
144
211k
    assert( mpWindowImpl );
145
211k
    assert( !mpWindowImpl->mbInDispose ); // should only be called from disposeOnce()
146
211k
    assert( (!mpWindowImpl->mpParent ||
147
211k
             mpWindowImpl->mpParent->mpWindowImpl) &&
148
211k
            "vcl::Window child should have its parent disposed first" );
149
150
    // remove Key and Mouse events issued by Application::PostKey/MouseEvent
151
211k
    Application::RemoveMouseAndKeyEvents( this );
152
153
    // Dispose of the canvas implementation (which, currently, has an
154
    // own wrapper window as a child to this one.
155
211k
    GetOutDev()->ImplDisposeCanvas();
156
157
211k
    mpWindowImpl->mbInDispose = true;
158
159
211k
    CallEventListeners( VclEventId::ObjectDying );
160
161
    // do not send child events for frames that were registered as native frames
162
211k
    if( !IsNativeFrame() && mpWindowImpl->mbReallyVisible )
163
0
        if ( ImplIsAccessibleCandidate() && GetAccessibleParentWindow() )
164
0
            GetAccessibleParentWindow()->CallEventListeners( VclEventId::WindowChildDestroyed, this );
165
166
    // remove associated data structures from dockingmanager
167
211k
    ImplGetDockingManager()->RemoveWindow( this );
168
169
    // remove ownerdraw decorated windows from list in the top-most frame window
170
211k
    if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
171
0
    {
172
0
        ::std::vector< VclPtr<vcl::Window> >& rList = ImplGetOwnerDrawList();
173
0
        auto p = ::std::find( rList.begin(), rList.end(), VclPtr<vcl::Window>(this) );
174
0
        if( p != rList.end() )
175
0
            rList.erase( p );
176
0
    }
177
178
    // shutdown drag and drop
179
211k
    if( mpWindowImpl->mxDNDListenerContainer.is() )
180
16.9k
        mpWindowImpl->mxDNDListenerContainer->dispose();
181
182
211k
    if( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData )
183
8.47k
    {
184
8.47k
        try
185
8.47k
        {
186
            // deregister drop target listener
187
8.47k
            if( mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
188
0
            {
189
0
                Reference< XDragGestureRecognizer > xDragGestureRecognizer(mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY);
190
0
                if( xDragGestureRecognizer.is() )
191
0
                {
192
0
                    xDragGestureRecognizer->removeDragGestureListener(mpWindowImpl->mpFrameData->mxDropTargetListener);
193
0
                }
194
195
0
                mpWindowImpl->mpFrameData->mxDropTarget->removeDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener );
196
0
                mpWindowImpl->mpFrameData->mxDropTargetListener.clear();
197
0
            }
198
199
            // shutdown drag and drop for this frame window
200
8.47k
            Reference< XComponent > xComponent( mpWindowImpl->mpFrameData->mxDropTarget, UNO_QUERY );
201
202
            // DNDEventDispatcher does not hold a reference of the DropTarget,
203
            // so it's ok if it does not support XComponent
204
8.47k
            if( xComponent.is() )
205
0
                xComponent->dispose();
206
8.47k
        }
207
8.47k
        catch (const Exception&)
208
8.47k
        {
209
            // can be safely ignored here.
210
0
        }
211
8.47k
    }
212
213
211k
    UnoWrapperBase* pWrapper = UnoWrapperBase::GetUnoWrapper( false );
214
211k
    if ( pWrapper )
215
211k
        pWrapper->WindowDestroyed( this );
216
217
211k
    if ( mpWindowImpl->mxAccessible.is() )
218
0
    {
219
0
        Reference< XComponent> xC( mpWindowImpl->mxAccessible, UNO_QUERY );
220
0
        if ( xC.is() )
221
0
            xC->dispose();
222
0
        mpWindowImpl->mxAccessible.clear();
223
0
    }
224
225
211k
    if (mpWindowImpl->mpAccessibleInfos)
226
0
        mpWindowImpl->mpAccessibleInfos->xAccessibleParent.clear();
227
228
211k
    ImplSVData* pSVData = ImplGetSVData();
229
230
211k
    if ( ImplGetSVHelpData().mpHelpWin && (ImplGetSVHelpData().mpHelpWin->GetParent() == this) )
231
0
        ImplDestroyHelpWindow( true );
232
233
211k
    SAL_WARN_IF(pSVData->mpWinData->mpTrackWin.get() == this, "vcl.window",
234
211k
                "Window::~Window(): Window is in TrackingMode");
235
211k
    SAL_WARN_IF(IsMouseCaptured(), "vcl.window",
236
211k
                "Window::~Window(): Window has the mouse captured");
237
238
    // due to old compatibility
239
211k
    if (pSVData->mpWinData->mpTrackWin == this)
240
0
        EndTracking();
241
211k
    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
211k
    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
211k
    remove_from_all_size_groups();
373
374
    // clear mnemonic labels
375
211k
    std::vector<VclPtr<FixedText> > aMnemonicLabels(list_mnemonic_labels());
376
211k
    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
211k
    Hide();
383
384
    // EndExtTextInputMode
385
211k
    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
211k
    bool bHasFocusedChild = false;
394
211k
    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
211k
    vcl::Window* pOverlapWindow = ImplGetFirstOverlapWindow();
408
211k
    if (pSVData->mpWinData->mpFocusWin == this
409
211k
        || 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
211k
    if ( pOverlapWindow != nullptr &&
445
211k
         pOverlapWindow->mpWindowImpl->mpLastFocusWindow == this )
446
0
        pOverlapWindow->mpWindowImpl->mpLastFocusWindow = nullptr;
447
448
    // reset hint for DefModalDialogParent
449
211k
    if( pSVData->maFrameData.mpActiveApplicationFrame == this )
450
0
        pSVData->maFrameData.mpActiveApplicationFrame = nullptr;
451
452
    // reset hint of what was the last wheeled window
453
211k
    if (pSVData->mpWinData->mpLastWheelWindow == this)
454
0
        pSVData->mpWinData->mpLastWheelWindow = nullptr;
455
456
    // reset marked windows
457
211k
    if ( mpWindowImpl->mpFrameData != nullptr )
458
211k
    {
459
211k
        if ( mpWindowImpl->mpFrameData->mpFocusWin == this )
460
0
            mpWindowImpl->mpFrameData->mpFocusWin = nullptr;
461
211k
        if ( mpWindowImpl->mpFrameData->mpMouseMoveWin == this )
462
0
            mpWindowImpl->mpFrameData->mpMouseMoveWin = nullptr;
463
211k
        if ( mpWindowImpl->mpFrameData->mpMouseDownWin == this )
464
0
            mpWindowImpl->mpFrameData->mpMouseDownWin = nullptr;
465
211k
    }
466
467
    // reset Deactivate-Window
468
211k
    if (pSVData->mpWinData->mpLastDeacWin == this)
469
0
        pSVData->mpWinData->mpLastDeacWin = nullptr;
470
471
211k
    if ( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData )
472
8.47k
    {
473
8.47k
        if ( mpWindowImpl->mpFrameData->mnFocusId )
474
0
            Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnFocusId );
475
8.47k
        mpWindowImpl->mpFrameData->mnFocusId = nullptr;
476
8.47k
        if ( mpWindowImpl->mpFrameData->mnMouseMoveId )
477
0
            Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnMouseMoveId );
478
8.47k
        mpWindowImpl->mpFrameData->mnMouseMoveId = nullptr;
479
8.47k
    }
480
481
    // release SalGraphics
482
211k
    VclPtr<OutputDevice> pOutDev = GetOutDev();
483
211k
    pOutDev->ReleaseGraphics();
484
485
    // remove window from the lists
486
211k
    ImplRemoveWindow( true );
487
488
    // de-register as "top window child" at our parent, if necessary
489
211k
    if ( mpWindowImpl->mbFrame )
490
8.47k
    {
491
8.47k
        bool bIsTopWindow
492
8.47k
            = mpWindowImpl->mpWinData && (mpWindowImpl->mpWinData->mnIsTopWindow == 1);
493
8.47k
        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
8.47k
    }
504
505
211k
    mpWindowImpl->mpWinData.reset();
506
507
    // remove BorderWindow or Frame window data
508
211k
    mpWindowImpl->mpBorderWindow.disposeAndClear();
509
211k
    if ( mpWindowImpl->mbFrame )
510
8.47k
    {
511
8.47k
        if ( pSVData->maFrameData.mpFirstFrame == this )
512
8.47k
            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
8.47k
        if (mpWindowImpl->mpFrame) // otherwise exception during init
533
8.47k
        {
534
8.47k
            mpWindowImpl->mpFrame->SetCallback( nullptr, nullptr );
535
8.47k
            pSVData->mpDefInst->DestroyFrame( mpWindowImpl->mpFrame );
536
8.47k
        }
537
8.47k
        assert (mpWindowImpl->mpFrameData->mnFocusId == nullptr);
538
8.47k
        assert (mpWindowImpl->mpFrameData->mnMouseMoveId == nullptr);
539
540
8.47k
        mpWindowImpl->mpFrameData->mpBuffer.disposeAndClear();
541
8.47k
        delete mpWindowImpl->mpFrameData;
542
8.47k
        mpWindowImpl->mpFrameData = nullptr;
543
8.47k
    }
544
545
211k
    if (mpWindowImpl->mxWindowPeer)
546
16.9k
        mpWindowImpl->mxWindowPeer->dispose();
547
548
    // should be the last statements
549
211k
    mpWindowImpl.reset();
550
551
211k
    pOutDev.disposeAndClear();
552
    // just to make loplugin:vclwidgets happy
553
211k
    VclReferenceBase::dispose();
554
211k
}
555
556
Window::~Window()
557
211k
{
558
211k
    disposeOnce();
559
211k
}
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
1.01M
{
569
1.01M
    return mpWindowImpl ? mpWindowImpl->mxOutDev.get() : nullptr;
570
1.01M
}
571
572
::OutputDevice* Window::GetOutDev()
573
6.94M
{
574
6.94M
    return mpWindowImpl ? mpWindowImpl->mxOutDev.get() : nullptr;
575
6.94M
}
576
577
Color WindowOutputDevice::GetBackgroundColor() const
578
0
{
579
0
    return mxOwnerWindow->GetDisplayBackground().GetColor();
580
0
}
581
582
bool WindowOutputDevice::CanEnableNativeWidget() const
583
59.1k
{
584
59.1k
    return mxOwnerWindow->IsNativeWidgetEnabled();
585
59.1k
}
586
587
} /* namespace vcl */
588
589
WindowImpl::WindowImpl( vcl::Window& rWindow, WindowType eType )
590
241k
{
591
241k
    mxOutDev = VclPtr<vcl::WindowOutputDevice>::Create(rWindow);
592
241k
    maZoom                              = Fraction( 1, 1 );
593
241k
    mfPartialScrollX                    = 0.0;
594
241k
    mfPartialScrollY                    = 0.0;
595
241k
    maWinRegion                         = vcl::Region(true);
596
241k
    maWinClipRegion                     = vcl::Region(true);
597
241k
    mpWinData                           = nullptr;                      // Extra Window Data, that we don't need for all windows
598
241k
    mpFrameData                         = nullptr;                      // Frame Data
599
241k
    mpFrame                             = nullptr;                      // Pointer to frame window
600
241k
    mpSysObj                            = nullptr;
601
241k
    mpFrameWindow                       = nullptr;                      // window to top level parent (same as frame window)
602
241k
    mpOverlapWindow                     = nullptr;                      // first overlap parent
603
241k
    mpBorderWindow                      = nullptr;                      // Border-Window
604
241k
    mpClientWindow                      = nullptr;                      // Client-Window of a FrameWindow
605
241k
    mpParent                            = nullptr;                      // parent (incl. BorderWindow)
606
241k
    mpRealParent                        = nullptr;                      // real parent (excl. BorderWindow)
607
241k
    mpFirstChild                        = nullptr;                      // first child window
608
241k
    mpLastChild                         = nullptr;                      // last child window
609
241k
    mpFirstOverlap                      = nullptr;                      // first overlap window (only set in overlap windows)
610
241k
    mpLastOverlap                       = nullptr;                      // last overlap window (only set in overlap windows)
611
241k
    mpPrev                              = nullptr;                      // prev window
612
241k
    mpNext                              = nullptr;                      // next window
613
241k
    mpNextOverlap                       = nullptr;                      // next overlap window of frame
614
241k
    mpLastFocusWindow                   = nullptr;                      // window for focus restore
615
241k
    mpDlgCtrlDownWindow                 = nullptr;                      // window for dialog control
616
241k
    mnEventListenersIteratingCount = 0;
617
241k
    mnChildEventListenersIteratingCount = 0;
618
241k
    mpCursor                            = nullptr;                      // cursor
619
241k
    maPointer                           = PointerStyle::Arrow;
620
241k
    mpVCLXWindow                        = nullptr;
621
241k
    mpAccessibleInfos                   = nullptr;
622
241k
    maControlForeground                 = COL_TRANSPARENT;  // no foreground set
623
241k
    maControlBackground                 = COL_TRANSPARENT;  // no background set
624
241k
    mnLeftBorder                        = 0;                         // width of left border
625
241k
    mnTopBorder                         = 0;                         // width of top border
626
241k
    mnRightBorder                       = 0;                         // width of right border
627
241k
    mnBottomBorder                      = 0;                         // width of bottom border
628
241k
    mnWidthRequest                      = -1;                        // width request
629
241k
    mnHeightRequest                     = -1;                        // height request
630
241k
    mnOptimalWidthCache                 = -1;                        // optimal width cache
631
241k
    mnOptimalHeightCache                = -1;                        // optimal height cache
632
241k
    mnX                                 = 0;                         // X-Position to Parent
633
241k
    mnY                                 = 0;                         // Y-Position to Parent
634
241k
    mnAbsScreenX                        = 0;                         // absolute X-position on screen, used for RTL window positioning
635
241k
    mpChildClipRegion                   = nullptr;                      // Child-Clip-Region when ClipChildren
636
241k
    mpPaintRegion                       = nullptr;                      // Paint-ClipRegion
637
241k
    mnStyle                             = 0;                         // style (init in ImplInitWindow)
638
241k
    mnPrevStyle                         = 0;                         // prevstyle (set in SetStyle)
639
241k
    mnExtendedStyle                     = WindowExtendedStyle::NONE; // extended style (init in ImplInitWindow)
640
241k
    meType                              = eType;                     // type
641
241k
    mnGetFocusFlags                     = GetFocusFlags::NONE;       // Flags for GetFocus()-Call
642
241k
    mnWaitCount                         = 0;                         // Wait-Count (>1 == "wait" mouse pointer)
643
241k
    mnPaintFlags                        = ImplPaintFlags::NONE;      // Flags for ImplCallPaint
644
241k
    mnParentClipMode                    = ParentClipMode::NONE;      // Flags for Parent-ClipChildren-Mode
645
241k
    mnActivateMode                      = ActivateModeFlags::NONE;   // Will be converted in System/Overlap-Windows
646
241k
    mnDlgCtrlFlags                      = DialogControlFlags::NONE;  // DialogControl-Flags
647
241k
    meAlwaysInputMode                   = AlwaysInputNone;           // AlwaysEnableInput not called
648
241k
    meHalign                            = VclAlign::Fill;
649
241k
    meValign                            = VclAlign::Fill;
650
241k
    mePackType                          = VclPackType::Start;
651
241k
    mnPadding                           = 0;
652
241k
    mnGridHeight                        = 1;
653
241k
    mnGridLeftAttach                    = -1;
654
241k
    mnGridTopAttach                     = -1;
655
241k
    mnGridWidth                         = 1;
656
241k
    mnBorderWidth                       = 0;
657
241k
    mnMarginLeft                        = 0;
658
241k
    mnMarginRight                       = 0;
659
241k
    mnMarginTop                         = 0;
660
241k
    mnMarginBottom                      = 0;
661
241k
    mbFrame                             = false;                     // true: Window is a frame window
662
241k
    mbBorderWin                         = false;                     // true: Window is a border window
663
241k
    mbOverlapWin                        = false;                     // true: Window is an overlap window
664
241k
    mbSysWin                            = false;                     // true: SystemWindow is the base class
665
241k
    mbDialog                            = false;                     // true: Dialog is the base class
666
241k
    mbDockWin                           = false;                     // true: DockingWindow is the base class
667
241k
    mbFloatWin                          = false;                     // true: FloatingWindow is the base class
668
241k
    mbPushButton                        = false;                     // true: PushButton is the base class
669
241k
    mbToolBox                           = false;                     // true: ToolBox is the base class
670
241k
    mbMenuFloatingWindow                = false;                     // true: MenuFloatingWindow is the base class
671
241k
    mbSplitter                          = false;                     // true: Splitter is the base class
672
241k
    mbVisible                           = false;                     // true: Show( true ) called
673
241k
    mbOverlapVisible                    = false;                     // true: Hide called for visible window from ImplHideAllOverlapWindow()
674
241k
    mbDisabled                          = false;                     // true: Enable( false ) called
675
241k
    mbInputDisabled                     = false;                     // true: EnableInput( false ) called
676
241k
    mbNoUpdate                          = false;                     // true: SetUpdateMode( false ) called
677
241k
    mbNoParentUpdate                    = false;                     // true: SetParentUpdateMode( false ) called
678
241k
    mbActive                            = false;                     // true: Window Active
679
241k
    mbReallyVisible                     = false;                     // true: this and all parents to an overlapped window are visible
680
241k
    mbReallyShown                       = false;                     // true: this and all parents to an overlapped window are shown
681
241k
    mbInInitShow                        = false;                     // true: we are in InitShow
682
241k
    mbChildPtrOverwrite                 = false;                     // true: PointerStyle overwrites Child-Pointer
683
241k
    mbNoPtrVisible                      = false;                     // true: ShowPointer( false ) called
684
241k
    mbPaintFrame                        = false;                     // true: Paint is visible, but not painted
685
241k
    mbInPaint                           = false;                     // true: Inside PaintHdl
686
241k
    mbMouseButtonDown                   = false;                     // true: BaseMouseButtonDown called
687
241k
    mbMouseButtonUp                     = false;                     // true: BaseMouseButtonUp called
688
241k
    mbKeyInput                          = false;                     // true: BaseKeyInput called
689
241k
    mbKeyUp                             = false;                     // true: BaseKeyUp called
690
241k
    mbCommand                           = false;                     // true: BaseCommand called
691
241k
    mbDefPos                            = true;                      // true: Position is not Set
692
241k
    mbDefSize                           = true;                      // true: Size is not Set
693
241k
    mbCallMove                          = true;                      // true: Move must be called by Show
694
241k
    mbCallResize                        = true;                      // true: Resize must be called by Show
695
241k
    mbWaitSystemResize                  = true;                      // true: Wait for System-Resize
696
241k
    mbInitWinClipRegion                 = true;                      // true: Calc Window Clip Region
697
241k
    mbInitChildRegion                   = false;                     // true: InitChildClipRegion
698
241k
    mbWinRegion                         = false;                     // true: Window Region
699
241k
    mbClipChildren                      = false;                     // true: Child-window should be clipped
700
241k
    mbClipSiblings                      = false;                     // true: Adjacent Child-window should be clipped
701
241k
    mbChildTransparent                  = false;                     // true: Child-windows are allowed to switch to transparent (incl. Parent-CLIPCHILDREN)
702
241k
    mbPaintTransparent                  = false;                     // true: Paints should be executed on the Parent
703
241k
    mbMouseTransparent                  = false;                     // true: Window is transparent for Mouse
704
241k
    mbDlgCtrlStart                      = false;                     // true: From here on own Dialog-Control
705
241k
    mbFocusVisible                      = false;                     // true: Focus Visible
706
241k
    mbUseNativeFocus                    = false;
707
241k
    mbNativeFocusVisible                = false;                     // true: native Focus Visible
708
241k
    mbInShowFocus                       = false;                     // prevent recursion
709
241k
    mbInHideFocus                       = false;                     // prevent recursion
710
241k
    mbTrackVisible                      = false;                     // true: Tracking Visible
711
241k
    mbControlForeground                 = false;                     // true: Foreground-Property set
712
241k
    mbControlBackground                 = false;                     // true: Background-Property set
713
241k
    mbAlwaysOnTop                       = false;                     // true: always visible for all others windows
714
241k
    mbCompoundControl                   = false;                     // true: Composite Control => Listener...
715
241k
    mbCompoundControlHasFocus           = false;                     // true: Composite Control has focus somewhere
716
241k
    mbPaintDisabled                     = false;                     // true: Paint should not be executed
717
241k
    mbAllResize                         = false;                     // true: Also sent ResizeEvents with 0,0
718
241k
    mbInDispose                         = false;                     // true: We're still in Window::dispose()
719
241k
    mbExtTextInput                      = false;                     // true: ExtTextInput-Mode is active
720
241k
    mbInFocusHdl                        = false;                     // true: Within GetFocus-Handler
721
241k
    mbCreatedWithToolkit                = false;
722
241k
    mbSuppressAccessibilityEvents       = false;                     // true: do not send any accessibility events
723
241k
    mbDrawSelectionBackground           = false;                     // true: draws transparent window background to indicate (toolbox) selection
724
241k
    mbIsInTaskPaneList                  = false;                     // true: window was added to the taskpanelist in the topmost system window
725
241k
    mnNativeBackground                  = ControlPart::NONE;         // initialize later, depends on type
726
241k
    mbHelpTextDynamic                   = false;                     // true: append help id in HELP_DEBUG case
727
241k
    mbFakeFocusSet                      = false;                     // true: pretend as if the window has focus.
728
241k
    mbHexpand                           = false;
729
241k
    mbVexpand                           = false;
730
241k
    mbExpand                            = false;
731
241k
    mbFill                              = true;
732
241k
    mbSecondary                         = false;
733
241k
    mbNonHomogeneous                    = false;
734
241k
    static bool bDoubleBuffer = getenv("VCL_DOUBLEBUFFERING_FORCE_ENABLE");
735
241k
    mbDoubleBufferingRequested = bDoubleBuffer; // when we are not sure, assume it cannot do double-buffering via RenderContext
736
241k
    mpLOKNotifier                       = nullptr;
737
241k
    mnLOKWindowId                       = 0;
738
241k
    mbUseFrameData                      = false;
739
241k
}
740
741
WindowImpl::~WindowImpl()
742
211k
{
743
211k
    mpChildClipRegion.reset();
744
211k
    mpAccessibleInfos.reset();
745
211k
}
746
747
ImplWinData::ImplWinData() :
748
216k
    mnCursorExtWidth(0),
749
216k
    mbVertical(false),
750
216k
    mnCompositionCharRects(0),
751
216k
    mnTrackFlags(ShowTrackFlags::NONE),
752
216k
    mnIsTopWindow(sal_uInt16(~0)), // not initialized yet, 0/1 will indicate TopWindow (see IsTopWindow())
753
216k
    mbMouseOver(false),
754
216k
    mbEnableNativeWidget(false)
755
216k
{
756
216k
}
757
758
ImplWinData::~ImplWinData()
759
211k
{
760
211k
    mpCompositionCharRects.reset();
761
211k
}
762
763
ImplFrameData::ImplFrameData( vcl::Window *pWindow )
764
12.7k
    : maPaintIdle( "vcl::Window maPaintIdle" ),
765
12.7k
      maResizeIdle( "vcl::Window maResizeIdle" )
766
12.7k
{
767
12.7k
    ImplSVData* pSVData = ImplGetSVData();
768
12.7k
    assert (pSVData->maFrameData.mpFirstFrame.get() != pWindow);
769
12.7k
    mpNextFrame        = pSVData->maFrameData.mpFirstFrame;
770
12.7k
    pSVData->maFrameData.mpFirstFrame = pWindow;
771
12.7k
    mpFirstOverlap     = nullptr;
772
12.7k
    mpFocusWin         = nullptr;
773
12.7k
    mpMouseMoveWin     = nullptr;
774
12.7k
    mpMouseDownWin     = nullptr;
775
12.7k
    mpTrackWin         = nullptr;
776
12.7k
    mxFontCollection   = pSVData->maGDIData.mxScreenFontList;
777
12.7k
    mxFontCache        = pSVData->maGDIData.mxScreenFontCache;
778
12.7k
    mnFocusId          = nullptr;
779
12.7k
    mnMouseMoveId      = nullptr;
780
12.7k
    mnLastMouseX       = -32767;
781
12.7k
    mnLastMouseY       = -32767;
782
12.7k
    mnBeforeLastMouseX = -32767;
783
12.7k
    mnBeforeLastMouseY = -32767;
784
12.7k
    mnFirstMouseX      = -32767;
785
12.7k
    mnFirstMouseY      = -32767;
786
12.7k
    mnLastMouseWinX    = -32767;
787
12.7k
    mnLastMouseWinY    = -32767;
788
12.7k
    mnModalMode        = 0;
789
12.7k
    mnMouseDownTime    = 0;
790
12.7k
    mnClickCount       = 0;
791
12.7k
    mnFirstMouseCode   = 0;
792
12.7k
    mnMouseCode        = 0;
793
12.7k
    mnMouseMode        = MouseEventModifiers::NONE;
794
12.7k
    mbHasFocus         = false;
795
12.7k
    mbInMouseMove      = false;
796
12.7k
    mbMouseIn          = false;
797
12.7k
    mbStartDragCalled  = false;
798
12.7k
    mbNeedSysWindow    = false;
799
12.7k
    mbMinimized        = false;
800
12.7k
    mbStartFocusState  = false;
801
12.7k
    mbInSysObjFocusHdl = false;
802
12.7k
    mbInSysObjToTopHdl = false;
803
12.7k
    mbSysObjFocus      = false;
804
12.7k
    maPaintIdle.SetPriority( TaskPriority::REPAINT );
805
12.7k
    maPaintIdle.SetInvokeHandler( LINK( pWindow, vcl::Window, ImplHandlePaintHdl ) );
806
12.7k
    maResizeIdle.SetPriority( TaskPriority::RESIZE );
807
12.7k
    maResizeIdle.SetInvokeHandler( LINK( pWindow, vcl::Window, ImplHandleResizeTimerHdl ) );
808
12.7k
    mbInternalDragGestureRecognizer = false;
809
12.7k
    mbDragging = false;
810
12.7k
    mbInBufferedPaint = false;
811
12.7k
    mnDPIX = 96;
812
12.7k
    mnDPIY = 96;
813
12.7k
    mnTouchPanPositionX = -1;
814
12.7k
    mnTouchPanPositionY = -1;
815
12.7k
}
816
817
namespace vcl {
818
819
bool WindowOutputDevice::AcquireGraphics() const
820
309k
{
821
309k
    DBG_TESTSOLARMUTEX();
822
823
309k
    if (isDisposed())
824
0
        return false;
825
826
309k
    if (mpGraphics)
827
157k
        return true;
828
829
152k
    mbInitLineColor     = true;
830
152k
    mbInitFillColor     = true;
831
152k
    mbInitFont          = true;
832
152k
    mbInitTextColor     = true;
833
152k
    mbInitClipRegion    = true;
834
835
152k
    ImplSVData* pSVData = ImplGetSVData();
836
837
152k
    mpGraphics = mxOwnerWindow->mpWindowImpl->mpFrame->AcquireGraphics();
838
    // try harder if no wingraphics was available directly
839
152k
    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
152k
    if ( mpGraphics )
870
152k
    {
871
        // update global LRU list of wingraphics
872
152k
        mpNextGraphics = pSVData->maGDIData.mpFirstWinGraphics.get();
873
152k
        pSVData->maGDIData.mpFirstWinGraphics = const_cast<vcl::WindowOutputDevice*>(this);
874
152k
        if ( mpNextGraphics )
875
152k
            mpNextGraphics->mpPrevGraphics = const_cast<vcl::WindowOutputDevice*>(this);
876
152k
        if ( !pSVData->maGDIData.mpLastWinGraphics )
877
30
            pSVData->maGDIData.mpLastWinGraphics = const_cast<vcl::WindowOutputDevice*>(this);
878
879
152k
        mpGraphics->SetXORMode( (RasterOp::Invert == meRasterOp) || (RasterOp::Xor == meRasterOp), RasterOp::Invert == meRasterOp );
880
152k
        mpGraphics->setAntiAlias(bool(mnAntialiasing & AntialiasingFlags::Enable));
881
152k
    }
882
883
152k
    return mpGraphics != nullptr;
884
309k
}
885
886
void WindowOutputDevice::ReleaseGraphics( bool bRelease )
887
423k
{
888
423k
    DBG_TESTSOLARMUTEX();
889
890
423k
    if ( !mpGraphics )
891
279k
        return;
892
893
    // release the fonts of the physically released graphics device
894
144k
    if( bRelease )
895
144k
        ImplReleaseFonts();
896
897
144k
    ImplSVData* pSVData = ImplGetSVData();
898
899
144k
    vcl::Window* pWindow = mxOwnerWindow.get();
900
144k
    if (!pWindow)
901
0
        return;
902
903
144k
    if ( bRelease )
904
144k
        pWindow->mpWindowImpl->mpFrame->ReleaseGraphics( mpGraphics );
905
    // remove from global LRU list of window graphics
906
144k
    if ( mpPrevGraphics )
907
118k
        mpPrevGraphics->mpNextGraphics = mpNextGraphics;
908
25.4k
    else
909
25.4k
        pSVData->maGDIData.mpFirstWinGraphics = static_cast<vcl::WindowOutputDevice*>(mpNextGraphics.get());
910
144k
    if ( mpNextGraphics )
911
144k
        mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
912
1
    else
913
1
        pSVData->maGDIData.mpLastWinGraphics = static_cast<vcl::WindowOutputDevice*>(mpPrevGraphics.get());
914
915
144k
    mpGraphics      = nullptr;
916
144k
    mpPrevGraphics  = nullptr;
917
144k
    mpNextGraphics  = nullptr;
918
144k
}
919
920
static sal_Int32 CountDPIScaleFactor(sal_Int32 nDPI)
921
241k
{
922
241k
#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
241k
    if (nDPI > 216)      // 96 * 2   + 96 / 4
929
0
        return 250;
930
241k
    else if (nDPI > 168) // 96 * 2   - 96 / 4
931
0
        return 200;
932
241k
    else if (nDPI > 120) // 96 * 1.5 - 96 / 4
933
0
        return 150;
934
#else
935
    (void)nDPI;
936
#endif
937
938
241k
    return 100;
939
241k
}
940
941
void Window::ImplInit( vcl::Window* pParent, WinBits nStyle, SystemParentData* pSystemParentData )
942
241k
{
943
241k
    SAL_WARN_IF( !mpWindowImpl->mbFrame && !pParent && GetType() != WindowType::FIXEDIMAGE, "vcl.window",
944
241k
        "Window::Window(): pParent == NULL" );
945
946
241k
    ImplSVData* pSVData = ImplGetSVData();
947
241k
    vcl::Window*     pRealParent = pParent;
948
949
    // inherit 3D look
950
241k
    if ( !mpWindowImpl->mbOverlapWin && pParent && (pParent->GetStyle() & WB_3DLOOK) )
951
101k
        nStyle |= WB_3DLOOK;
952
953
    // create border window if necessary
954
241k
    if ( !mpWindowImpl->mbFrame && !mpWindowImpl->mbBorderWin && !mpWindowImpl->mpBorderWindow
955
241k
         && (nStyle & (WB_BORDER | WB_SYSTEMCHILDWINDOW) ) )
956
8.47k
    {
957
8.47k
        BorderWindowStyle nBorderTypeStyle = BorderWindowStyle::NONE;
958
8.47k
        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
8.47k
        VclPtrInstance<ImplBorderWindow> pBorderWin( pParent, nStyle & (WB_BORDER | WB_DIALOGCONTROL | WB_NODIALOGCONTROL), nBorderTypeStyle );
968
8.47k
        static_cast<vcl::Window*>(pBorderWin)->mpWindowImpl->mpClientWindow = this;
969
8.47k
        pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
970
8.47k
        mpWindowImpl->mpBorderWindow  = pBorderWin;
971
8.47k
        pParent = mpWindowImpl->mpBorderWindow;
972
8.47k
    }
973
233k
    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
241k
    ImplInsertWindow( pParent );
981
241k
    mpWindowImpl->mnStyle = nStyle;
982
983
241k
    if( pParent && ! mpWindowImpl->mbFrame )
984
228k
        mpWindowImpl->mxOutDev->mbEnableRTL = AllSettings::GetLayoutRTL();
985
986
    // test for frame creation
987
241k
    if ( mpWindowImpl->mbFrame )
988
12.7k
    {
989
        // create frame
990
12.7k
        SalFrameStyleFlags nFrameStyle = SalFrameStyleFlags::NONE;
991
992
12.7k
        if ( nStyle & WB_MOVEABLE )
993
12.7k
            nFrameStyle |= SalFrameStyleFlags::MOVEABLE;
994
12.7k
        if ( nStyle & WB_SIZEABLE )
995
12.7k
            nFrameStyle |= SalFrameStyleFlags::SIZEABLE;
996
12.7k
        if ( nStyle & WB_CLOSEABLE )
997
12.7k
            nFrameStyle |= SalFrameStyleFlags::CLOSEABLE;
998
12.7k
        if ( nStyle & WB_APP )
999
0
            nFrameStyle |= SalFrameStyleFlags::DEFAULT;
1000
        // check for undecorated floating window
1001
12.7k
        if( // 1. floating windows that are not moveable/sizeable (only closeable allowed)
1002
12.7k
            ( !(nFrameStyle & ~SalFrameStyleFlags::CLOSEABLE) &&
1003
12.7k
            ( mpWindowImpl->mbFloatWin || ((GetType() == WindowType::BORDERWINDOW) && static_cast<ImplBorderWindow*>(this)->mbFloatWindow) || (nStyle & WB_SYSTEMFLOATWIN) ) ) ||
1004
            // 2. borderwindows of floaters with ownerdraw decoration
1005
12.7k
            ((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
12.7k
        else if( mpWindowImpl->mbFloatWin )
1012
0
            nFrameStyle |= SalFrameStyleFlags::TOOLWINDOW;
1013
1014
12.7k
        if( nStyle & WB_INTROWIN )
1015
0
            nFrameStyle |= SalFrameStyleFlags::INTRO;
1016
12.7k
        if( nStyle & WB_TOOLTIPWIN )
1017
0
            nFrameStyle |= SalFrameStyleFlags::TOOLTIP;
1018
1019
12.7k
        if( nStyle & WB_NOSHADOW )
1020
0
            nFrameStyle |= SalFrameStyleFlags::NOSHADOW;
1021
1022
12.7k
        if( nStyle & WB_SYSTEMCHILDWINDOW )
1023
0
            nFrameStyle |= SalFrameStyleFlags::SYSTEMCHILD;
1024
1025
12.7k
        switch (mpWindowImpl->meType)
1026
12.7k
        {
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
12.7k
            default:
1038
12.7k
                break;
1039
12.7k
        }
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
12.7k
        if( nStyle & WB_DEFAULTWIN )
1046
30
            nFrameStyle |= SalFrameStyleFlags::NOICON;
1047
1048
12.7k
        SalFrame* pParentFrame = nullptr;
1049
12.7k
        if ( pParent )
1050
0
            pParentFrame = pParent->mpWindowImpl->mpFrame;
1051
12.7k
        SalFrame* pFrame;
1052
12.7k
        if ( pSystemParentData )
1053
0
            pFrame = pSVData->mpDefInst->CreateChildFrame( pSystemParentData, nFrameStyle | SalFrameStyleFlags::PLUG );
1054
12.7k
        else
1055
12.7k
            pFrame = pSVData->mpDefInst->CreateFrame( pParentFrame, nFrameStyle );
1056
12.7k
        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
12.7k
        pFrame->SetCallback( this, ImplWindowFrameProc );
1065
1066
        // set window frame data
1067
12.7k
        mpWindowImpl->mpFrameData     = new ImplFrameData( this );
1068
12.7k
        mpWindowImpl->mpFrame         = pFrame;
1069
12.7k
        mpWindowImpl->mpFrameWindow   = this;
1070
12.7k
        mpWindowImpl->mpOverlapWindow = this;
1071
1072
12.7k
        if (!(nStyle & WB_DEFAULTWIN) && mpWindowImpl->mbDoubleBufferingRequested)
1073
0
            RequestDoubleBuffering(true);
1074
1075
12.7k
        if ( pRealParent && IsTopWindow() )
1076
0
        {
1077
0
            ImplWinData* pParentWinData = pRealParent->ImplGetWinData();
1078
0
            pParentWinData->maTopWindowChildren.emplace_back(this );
1079
0
        }
1080
12.7k
    }
1081
1082
    // init data
1083
241k
    mpWindowImpl->mpRealParent = pRealParent;
1084
1085
    // #99318: make sure fontcache and list is available before call to SetSettings
1086
241k
    mpWindowImpl->mxOutDev->mxFontCollection = mpWindowImpl->mpFrameData->mxFontCollection;
1087
241k
    mpWindowImpl->mxOutDev->mxFontCache = mpWindowImpl->mpFrameData->mxFontCache;
1088
1089
241k
    if ( mpWindowImpl->mbFrame )
1090
12.7k
    {
1091
12.7k
        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
12.7k
        else
1097
12.7k
        {
1098
12.7k
            if (auto* pGraphics = GetOutDev()->GetGraphics())
1099
12.7k
            {
1100
12.7k
                pGraphics->GetResolution(mpWindowImpl->mpFrameData->mnDPIX,
1101
12.7k
                                         mpWindowImpl->mpFrameData->mnDPIY);
1102
12.7k
            }
1103
12.7k
        }
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
12.7k
        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
12.7k
        if ( !pSVData->maAppData.mbSettingsInit &&
1113
12.7k
             ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN))
1114
12.7k
             )
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
12.7k
        if ( nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_APP) )
1126
12.7k
            mpWindowImpl->mpFrame->GetClientSize( mpWindowImpl->mxOutDev->mnOutWidth, mpWindowImpl->mxOutDev->mnOutHeight );
1127
12.7k
    }
1128
228k
    else
1129
228k
    {
1130
228k
        if ( pParent )
1131
228k
        {
1132
228k
            if ( !ImplIsOverlapWindow() )
1133
228k
            {
1134
228k
                mpWindowImpl->mbDisabled          = pParent->mpWindowImpl->mbDisabled;
1135
228k
                mpWindowImpl->mbInputDisabled     = pParent->mpWindowImpl->mbInputDisabled;
1136
228k
                mpWindowImpl->meAlwaysInputMode   = pParent->mpWindowImpl->meAlwaysInputMode;
1137
228k
            }
1138
1139
228k
            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
228k
        }
1146
1147
228k
    }
1148
1149
    // setup the scale factor for HiDPI displays
1150
241k
    mpWindowImpl->mxOutDev->mnDPIScalePercentage = CountDPIScaleFactor(mpWindowImpl->mpFrameData->mnDPIY);
1151
241k
    mpWindowImpl->mxOutDev->mnDPIX = mpWindowImpl->mpFrameData->mnDPIX;
1152
241k
    mpWindowImpl->mxOutDev->mnDPIY = mpWindowImpl->mpFrameData->mnDPIY;
1153
1154
241k
    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
241k
    else
1171
241k
    {
1172
241k
        mpWindowImpl->mxOutDev->maFont = OutputDevice::GetDefaultFont( DefaultFontType::FIXED, LANGUAGE_ENGLISH_US, GetDefaultFontFlags::NONE );
1173
241k
    }
1174
1175
241k
    ImplPointToLogic(*GetOutDev(), mpWindowImpl->mxOutDev->maFont);
1176
1177
241k
    (void)ImplUpdatePos();
1178
1179
    // calculate app font res (except for the Intro Window or the default window)
1180
241k
    if ( mpWindowImpl->mbFrame && !pSVData->maGDIData.mnAppFontX && ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN)) )
1181
2
        ImplInitAppFontData( this );
1182
241k
}
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
286k
{
1228
286k
    if (!mpWindowImpl->mpWinData)
1229
216k
    {
1230
216k
        static const char* pNoNWF = getenv( "SAL_NO_NWF" );
1231
1232
216k
        const_cast<vcl::Window*>(this)->mpWindowImpl->mpWinData.reset(new ImplWinData);
1233
216k
        mpWindowImpl->mpWinData->mbEnableNativeWidget = !(pNoNWF && *pNoNWF); // true: try to draw this control with native theme API
1234
216k
    }
1235
1236
286k
    return mpWindowImpl->mpWinData.get();
1237
286k
}
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
79.5k
{
1349
    // recalculate AppFont-resolution and DPI-resolution
1350
79.5k
    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
79.5k
    else if ( mpWindowImpl->mpParent )
1361
79.5k
    {
1362
79.5k
        GetOutDev()->mnDPIX  = mpWindowImpl->mpParent->GetOutDev()->mnDPIX;
1363
79.5k
        GetOutDev()->mnDPIY  = mpWindowImpl->mpParent->GetOutDev()->mnDPIY;
1364
79.5k
        GetOutDev()->mnDPIScalePercentage = mpWindowImpl->mpParent->GetOutDev()->mnDPIScalePercentage;
1365
79.5k
    }
1366
1367
    // update the recalculated values for logical units
1368
    // and also tools belonging to the values
1369
79.5k
    if (IsMapModeEnabled())
1370
79.5k
    {
1371
79.5k
        MapMode aMapMode = GetMapMode();
1372
79.5k
        SetMapMode();
1373
79.5k
        SetMapMode( aMapMode );
1374
79.5k
    }
1375
79.5k
}
1376
1377
void Window::ImplPointToLogic(vcl::RenderContext const & rRenderContext, vcl::Font& rFont,
1378
                            bool bUseRenderContextDPI) const
1379
271k
{
1380
271k
    Size aSize = rFont.GetFontSize();
1381
1382
271k
    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
271k
    aSize.setHeight( aSize.Height()
1390
271k
        * ( bUseRenderContextDPI ? rRenderContext.GetDPIY() : mpWindowImpl->mpFrameData->mnDPIY) );
1391
271k
    aSize.AdjustHeight(72/2 );
1392
271k
    aSize.setHeight( aSize.Height() / 72 );
1393
1394
271k
    aSize = rRenderContext.PixelToLogic(aSize);
1395
1396
271k
    rFont.SetFontSize(aSize);
1397
271k
}
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
309k
{
1419
309k
    bool bSysChild = false;
1420
1421
309k
    if ( ImplIsOverlapWindow() )
1422
12.7k
    {
1423
12.7k
        GetOutDev()->mnOutOffX  = mpWindowImpl->mnX;
1424
12.7k
        GetOutDev()->mnOutOffY  = mpWindowImpl->mnY;
1425
12.7k
    }
1426
296k
    else
1427
296k
    {
1428
296k
        vcl::Window* pParent = ImplGetParent();
1429
1430
296k
        GetOutDev()->mnOutOffX  = mpWindowImpl->mnX + pParent->GetOutDev()->mnOutOffX;
1431
296k
        GetOutDev()->mnOutOffY  = mpWindowImpl->mnY + pParent->GetOutDev()->mnOutOffY;
1432
296k
    }
1433
1434
309k
    VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
1435
309k
    while ( pChild )
1436
0
    {
1437
0
        if ( pChild->ImplUpdatePos() )
1438
0
            bSysChild = true;
1439
0
        pChild = pChild->mpWindowImpl->mpNext;
1440
0
    }
1441
1442
309k
    if ( mpWindowImpl->mpSysObj )
1443
0
        bSysChild = true;
1444
1445
309k
    return bSysChild;
1446
309k
}
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
148k
{
1464
148k
    bool    bNewPos         = false;
1465
148k
    bool    bNewSize        = false;
1466
148k
    bool    bCopyBits       = false;
1467
148k
    tools::Long    nOldOutOffX     = GetOutDev()->mnOutOffX;
1468
148k
    tools::Long    nOldOutOffY     = GetOutDev()->mnOutOffY;
1469
148k
    tools::Long    nOldOutWidth    = GetOutDev()->mnOutWidth;
1470
148k
    tools::Long    nOldOutHeight   = GetOutDev()->mnOutHeight;
1471
148k
    std::unique_ptr<vcl::Region> pOverlapRegion;
1472
148k
    std::unique_ptr<vcl::Region> pOldRegion;
1473
1474
148k
    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
148k
    bool bnXRecycled = false; // avoid duplicate mirroring in RTL case
1489
148k
    if ( nFlags & PosSizeFlags::Width )
1490
148k
    {
1491
148k
        if(!( nFlags & PosSizeFlags::X ))
1492
72.0k
        {
1493
72.0k
            nX = mpWindowImpl->mnX;
1494
72.0k
            nFlags |= PosSizeFlags::X;
1495
72.0k
            bnXRecycled = true; // we're using a mnX which was already mirrored in RTL case
1496
72.0k
        }
1497
1498
148k
        if ( nWidth < 0 )
1499
8.47k
            nWidth = 0;
1500
148k
        if ( nWidth != GetOutDev()->mnOutWidth )
1501
38.1k
        {
1502
38.1k
            GetOutDev()->mnOutWidth = nWidth;
1503
38.1k
            bNewSize = true;
1504
38.1k
            bCopyBits = false;
1505
38.1k
        }
1506
148k
    }
1507
148k
    if ( nFlags & PosSizeFlags::Height )
1508
148k
    {
1509
148k
        if ( nHeight < 0 )
1510
8.47k
            nHeight = 0;
1511
148k
        if ( nHeight != GetOutDev()->mnOutHeight )
1512
38.1k
        {
1513
38.1k
            GetOutDev()->mnOutHeight = nHeight;
1514
38.1k
            bNewSize = true;
1515
38.1k
            bCopyBits = false;
1516
38.1k
        }
1517
148k
    }
1518
1519
148k
    if ( nFlags & PosSizeFlags::X )
1520
148k
    {
1521
148k
        tools::Long nOrgX = nX;
1522
148k
        Point aPtDev( nX+GetOutDev()->mnOutOffX, 0 );
1523
148k
        OutputDevice *pOutDev = GetOutDev();
1524
148k
        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
148k
        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
148k
        if ( mpWindowImpl->mnAbsScreenX != aPtDev.X() || nX != mpWindowImpl->mnX || nOrgX != mpWindowImpl->maPos.X() )
1555
67.8k
        {
1556
67.8k
            if ( bCopyBits && !pOverlapRegion )
1557
0
            {
1558
0
                pOverlapRegion.reset( new vcl::Region() );
1559
0
                ImplCalcOverlapRegion( GetOutputRectPixel(),
1560
0
                                       *pOverlapRegion, false, true );
1561
0
            }
1562
67.8k
            mpWindowImpl->mnX = nX;
1563
67.8k
            mpWindowImpl->maPos.setX( nOrgX );
1564
67.8k
            mpWindowImpl->mnAbsScreenX = aPtDev.X();
1565
67.8k
            bNewPos = true;
1566
67.8k
        }
1567
148k
    }
1568
148k
    if ( nFlags & PosSizeFlags::Y )
1569
76.2k
    {
1570
        // check maPos as well, as it could have been changed for client windows (ImplCallMove())
1571
76.2k
        if ( nY != mpWindowImpl->mnY || nY != mpWindowImpl->maPos.Y() )
1572
8.47k
        {
1573
8.47k
            if ( bCopyBits && !pOverlapRegion )
1574
0
            {
1575
0
                pOverlapRegion.reset( new vcl::Region() );
1576
0
                ImplCalcOverlapRegion( GetOutputRectPixel(),
1577
0
                                       *pOverlapRegion, false, true );
1578
0
            }
1579
8.47k
            mpWindowImpl->mnY = nY;
1580
8.47k
            mpWindowImpl->maPos.setY( nY );
1581
8.47k
            bNewPos = true;
1582
8.47k
        }
1583
76.2k
    }
1584
1585
148k
    if ( !(bNewPos || bNewSize) )
1586
67.8k
        return;
1587
1588
80.5k
    bool bUpdateSysObjPos = false;
1589
80.5k
    if ( bNewPos )
1590
67.8k
        bUpdateSysObjPos = ImplUpdatePos();
1591
1592
    // the borderwindow always specifies the position for its client window
1593
80.5k
    if ( mpWindowImpl->mpBorderWindow )
1594
8.47k
        mpWindowImpl->maPos = mpWindowImpl->mpBorderWindow->mpWindowImpl->maPos;
1595
1596
80.5k
    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
80.5k
    if ( IsVisible() )
1623
8.47k
    {
1624
8.47k
        if ( bNewPos )
1625
8.47k
        {
1626
8.47k
            ImplCallMove();
1627
8.47k
        }
1628
8.47k
        if ( bNewSize )
1629
0
        {
1630
0
            ImplCallResize();
1631
0
        }
1632
8.47k
    }
1633
72.0k
    else
1634
72.0k
    {
1635
72.0k
        if ( bNewPos )
1636
59.3k
            mpWindowImpl->mbCallMove = true;
1637
72.0k
        if ( bNewSize )
1638
63.5k
            mpWindowImpl->mbCallResize = true;
1639
72.0k
    }
1640
1641
80.5k
    bool bUpdateSysObjClip = false;
1642
80.5k
    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
80.5k
    if ( bUpdateSysObjClip )
1736
0
        ImplUpdateSysObjClip();
1737
80.5k
    if ( bUpdateSysObjPos )
1738
0
        ImplUpdateSysObjPos();
1739
80.5k
    if ( bNewSize && mpWindowImpl->mpSysObj )
1740
0
        mpWindowImpl->mpSysObj->SetPosSize( GetOutDev()->mnOutOffX, GetOutDev()->mnOutOffY, GetOutDev()->mnOutWidth, GetOutDev()->mnOutHeight );
1741
80.5k
}
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
16.9k
{
1792
16.9k
    ImplGetFrame()->SetModalHierarchyHdl(rLink);
1793
16.9k
}
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
50.7k
void Window::Move() {}
1836
1837
16.9k
void Window::Resize() {}
1838
1839
0
void Window::Activate() {}
1840
1841
12.7k
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::SetHelpHdl(const Link<vcl::Window&, bool>& rLink)
1864
0
{
1865
0
    if (mpWindowImpl) // may be called after dispose
1866
0
    {
1867
0
        mpWindowImpl->maHelpRequestHdl = rLink;
1868
0
    }
1869
0
}
1870
1871
void Window::RequestHelp( const HelpEvent& rHEvt )
1872
0
{
1873
    // if Balloon-Help is requested, show the balloon
1874
    // with help text set
1875
0
    if ( rHEvt.GetMode() & HelpEventMode::BALLOON )
1876
0
    {
1877
0
        OUString rStr = GetHelpText();
1878
0
        if ( rStr.isEmpty() )
1879
0
            rStr = GetQuickHelpText();
1880
0
        if ( rStr.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() )
1881
0
            ImplGetParent()->RequestHelp( rHEvt );
1882
0
        else
1883
0
        {
1884
0
            Point aPos = GetPosPixel();
1885
0
            if ( ImplGetParent() && !ImplIsOverlapWindow() )
1886
0
                aPos = OutputToScreenPixel(Point(0, 0));
1887
0
            tools::Rectangle   aRect( aPos, GetSizePixel() );
1888
1889
0
            Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), aRect, rStr );
1890
0
        }
1891
0
    }
1892
0
    else if ( rHEvt.GetMode() & HelpEventMode::QUICK )
1893
0
    {
1894
0
        const OUString& rStr = GetQuickHelpText();
1895
0
        if ( rStr.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() )
1896
0
            ImplGetParent()->RequestHelp( rHEvt );
1897
0
        else
1898
0
        {
1899
0
            Point aPos = GetPosPixel();
1900
0
            if ( ImplGetParent() && !ImplIsOverlapWindow() )
1901
0
                aPos = OutputToScreenPixel(Point(0, 0));
1902
0
            tools::Rectangle   aRect( aPos, GetSizePixel() );
1903
0
            Help::ShowQuickHelp( this, aRect, rStr, QuickHelpFlags::CtrlText );
1904
0
        }
1905
0
    }
1906
0
    else if (!mpWindowImpl->maHelpRequestHdl.IsSet() || mpWindowImpl->maHelpRequestHdl.Call(*this))
1907
0
    {
1908
0
        OUString aStrHelpId( GetHelpId() );
1909
0
        if ( aStrHelpId.isEmpty() && ImplGetParent() )
1910
0
            ImplGetParent()->RequestHelp( rHEvt );
1911
0
        else
1912
0
        {
1913
0
            Help* pHelp = Application::GetHelp();
1914
0
            if ( pHelp )
1915
0
            {
1916
0
                if( !aStrHelpId.isEmpty() )
1917
0
                    pHelp->Start( aStrHelpId, this );
1918
0
                else
1919
0
                    pHelp->Start( u"" OOO_HELP_INDEX ""_ustr, this );
1920
0
            }
1921
0
        }
1922
0
    }
1923
0
}
1924
1925
void Window::Command( const CommandEvent& rCEvt )
1926
0
{
1927
0
    CallEventListeners( VclEventId::WindowCommand, const_cast<CommandEvent *>(&rCEvt) );
1928
1929
0
    NotifyEvent aNEvt( NotifyEventType::COMMAND, this, &rCEvt );
1930
0
    if ( !CompatNotify( aNEvt ) )
1931
0
        mpWindowImpl->mbCommand = true;
1932
0
}
1933
1934
void Window::Tracking( const TrackingEvent& rTEvt )
1935
0
{
1936
1937
0
    ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1938
0
    if( pWrapper )
1939
0
        pWrapper->Tracking( rTEvt );
1940
0
}
1941
1942
void Window::StateChanged(StateChangedType eType)
1943
131k
{
1944
131k
    switch (eType)
1945
131k
    {
1946
        //stuff that doesn't invalidate the layout
1947
0
        case StateChangedType::ControlForeground:
1948
12.7k
        case StateChangedType::ControlBackground:
1949
29.4k
        case StateChangedType::UpdateMode:
1950
29.4k
        case StateChangedType::ReadOnly:
1951
29.4k
        case StateChangedType::Enable:
1952
29.4k
        case StateChangedType::State:
1953
29.4k
        case StateChangedType::Data:
1954
29.4k
        case StateChangedType::InitShow:
1955
29.4k
        case StateChangedType::ControlFocus:
1956
29.4k
            break;
1957
        //stuff that does invalidate the layout
1958
101k
        default:
1959
101k
            queue_resize(eType);
1960
101k
            break;
1961
131k
    }
1962
131k
}
1963
1964
void Window::SetStyle( WinBits nStyle )
1965
0
{
1966
0
    if ( mpWindowImpl && mpWindowImpl->mnStyle != nStyle )
1967
0
    {
1968
0
        mpWindowImpl->mnPrevStyle = mpWindowImpl->mnStyle;
1969
0
        mpWindowImpl->mnStyle = nStyle;
1970
0
        CompatStateChanged( StateChangedType::Style );
1971
0
    }
1972
0
}
1973
1974
void Window::SetExtendedStyle( WindowExtendedStyle nExtendedStyle )
1975
89.1k
{
1976
1977
89.1k
    if ( mpWindowImpl->mnExtendedStyle == nExtendedStyle )
1978
75.1k
        return;
1979
1980
13.9k
    vcl::Window* pWindow = ImplGetBorderWindow();
1981
13.9k
    if( ! pWindow )
1982
0
        pWindow = this;
1983
13.9k
    if( pWindow->mpWindowImpl->mbFrame )
1984
13.9k
    {
1985
13.9k
        SalExtStyle nExt = 0;
1986
13.9k
        if( nExtendedStyle & WindowExtendedStyle::Document )
1987
12.7k
            nExt |= SAL_FRAME_EXT_STYLE_DOCUMENT;
1988
13.9k
        if( nExtendedStyle & WindowExtendedStyle::DocModified )
1989
0
            nExt |= SAL_FRAME_EXT_STYLE_DOCMODIFIED;
1990
1991
13.9k
        pWindow->ImplGetFrame()->SetExtendedFrameStyle( nExt );
1992
13.9k
    }
1993
13.9k
    mpWindowImpl->mnExtendedStyle = nExtendedStyle;
1994
13.9k
}
1995
1996
void Window::SetBorderStyle( WindowBorderStyle nBorderStyle )
1997
8.47k
{
1998
1999
8.47k
    if ( !mpWindowImpl->mpBorderWindow )
2000
0
        return;
2001
2002
8.47k
    if( nBorderStyle == WindowBorderStyle::REMOVEBORDER &&
2003
8.47k
        ! mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame &&
2004
8.47k
        mpWindowImpl->mpBorderWindow->mpWindowImpl->mpParent
2005
8.47k
        )
2006
0
    {
2007
        // this is a little awkward: some controls (e.g. svtools ProgressBar)
2008
        // cannot avoid getting constructed with WB_BORDER but want to disable
2009
        // borders in case of NWF drawing. So they need a method to remove their border window
2010
0
        VclPtr<vcl::Window> pBorderWin = mpWindowImpl->mpBorderWindow;
2011
        // remove us as border window's client
2012
0
        pBorderWin->mpWindowImpl->mpClientWindow = nullptr;
2013
0
        mpWindowImpl->mpBorderWindow = nullptr;
2014
0
        mpWindowImpl->mpRealParent = pBorderWin->mpWindowImpl->mpParent;
2015
        // reparent us above the border window
2016
0
        SetParent( pBorderWin->mpWindowImpl->mpParent );
2017
        // set us to the position and size of our previous border
2018
0
        Point aBorderPos( pBorderWin->GetPosPixel() );
2019
0
        Size aBorderSize( pBorderWin->GetSizePixel() );
2020
0
        setPosSizePixel( aBorderPos.X(), aBorderPos.Y(), aBorderSize.Width(), aBorderSize.Height() );
2021
        // release border window
2022
0
        pBorderWin.disposeAndClear();
2023
2024
        // set new style bits
2025
0
        SetStyle( GetStyle() & (~WB_BORDER) );
2026
0
    }
2027
8.47k
    else
2028
8.47k
    {
2029
8.47k
        if ( mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW )
2030
8.47k
            static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetBorderStyle( nBorderStyle );
2031
0
        else
2032
0
            mpWindowImpl->mpBorderWindow->SetBorderStyle( nBorderStyle );
2033
8.47k
    }
2034
8.47k
}
2035
2036
WindowBorderStyle Window::GetBorderStyle() const
2037
0
{
2038
2039
0
    if ( mpWindowImpl->mpBorderWindow )
2040
0
    {
2041
0
        if ( mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW )
2042
0
            return static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->GetBorderStyle();
2043
0
        else
2044
0
            return mpWindowImpl->mpBorderWindow->GetBorderStyle();
2045
0
    }
2046
2047
0
    return WindowBorderStyle::NONE;
2048
0
}
2049
2050
tools::Long Window::CalcTitleWidth() const
2051
0
{
2052
2053
0
    if ( mpWindowImpl->mpBorderWindow )
2054
0
    {
2055
0
        if ( mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW )
2056
0
            return static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->CalcTitleWidth();
2057
0
        else
2058
0
            return mpWindowImpl->mpBorderWindow->CalcTitleWidth();
2059
0
    }
2060
0
    else if ( mpWindowImpl->mbFrame && (mpWindowImpl->mnStyle & WB_MOVEABLE) )
2061
0
    {
2062
        // we guess the width for frame windows as we do not know the
2063
        // border of external dialogs
2064
0
        const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
2065
0
        vcl::Font aFont = GetFont();
2066
0
        const_cast<vcl::Window*>(this)->SetPointFont(const_cast<::OutputDevice&>(*GetOutDev()), rStyleSettings.GetTitleFont());
2067
0
        tools::Long nTitleWidth = GetTextWidth( GetText() );
2068
0
        const_cast<vcl::Window*>(this)->SetFont( aFont );
2069
0
        nTitleWidth += rStyleSettings.GetTitleHeight() * 3;
2070
0
        nTitleWidth += StyleSettings::GetBorderSize() * 2;
2071
0
        nTitleWidth += 10;
2072
0
        return nTitleWidth;
2073
0
    }
2074
2075
0
    return 0;
2076
0
}
2077
2078
void Window::SetInputContext( const InputContext& rInputContext )
2079
16.9k
{
2080
2081
16.9k
    mpWindowImpl->maInputContext = rInputContext;
2082
16.9k
    if ( !mpWindowImpl->mbInFocusHdl && HasFocus() )
2083
0
        ImplNewInputContext();
2084
16.9k
}
2085
2086
void Window::PostExtTextInputEvent(VclEventId nType, const OUString& rText)
2087
0
{
2088
0
    switch (nType)
2089
0
    {
2090
0
    case VclEventId::ExtTextInput:
2091
0
    {
2092
0
        std::unique_ptr<ExtTextInputAttr[]> pAttr(new ExtTextInputAttr[rText.getLength()]);
2093
0
        for (int i = 0; i < rText.getLength(); ++i) {
2094
0
            pAttr[i] = ExtTextInputAttr::Underline;
2095
0
        }
2096
0
        SalExtTextInputEvent aEvent { rText, pAttr.get(), rText.getLength(), EXTTEXTINPUT_CURSOR_OVERWRITE };
2097
0
        ImplWindowFrameProc(this, SalEvent::ExtTextInput, &aEvent);
2098
0
    }
2099
0
    break;
2100
0
    case VclEventId::EndExtTextInput:
2101
0
        ImplWindowFrameProc(this, SalEvent::EndExtTextInput, nullptr);
2102
0
        break;
2103
0
    default:
2104
0
        assert(false);
2105
0
    }
2106
0
}
2107
2108
void Window::EndExtTextInput()
2109
0
{
2110
0
    if ( mpWindowImpl->mbExtTextInput )
2111
0
        ImplGetFrame()->EndExtTextInput( EndExtTextInputFlags::Complete );
2112
0
}
2113
2114
void Window::SetCursorRect( const tools::Rectangle* pRect, tools::Long nExtTextInputWidth )
2115
0
{
2116
2117
0
    ImplWinData* pWinData = ImplGetWinData();
2118
0
    if ( pWinData->mpCursorRect )
2119
0
    {
2120
0
        if ( pRect )
2121
0
            pWinData->mpCursorRect = *pRect;
2122
0
        else
2123
0
            pWinData->mpCursorRect.reset();
2124
0
    }
2125
0
    else
2126
0
    {
2127
0
        if ( pRect )
2128
0
            pWinData->mpCursorRect = *pRect;
2129
0
    }
2130
2131
0
    pWinData->mnCursorExtWidth = nExtTextInputWidth;
2132
2133
0
}
2134
2135
const tools::Rectangle* Window::GetCursorRect() const
2136
0
{
2137
2138
0
    ImplWinData* pWinData = ImplGetWinData();
2139
0
    return pWinData->mpCursorRect ? &*pWinData->mpCursorRect : nullptr;
2140
0
}
2141
2142
tools::Long Window::GetCursorExtTextInputWidth() const
2143
0
{
2144
2145
0
    ImplWinData* pWinData = ImplGetWinData();
2146
0
    return pWinData->mnCursorExtWidth;
2147
0
}
2148
2149
0
void Window::SetCompositionCharRect( const tools::Rectangle* pRect, tools::Long nCompositionLength, bool bVertical ) {
2150
2151
0
    ImplWinData* pWinData = ImplGetWinData();
2152
0
    pWinData->mpCompositionCharRects.reset();
2153
0
    pWinData->mbVertical = bVertical;
2154
0
    pWinData->mnCompositionCharRects = nCompositionLength;
2155
0
    if ( pRect && (nCompositionLength > 0) )
2156
0
    {
2157
0
        pWinData->mpCompositionCharRects.reset( new tools::Rectangle[nCompositionLength] );
2158
0
        for (tools::Long i = 0; i < nCompositionLength; ++i)
2159
0
            pWinData->mpCompositionCharRects[i] = pRect[i];
2160
0
    }
2161
0
}
2162
2163
void Window::CollectChildren(::std::vector<vcl::Window *>& rAllChildren )
2164
0
{
2165
0
    rAllChildren.push_back( this );
2166
2167
0
    VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
2168
0
    while ( pChild )
2169
0
    {
2170
0
        pChild->CollectChildren( rAllChildren );
2171
0
        pChild = pChild->mpWindowImpl->mpNext;
2172
0
    }
2173
0
}
2174
2175
void Window::SetPointFont(vcl::RenderContext& rRenderContext, const vcl::Font& rFont,
2176
                          bool bUseRenderContextDPI)
2177
29.6k
{
2178
29.6k
    vcl::Font aFont = rFont;
2179
29.6k
    ImplPointToLogic(rRenderContext, aFont, bUseRenderContextDPI);
2180
29.6k
    rRenderContext.SetFont(aFont);
2181
29.6k
}
2182
2183
vcl::Font Window::GetPointFont(vcl::RenderContext const & rRenderContext) const
2184
0
{
2185
0
    vcl::Font aFont = rRenderContext.GetFont();
2186
0
    ImplLogicToPoint(rRenderContext, aFont);
2187
0
    return aFont;
2188
0
}
2189
2190
void Window::Show(bool bVisible, ShowFlags nFlags)
2191
313k
{
2192
313k
    if ( !mpWindowImpl || mpWindowImpl->mbVisible == bVisible )
2193
229k
        return;
2194
2195
84.5k
    VclPtr<vcl::Window> xWindow(this);
2196
2197
84.5k
    bool bRealVisibilityChanged = false;
2198
84.5k
    mpWindowImpl->mbVisible = bVisible;
2199
2200
84.5k
    if ( !bVisible )
2201
42.2k
    {
2202
42.2k
        ImplHideAllOverlaps();
2203
42.2k
        if( !xWindow->mpWindowImpl )
2204
0
            return;
2205
2206
42.2k
        if ( mpWindowImpl->mpBorderWindow )
2207
8.47k
        {
2208
8.47k
            bool bOldUpdate = mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate;
2209
8.47k
            if ( mpWindowImpl->mbNoParentUpdate )
2210
0
                mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = true;
2211
8.47k
            mpWindowImpl->mpBorderWindow->Show( false, nFlags );
2212
8.47k
            mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = bOldUpdate;
2213
8.47k
        }
2214
33.8k
        else if ( mpWindowImpl->mbFrame )
2215
0
        {
2216
0
            mpWindowImpl->mbSuppressAccessibilityEvents = true;
2217
0
            mpWindowImpl->mpFrame->Show( false );
2218
0
        }
2219
2220
42.2k
        CompatStateChanged( StateChangedType::Visible );
2221
2222
42.2k
        if ( mpWindowImpl->mbReallyVisible )
2223
0
        {
2224
0
            if ( mpWindowImpl->mbInitWinClipRegion )
2225
0
                ImplInitWinClipRegion();
2226
2227
0
            vcl::Region aInvRegion = mpWindowImpl->maWinClipRegion;
2228
2229
0
            if( !xWindow->mpWindowImpl )
2230
0
                return;
2231
2232
0
            bRealVisibilityChanged = mpWindowImpl->mbReallyVisible;
2233
0
            ImplResetReallyVisible();
2234
0
            ImplSetClipFlag();
2235
2236
0
            if ( ImplIsOverlapWindow() && !mpWindowImpl->mbFrame )
2237
0
            {
2238
                // convert focus
2239
0
                if ( !(nFlags & ShowFlags::NoFocusChange) && HasChildPathFocus() )
2240
0
                {
2241
0
                    if ( mpWindowImpl->mpOverlapWindow->IsEnabled() &&
2242
0
                         mpWindowImpl->mpOverlapWindow->IsInputEnabled() &&
2243
0
                         ! mpWindowImpl->mpOverlapWindow->IsInModalMode()
2244
0
                         )
2245
0
                        mpWindowImpl->mpOverlapWindow->GrabFocus();
2246
0
                }
2247
0
            }
2248
2249
0
            if ( !mpWindowImpl->mbFrame )
2250
0
            {
2251
0
                if (mpWindowImpl->mpWinData && mpWindowImpl->mpWinData->mbEnableNativeWidget)
2252
0
                {
2253
                    /*
2254
                    * #i48371# native theming: some themes draw outside the control
2255
                    * area we tell them to (bad thing, but we cannot do much about it ).
2256
                    * On hiding these controls they get invalidated with their window rectangle
2257
                    * which leads to the parts outside the control area being left and not
2258
                    * invalidated. Workaround: invalidate an area on the parent, too
2259
                    */
2260
0
                    const int workaround_border = 5;
2261
0
                    tools::Rectangle aBounds( aInvRegion.GetBoundRect() );
2262
0
                    aBounds.AdjustLeft( -workaround_border );
2263
0
                    aBounds.AdjustTop( -workaround_border );
2264
0
                    aBounds.AdjustRight(workaround_border );
2265
0
                    aBounds.AdjustBottom(workaround_border );
2266
0
                    aInvRegion = aBounds;
2267
0
                }
2268
0
                if ( !mpWindowImpl->mbNoParentUpdate )
2269
0
                {
2270
0
                    if ( !aInvRegion.IsEmpty() )
2271
0
                        ImplInvalidateParentFrameRegion( aInvRegion );
2272
0
                }
2273
0
                ImplGenerateMouseMove();
2274
0
            }
2275
0
        }
2276
42.2k
    }
2277
42.2k
    else
2278
42.2k
    {
2279
        // inherit native widget flag for form controls
2280
        // required here, because frames never show up in the child hierarchy - which should be fixed...
2281
        // eg, the drop down of a combobox which is a system floating window
2282
42.2k
        if( mpWindowImpl->mbFrame && GetParent() && !GetParent()->isDisposed() &&
2283
42.2k
            GetParent()->IsCompoundControl() &&
2284
42.2k
            GetParent()->IsNativeWidgetEnabled() != IsNativeWidgetEnabled() &&
2285
42.2k
            !(GetStyle() & WB_TOOLTIPWIN) )
2286
0
        {
2287
0
            EnableNativeWidget( GetParent()->IsNativeWidgetEnabled() );
2288
0
        }
2289
2290
42.2k
        if ( mpWindowImpl->mbCallMove )
2291
42.2k
        {
2292
42.2k
            ImplCallMove();
2293
42.2k
        }
2294
42.2k
        if ( mpWindowImpl->mbCallResize )
2295
42.2k
        {
2296
42.2k
            ImplCallResize();
2297
42.2k
        }
2298
2299
42.2k
        CompatStateChanged( StateChangedType::Visible );
2300
2301
42.2k
        vcl::Window* pTestParent;
2302
42.2k
        if ( ImplIsOverlapWindow() )
2303
0
            pTestParent = mpWindowImpl->mpOverlapWindow;
2304
42.2k
        else
2305
42.2k
            pTestParent = ImplGetParent();
2306
42.2k
        if ( mpWindowImpl->mbFrame || pTestParent->mpWindowImpl->mbReallyVisible )
2307
0
        {
2308
            // if a window becomes visible, send all child windows a StateChange,
2309
            // such that these can initialise themselves
2310
0
            ImplCallInitShow();
2311
2312
            // If it is a SystemWindow it automatically pops up on top of
2313
            // all other windows if needed.
2314
0
            if (ImplIsOverlapWindow())
2315
0
            {
2316
0
                if (!(nFlags & ShowFlags::NoActivate))
2317
0
                {
2318
0
                    ImplStartToTop((nFlags & ShowFlags::ForegroundTask) ? ToTopFlags::ForegroundTask
2319
0
                                                                        : ToTopFlags::NONE);
2320
0
                    ImplFocusToTop(ToTopFlags::NONE, false);
2321
2322
0
                    if (!(nFlags & ShowFlags::ForegroundTask))
2323
0
                    {
2324
                        // Inform user about window if we did not popup it at foreground
2325
0
                        FlashWindow();
2326
0
                    }
2327
0
                }
2328
0
            }
2329
2330
            // adjust mpWindowImpl->mbReallyVisible
2331
0
            bRealVisibilityChanged = !mpWindowImpl->mbReallyVisible;
2332
0
            ImplSetReallyVisible();
2333
2334
            // assure clip rectangles will be recalculated
2335
0
            ImplSetClipFlag();
2336
2337
0
            if ( !mpWindowImpl->mbFrame )
2338
0
            {
2339
0
                InvalidateFlags nInvalidateFlags = InvalidateFlags::Children;
2340
0
                if( ! IsPaintTransparent() )
2341
0
                    nInvalidateFlags |= InvalidateFlags::NoTransparent;
2342
0
                ImplInvalidate( nullptr, nInvalidateFlags );
2343
0
                ImplGenerateMouseMove();
2344
0
            }
2345
0
        }
2346
2347
42.2k
        if ( mpWindowImpl->mpBorderWindow )
2348
8.47k
            mpWindowImpl->mpBorderWindow->Show( true, nFlags );
2349
33.8k
        else if ( mpWindowImpl->mbFrame )
2350
0
        {
2351
            // #106431#, hide SplashScreen
2352
0
            ImplSVData* pSVData = ImplGetSVData();
2353
0
            if ( !pSVData->mpIntroWindow )
2354
0
            {
2355
                // The right way would be just to call this (not even in the 'if')
2356
0
                auto pApp = GetpApp();
2357
0
                if ( pApp )
2358
0
                    pApp->InitFinished();
2359
0
            }
2360
0
            else if ( !ImplIsWindowOrChild( pSVData->mpIntroWindow ) )
2361
0
            {
2362
                // ... but the VCL splash is broken, and it needs this
2363
                // (for ./soffice .uno:NewDoc)
2364
0
                pSVData->mpIntroWindow->Hide();
2365
0
            }
2366
2367
            //SAL_WARN_IF( mpWindowImpl->mbSuppressAccessibilityEvents, "vcl", "Window::Show() - Frame reactivated");
2368
0
            mpWindowImpl->mbSuppressAccessibilityEvents = false;
2369
2370
0
            mpWindowImpl->mbPaintFrame = true;
2371
0
            if (!Application::IsHeadlessModeEnabled())
2372
0
            {
2373
0
                bool bNoActivate(nFlags & (ShowFlags::NoActivate|ShowFlags::NoFocusChange));
2374
0
                mpWindowImpl->mpFrame->Show( true, bNoActivate );
2375
0
            }
2376
0
            if( !xWindow->mpWindowImpl )
2377
0
                return;
2378
2379
            // Query the correct size of the window, if we are waiting for
2380
            // a system resize
2381
0
            if ( mpWindowImpl->mbWaitSystemResize )
2382
0
            {
2383
0
                tools::Long nOutWidth;
2384
0
                tools::Long nOutHeight;
2385
0
                mpWindowImpl->mpFrame->GetClientSize( nOutWidth, nOutHeight );
2386
0
                ImplHandleResize( this, nOutWidth, nOutHeight );
2387
0
            }
2388
2389
0
            if (mpWindowImpl->mpFrameData->mpBuffer && mpWindowImpl->mpFrameData->mpBuffer->GetOutputSizePixel() != GetOutputSizePixel())
2390
                // Make sure that the buffer size matches the window size, even if no resize was needed.
2391
0
                mpWindowImpl->mpFrameData->mpBuffer->SetOutputSizePixel(GetOutputSizePixel());
2392
0
        }
2393
2394
42.2k
        if( !xWindow->mpWindowImpl )
2395
0
            return;
2396
2397
42.2k
        ImplShowAllOverlaps();
2398
42.2k
    }
2399
2400
84.5k
    if( !xWindow->mpWindowImpl )
2401
0
        return;
2402
2403
    // the SHOW/HIDE events also serve as indicators to send child creation/destroy events to the access bridge
2404
    // However, the access bridge only uses this event if the data member is not NULL (it's kind of a hack that
2405
    // we re-use the SHOW/HIDE events this way, with this particular semantics).
2406
    // Since #104887#, the notifications for the access bridge are done in Impl(Set|Reset)ReallyVisible. Here, we
2407
    // now only notify with a NULL data pointer, for all other clients except the access bridge.
2408
84.5k
    if ( !bRealVisibilityChanged )
2409
84.5k
        CallEventListeners( mpWindowImpl->mbVisible ? VclEventId::WindowShow : VclEventId::WindowHide );
2410
84.5k
}
2411
2412
Size Window::GetSizePixel() const
2413
88.1k
{
2414
88.1k
    if (!mpWindowImpl)
2415
0
    {
2416
0
        SAL_WARN("vcl.layout", "WTF no windowimpl");
2417
0
        return Size(0,0);
2418
0
    }
2419
2420
    // #i43257# trigger pending resize handler to assure correct window sizes
2421
88.1k
    if( mpWindowImpl->mpFrameData->maResizeIdle.IsActive() )
2422
0
    {
2423
0
        VclPtr<vcl::Window> xWindow( const_cast<Window*>(this) );
2424
0
        mpWindowImpl->mpFrameData->maResizeIdle.Stop();
2425
0
        mpWindowImpl->mpFrameData->maResizeIdle.Invoke( nullptr );
2426
0
        if( xWindow->isDisposed() )
2427
0
            return Size(0,0);
2428
0
    }
2429
2430
88.1k
    return Size( GetOutDev()->mnOutWidth + mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
2431
88.1k
                 GetOutDev()->mnOutHeight + mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder );
2432
88.1k
}
2433
2434
void Window::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
2435
                               sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
2436
37.3k
{
2437
37.3k
    rLeftBorder     = mpWindowImpl->mnLeftBorder;
2438
37.3k
    rTopBorder      = mpWindowImpl->mnTopBorder;
2439
37.3k
    rRightBorder    = mpWindowImpl->mnRightBorder;
2440
37.3k
    rBottomBorder   = mpWindowImpl->mnBottomBorder;
2441
37.3k
}
2442
2443
void Window::Enable( bool bEnable, bool bChild )
2444
0
{
2445
0
    if ( isDisposed() )
2446
0
        return;
2447
2448
0
    if ( !bEnable )
2449
0
    {
2450
        // the tracking mode will be stopped or the capture will be stolen
2451
        // when a window is disabled,
2452
0
        if ( IsTracking() )
2453
0
            EndTracking( TrackingEventFlags::Cancel );
2454
0
        if ( IsMouseCaptured() )
2455
0
            ReleaseMouse();
2456
        // try to pass focus to the next control
2457
        // if the window has focus and is contained in the dialog control
2458
        // mpWindowImpl->mbDisabled should only be set after a call of ImplDlgCtrlNextWindow().
2459
        // Otherwise ImplDlgCtrlNextWindow() should be used
2460
0
        if ( HasFocus() )
2461
0
            ImplDlgCtrlNextWindow();
2462
0
    }
2463
2464
0
    if ( mpWindowImpl->mpBorderWindow )
2465
0
    {
2466
0
        mpWindowImpl->mpBorderWindow->Enable( bEnable, false );
2467
0
        if ( (mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW) &&
2468
0
             static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->mpMenuBarWindow )
2469
0
            static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->mpMenuBarWindow->Enable( bEnable );
2470
0
    }
2471
2472
    // #i56102# restore app focus win in case the
2473
    // window was disabled when the frame focus changed
2474
0
    ImplSVData* pSVData = ImplGetSVData();
2475
0
    if (bEnable && pSVData->mpWinData->mpFocusWin == nullptr
2476
0
        && mpWindowImpl->mpFrameData->mbHasFocus && mpWindowImpl->mpFrameData->mpFocusWin == this)
2477
0
        pSVData->mpWinData->mpFocusWin = this;
2478
2479
0
    if ( mpWindowImpl->mbDisabled != !bEnable )
2480
0
    {
2481
0
        mpWindowImpl->mbDisabled = !bEnable;
2482
0
        if ( mpWindowImpl->mpSysObj )
2483
0
            mpWindowImpl->mpSysObj->Enable( bEnable && !mpWindowImpl->mbInputDisabled );
2484
0
        CompatStateChanged( StateChangedType::Enable );
2485
2486
0
        CallEventListeners( bEnable ? VclEventId::WindowEnabled : VclEventId::WindowDisabled );
2487
0
    }
2488
2489
0
    if ( bChild )
2490
0
    {
2491
0
        VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
2492
0
        while ( pChild )
2493
0
        {
2494
0
            pChild->Enable( bEnable, bChild );
2495
0
            pChild = pChild->mpWindowImpl->mpNext;
2496
0
        }
2497
0
    }
2498
2499
0
    if ( IsReallyVisible() )
2500
0
        ImplGenerateMouseMove();
2501
0
}
2502
2503
void Window::EnableInput( bool bEnable, bool bChild )
2504
0
{
2505
0
    if (!mpWindowImpl)
2506
0
        return;
2507
2508
0
    if ( mpWindowImpl->mpBorderWindow )
2509
0
    {
2510
0
        mpWindowImpl->mpBorderWindow->EnableInput( bEnable, false );
2511
0
        if ( (mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW) &&
2512
0
             static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->mpMenuBarWindow )
2513
0
            static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->mpMenuBarWindow->EnableInput( bEnable );
2514
0
    }
2515
2516
0
    if ( (!bEnable && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled) || bEnable )
2517
0
    {
2518
        // automatically stop the tracking mode or steal capture
2519
        // if the window is disabled
2520
0
        if ( !bEnable )
2521
0
        {
2522
0
            if ( IsTracking() )
2523
0
                EndTracking( TrackingEventFlags::Cancel );
2524
0
            if ( IsMouseCaptured() )
2525
0
                ReleaseMouse();
2526
0
        }
2527
2528
0
        if ( mpWindowImpl->mbInputDisabled != !bEnable )
2529
0
        {
2530
0
            mpWindowImpl->mbInputDisabled = !bEnable;
2531
0
            if ( mpWindowImpl->mpSysObj )
2532
0
                mpWindowImpl->mpSysObj->Enable( !mpWindowImpl->mbDisabled && bEnable );
2533
0
        }
2534
0
    }
2535
2536
    // #i56102# restore app focus win in case the
2537
    // window was disabled when the frame focus changed
2538
0
    ImplSVData* pSVData = ImplGetSVData();
2539
0
    if (bEnable && pSVData->mpWinData->mpFocusWin == nullptr
2540
0
        && mpWindowImpl->mpFrameData->mbHasFocus && mpWindowImpl->mpFrameData->mpFocusWin == this)
2541
0
        pSVData->mpWinData->mpFocusWin = this;
2542
2543
0
    if ( bChild )
2544
0
    {
2545
0
        VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
2546
0
        while ( pChild )
2547
0
        {
2548
0
            pChild->EnableInput( bEnable, bChild );
2549
0
            pChild = pChild->mpWindowImpl->mpNext;
2550
0
        }
2551
0
    }
2552
2553
0
    if ( IsReallyVisible() )
2554
0
        ImplGenerateMouseMove();
2555
0
}
2556
2557
void Window::EnableInput( bool bEnable, const vcl::Window* pExcludeWindow )
2558
0
{
2559
0
    if (!mpWindowImpl)
2560
0
        return;
2561
2562
0
    EnableInput( bEnable );
2563
2564
    // pExecuteWindow is the first Overlap-Frame --> if this
2565
    // shouldn't be the case, then this must be changed in dialog.cxx
2566
0
    if( pExcludeWindow )
2567
0
        pExcludeWindow = pExcludeWindow->ImplGetFirstOverlapWindow();
2568
0
    vcl::Window* pSysWin = mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mpFirstOverlap;
2569
0
    while ( pSysWin )
2570
0
    {
2571
        // Is Window in the path from this window
2572
0
        if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pSysWin, true ) )
2573
0
        {
2574
            // Is Window not in the exclude window path or not the
2575
            // exclude window, then change the status
2576
0
            if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( pSysWin, true ) )
2577
0
                pSysWin->EnableInput( bEnable );
2578
0
        }
2579
0
        pSysWin = pSysWin->mpWindowImpl->mpNextOverlap;
2580
0
    }
2581
2582
    // enable/disable floating system windows as well
2583
0
    vcl::Window* pFrameWin = ImplGetSVData()->maFrameData.mpFirstFrame;
2584
0
    while ( pFrameWin )
2585
0
    {
2586
0
        if( pFrameWin->ImplIsFloatingWindow() )
2587
0
        {
2588
            // Is Window in the path from this window
2589
0
            if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pFrameWin, true ) )
2590
0
            {
2591
                // Is Window not in the exclude window path or not the
2592
                // exclude window, then change the status
2593
0
                if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( pFrameWin, true ) )
2594
0
                    pFrameWin->EnableInput( bEnable );
2595
0
            }
2596
0
        }
2597
0
        pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame;
2598
0
    }
2599
2600
    // the same for ownerdraw floating windows
2601
0
    if( !mpWindowImpl->mbFrame )
2602
0
        return;
2603
2604
0
    ::std::vector< VclPtr<vcl::Window> >& rList = mpWindowImpl->mpFrameData->maOwnerDrawList;
2605
0
    for (auto const& elem : rList)
2606
0
    {
2607
        // Is Window in the path from this window
2608
0
        if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( elem, true ) )
2609
0
        {
2610
            // Is Window not in the exclude window path or not the
2611
            // exclude window, then change the status
2612
0
            if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( elem, true ) )
2613
0
                elem->EnableInput( bEnable );
2614
0
        }
2615
0
    }
2616
0
}
2617
2618
void Window::AlwaysEnableInput( bool bAlways, bool bChild )
2619
0
{
2620
2621
0
    if ( mpWindowImpl->mpBorderWindow )
2622
0
        mpWindowImpl->mpBorderWindow->AlwaysEnableInput( bAlways, false );
2623
2624
0
    if( bAlways && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled )
2625
0
    {
2626
0
        mpWindowImpl->meAlwaysInputMode = AlwaysInputEnabled;
2627
0
        EnableInput(true, false);
2628
0
    }
2629
0
    else if( ! bAlways && mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled )
2630
0
    {
2631
0
        mpWindowImpl->meAlwaysInputMode = AlwaysInputNone;
2632
0
    }
2633
2634
0
    if ( bChild )
2635
0
    {
2636
0
        VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
2637
0
        while ( pChild )
2638
0
        {
2639
0
            pChild->AlwaysEnableInput( bAlways, bChild );
2640
0
            pChild = pChild->mpWindowImpl->mpNext;
2641
0
        }
2642
0
    }
2643
0
}
2644
2645
void Window::SetActivateMode( ActivateModeFlags nMode )
2646
25.4k
{
2647
2648
25.4k
    if ( mpWindowImpl->mpBorderWindow )
2649
12.7k
        mpWindowImpl->mpBorderWindow->SetActivateMode( nMode );
2650
2651
25.4k
    if ( mpWindowImpl->mnActivateMode == nMode )
2652
12.7k
        return;
2653
2654
12.7k
    mpWindowImpl->mnActivateMode = nMode;
2655
2656
    // possibly trigger Deactivate/Activate
2657
12.7k
    if ( mpWindowImpl->mnActivateMode != ActivateModeFlags::NONE )
2658
12.7k
    {
2659
12.7k
        if ( (mpWindowImpl->mbActive || (GetType() == WindowType::BORDERWINDOW)) &&
2660
12.7k
             !HasChildPathFocus( true ) )
2661
12.7k
        {
2662
12.7k
            mpWindowImpl->mbActive = false;
2663
12.7k
            Deactivate();
2664
12.7k
        }
2665
12.7k
    }
2666
0
    else
2667
0
    {
2668
0
        if ( !mpWindowImpl->mbActive || (GetType() == WindowType::BORDERWINDOW) )
2669
0
        {
2670
0
            mpWindowImpl->mbActive = true;
2671
0
            Activate();
2672
0
        }
2673
0
    }
2674
12.7k
}
2675
2676
void Window::setPosSizePixel( tools::Long nX, tools::Long nY,
2677
                              tools::Long nWidth, tools::Long nHeight, PosSizeFlags nFlags )
2678
139k
{
2679
139k
    bool bHasValidSize = !mpWindowImpl->mbDefSize;
2680
2681
139k
    if ( nFlags & PosSizeFlags::Pos )
2682
67.8k
        mpWindowImpl->mbDefPos = false;
2683
139k
    if ( nFlags & PosSizeFlags::Size )
2684
139k
        mpWindowImpl->mbDefSize = false;
2685
2686
    // The top BorderWindow is the window which is to be positioned
2687
139k
    VclPtr<vcl::Window> pWindow = this;
2688
139k
    while ( pWindow->mpWindowImpl->mpBorderWindow )
2689
0
        pWindow = pWindow->mpWindowImpl->mpBorderWindow;
2690
2691
139k
    if ( pWindow->mpWindowImpl->mbFrame )
2692
0
    {
2693
        // Note: if we're positioning a frame, the coordinates are interpreted
2694
        // as being the top-left corner of the window's client area and NOT
2695
        // as the position of the border ! (due to limitations of several UNIX window managers)
2696
0
        tools::Long nOldWidth  = pWindow->GetOutDev()->mnOutWidth;
2697
2698
0
        if ( !(nFlags & PosSizeFlags::Width) )
2699
0
            nWidth = pWindow->GetOutDev()->mnOutWidth;
2700
0
        if ( !(nFlags & PosSizeFlags::Height) )
2701
0
            nHeight = pWindow->GetOutDev()->mnOutHeight;
2702
2703
0
        sal_uInt16 nSysFlags=0;
2704
0
        VclPtr<vcl::Window> pParent = GetParent();
2705
0
        VclPtr<vcl::Window> pWinParent = pWindow->GetParent();
2706
2707
0
        if( nFlags & PosSizeFlags::Width )
2708
0
            nSysFlags |= SAL_FRAME_POSSIZE_WIDTH;
2709
0
        if( nFlags & PosSizeFlags::Height )
2710
0
            nSysFlags |= SAL_FRAME_POSSIZE_HEIGHT;
2711
0
        if( nFlags & PosSizeFlags::X )
2712
0
        {
2713
0
            nSysFlags |= SAL_FRAME_POSSIZE_X;
2714
0
            if( pWinParent && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) )
2715
0
            {
2716
0
                nX += pWinParent->GetOutDev()->mnOutOffX;
2717
0
            }
2718
0
            if( pParent && pParent->GetOutDev()->ImplIsAntiparallel() )
2719
0
            {
2720
0
                tools::Rectangle aRect( Point ( nX, nY ), Size( nWidth, nHeight ) );
2721
0
                const OutputDevice *pParentOutDev = pParent->GetOutDev();
2722
0
                if (!comphelper::LibreOfficeKit::isActive())
2723
0
                    pParentOutDev->ReMirror( aRect );
2724
0
                nX = aRect.Left();
2725
0
            }
2726
0
        }
2727
0
        if( !comphelper::LibreOfficeKit::isActive() &&
2728
0
            !(nFlags & PosSizeFlags::X) && bHasValidSize &&
2729
0
            pWindow->mpWindowImpl->mpFrame->GetWidth())
2730
0
        {
2731
            // RTL: make sure the old right aligned position is not changed
2732
            // system windows will always grow to the right
2733
0
            if ( pWinParent )
2734
0
            {
2735
0
                OutputDevice *pParentOutDev = pWinParent->GetOutDev();
2736
0
                if( pParentOutDev->HasMirroredGraphics() )
2737
0
                {
2738
0
                    const SalFrameGeometry aSysGeometry = mpWindowImpl->mpFrame->GetUnmirroredGeometry();
2739
0
                    const SalFrameGeometry aParentSysGeometry =
2740
0
                        pWinParent->mpWindowImpl->mpFrame->GetUnmirroredGeometry();
2741
0
                    tools::Long myWidth = nOldWidth;
2742
0
                    if( !myWidth )
2743
0
                        myWidth = aSysGeometry.width();
2744
0
                    if( !myWidth )
2745
0
                        myWidth = nWidth;
2746
0
                    nFlags |= PosSizeFlags::X;
2747
0
                    nSysFlags |= SAL_FRAME_POSSIZE_X;
2748
0
                    nX = aParentSysGeometry.x() - aSysGeometry.leftDecoration() + aParentSysGeometry.width()
2749
0
                        - myWidth - 1 - aSysGeometry.x();
2750
0
                }
2751
0
            }
2752
0
        }
2753
0
        if( nFlags & PosSizeFlags::Y )
2754
0
        {
2755
0
            nSysFlags |= SAL_FRAME_POSSIZE_Y;
2756
0
            if( pWinParent && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) )
2757
0
            {
2758
0
                nY += pWinParent->GetOutDev()->mnOutOffY;
2759
0
            }
2760
0
        }
2761
2762
0
        if( nSysFlags & (SAL_FRAME_POSSIZE_WIDTH|SAL_FRAME_POSSIZE_HEIGHT) )
2763
0
        {
2764
            // check for min/max client size and adjust size accordingly
2765
            // otherwise it may happen that the resize event is ignored, i.e. the old size remains
2766
            // unchanged but ImplHandleResize() is called with the wrong size
2767
0
            SystemWindow *pSystemWindow = dynamic_cast< SystemWindow* >( pWindow.get() );
2768
0
            if( pSystemWindow )
2769
0
            {
2770
0
                Size aMinSize = pSystemWindow->GetMinOutputSizePixel();
2771
0
                Size aMaxSize = pSystemWindow->GetMaxOutputSizePixel();
2772
0
                if( nWidth < aMinSize.Width() )
2773
0
                    nWidth = aMinSize.Width();
2774
0
                if( nHeight < aMinSize.Height() )
2775
0
                    nHeight = aMinSize.Height();
2776
2777
0
                if( nWidth > aMaxSize.Width() )
2778
0
                    nWidth = aMaxSize.Width();
2779
0
                if( nHeight > aMaxSize.Height() )
2780
0
                    nHeight = aMaxSize.Height();
2781
0
            }
2782
0
        }
2783
2784
0
        pWindow->mpWindowImpl->mpFrame->SetPosSize( nX, nY, nWidth, nHeight, nSysFlags );
2785
2786
        // Adjust resize with the hack of different client size and frame geometries to fix
2787
        // native menu bars. Eventually this should be replaced by proper mnTopBorder usage.
2788
0
        pWindow->mpWindowImpl->mpFrame->GetClientSize(nWidth, nHeight);
2789
2790
        // Resize should be called directly. If we haven't
2791
        // set the correct size, we get a second resize from
2792
        // the system with the correct size. This can be happened
2793
        // if the size is too small or too large.
2794
0
        ImplHandleResize( pWindow, nWidth, nHeight );
2795
0
    }
2796
139k
    else
2797
139k
    {
2798
139k
        pWindow->ImplPosSizeWindow( nX, nY, nWidth, nHeight, nFlags );
2799
139k
        if ( IsReallyVisible() )
2800
0
            ImplGenerateMouseMove();
2801
139k
    }
2802
139k
}
2803
2804
Point Window::GetPosPixel() const
2805
1.72k
{
2806
1.72k
    return mpWindowImpl->maPos;
2807
1.72k
}
2808
2809
AbsoluteScreenPixelRectangle Window::GetDesktopRectPixel() const
2810
0
{
2811
0
    AbsoluteScreenPixelRectangle rRect;
2812
0
    mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrame->GetWorkArea( rRect );
2813
0
    return rRect;
2814
0
}
2815
2816
Point Window::OutputToScreenPixel( const Point& rPos ) const
2817
8.48k
{
2818
    // relative to top level parent
2819
8.48k
    return Point( rPos.X() + GetOutDev()->mnOutOffX, rPos.Y() + GetOutDev()->mnOutOffY );
2820
8.48k
}
2821
2822
Point Window::ScreenToOutputPixel( const Point& rPos ) const
2823
34.1k
{
2824
    // relative to top level parent
2825
34.1k
    return Point( rPos.X() - GetOutDev()->mnOutOffX, rPos.Y() - GetOutDev()->mnOutOffY );
2826
34.1k
}
2827
2828
tools::Long Window::ImplGetUnmirroredOutOffX() const
2829
0
{
2830
    // revert mnOutOffX changes that were potentially made in ImplPosSizeWindow
2831
0
    tools::Long offx = GetOutDev()->mnOutOffX;
2832
0
    const OutputDevice *pOutDev = GetOutDev();
2833
0
    if( pOutDev->HasMirroredGraphics() )
2834
0
    {
2835
0
        if( mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->GetOutDev()->ImplIsAntiparallel() )
2836
0
        {
2837
0
            if ( !ImplIsOverlapWindow() )
2838
0
                offx -= mpWindowImpl->mpParent->GetOutDev()->mnOutOffX;
2839
2840
0
            offx = mpWindowImpl->mpParent->GetOutDev()->mnOutWidth - GetOutDev()->mnOutWidth - offx;
2841
2842
0
            if ( !ImplIsOverlapWindow() )
2843
0
                offx += mpWindowImpl->mpParent->GetOutDev()->mnOutOffX;
2844
2845
0
        }
2846
0
    }
2847
0
    return offx;
2848
0
}
2849
2850
// normalized screen pixel are independent of mirroring
2851
Point Window::OutputToNormalizedScreenPixel( const Point& rPos ) const
2852
0
{
2853
    // relative to top level parent
2854
0
    tools::Long offx = ImplGetUnmirroredOutOffX();
2855
0
    return Point( rPos.X()+offx, rPos.Y() + GetOutDev()->mnOutOffY );
2856
0
}
2857
2858
Point Window::NormalizedScreenToOutputPixel( const Point& rPos ) const
2859
0
{
2860
    // relative to top level parent
2861
0
    tools::Long offx = ImplGetUnmirroredOutOffX();
2862
0
    return Point( rPos.X()-offx, rPos.Y() - GetOutDev()->mnOutOffY );
2863
0
}
2864
2865
AbsoluteScreenPixelPoint Window::OutputToAbsoluteScreenPixel( const Point& rPos ) const
2866
0
{
2867
    // relative to the screen
2868
0
    Point p = OutputToScreenPixel( rPos );
2869
0
    SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
2870
0
    p.AdjustX(g.x() );
2871
0
    p.AdjustY(g.y() );
2872
0
    return AbsoluteScreenPixelPoint(p);
2873
0
}
2874
2875
Point Window::AbsoluteScreenToOutputPixel( const AbsoluteScreenPixelPoint& rPos ) const
2876
0
{
2877
    // relative to the screen
2878
0
    Point p = ScreenToOutputPixel( Point(rPos) );
2879
0
    SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
2880
0
    p.AdjustX( -(g.x()) );
2881
0
    p.AdjustY( -(g.y()) );
2882
0
    return p;
2883
0
}
2884
2885
AbsoluteScreenPixelRectangle Window::ImplOutputToUnmirroredAbsoluteScreenPixel( const tools::Rectangle &rRect ) const
2886
0
{
2887
    // this method creates unmirrored screen coordinates to be compared with the desktop
2888
    // and is used for positioning of RTL popup windows correctly on the screen
2889
0
    SalFrameGeometry g = mpWindowImpl->mpFrame->GetUnmirroredGeometry();
2890
2891
0
    Point p1 = rRect.TopRight();
2892
0
    p1 = OutputToScreenPixel(p1);
2893
0
    p1.setX( g.x()+g.width()-p1.X() );
2894
0
    p1.AdjustY(g.y() );
2895
2896
0
    Point p2 = rRect.BottomLeft();
2897
0
    p2 = OutputToScreenPixel(p2);
2898
0
    p2.setX( g.x()+g.width()-p2.X() );
2899
0
    p2.AdjustY(g.y() );
2900
2901
0
    return AbsoluteScreenPixelRectangle( AbsoluteScreenPixelPoint(p1), AbsoluteScreenPixelPoint(p2) );
2902
0
}
2903
2904
tools::Rectangle Window::ImplUnmirroredAbsoluteScreenToOutputPixel( const AbsoluteScreenPixelRectangle &rRect ) const
2905
0
{
2906
    // undo ImplOutputToUnmirroredAbsoluteScreenPixel
2907
0
    SalFrameGeometry g = mpWindowImpl->mpFrame->GetUnmirroredGeometry();
2908
2909
0
    Point p1( rRect.TopRight() );
2910
0
    p1.AdjustY(-g.y() );
2911
0
    p1.setX( g.x()+g.width()-p1.X() );
2912
0
    p1 = ScreenToOutputPixel(p1);
2913
2914
0
    Point p2( rRect.BottomLeft() );
2915
0
    p2.AdjustY(-g.y());
2916
0
    p2.setX( g.x()+g.width()-p2.X() );
2917
0
    p2 = ScreenToOutputPixel(p2);
2918
2919
0
    return tools::Rectangle( p1, p2 );
2920
0
}
2921
2922
2923
// with decoration
2924
tools::Rectangle Window::GetWindowExtentsRelative(const vcl::Window & rRelativeWindow) const
2925
0
{
2926
0
    AbsoluteScreenPixelRectangle aRect = GetWindowExtentsAbsolute();
2927
    // #106399# express coordinates relative to borderwindow
2928
0
    const vcl::Window *pRelWin = rRelativeWindow.mpWindowImpl->mpBorderWindow ? rRelativeWindow.mpWindowImpl->mpBorderWindow.get() : &rRelativeWindow;
2929
0
    return tools::Rectangle(
2930
0
        pRelWin->AbsoluteScreenToOutputPixel( aRect.GetPos() ),
2931
0
        aRect.GetSize() );
2932
0
}
2933
2934
// with decoration
2935
AbsoluteScreenPixelRectangle Window::GetWindowExtentsAbsolute() const
2936
0
{
2937
    // make sure we use the extent of our border window,
2938
    // otherwise we miss a few pixels
2939
0
    const vcl::Window *pWin = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow : this;
2940
2941
0
    AbsoluteScreenPixelPoint aPos( pWin->OutputToAbsoluteScreenPixel( Point(0,0) ) );
2942
0
    Size aSize ( pWin->GetSizePixel() );
2943
    // #104088# do not add decoration to the workwindow to be compatible to java accessibility api
2944
0
    if( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame && GetType() != WindowType::WORKWINDOW) )
2945
0
    {
2946
0
        SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
2947
0
        aPos.AdjustX( -sal_Int32(g.leftDecoration()) );
2948
0
        aPos.AdjustY( -sal_Int32(g.topDecoration()) );
2949
0
        aSize.AdjustWidth(g.leftDecoration() + g.rightDecoration() );
2950
0
        aSize.AdjustHeight(g.topDecoration() + g.bottomDecoration() );
2951
0
    }
2952
0
    return AbsoluteScreenPixelRectangle( aPos, aSize );
2953
0
}
2954
2955
void Window::Scroll( tools::Long nHorzScroll, tools::Long nVertScroll, ScrollFlags nFlags )
2956
0
{
2957
2958
0
    ImplScroll( GetOutputRectPixel(),
2959
0
                nHorzScroll, nVertScroll, nFlags & ~ScrollFlags::Clip );
2960
0
}
2961
2962
void Window::Scroll( tools::Long nHorzScroll, tools::Long nVertScroll,
2963
                     const tools::Rectangle& rRect, ScrollFlags nFlags )
2964
0
{
2965
0
    OutputDevice *pOutDev = GetOutDev();
2966
0
    tools::Rectangle aRect = pOutDev->ImplLogicToDevicePixel( rRect );
2967
0
    aRect.Intersection( GetOutputRectPixel() );
2968
0
    if ( !aRect.IsEmpty() )
2969
0
        ImplScroll( aRect, nHorzScroll, nVertScroll, nFlags );
2970
0
}
2971
2972
void WindowOutputDevice::Flush()
2973
0
{
2974
0
    if (mxOwnerWindow->mpWindowImpl)
2975
0
        mxOwnerWindow->mpWindowImpl->mpFrame->Flush( GetOutputRectPixel() );
2976
0
}
2977
2978
void Window::SetUpdateMode( bool bUpdate )
2979
16.7k
{
2980
16.7k
    if (mpWindowImpl)
2981
16.7k
    {
2982
16.7k
        mpWindowImpl->mbNoUpdate = !bUpdate;
2983
16.7k
        CompatStateChanged( StateChangedType::UpdateMode );
2984
16.7k
    }
2985
16.7k
}
2986
2987
void Window::GrabFocus()
2988
0
{
2989
0
    ImplGrabFocus( GetFocusFlags::NONE );
2990
0
}
2991
2992
bool Window::HasFocus() const
2993
16.9k
{
2994
16.9k
    return (this == ImplGetSVData()->mpWinData->mpFocusWin);
2995
16.9k
}
2996
2997
void Window::GrabFocusToDocument()
2998
0
{
2999
0
    ImplGrabFocusToDocument(GetFocusFlags::NONE);
3000
0
}
3001
3002
VclPtr<vcl::Window> Window::GetFocusedWindow() const
3003
0
{
3004
0
    if (mpWindowImpl && mpWindowImpl->mpFrameData)
3005
0
        return mpWindowImpl->mpFrameData->mpFocusWin;
3006
0
    else
3007
0
        return VclPtr<vcl::Window>();
3008
0
}
3009
3010
void Window::SetFakeFocus( bool bFocus )
3011
0
{
3012
0
    ImplGetWindowImpl()->mbFakeFocusSet = bFocus;
3013
0
}
3014
3015
bool Window::HasChildPathFocus( bool bSystemWindow ) const
3016
55.1k
{
3017
3018
55.1k
    vcl::Window* pFocusWin = ImplGetSVData()->mpWinData->mpFocusWin;
3019
55.1k
    if ( pFocusWin )
3020
0
        return ImplIsWindowOrChild( pFocusWin, bSystemWindow );
3021
55.1k
    return false;
3022
55.1k
}
3023
3024
void Window::SetCursor( vcl::Cursor* pCursor )
3025
16.9k
{
3026
3027
16.9k
    if ( mpWindowImpl->mpCursor != pCursor )
3028
16.9k
    {
3029
16.9k
        if ( mpWindowImpl->mpCursor )
3030
8.47k
            mpWindowImpl->mpCursor->ImplHide();
3031
16.9k
        mpWindowImpl->mpCursor = pCursor;
3032
16.9k
        if ( pCursor )
3033
8.47k
            pCursor->ImplShow();
3034
16.9k
    }
3035
16.9k
}
3036
3037
void Window::SetText( const OUString& rStr )
3038
25.4k
{
3039
25.4k
    if (!mpWindowImpl || rStr == mpWindowImpl->maText)
3040
8.47k
        return;
3041
3042
17.0k
    OUString oldTitle( mpWindowImpl->maText );
3043
17.0k
    mpWindowImpl->maText = rStr;
3044
3045
17.0k
    if ( mpWindowImpl->mpBorderWindow )
3046
8.50k
        mpWindowImpl->mpBorderWindow->SetText( rStr );
3047
8.50k
    else if ( mpWindowImpl->mbFrame )
3048
8.50k
        mpWindowImpl->mpFrame->SetTitle( rStr );
3049
3050
17.0k
    CallEventListeners( VclEventId::WindowFrameTitleChanged, &oldTitle );
3051
3052
    // #107247# needed for accessibility
3053
    // The VclEventId::WindowFrameTitleChanged is (mis)used to notify accessible name changes.
3054
    // Therefore a window, which is labeled by this window, must also notify an accessible
3055
    // name change.
3056
17.0k
    if ( IsReallyVisible() )
3057
0
    {
3058
0
        vcl::Window* pWindow = GetAccessibleRelationLabelFor();
3059
0
        if ( pWindow && pWindow != this )
3060
0
            pWindow->CallEventListeners( VclEventId::WindowFrameTitleChanged, &oldTitle );
3061
0
    }
3062
3063
17.0k
    CompatStateChanged( StateChangedType::Text );
3064
17.0k
}
3065
3066
OUString Window::GetText() const
3067
0
{
3068
3069
0
    return mpWindowImpl->maText;
3070
0
}
3071
3072
OUString Window::GetDisplayText() const
3073
0
{
3074
3075
0
    return GetText();
3076
0
}
3077
3078
const Wallpaper& Window::GetDisplayBackground() const
3079
0
{
3080
    // FIXME: fix issue 52349, need to fix this really in
3081
    // all NWF enabled controls
3082
0
    const ToolBox* pTB = dynamic_cast<const ToolBox*>(this);
3083
0
    if( pTB && IsNativeWidgetEnabled() )
3084
0
        return pTB->ImplGetToolBoxPrivateData()->maDisplayBackground;
3085
3086
0
    if( !IsBackground() )
3087
0
    {
3088
0
        if( mpWindowImpl->mpParent )
3089
0
            return mpWindowImpl->mpParent->GetDisplayBackground();
3090
0
    }
3091
3092
0
    const Wallpaper& rBack = GetBackground();
3093
0
    if( ! rBack.IsBitmap() &&
3094
0
        ! rBack.IsGradient() &&
3095
0
        rBack.GetColor()== COL_TRANSPARENT &&
3096
0
        mpWindowImpl->mpParent )
3097
0
            return mpWindowImpl->mpParent->GetDisplayBackground();
3098
0
    return rBack;
3099
0
}
3100
3101
const OUString& Window::GetHelpText() const
3102
0
{
3103
0
    const OUString& rStrHelpId(GetHelpId());
3104
0
    const bool bStrHelpId = !rStrHelpId.isEmpty();
3105
3106
0
    if (mpWindowImpl->mbHelpTextDynamic && bStrHelpId)
3107
0
    {
3108
0
        static const char* pEnv = getenv( "HELP_DEBUG" );
3109
0
        if( pEnv && *pEnv )
3110
0
        {
3111
0
            mpWindowImpl->maHelpText = mpWindowImpl->maHelpText + "\n------------------\n" + rStrHelpId;
3112
0
        }
3113
0
        mpWindowImpl->mbHelpTextDynamic = false;
3114
0
    }
3115
3116
    //Fallback to Window::GetAccessibleDescription without reentry to GetHelpText()
3117
0
    if (mpWindowImpl->maHelpText.isEmpty() && mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleDescription)
3118
0
        return *mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
3119
0
    return mpWindowImpl->maHelpText;
3120
0
}
3121
3122
void Window::SetWindowPeer( Reference< css::awt::XVclWindowPeer > const & xPeer, VCLXWindow* pVCLXWindow  )
3123
228k
{
3124
228k
    if (!mpWindowImpl || mpWindowImpl->mbInDispose)
3125
16.9k
        return;
3126
3127
    // be safe against re-entrance: first clear the old ref, then assign the new one
3128
211k
    if (mpWindowImpl->mxWindowPeer)
3129
84.7k
    {
3130
        // first, disconnect the peer from ourself, otherwise disposing it, will dispose us
3131
84.7k
        UnoWrapperBase* pWrapper = UnoWrapperBase::GetUnoWrapper();
3132
84.7k
        SAL_WARN_IF( !pWrapper, "vcl.window", "SetComponentInterface: No Wrapper!" );
3133
84.7k
        if ( pWrapper )
3134
84.7k
            pWrapper->SetWindowInterface( nullptr, mpWindowImpl->mxWindowPeer );
3135
84.7k
        mpWindowImpl->mxWindowPeer->dispose();
3136
84.7k
        mpWindowImpl->mxWindowPeer.clear();
3137
84.7k
    }
3138
211k
    mpWindowImpl->mxWindowPeer = xPeer;
3139
3140
211k
    mpWindowImpl->mpVCLXWindow = pVCLXWindow;
3141
211k
}
3142
3143
Reference< css::awt::XVclWindowPeer > Window::GetComponentInterface( bool bCreate )
3144
394k
{
3145
394k
    if ( !mpWindowImpl->mxWindowPeer.is() && bCreate )
3146
114k
    {
3147
114k
        UnoWrapperBase* pWrapper = UnoWrapperBase::GetUnoWrapper();
3148
114k
        if ( pWrapper )
3149
114k
            mpWindowImpl->mxWindowPeer = pWrapper->GetWindowInterface( this );
3150
114k
    }
3151
394k
    return mpWindowImpl->mxWindowPeer;
3152
394k
}
3153
3154
void Window::SetComponentInterface( Reference< css::awt::XVclWindowPeer > const & xIFace )
3155
12.7k
{
3156
12.7k
    UnoWrapperBase* pWrapper = UnoWrapperBase::GetUnoWrapper();
3157
12.7k
    SAL_WARN_IF( !pWrapper, "vcl.window", "SetComponentInterface: No Wrapper!" );
3158
12.7k
    if ( pWrapper )
3159
12.7k
        pWrapper->SetWindowInterface( this, xIFace );
3160
12.7k
}
3161
3162
typedef std::map<vcl::LOKWindowId, VclPtr<vcl::Window>> LOKWindowsMap;
3163
3164
namespace {
3165
3166
LOKWindowsMap& GetLOKWindowsMap()
3167
0
{
3168
    // Map to remember the LOKWindowId <-> Window binding.
3169
0
    static LOKWindowsMap s_aLOKWindowsMap;
3170
3171
0
    return s_aLOKWindowsMap;
3172
0
}
3173
3174
}
3175
3176
void Window::SetLOKNotifier(const vcl::ILibreOfficeKitNotifier* pNotifier, bool bParent)
3177
0
{
3178
    // don't allow setting this twice
3179
0
    assert(mpWindowImpl->mpLOKNotifier == nullptr);
3180
0
    assert(pNotifier);
3181
    // never use this in the desktop case
3182
0
    assert(comphelper::LibreOfficeKit::isActive());
3183
3184
0
    if (!bParent)
3185
0
    {
3186
        // Counter to be able to have unique id's for each window.
3187
0
        static vcl::LOKWindowId sLastLOKWindowId = 1;
3188
3189
        // assign the LOK window id
3190
0
        assert(mpWindowImpl->mnLOKWindowId == 0);
3191
0
        mpWindowImpl->mnLOKWindowId = sLastLOKWindowId++;
3192
0
        GetLOKWindowsMap().emplace(mpWindowImpl->mnLOKWindowId, this);
3193
0
    }
3194
3195
0
    mpWindowImpl->mpLOKNotifier = pNotifier;
3196
0
}
3197
3198
VclPtr<Window> Window::FindLOKWindow(vcl::LOKWindowId nWindowId)
3199
0
{
3200
0
    const auto it = GetLOKWindowsMap().find(nWindowId);
3201
0
    if (it != GetLOKWindowsMap().end())
3202
0
        return it->second;
3203
3204
0
    return VclPtr<Window>();
3205
0
}
3206
3207
bool Window::IsLOKWindowsEmpty()
3208
0
{
3209
0
    return GetLOKWindowsMap().empty();
3210
0
}
3211
3212
void Window::ReleaseLOKNotifier()
3213
0
{
3214
    // unregister the LOK window binding
3215
0
    if (mpWindowImpl->mnLOKWindowId > 0)
3216
0
        GetLOKWindowsMap().erase(mpWindowImpl->mnLOKWindowId);
3217
3218
0
    mpWindowImpl->mpLOKNotifier = nullptr;
3219
0
    mpWindowImpl->mnLOKWindowId = 0;
3220
0
}
3221
3222
ILibreOfficeKitNotifier::~ILibreOfficeKitNotifier()
3223
8.47k
{
3224
8.47k
    if (!comphelper::LibreOfficeKit::isActive())
3225
8.47k
    {
3226
8.47k
        return;
3227
8.47k
    }
3228
3229
0
    for (auto it = GetLOKWindowsMap().begin(); it != GetLOKWindowsMap().end();)
3230
0
    {
3231
0
        WindowImpl* pWindowImpl = it->second->ImplGetWindowImpl();
3232
0
        if (pWindowImpl && pWindowImpl->mpLOKNotifier == this)
3233
0
        {
3234
0
            pWindowImpl->mpLOKNotifier = nullptr;
3235
0
            pWindowImpl->mnLOKWindowId = 0;
3236
0
            it = GetLOKWindowsMap().erase(it);
3237
0
            continue;
3238
0
        }
3239
3240
0
        ++it;
3241
0
    }
3242
0
}
3243
3244
const vcl::ILibreOfficeKitNotifier* Window::GetLOKNotifier() const
3245
499k
{
3246
499k
    return mpWindowImpl ? mpWindowImpl->mpLOKNotifier : nullptr;
3247
499k
}
3248
3249
vcl::LOKWindowId Window::GetLOKWindowId() const
3250
0
{
3251
0
    return mpWindowImpl ? mpWindowImpl->mnLOKWindowId : 0;
3252
0
}
3253
3254
VclPtr<vcl::Window> Window::GetParentWithLOKNotifier()
3255
135k
{
3256
135k
    VclPtr<vcl::Window> pWindow(this);
3257
3258
601k
    while (pWindow && !pWindow->GetLOKNotifier())
3259
465k
        pWindow = pWindow->GetParent();
3260
3261
135k
    return pWindow;
3262
135k
}
3263
3264
namespace
3265
{
3266
3267
std::string_view windowTypeName(WindowType nWindowType)
3268
0
{
3269
0
    switch (nWindowType)
3270
0
    {
3271
0
        case WindowType::NONE:                      return "none";
3272
0
        case WindowType::MESSBOX:                   return "messagebox";
3273
0
        case WindowType::INFOBOX:                   return "infobox";
3274
0
        case WindowType::WARNINGBOX:                return "warningbox";
3275
0
        case WindowType::ERRORBOX:                  return "errorbox";
3276
0
        case WindowType::QUERYBOX:                  return "querybox";
3277
0
        case WindowType::WINDOW:                    return "window";
3278
0
        case WindowType::WORKWINDOW:                return "workwindow";
3279
0
        case WindowType::CONTAINER:                 return "container";
3280
0
        case WindowType::FLOATINGWINDOW:            return "floatingwindow";
3281
0
        case WindowType::DIALOG:                    return "dialog";
3282
0
        case WindowType::MODELESSDIALOG:            return "modelessdialog";
3283
0
        case WindowType::CONTROL:                   return "control";
3284
0
        case WindowType::PUSHBUTTON:                return "pushbutton";
3285
0
        case WindowType::OKBUTTON:                  return "okbutton";
3286
0
        case WindowType::CANCELBUTTON:              return "cancelbutton";
3287
0
        case WindowType::HELPBUTTON:                return "helpbutton";
3288
0
        case WindowType::IMAGEBUTTON:               return "imagebutton";
3289
0
        case WindowType::MENUBUTTON:                return "menubutton";
3290
0
        case WindowType::MOREBUTTON:                return "morebutton";
3291
0
        case WindowType::SPINBUTTON:                return "spinbutton";
3292
0
        case WindowType::RADIOBUTTON:               return "radiobutton";
3293
0
        case WindowType::CHECKBOX:                  return "checkbox";
3294
0
        case WindowType::TRISTATEBOX:               return "tristatebox";
3295
0
        case WindowType::EDIT:                      return "edit";
3296
0
        case WindowType::MULTILINEEDIT:             return "multilineedit";
3297
0
        case WindowType::COMBOBOX:                  return "combobox";
3298
0
        case WindowType::LISTBOX:                   return "listbox";
3299
0
        case WindowType::MULTILISTBOX:              return "multilistbox";
3300
0
        case WindowType::FIXEDTEXT:                 return "fixedtext";
3301
0
        case WindowType::FIXEDLINE:                 return "fixedline";
3302
0
        case WindowType::FIXEDBITMAP:               return "fixedbitmap";
3303
0
        case WindowType::FIXEDIMAGE:                return "fixedimage";
3304
0
        case WindowType::GROUPBOX:                  return "groupbox";
3305
0
        case WindowType::SCROLLBAR:                 return "scrollbar";
3306
0
        case WindowType::SCROLLBARBOX:              return "scrollbarbox";
3307
0
        case WindowType::SPLITTER:                  return "splitter";
3308
0
        case WindowType::SPLITWINDOW:               return "splitwindow";
3309
0
        case WindowType::SPINFIELD:                 return "spinfield";
3310
0
        case WindowType::PATTERNFIELD:              return "patternfield";
3311
0
        case WindowType::METRICFIELD:               return "metricfield";
3312
0
        case WindowType::FORMATTEDFIELD:            return "formattedfield";
3313
0
        case WindowType::CURRENCYFIELD:             return "currencyfield";
3314
0
        case WindowType::DATEFIELD:                 return "datefield";
3315
0
        case WindowType::TIMEFIELD:                 return "timefield";
3316
0
        case WindowType::PATTERNBOX:                return "patternbox";
3317
0
        case WindowType::NUMERICBOX:                return "numericbox";
3318
0
        case WindowType::METRICBOX:                 return "metricbox";
3319
0
        case WindowType::CURRENCYBOX:               return "currencybox";
3320
0
        case WindowType::DATEBOX:                   return "datebox";
3321
0
        case WindowType::TIMEBOX:                   return "timebox";
3322
0
        case WindowType::LONGCURRENCYBOX:           return "longcurrencybox";
3323
0
        case WindowType::SCROLLWINDOW:              return "scrollwindow";
3324
0
        case WindowType::TOOLBOX:                   return "toolbox";
3325
0
        case WindowType::DOCKINGWINDOW:             return "dockingwindow";
3326
0
        case WindowType::STATUSBAR:                 return "statusbar";
3327
0
        case WindowType::TABPAGE:                   return "tabpage";
3328
0
        case WindowType::TABCONTROL:                return "tabcontrol";
3329
0
        case WindowType::TABDIALOG:                 return "tabdialog";
3330
0
        case WindowType::BORDERWINDOW:              return "borderwindow";
3331
0
        case WindowType::BUTTONDIALOG:              return "buttondialog";
3332
0
        case WindowType::SYSTEMCHILDWINDOW:         return "systemchildwindow";
3333
0
        case WindowType::SLIDER:                    return "slider";
3334
0
        case WindowType::MENUBARWINDOW:             return "menubarwindow";
3335
0
        case WindowType::TREELISTBOX:               return "treelistbox";
3336
0
        case WindowType::HELPTEXTWINDOW:            return "helptextwindow";
3337
0
        case WindowType::INTROWINDOW:               return "introwindow";
3338
0
        case WindowType::LISTBOXWINDOW:             return "listboxwindow";
3339
0
        case WindowType::DOCKINGAREA:               return "dockingarea";
3340
0
        case WindowType::RULER:                     return "ruler";
3341
0
        case WindowType::HEADERBAR:                 return "headerbar";
3342
0
        case WindowType::VERTICALTABCONTROL:        return "verticaltabcontrol";
3343
0
        case WindowType::PROGRESSBAR:               return "progressbar";
3344
0
        case WindowType::LINK_BUTTON:               return "linkbutton";
3345
3346
        // nothing to do here, but for completeness
3347
0
        case WindowType::TOOLKIT_FRAMEWINDOW:       return "toolkit_framewindow";
3348
0
        case WindowType::TOOLKIT_SYSTEMCHILDWINDOW: return "toolkit_systemchildwindow";
3349
0
    }
3350
3351
0
    return "none";
3352
0
}
3353
3354
}
3355
3356
void Window::DumpAsPropertyTree(tools::JsonWriter& rJsonWriter)
3357
0
{
3358
0
    if (!mpWindowImpl)
3359
0
        return;
3360
3361
0
    rJsonWriter.put("id", get_id());  // TODO could be missing - sort out
3362
0
    rJsonWriter.put("type", windowTypeName(GetType()));
3363
0
    rJsonWriter.put("text", GetText());
3364
0
    rJsonWriter.put("enabled", IsEnabled());
3365
0
    if (!IsVisible())
3366
0
        rJsonWriter.put("visible", false);
3367
3368
0
    if (vcl::Window* pChild = mpWindowImpl->mpFirstChild)
3369
0
    {
3370
0
        auto childrenNode = rJsonWriter.startArray("children");
3371
0
        while (pChild)
3372
0
        {
3373
0
            {
3374
0
                auto childNode = rJsonWriter.startStruct();
3375
0
                pChild->DumpAsPropertyTree(rJsonWriter);
3376
0
                sal_Int32 nLeft = pChild->get_grid_left_attach();
3377
0
                sal_Int32 nTop = pChild->get_grid_top_attach();
3378
0
                if (nLeft != -1 && nTop != -1)
3379
0
                {
3380
0
                    rJsonWriter.put("left", nLeft);
3381
0
                    rJsonWriter.put("top", nTop);
3382
0
                }
3383
3384
0
                sal_Int32 nWidth = pChild->get_grid_width();
3385
0
                if (nWidth > 1)
3386
0
                    rJsonWriter.put("width", nWidth);
3387
0
            }
3388
0
            pChild = pChild->mpWindowImpl->mpNext;
3389
0
        }
3390
0
    }
3391
3392
0
    vcl::Window* pAccLabelFor = getAccessibleRelationLabelFor();
3393
0
    if (pAccLabelFor)
3394
0
        rJsonWriter.put("labelFor", pAccLabelFor->get_id());
3395
3396
0
    vcl::Window* pAccLabelledBy = GetAccessibleRelationLabeledBy();
3397
0
    if (pAccLabelledBy)
3398
0
        rJsonWriter.put("labelledBy", pAccLabelledBy->get_id());
3399
3400
0
    if(!pAccLabelFor && !pAccLabelledBy)
3401
0
    {
3402
0
        OUString sAccName = GetAccessibleName();
3403
0
        OUString sAccDesc = GetAccessibleDescription();
3404
3405
0
        if (!sAccName.isEmpty() || !sAccDesc.isEmpty())
3406
0
        {
3407
0
            auto aAria = rJsonWriter.startNode("aria");
3408
0
            if (!sAccName.isEmpty())
3409
0
                rJsonWriter.put("label", sAccName);
3410
0
            if (!sAccDesc.isEmpty())
3411
0
                rJsonWriter.put("description", sAccDesc);
3412
0
        }
3413
0
    }
3414
3415
0
    mpWindowImpl->maDumpAsPropertyTreeHdl.Call(rJsonWriter);
3416
0
}
3417
3418
void Window::ImplCallDeactivateListeners( vcl::Window *pNew )
3419
0
{
3420
    // no deactivation if the newly activated window is my child
3421
0
    if ( !pNew || !ImplIsChild( pNew ) )
3422
0
    {
3423
0
        VclPtr<vcl::Window> xWindow(this);
3424
0
        CallEventListeners( VclEventId::WindowDeactivate, pNew );
3425
0
        if( !xWindow->mpWindowImpl )
3426
0
            return;
3427
3428
        // #100759#, avoid walking the wrong frame's hierarchy
3429
        //           eg, undocked docking windows (ImplDockFloatWin)
3430
0
        if ( ImplGetParent() && ImplGetParent()->mpWindowImpl &&
3431
0
             mpWindowImpl->mpFrameWindow == ImplGetParent()->mpWindowImpl->mpFrameWindow )
3432
0
            ImplGetParent()->ImplCallDeactivateListeners( pNew );
3433
0
    }
3434
0
}
3435
3436
void Window::ImplCallActivateListeners( vcl::Window *pOld )
3437
0
{
3438
    // no activation if the old active window is my child
3439
0
    if ( pOld && ImplIsChild( pOld ))
3440
0
        return;
3441
3442
0
    VclPtr<vcl::Window> xWindow(this);
3443
0
    CallEventListeners( VclEventId::WindowActivate, pOld );
3444
0
    if( !xWindow->mpWindowImpl )
3445
0
        return;
3446
3447
0
    if ( ImplGetParent() )
3448
0
        ImplGetParent()->ImplCallActivateListeners( pOld );
3449
0
    else if( (mpWindowImpl->mnStyle & WB_INTROWIN) == 0 )
3450
0
    {
3451
        // top level frame reached: store hint for DefModalDialogParent
3452
0
        ImplGetSVData()->maFrameData.mpActiveApplicationFrame = mpWindowImpl->mpFrameWindow;
3453
0
    }
3454
0
}
3455
3456
void Window::SetClipboard(Reference<XClipboard> const & xClipboard)
3457
0
{
3458
0
    if (mpWindowImpl->mpFrameData)
3459
0
        mpWindowImpl->mpFrameData->mxClipboard = xClipboard;
3460
0
}
3461
3462
Reference< XClipboard > Window::GetClipboard()
3463
8.47k
{
3464
8.47k
    if (!mpWindowImpl->mpFrameData)
3465
0
        return static_cast<XClipboard*>(nullptr);
3466
8.47k
    if (!mpWindowImpl->mpFrameData->mxClipboard.is())
3467
8.47k
        mpWindowImpl->mpFrameData->mxClipboard = GetSystemClipboard();
3468
8.47k
    return mpWindowImpl->mpFrameData->mxClipboard;
3469
8.47k
}
3470
3471
void Window::RecordLayoutData( vcl::ControlLayoutData* pLayout, const tools::Rectangle& rRect )
3472
0
{
3473
0
    assert(GetOutDev()->mpOutDevData);
3474
0
    GetOutDev()->mpOutDevData->mpRecordLayout = pLayout;
3475
0
    GetOutDev()->mpOutDevData->maRecordRect = rRect;
3476
0
    Paint(*GetOutDev(), rRect);
3477
0
    GetOutDev()->mpOutDevData->mpRecordLayout = nullptr;
3478
0
}
3479
3480
void Window::DrawSelectionBackground( const tools::Rectangle& rRect,
3481
                                      sal_uInt16 highlight,
3482
                                      bool bChecked,
3483
                                      bool bDrawBorder
3484
                                      )
3485
0
{
3486
0
    if( rRect.IsEmpty() )
3487
0
        return;
3488
3489
0
    const StyleSettings& rStyles = GetSettings().GetStyleSettings();
3490
3491
    // colors used for item highlighting
3492
0
    Color aSelectionBorderCol( rStyles.GetHighlightColor() );
3493
0
    Color aSelectionFillCol( aSelectionBorderCol );
3494
3495
0
    bool bDark = rStyles.GetFaceColor().IsDark();
3496
0
    bool bBright = ( rStyles.GetFaceColor() == COL_WHITE );
3497
3498
0
    int c1 = aSelectionBorderCol.GetLuminance();
3499
0
    int c2 = GetBackgroundColor().GetLuminance();
3500
3501
0
    if( !bDark && !bBright && abs( c2-c1 ) < 75 )
3502
0
    {
3503
        // contrast too low
3504
0
        sal_uInt16 h,s,b;
3505
0
        aSelectionFillCol.RGBtoHSB( h, s, b );
3506
0
        if( b > 50 )    b -= 40;
3507
0
        else            b += 40;
3508
0
        aSelectionFillCol = Color::HSBtoRGB( h, s, b );
3509
0
        aSelectionBorderCol = aSelectionFillCol;
3510
0
    }
3511
3512
0
    tools::Rectangle aRect( rRect );
3513
0
    GetOutDev()->Push(vcl::PushFlags::FILLCOLOR | vcl::PushFlags::LINECOLOR);
3514
3515
0
    if( bDrawBorder )
3516
0
        GetOutDev()->SetLineColor( bDark ? COL_WHITE : ( bBright ? COL_BLACK : aSelectionBorderCol ) );
3517
0
    else
3518
0
        GetOutDev()->SetLineColor();
3519
3520
0
    sal_uInt16 nPercent = 0;
3521
0
    if( !highlight )
3522
0
    {
3523
0
        if( bDark )
3524
0
            aSelectionFillCol = COL_BLACK;
3525
0
        else
3526
0
            nPercent = 80;  // just checked (light)
3527
0
    }
3528
0
    else
3529
0
    {
3530
0
        if( bChecked && highlight == 2 )
3531
0
        {
3532
0
            if( bDark )
3533
0
                aSelectionFillCol = COL_LIGHTGRAY;
3534
0
            else if ( bBright )
3535
0
            {
3536
0
                aSelectionFillCol = COL_BLACK;
3537
0
                GetOutDev()->SetLineColor( COL_BLACK );
3538
0
                nPercent = 0;
3539
0
            }
3540
0
            else
3541
0
                nPercent = 20;          // selected, pressed or checked ( very dark )
3542
0
        }
3543
0
        else if( bChecked || highlight == 1 )
3544
0
        {
3545
0
            if( bDark )
3546
0
                aSelectionFillCol = COL_GRAY;
3547
0
            else if ( bBright )
3548
0
            {
3549
0
                aSelectionFillCol = COL_BLACK;
3550
0
                GetOutDev()->SetLineColor( COL_BLACK );
3551
0
                nPercent = 0;
3552
0
            }
3553
0
            else
3554
0
                nPercent = 35;          // selected, pressed or checked ( very dark )
3555
0
        }
3556
0
        else
3557
0
        {
3558
0
            if( bDark )
3559
0
                aSelectionFillCol = COL_LIGHTGRAY;
3560
0
            else if ( bBright )
3561
0
            {
3562
0
                aSelectionFillCol = COL_BLACK;
3563
0
                GetOutDev()->SetLineColor( COL_BLACK );
3564
0
                if( highlight == 3 )
3565
0
                    nPercent = 80;
3566
0
                else
3567
0
                    nPercent = 0;
3568
0
            }
3569
0
            else
3570
0
                nPercent = 70;          // selected ( dark )
3571
0
        }
3572
0
    }
3573
3574
0
    GetOutDev()->SetFillColor( aSelectionFillCol );
3575
3576
0
    if( bDark )
3577
0
    {
3578
0
        GetOutDev()->DrawRect( aRect );
3579
0
    }
3580
0
    else
3581
0
    {
3582
0
        tools::Polygon aPoly( aRect );
3583
0
        tools::PolyPolygon aPolyPoly( aPoly );
3584
0
        GetOutDev()->DrawTransparent( aPolyPoly, nPercent );
3585
0
    }
3586
3587
0
    GetOutDev()->Pop();
3588
0
}
3589
3590
bool Window::IsScrollable() const
3591
0
{
3592
    // check for scrollbars
3593
0
    VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
3594
0
    while( pChild )
3595
0
    {
3596
0
        if( pChild->GetType() == WindowType::SCROLLBAR )
3597
0
            return true;
3598
0
        else
3599
0
            pChild = pChild->mpWindowImpl->mpNext;
3600
0
    }
3601
0
    return false;
3602
0
}
3603
3604
void Window::ImplMirrorFramePos( Point &pt ) const
3605
0
{
3606
0
    pt.setX(mpWindowImpl->mpFrame->GetWidth() - 1 - pt.X());
3607
0
}
3608
3609
// frame based modal counter (dialogs are not modal to the whole application anymore)
3610
bool Window::IsInModalMode() const
3611
16.9k
{
3612
16.9k
    return (mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mnModalMode != 0);
3613
16.9k
}
3614
3615
void Window::IncModalCount()
3616
0
{
3617
0
    vcl::Window* pFrameWindow = mpWindowImpl->mpFrameWindow;
3618
0
    vcl::Window* pParent = pFrameWindow;
3619
0
    while( pFrameWindow )
3620
0
    {
3621
0
        pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode++;
3622
0
        while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow )
3623
0
        {
3624
0
            pParent = pParent->GetParent();
3625
0
        }
3626
0
        pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow.get() : nullptr;
3627
0
    }
3628
0
}
3629
void Window::DecModalCount()
3630
0
{
3631
0
    vcl::Window* pFrameWindow = mpWindowImpl->mpFrameWindow;
3632
0
    vcl::Window* pParent = pFrameWindow;
3633
0
    while( pFrameWindow )
3634
0
    {
3635
0
        pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode--;
3636
0
        while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow )
3637
0
        {
3638
0
            pParent = pParent->GetParent();
3639
0
        }
3640
0
        pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow.get() : nullptr;
3641
0
    }
3642
0
}
3643
3644
void Window::ImplIsInTaskPaneList( bool mbIsInTaskList )
3645
0
{
3646
0
    mpWindowImpl->mbIsInTaskPaneList = mbIsInTaskList;
3647
0
}
3648
3649
void Window::ImplNotifyIconifiedState( bool bIconified )
3650
0
{
3651
0
    mpWindowImpl->mpFrameWindow->CallEventListeners( bIconified ? VclEventId::WindowMinimize : VclEventId::WindowNormalize );
3652
    // #109206# notify client window as well to have toolkit topwindow listeners notified
3653
0
    if( mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow && mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow )
3654
0
        mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow->CallEventListeners( bIconified ? VclEventId::WindowMinimize : VclEventId::WindowNormalize );
3655
0
}
3656
3657
bool Window::HasActiveChildFrame() const
3658
0
{
3659
0
    bool bRet = false;
3660
0
    vcl::Window *pFrameWin = ImplGetSVData()->maFrameData.mpFirstFrame;
3661
0
    while( pFrameWin )
3662
0
    {
3663
0
        if( pFrameWin != mpWindowImpl->mpFrameWindow )
3664
0
        {
3665
0
            bool bDecorated = false;
3666
0
            VclPtr< vcl::Window > pChildFrame = pFrameWin->ImplGetWindow();
3667
            // #i15285# unfortunately WB_MOVEABLE is the same as WB_TABSTOP which can
3668
            // be removed for ToolBoxes to influence the keyboard accessibility
3669
            // thus WB_MOVEABLE is no indicator for decoration anymore
3670
            // but FloatingWindows carry this information in their TitleType...
3671
            // TODO: avoid duplicate WinBits !!!
3672
0
            if( pChildFrame && pChildFrame->ImplIsFloatingWindow() )
3673
0
                bDecorated = static_cast<FloatingWindow*>(pChildFrame.get())->GetTitleType() != FloatWinTitleType::NONE;
3674
0
            if( bDecorated || (pFrameWin->mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE) ) )
3675
0
                if( pChildFrame && pChildFrame->IsVisible() && pChildFrame->IsActive() )
3676
0
                {
3677
0
                    if( ImplIsChild( pChildFrame, true ) )
3678
0
                    {
3679
0
                        bRet = true;
3680
0
                        break;
3681
0
                    }
3682
0
                }
3683
0
        }
3684
0
        pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame;
3685
0
    }
3686
0
    return bRet;
3687
0
}
3688
3689
LanguageType Window::GetInputLanguage() const
3690
0
{
3691
0
    return mpWindowImpl->mpFrame->GetInputLanguage();
3692
0
}
3693
3694
void Window::EnableNativeWidget( bool bEnable )
3695
0
{
3696
0
    static const char* pNoNWF = getenv( "SAL_NO_NWF" );
3697
0
    if( pNoNWF && *pNoNWF )
3698
0
        bEnable = false;
3699
3700
0
    if( bEnable != ImplGetWinData()->mbEnableNativeWidget )
3701
0
    {
3702
0
        ImplGetWinData()->mbEnableNativeWidget = bEnable;
3703
3704
        // send datachanged event to allow for internal changes required for NWF
3705
        // like clipmode, transparency, etc.
3706
0
        DataChangedEvent aDCEvt( DataChangedEventType::SETTINGS, &*GetOutDev()->moSettings, AllSettingsFlags::STYLE );
3707
0
        CompatDataChanged( aDCEvt );
3708
3709
        // sometimes the borderwindow is queried, so keep it in sync
3710
0
        if( mpWindowImpl->mpBorderWindow )
3711
0
            mpWindowImpl->mpBorderWindow->ImplGetWinData()->mbEnableNativeWidget = bEnable;
3712
0
    }
3713
3714
    // push down, useful for compound controls
3715
0
    VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
3716
0
    while( pChild )
3717
0
    {
3718
0
        pChild->EnableNativeWidget( bEnable );
3719
0
        pChild = pChild->mpWindowImpl->mpNext;
3720
0
    }
3721
0
}
3722
3723
bool Window::IsNativeWidgetEnabled() const
3724
59.1k
{
3725
59.1k
    return mpWindowImpl && ImplGetWinData()->mbEnableNativeWidget;
3726
59.1k
}
3727
3728
Reference< css::rendering::XCanvas > WindowOutputDevice::ImplGetCanvas( bool bSpriteCanvas ) const
3729
0
{
3730
    // Feed any with operating system's window handle
3731
3732
    // common: first any is VCL pointer to window (for VCL canvas)
3733
0
    Sequence< Any > aArg{
3734
0
        Any(reinterpret_cast<sal_Int64>(this)),
3735
0
        Any(css::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight )),
3736
0
        Any(mxOwnerWindow->mpWindowImpl->mbAlwaysOnTop),
3737
0
        Any(Reference< css::awt::XWindow >(
3738
0
                             mxOwnerWindow->GetComponentInterface(),
3739
0
                             UNO_QUERY )),
3740
0
        GetSystemGfxDataAny()
3741
0
    };
3742
3743
0
    const Reference< XComponentContext >& xContext = comphelper::getProcessComponentContext();
3744
3745
    // Create canvas instance with window handle
3746
3747
0
    static tools::DeleteUnoReferenceOnDeinit<XMultiComponentFactory> xStaticCanvasFactory(
3748
0
        css::rendering::CanvasFactory::create( xContext ) );
3749
0
    Reference<XMultiComponentFactory> xCanvasFactory(xStaticCanvasFactory.get());
3750
0
    Reference< css::rendering::XCanvas > xCanvas;
3751
3752
0
    if(xCanvasFactory.is())
3753
0
    {
3754
#ifdef _WIN32
3755
        // see #140456# - if we're running on a multiscreen setup,
3756
        // request special, multi-screen safe sprite canvas
3757
        // implementation (not DX5 canvas, as it cannot cope with
3758
        // surfaces spanning multiple displays). Note: canvas
3759
        // (without sprite) stays the same)
3760
        const sal_uInt32 nDisplay = static_cast< WinSalFrame* >( mxOwnerWindow->mpWindowImpl->mpFrame )->mnDisplay;
3761
        if( nDisplay >= Application::GetScreenCount() )
3762
        {
3763
            xCanvas.set( xCanvasFactory->createInstanceWithArgumentsAndContext(
3764
                                 bSpriteCanvas ?
3765
                                 OUString( "com.sun.star.rendering.SpriteCanvas.MultiScreen" ) :
3766
                                 OUString( "com.sun.star.rendering.Canvas.MultiScreen" ),
3767
                                 aArg,
3768
                                 xContext ),
3769
                             UNO_QUERY );
3770
3771
        }
3772
        else
3773
#endif
3774
0
        {
3775
0
            xCanvas.set( xCanvasFactory->createInstanceWithArgumentsAndContext(
3776
0
                             bSpriteCanvas ?
3777
0
                             u"com.sun.star.rendering.SpriteCanvas"_ustr :
3778
0
                             u"com.sun.star.rendering.Canvas"_ustr,
3779
0
                             aArg,
3780
0
                             xContext ),
3781
0
                         UNO_QUERY );
3782
3783
0
        }
3784
0
    }
3785
3786
    // no factory??? Empty reference, then.
3787
0
    return xCanvas;
3788
0
}
3789
3790
OUString Window::GetSurroundingText() const
3791
0
{
3792
0
  return OUString();
3793
0
}
3794
3795
Selection Window::GetSurroundingTextSelection() const
3796
0
{
3797
0
  return Selection( 0, 0 );
3798
0
}
3799
3800
namespace
3801
{
3802
    using namespace com::sun::star;
3803
3804
    uno::Reference<accessibility::XAccessibleEditableText> lcl_GetxText(vcl::Window *pFocusWin)
3805
0
    {
3806
0
        uno::Reference<accessibility::XAccessibleEditableText> xText;
3807
0
        try
3808
0
        {
3809
0
            uno::Reference< accessibility::XAccessible > xAccessible( pFocusWin->GetAccessible() );
3810
0
            if (xAccessible.is())
3811
0
                xText = FindFocusedEditableText(xAccessible->getAccessibleContext());
3812
0
        }
3813
0
        catch(const uno::Exception&)
3814
0
        {
3815
0
            TOOLS_WARN_EXCEPTION( "vcl.gtk3", "Exception in getting input method surrounding text");
3816
0
        }
3817
0
        return xText;
3818
0
    }
3819
}
3820
3821
// this is a rubbish implementation using a11y, ideally all subclasses implementing
3822
// GetSurroundingText/GetSurroundingTextSelection should implement this and then this
3823
// should be removed in favor of a stub that returns false
3824
bool Window::DeleteSurroundingText(const Selection& rSelection)
3825
0
{
3826
0
    uno::Reference<accessibility::XAccessibleEditableText> xText = lcl_GetxText(this);
3827
0
    if (xText.is())
3828
0
    {
3829
0
        sal_Int32 nPosition = xText->getCaretPosition();
3830
        // #i111768# range checking
3831
0
        sal_Int32 nDeletePos = rSelection.Min();
3832
0
        sal_Int32 nDeleteEnd = rSelection.Max();
3833
0
        if (nDeletePos < 0)
3834
0
            nDeletePos = 0;
3835
0
        if (nDeleteEnd < 0)
3836
0
            nDeleteEnd = 0;
3837
0
        if (nDeleteEnd > xText->getCharacterCount())
3838
0
            nDeleteEnd = xText->getCharacterCount();
3839
3840
0
        xText->deleteText(nDeletePos, nDeleteEnd);
3841
        //tdf91641 adjust cursor if deleted chars shift it forward (normal case)
3842
0
        if (nDeletePos < nPosition)
3843
0
        {
3844
0
            if (nDeleteEnd <= nPosition)
3845
0
                nPosition = nPosition - (nDeleteEnd - nDeletePos);
3846
0
            else
3847
0
                nPosition = nDeletePos;
3848
3849
0
            if (xText->getCharacterCount() >= nPosition)
3850
0
                xText->setCaretPosition( nPosition );
3851
0
        }
3852
0
        return true;
3853
0
    }
3854
3855
0
    return false;
3856
0
}
3857
3858
bool WindowOutputDevice::UsePolyPolygonForComplexGradient()
3859
0
{
3860
0
    return meRasterOp != RasterOp::OverPaint;
3861
0
}
3862
3863
void Window::ApplySettings(vcl::RenderContext& /*rRenderContext*/)
3864
0
{
3865
0
}
3866
3867
const SystemEnvData* Window::GetSystemData() const
3868
0
{
3869
3870
0
    return mpWindowImpl->mpFrame ? &mpWindowImpl->mpFrame->GetSystemData() : nullptr;
3871
0
}
3872
3873
bool Window::SupportsDoubleBuffering() const
3874
4
{
3875
4
    return mpWindowImpl->mpFrameData->mpBuffer;
3876
4
}
3877
3878
void Window::RequestDoubleBuffering(bool bRequest)
3879
0
{
3880
0
    if (bRequest)
3881
0
    {
3882
0
        mpWindowImpl->mpFrameData->mpBuffer = VclPtrInstance<VirtualDevice>();
3883
        // Make sure that the buffer size matches the frame size.
3884
0
        mpWindowImpl->mpFrameData->mpBuffer->SetOutputSizePixel(mpWindowImpl->mpFrameWindow->GetOutputSizePixel());
3885
0
    }
3886
0
    else
3887
0
        mpWindowImpl->mpFrameData->mpBuffer.reset();
3888
0
}
3889
3890
/*
3891
 * The rationale here is that we moved destructors to
3892
 * dispose and this altered a lot of code paths, that
3893
 * are better left unchanged for now.
3894
 */
3895
void Window::CompatGetFocus()
3896
0
{
3897
0
    if (!mpWindowImpl || mpWindowImpl->mbInDispose)
3898
0
        Window::GetFocus();
3899
0
    else
3900
0
        GetFocus();
3901
0
}
3902
3903
void Window::CompatLoseFocus()
3904
0
{
3905
0
    if (!mpWindowImpl || mpWindowImpl->mbInDispose)
3906
0
        Window::LoseFocus();
3907
0
    else
3908
0
        LoseFocus();
3909
0
}
3910
3911
void Window::CompatStateChanged( StateChangedType nStateChange )
3912
131k
{
3913
131k
    if (!mpWindowImpl || mpWindowImpl->mbInDispose)
3914
25.3k
        Window::StateChanged(nStateChange);
3915
105k
    else
3916
105k
        StateChanged(nStateChange);
3917
131k
}
3918
3919
void Window::CompatDataChanged( const DataChangedEvent& rDCEvt )
3920
0
{
3921
0
    if (!mpWindowImpl || mpWindowImpl->mbInDispose)
3922
0
        Window::DataChanged(rDCEvt);
3923
0
    else
3924
0
        DataChanged(rDCEvt);
3925
0
}
3926
3927
bool Window::CompatPreNotify( NotifyEvent& rNEvt )
3928
0
{
3929
0
    if (!mpWindowImpl || mpWindowImpl->mbInDispose)
3930
0
        return Window::PreNotify( rNEvt );
3931
0
    else
3932
0
        return PreNotify( rNEvt );
3933
0
}
3934
3935
bool Window::CompatNotify( NotifyEvent& rNEvt )
3936
0
{
3937
0
    if (!mpWindowImpl || mpWindowImpl->mbInDispose)
3938
0
        return Window::EventNotify( rNEvt );
3939
0
    else
3940
0
        return EventNotify( rNEvt );
3941
0
}
3942
3943
void Window::set_id(const OUString& rID)
3944
8.47k
{
3945
8.47k
    mpWindowImpl->maID = rID;
3946
8.47k
}
3947
3948
const OUString& Window::get_id() const
3949
0
{
3950
0
    static OUString empty;
3951
0
    return mpWindowImpl ? mpWindowImpl->maID : empty;
3952
0
}
3953
3954
FactoryFunction Window::GetUITestFactory() const
3955
0
{
3956
0
    return WindowUIObject::create;
3957
0
}
3958
3959
WindowOutputDevice::WindowOutputDevice(vcl::Window& rOwnerWindow) :
3960
241k
    ::OutputDevice(OUTDEV_WINDOW),
3961
241k
    mxOwnerWindow(&rOwnerWindow)
3962
241k
{
3963
241k
    assert(mxOwnerWindow);
3964
241k
}
Unexecuted instantiation: vcl::WindowOutputDevice::WindowOutputDevice(vcl::Window&)
vcl::WindowOutputDevice::WindowOutputDevice(vcl::Window&)
Line
Count
Source
3960
241k
    ::OutputDevice(OUTDEV_WINDOW),
3961
241k
    mxOwnerWindow(&rOwnerWindow)
3962
241k
{
3963
241k
    assert(mxOwnerWindow);
3964
241k
}
3965
3966
WindowOutputDevice::~WindowOutputDevice()
3967
211k
{
3968
211k
    disposeOnce();
3969
211k
}
3970
3971
void WindowOutputDevice::dispose()
3972
211k
{
3973
211k
    assert((!mxOwnerWindow || mxOwnerWindow->isDisposed()) && "This belongs to the associated window and must be disposed after it");
3974
211k
    ::OutputDevice::dispose();
3975
    // need to do this after OutputDevice::dispose so that the call to WindowOutputDevice::ReleaseGraphics
3976
    // can release the graphics properly
3977
211k
    mxOwnerWindow.reset();
3978
211k
}
3979
3980
css::awt::DeviceInfo WindowOutputDevice::GetDeviceInfo() const
3981
37.3k
{
3982
37.3k
    css::awt::DeviceInfo aInfo = GetCommonDeviceInfo(mxOwnerWindow->GetSizePixel());
3983
37.3k
    mxOwnerWindow->GetBorder(aInfo.LeftInset, aInfo.TopInset, aInfo.RightInset, aInfo.BottomInset);
3984
37.3k
    return aInfo;
3985
37.3k
}
3986
3987
3988
} /* namespace vcl */
3989
3990
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */