Coverage Report

Created: 2026-11-06 11:29

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