    /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
    /*
     * This file is part of the LibreOffice project.
     *
     * This Source Code Form is subject to the terms of the Mozilla Public
     * License, v. 2.0. If a copy of the MPL was not distributed with this
     * file, You can obtain one at http://mozilla.org/MPL/2.0/.
     *
     * This file incorporates work covered by the following license notice:
     *
     *   Licensed to the Apache Software Foundation (ASF) under one or more
     *   contributor license agreements. See the NOTICE file distributed
     *   with this work for additional information regarding copyright
     *   ownership. The ASF licenses this file to you under the Apache
     *   License, Version 2.0 (the "License"); you may not use this file
     *   except in compliance with the License. You may obtain a copy of
     *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
     */

    #include <config_features.h>
    #include <rtl/strbuf.hxx>
    #include <sal/log.hxx>

    #include <sal/types.h>
    #include <vcl/salgtype.hxx>
    #include <vcl/event.hxx>
    #include <vcl/help.hxx>
    #include <vcl/cursor.hxx>
    #include <vcl/svapp.hxx>
    #include <vcl/vclevent.hxx>
    #include <vcl/window.hxx>
    #include <vcl/syswin.hxx>
    #include <vcl/syschild.hxx>
    #include <vcl/dockwin.hxx>
    #include <vcl/wall.hxx>
    #include <vcl/fixed.hxx>
    #include <vcl/gradient.hxx>
    #include <vcl/button.hxx>
    #include <vcl/taskpanelist.hxx>
    #include <vcl/dialog.hxx>
    #include <vcl/unowrap.hxx>
    #include <vcl/gdimtf.hxx>
    #include <vcl/lazydelete.hxx>
    #include <vcl/virdev.hxx>
    #include <vcl/settings.hxx>
    #include <vcl/sysdata.hxx>
    #include <vcl/IDialogRenderable.hxx>

    #include <vcl/uitest/uiobject.hxx>
    #include <vcl/uitest/uitest.hxx>

    #include <salframe.hxx>
    #include <salobj.hxx>
    #include <salinst.hxx>
    #include <salgdi.hxx>
    #include <svdata.hxx>
    #include <window.h>
    #include <toolbox.h>
    #include <outdev.h>
    #include <brdwin.hxx>
    #include <helpwin.hxx>
    #include <dndlistenercontainer.hxx>

    #include <com/sun/star/awt/XDisplayConnection.hpp>
    #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
    #include <com/sun/star/datatransfer/clipboard/SystemClipboard.hpp>
    #include <com/sun/star/rendering/CanvasFactory.hpp>
    #include <com/sun/star/rendering/XSpriteCanvas.hpp>
    #include <comphelper/lok.hxx>
    #include <comphelper/processfactory.hxx>
    #include <unotools/configmgr.hxx>

    #include <cassert>
    #include <set>
    #include <typeinfo>

    #ifdef _WIN32 // see #140456#
    #include <win/salframe.h>
    #endif

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::datatransfer::clipboard;
    using namespace ::com::sun::star::datatransfer::dnd;

    namespace vcl {

    Window::Window( WindowType nType ) :
        mpWindowImpl(new WindowImpl( nType ))
    {
        meOutDevType = OUTDEV_WINDOW;

        // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
        mbEnableRTL = AllSettings::GetLayoutRTL();
    }

    Window::Window( vcl::Window* pParent, WinBits nStyle ) :
        mpWindowImpl(new WindowImpl( WindowType::WINDOW ))
    {
        meOutDevType = OUTDEV_WINDOW;

        // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
        mbEnableRTL = AllSettings::GetLayoutRTL();

        ImplInit( pParent, nStyle, nullptr );
    }

    #if OSL_DEBUG_LEVEL > 0
    namespace
    {
         OString lcl_createWindowInfo(const vcl::Window* pWindow)
         {
             // skip border windows, they do not carry information that
             // would help with diagnosing the problem
             const vcl::Window* pTempWin( pWindow );
             while ( pTempWin && pTempWin->GetType() == WindowType::BORDERWINDOW ) {
                 pTempWin = pTempWin->GetWindow( GetWindowType::FirstChild );
             }
             // check if pTempWin is not null, otherwise use the
             // original address
             if ( pTempWin ) {
                 pWindow = pTempWin;
             }

             OStringBuffer aErrorString;
             aErrorString.append(' ');
             aErrorString.append(typeid( *pWindow ).name());
             aErrorString.append("(");
             aErrorString.append(
                     OUStringToOString(
                         pWindow->GetText(),
                         RTL_TEXTENCODING_UTF8
                         )
                     );
             aErrorString.append(")");
             return aErrorString.makeStringAndClear();
         }
    }
    #endif

    bool Window::IsDisposed() const
    {
        return !mpWindowImpl;
    }

    void Window::dispose()
    {
        assert( mpWindowImpl );
        assert( !mpWindowImpl->mbInDispose ); // should only be called from disposeOnce()
        assert( (!mpWindowImpl->mpParent ||
                !mpWindowImpl->mpParent->IsDisposed()) &&
                "vcl::Window child should have its parent disposed first" );

        // remove Key and Mouse events issued by Application::PostKey/MouseEvent
        Application::RemoveMouseAndKeyEvents( this );

        // Dispose of the canvas implementation (which, currently, has an
        // own wrapper window as a child to this one.
        Reference< css::rendering::XCanvas > xCanvas( mpWindowImpl->mxCanvas );
        if( xCanvas.is() )
        {
            Reference < XComponent > xCanvasComponent( xCanvas, UNO_QUERY );
            if( xCanvasComponent.is() )
                xCanvasComponent->dispose();
        }

        mpWindowImpl->mbInDispose = true;

        CallEventListeners( VclEventId::ObjectDying );

        // do not send child events for frames that were registered as native frames
        if( !ImplIsAccessibleNativeFrame() && mpWindowImpl->mbReallyVisible )
            if ( ImplIsAccessibleCandidate() && GetAccessibleParentWindow() )
                GetAccessibleParentWindow()->CallEventListeners( VclEventId::WindowChildDestroyed, this );

        // remove associated data structures from dockingmanager
        ImplGetDockingManager()->RemoveWindow( this );

        // remove ownerdraw decorated windows from list in the top-most frame window
        if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
        {
            ::std::vector< VclPtr<vcl::Window> >& rList = ImplGetOwnerDrawList();
            auto p = ::std::find( rList.begin(), rList.end(), VclPtr<vcl::Window>(this) );
            if( p != rList.end() )
                rList.erase( p );
        }

        // shutdown drag and drop
        Reference < XComponent > xDnDComponent( mpWindowImpl->mxDNDListenerContainer, UNO_QUERY );

        if( xDnDComponent.is() )
            xDnDComponent->dispose();

        if( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData )
        {
            try
            {
                // deregister drop target listener
                if( mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
                {
                    Reference< XDragGestureRecognizer > xDragGestureRecognizer =
                        Reference< XDragGestureRecognizer > (mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY);
                    if( xDragGestureRecognizer.is() )
                    {
                        xDragGestureRecognizer->removeDragGestureListener(
                            Reference< XDragGestureListener > (mpWindowImpl->mpFrameData->mxDropTargetListener, UNO_QUERY));
                    }

                    mpWindowImpl->mpFrameData->mxDropTarget->removeDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener );
                    mpWindowImpl->mpFrameData->mxDropTargetListener.clear();
                }

                // shutdown drag and drop for this frame window
                Reference< XComponent > xComponent( mpWindowImpl->mpFrameData->mxDropTarget, UNO_QUERY );

                // DNDEventDispatcher does not hold a reference of the DropTarget,
                // so it's ok if it does not support XComponent
                if( xComponent.is() )
                    xComponent->dispose();
            }
            catch (const Exception&)
            {
                // can be safely ignored here.
            }
        }

        UnoWrapperBase* pWrapper = Application::GetUnoWrapper( false );
        if ( pWrapper )
            pWrapper->WindowDestroyed( this );

        // MT: Must be called after WindowDestroyed!
        // Otherwise, if the accessible is a VCLXWindow, it will try to destroy this window again!
        // But accessibility implementations from applications need this dispose.
        if ( mpWindowImpl->mxAccessible.is() )
        {
            Reference< XComponent> xC( mpWindowImpl->mxAccessible, UNO_QUERY );
            if ( xC.is() )
                xC->dispose();
        }

        ImplSVData* pSVData = ImplGetSVData();

        if ( pSVData->maHelpData.mpHelpWin && (pSVData->maHelpData.mpHelpWin->GetParent() == this) )
            ImplDestroyHelpWindow( true );

        SAL_WARN_IF( pSVData->maWinData.mpTrackWin.get() == this, "vcl.window",
                    "Window::~Window(): Window is in TrackingMode" );
        SAL_WARN_IF(IsMouseCaptured(), "vcl.window",
                    "Window::~Window(): Window has the mouse captured");

        // due to old compatibility
        if ( pSVData->maWinData.mpTrackWin == this )
            EndTracking();
        if (IsMouseCaptured())
            ReleaseMouse();

    #if OSL_DEBUG_LEVEL > 0
        if ( true ) // always perform these tests in debug builds
        {
            OStringBuffer aErrorStr;
            bool        bError = false;
            vcl::Window*     pTempWin;

            if ( mpWindowImpl->mpFirstChild )
            {
                OStringBuffer aTempStr("Window (");
                aTempStr.append(lcl_createWindowInfo(this));
                aTempStr.append(") with live children destroyed: ");
                pTempWin = mpWindowImpl->mpFirstChild;
                while ( pTempWin )
                {
                    aTempStr.append(lcl_createWindowInfo(pTempWin));
                    pTempWin = pTempWin->mpWindowImpl->mpNext;
                }
                OSL_FAIL( aTempStr.getStr() );
                Application::Abort(OStringToOUString(aTempStr.makeStringAndClear(), RTL_TEXTENCODING_UTF8));   // abort in debug builds, this must be fixed!
            }

            if (mpWindowImpl->mpFrameData != nullptr)
            {
                pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap;
                while ( pTempWin )
                {
                    if ( ImplIsRealParentPath( pTempWin ) )
                    {
                        bError = true;
                        aErrorStr.append(lcl_createWindowInfo(pTempWin));
                    }
                    pTempWin = pTempWin->mpWindowImpl->mpNextOverlap;
                }
                if ( bError )
                {
                    OStringBuffer aTempStr;
                    aTempStr.append("Window (");
                    aTempStr.append(lcl_createWindowInfo(this));
                    aTempStr.append(") with live SystemWindows destroyed: ");
                    aTempStr.append(aErrorStr.toString());
                    OSL_FAIL(aTempStr.getStr());
                    // abort in debug builds, must be fixed!
                    Application::Abort(OStringToOUString(
                                         aTempStr.makeStringAndClear(), RTL_TEXTENCODING_UTF8));
                }
            }

            bError = false;
            pTempWin = pSVData->maWinData.mpFirstFrame;
            while ( pTempWin )
            {
                if ( ImplIsRealParentPath( pTempWin ) )
                {
                    bError = true;
                    aErrorStr.append(lcl_createWindowInfo(pTempWin));
                }
                pTempWin = pTempWin->mpWindowImpl->mpFrameData->mpNextFrame;
            }
            if ( bError )
            {
                OStringBuffer aTempStr( "Window (" );
                aTempStr.append(lcl_createWindowInfo(this));
                aTempStr.append(") with live SystemWindows destroyed: ");
                aTempStr.append(aErrorStr.toString());
                OSL_FAIL( aTempStr.getStr() );
                Application::Abort(OStringToOUString(aTempStr.makeStringAndClear(), RTL_TEXTENCODING_UTF8));   // abort in debug builds, this must be fixed!
            }

            if ( mpWindowImpl->mpFirstOverlap )
            {
                OStringBuffer aTempStr("Window (");
                aTempStr.append(lcl_createWindowInfo(this));
                aTempStr.append(") with live SystemWindows destroyed: ");
                pTempWin = mpWindowImpl->mpFirstOverlap;
                while ( pTempWin )
                {
                    aTempStr.append(lcl_createWindowInfo(pTempWin));
                    pTempWin = pTempWin->mpWindowImpl->mpNext;
                }
                OSL_FAIL( aTempStr.getStr() );
                Application::Abort(OStringToOUString(aTempStr.makeStringAndClear(), RTL_TEXTENCODING_UTF8));   // abort in debug builds, this must be fixed!
            }

            vcl::Window* pMyParent = GetParent();
            SystemWindow* pMySysWin = nullptr;

            while ( pMyParent )
            {
                if ( pMyParent->IsSystemWindow() )
                {
                    pMySysWin = dynamic_cast<SystemWindow *>(pMyParent);
                }
                pMyParent = pMyParent->GetParent();
            }
            if ( pMySysWin && pMySysWin->ImplIsInTaskPaneList( this ) )
            {
                OStringBuffer aTempStr("Window (");
                aTempStr.append(lcl_createWindowInfo(this));
                aTempStr.append(") still in TaskPanelList!");
                OSL_FAIL( aTempStr.getStr() );
                Application::Abort(OStringToOUString(aTempStr.makeStringAndClear(), RTL_TEXTENCODING_UTF8));   // abort in debug builds, this must be fixed!
            }
        }
    #endif

        if( mpWindowImpl->mbIsInTaskPaneList )
        {
            vcl::Window* pMyParent = GetParent();
            SystemWindow* pMySysWin = nullptr;

            while ( pMyParent )
            {
                if ( pMyParent->IsSystemWindow() )
                {
                    pMySysWin = dynamic_cast<SystemWindow *>(pMyParent);
                }
                pMyParent = pMyParent->GetParent();
            }
            if ( pMySysWin && pMySysWin->ImplIsInTaskPaneList( this ) )
            {
                pMySysWin->GetTaskPaneList()->RemoveWindow( this );
            }
            else
            {
                SAL_WARN( "vcl", "Window (" << GetText() << ") not found in TaskPanelList");
            }
        }

        // remove from size-group if necessary
        remove_from_all_size_groups();

        // clear mnemonic labels
        std::vector<VclPtr<FixedText> > aMnemonicLabels(list_mnemonic_labels());
        for (auto const& mnemonicLabel : aMnemonicLabels)
        {
            remove_mnemonic_label(mnemonicLabel);
        }

        // hide window in order to trigger the Paint-Handling
        Hide();

        // announce the window is to be destroyed
        {
            NotifyEvent aNEvt( MouseNotifyEvent::DESTROY, this );
            CompatNotify( aNEvt );
        }

        // EndExtTextInputMode
        if ( pSVData->maWinData.mpExtTextInputWin == this )
        {
            EndExtTextInput();
            if ( pSVData->maWinData.mpExtTextInputWin == this )
                pSVData->maWinData.mpExtTextInputWin = nullptr;
        }

        // check if the focus window is our child
        bool bHasFocussedChild = false;
        if( pSVData->maWinData.mpFocusWin && ImplIsRealParentPath( pSVData->maWinData.mpFocusWin ) )
        {
            // #122232#, this must not happen and is an application bug ! but we try some cleanup to hopefully avoid crashes, see below
            bHasFocussedChild = true;
    #if OSL_DEBUG_LEVEL > 0
            OUString aTempStr = "Window (" + GetText() +
                    ") with focused child window destroyed ! THIS WILL LEAD TO CRASHES AND MUST BE FIXED !";
            SAL_WARN( "vcl", aTempStr );
            Application::Abort(aTempStr);   // abort in debug build version, this must be fixed!
    #endif
        }

        // if we get focus pass focus to another window
        vcl::Window* pOverlapWindow = ImplGetFirstOverlapWindow();
        if ( pSVData->maWinData.mpFocusWin == this
            || bHasFocussedChild )  // #122232#, see above, try some cleanup
        {
            if ( mpWindowImpl->mbFrame )
            {
                pSVData->maWinData.mpFocusWin = nullptr;
                pOverlapWindow->mpWindowImpl->mpLastFocusWindow = nullptr;
            }
            else
            {
                vcl::Window* pParent = GetParent();
                vcl::Window* pBorderWindow = mpWindowImpl->mpBorderWindow;
            // when windows overlap, give focus to the parent
            // of the next FrameWindow
                if ( pBorderWindow )
                {
                    if ( pBorderWindow->ImplIsOverlapWindow() )
                        pParent = pBorderWindow->mpWindowImpl->mpOverlapWindow;
                }
                else if ( ImplIsOverlapWindow() )
                    pParent = mpWindowImpl->mpOverlapWindow;

                if ( pParent && pParent->IsEnabled() && pParent->IsInputEnabled() && ! pParent->IsInModalMode() )
                    pParent->GrabFocus();
                else
                    mpWindowImpl->mpFrameWindow->GrabFocus();

                // If the focus was set back to 'this' set it to nothing
                if ( pSVData->maWinData.mpFocusWin == this )
                {
                    pSVData->maWinData.mpFocusWin = nullptr;
                    pOverlapWindow->mpWindowImpl->mpLastFocusWindow = nullptr;
                }
            }
        }

        if ( pOverlapWindow != nullptr &&
             pOverlapWindow->mpWindowImpl->mpLastFocusWindow == this )
            pOverlapWindow->mpWindowImpl->mpLastFocusWindow = nullptr;

        // reset hint for DefModalDialogParent
        if( pSVData->maWinData.mpActiveApplicationFrame == this )
            pSVData->maWinData.mpActiveApplicationFrame = nullptr;

        // reset hint of what was the last wheeled window
        if( pSVData->maWinData.mpLastWheelWindow == this )
            pSVData->maWinData.mpLastWheelWindow = nullptr;

        // reset marked windows
        if ( mpWindowImpl->mpFrameData != nullptr )
        {
            if ( mpWindowImpl->mpFrameData->mpFocusWin == this )
                mpWindowImpl->mpFrameData->mpFocusWin = nullptr;
            if ( mpWindowImpl->mpFrameData->mpMouseMoveWin == this )
                mpWindowImpl->mpFrameData->mpMouseMoveWin = nullptr;
            if ( mpWindowImpl->mpFrameData->mpMouseDownWin == this )
                mpWindowImpl->mpFrameData->mpMouseDownWin = nullptr;
        }

        // reset Deactivate-Window
        if ( pSVData->maWinData.mpLastDeacWin == this )
            pSVData->maWinData.mpLastDeacWin = nullptr;

        if ( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData )
        {
            if ( mpWindowImpl->mpFrameData->mnFocusId )
                Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnFocusId );
            mpWindowImpl->mpFrameData->mnFocusId = nullptr;
            if ( mpWindowImpl->mpFrameData->mnMouseMoveId )
                Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnMouseMoveId );
            mpWindowImpl->mpFrameData->mnMouseMoveId = nullptr;
        }

        // release SalGraphics
        OutputDevice *pOutDev = GetOutDev();
        pOutDev->ReleaseGraphics();

        // remove window from the lists
        ImplRemoveWindow( true );

        // de-register as "top window child" at our parent, if necessary
        if ( mpWindowImpl->mbFrame )
        {
            bool bIsTopWindow = mpWindowImpl->mpWinData && ( mpWindowImpl->mpWinData->mnIsTopWindow == 1 );
            if ( mpWindowImpl->mpRealParent && bIsTopWindow )
            {
                ImplWinData* pParentWinData = mpWindowImpl->mpRealParent->ImplGetWinData();

                auto myPos = ::std::find( pParentWinData->maTopWindowChildren.begin(),
                    pParentWinData->maTopWindowChildren.end(), VclPtr<vcl::Window>(this) );
                SAL_WARN_IF( myPos == pParentWinData->maTopWindowChildren.end(), "vcl.window", "Window::~Window: inconsistency in top window chain!" );
                if ( myPos != pParentWinData->maTopWindowChildren.end() )
                    pParentWinData->maTopWindowChildren.erase( myPos );
            }
        }

        delete mpWindowImpl->mpWinData;
        mpWindowImpl->mpWinData = nullptr;

        // remove BorderWindow or Frame window data
        mpWindowImpl->mpBorderWindow.disposeAndClear();
        if ( mpWindowImpl->mbFrame )
        {
            if ( pSVData->maWinData.mpFirstFrame == this )
                pSVData->maWinData.mpFirstFrame = mpWindowImpl->mpFrameData->mpNextFrame;
            else
            {
                sal_Int32 nWindows = 0;
                vcl::Window* pSysWin = pSVData->maWinData.mpFirstFrame;
                while ( pSysWin && pSysWin->mpWindowImpl->mpFrameData->mpNextFrame.get() != this )
                {
                    pSysWin = pSysWin->mpWindowImpl->mpFrameData->mpNextFrame;
                    nWindows++;
                }

                if ( pSysWin )
                {
                    assert (mpWindowImpl->mpFrameData->mpNextFrame.get() != pSysWin);
                    pSysWin->mpWindowImpl->mpFrameData->mpNextFrame = mpWindowImpl->mpFrameData->mpNextFrame;
                }
                else // if it is not in the list, we can't remove it.
                    SAL_WARN("vcl.window", "Window " << this << " marked as frame window, "
                             "is missing from list of " << nWindows << " frames");
            }
            if (mpWindowImpl->mpFrame) // otherwise exception during init
            {
                mpWindowImpl->mpFrame->SetCallback( nullptr, nullptr );
                pSVData->mpDefInst->DestroyFrame( mpWindowImpl->mpFrame );
            }
            assert (mpWindowImpl->mpFrameData->mnFocusId == nullptr);
            assert (mpWindowImpl->mpFrameData->mnMouseMoveId == nullptr);

            delete mpWindowImpl->mpFrameData;
            mpWindowImpl->mpFrameData = nullptr;
        }

        // should be the last statements
        mpWindowImpl.reset();

        OutputDevice::dispose();
    }

    Window::~Window()
    {
        // FIXME: we should kill all LazyDeletor usage.
        vcl::LazyDeletor::Undelete( this );
        disposeOnce();
    }

    // We will eventually being removing the inheritance of OutputDevice
    // from Window. It will be replaced with a transient relationship such
    // that the OutputDevice is only live for the scope of the Paint method.
    // In the meantime this can help move us towards a Window use an
    // OutputDevice, not being one.

    ::OutputDevice const* Window::GetOutDev() const
    {
        return this;
    }

    ::OutputDevice* Window::GetOutDev()
    {
        return this;
    }

    } /* namespace vcl */

    WindowImpl::WindowImpl( WindowType nType )
    {
        maZoom                              = Fraction( 1, 1 );
        maWinRegion                         = vcl::Region(true);
        maWinClipRegion                     = vcl::Region(true);
        mpWinData                           = nullptr;                      // Extra Window Data, that we don't need for all windows
        mpFrameData                         = nullptr;                      // Frame Data
        mpFrame                             = nullptr;                      // Pointer to frame window
        mpSysObj                            = nullptr;
        mpFrameWindow                       = nullptr;                      // window to top level parent (same as frame window)
        mpOverlapWindow                     = nullptr;                      // first overlap parent
        mpBorderWindow                      = nullptr;                      // Border-Window
        mpClientWindow                      = nullptr;                      // Client-Window of a FrameWindow
        mpParent                            = nullptr;                      // parent (incl. BorderWindow)
        mpRealParent                        = nullptr;                      // real parent (excl. BorderWindow)
        mpFirstChild                        = nullptr;                      // first child window
        mpLastChild                         = nullptr;                      // last child window
        mpFirstOverlap                      = nullptr;                      // first overlap window (only set in overlap windows)
        mpLastOverlap                       = nullptr;                      // last overlap window (only set in overlap windows)
        mpPrev                              = nullptr;                      // prev window
        mpNext                              = nullptr;                      // next window
        mpNextOverlap                       = nullptr;                      // next overlap window of frame
        mpLastFocusWindow                   = nullptr;                      // window for focus restore
        mpDlgCtrlDownWindow                 = nullptr;                      // window for dialog control
        mnEventListenersIteratingCount = 0;
        mnChildEventListenersIteratingCount = 0;
        mpCursor                            = nullptr;                      // cursor
        mpVCLXWindow                        = nullptr;
        mpAccessibleInfos                   = nullptr;
        maControlForeground                 = COL_TRANSPARENT;  // no foreground set
        maControlBackground                 = COL_TRANSPARENT;  // no background set
        mnLeftBorder                        = 0;                         // left border
        mnTopBorder                         = 0;                         // top border
        mnRightBorder                       = 0;                         // right border
        mnBottomBorder                      = 0;                         // bottom border
        mnWidthRequest                      = -1;                        // width request
        mnHeightRequest                     = -1;                        // height request
        mnOptimalWidthCache                 = -1;                        // optimal width cache
        mnOptimalHeightCache                = -1;                        // optimal height cache
        mnX                                 = 0;                         // X-Position to Parent
        mnY                                 = 0;                         // Y-Position to Parent
        mnAbsScreenX                        = 0;                         // absolute X-position on screen, used for RTL window positioning
        mpChildClipRegion                   = nullptr;                      // Child-Clip-Region when ClipChildren
        mpPaintRegion                       = nullptr;                      // Paint-ClipRegion
        mnStyle                             = 0;                         // style (init in ImplInitWindow)
        mnPrevStyle                         = 0;                         // prevstyle (set in SetStyle)
        mnExtendedStyle                     = WindowExtendedStyle::NONE; // extended style (init in ImplInitWindow)
        mnType                              = nType;                     // type
        mnGetFocusFlags                     = GetFocusFlags::NONE;       // Flags for GetFocus()-Call
        mnWaitCount                         = 0;                         // Wait-Count (>1 == "wait" mouse pointer)
        mnPaintFlags                        = ImplPaintFlags::NONE;      // Flags for ImplCallPaint
        mnParentClipMode                    = ParentClipMode::NONE;      // Flags for Parent-ClipChildren-Mode
        mnActivateMode                      = ActivateModeFlags::NONE;   // Will be converted in System/Overlap-Windows
        mnDlgCtrlFlags                      = DialogControlFlags::NONE;  // DialogControl-Flags
        meAlwaysInputMode                   = AlwaysInputNone;           // neither AlwaysEnableInput nor AlwaysDisableInput called
        meHalign                            = VclAlign::Fill;
        meValign                            = VclAlign::Fill;
        mePackType                          = VclPackType::Start;
        mnPadding                           = 0;
        mnGridHeight                        = 1;
        mnGridLeftAttach                    = -1;
        mnGridTopAttach                     = -1;
        mnGridWidth                         = 1;
        mnBorderWidth                       = 0;
        mnMarginLeft                        = 0;
        mnMarginRight                       = 0;
        mnMarginTop                         = 0;
        mnMarginBottom                      = 0;
        mbFrame                             = false;                     // true: Window is a frame window
        mbBorderWin                         = false;                     // true: Window is a border window
        mbOverlapWin                        = false;                     // true: Window is a overlap window
        mbSysWin                            = false;                     // true: SystemWindow is the base class
        mbDialog                            = false;                     // true: Dialog is the base class
        mbDockWin                           = false;                     // true: DockingWindow is the base class
        mbFloatWin                          = false;                     // true: FloatingWindow is the base class
        mbPushButton                        = false;                     // true: PushButton is the base class
        mbToolBox                           = false;                     // true: ToolBox is the base class
        mbMenuFloatingWindow                = false;                     // true: MenuFloatingWindow is the base class
        mbToolbarFloatingWindow             = false;                     // true: ImplPopupFloatWin is the base class, used for subtoolbars
        mbSplitter                          = false;                     // true: Splitter is the base class
        mbVisible                           = false;                     // true: Show( true ) called
        mbOverlapVisible                    = false;                     // true: Hide called for visible window from ImplHideAllOverlapWindow()
        mbDisabled                          = false;                     // true: Enable( false ) called
        mbInputDisabled                     = false;                     // true: EnableInput( false ) called
        mbNoUpdate                          = false;                     // true: SetUpdateMode( false ) called
        mbNoParentUpdate                    = false;                     // true: SetParentUpdateMode( false ) called
        mbActive                            = false;                     // true: Window Active
        mbReallyVisible                     = false;                     // true: this and all parents to an overlapped window are visible
        mbReallyShown                       = false;                     // true: this and all parents to an overlapped window are shown
        mbInInitShow                        = false;                     // true: we are in InitShow
        mbChildPtrOverwrite                 = false;                     // true: PointerStyle overwrites Child-Pointer
        mbNoPtrVisible                      = false;                     // true: ShowPointer( false ) called
        mbPaintFrame                        = false;                     // true: Paint is visible, but not painted
        mbInPaint                           = false;                     // true: Inside PaintHdl
        mbMouseButtonDown                   = false;                     // true: BaseMouseButtonDown called
        mbMouseButtonUp                     = false;                     // true: BaseMouseButtonUp called
        mbKeyInput                          = false;                     // true: BaseKeyInput called
        mbKeyUp                             = false;                     // true: BaseKeyUp called
        mbCommand                           = false;                     // true: BaseCommand called
        mbDefPos                            = true;                      // true: Position is not Set
        mbDefSize                           = true;                      // true: Size is not Set
        mbCallMove                          = true;                      // true: Move must be called by Show
        mbCallResize                        = true;                      // true: Resize must be called by Show
        mbWaitSystemResize                  = true;                      // true: Wait for System-Resize
        mbInitWinClipRegion                 = true;                      // true: Calc Window Clip Region
        mbInitChildRegion                   = false;                     // true: InitChildClipRegion
        mbWinRegion                         = false;                     // true: Window Region
        mbClipChildren                      = false;                     // true: Child-window should be clipped
        mbClipSiblings                      = false;                     // true: Adjacent Child-window should be clipped
        mbChildTransparent                  = false;                     // true: Child-windows are allowed to switch to transparent (incl. Parent-CLIPCHILDREN)
        mbPaintTransparent                  = false;                     // true: Paints should be executed on the Parent
        mbMouseTransparent                  = false;                     // true: Window is transparent for Mouse
        mbDlgCtrlStart                      = false;                     // true: From here on own Dialog-Control
        mbFocusVisible                      = false;                     // true: Focus Visible
        mbUseNativeFocus                    = false;
        mbNativeFocusVisible                = false;                     // true: native Focus Visible
        mbInShowFocus                       = false;                     // prevent recursion
        mbInHideFocus                       = false;                     // prevent recursion
        mbTrackVisible                      = false;                     // true: Tracking Visible
        mbControlForeground                 = false;                     // true: Foreground-Property set
        mbControlBackground                 = false;                     // true: Background-Property set
        mbAlwaysOnTop                       = false;                     // true: always visible for all others windows
        mbCompoundControl                   = false;                     // true: Composite Control => Listener...
        mbCompoundControlHasFocus           = false;                     // true: Composite Control has focus somewhere
        mbPaintDisabled                     = false;                     // true: Paint should not be executed
        mbAllResize                         = false;                     // true: Also sent ResizeEvents with 0,0
        mbInDispose                         = false;                     // true: We're still in Window::dispose()
        mbExtTextInput                      = false;                     // true: ExtTextInput-Mode is active
        mbInFocusHdl                        = false;                     // true: Within GetFocus-Handler
        mbCreatedWithToolkit                = false;
        mbSuppressAccessibilityEvents       = false;                     // true: do not send any accessibility events
        mbDrawSelectionBackground           = false;                     // true: draws transparent window background to indicate (toolbox) selection
        mbIsInTaskPaneList                  = false;                     // true: window was added to the taskpanelist in the topmost system window
        mnNativeBackground                  = ControlPart::NONE;         // initialize later, depends on type
        mbCallHandlersDuringInputDisabled   = false;                     // true: call event handlers even if input is disabled
        mbHelpTextDynamic                   = false;                     // true: append help id in HELP_DEBUG case
        mbFakeFocusSet                      = false;                     // true: pretend as if the window has focus.
        mbHexpand                           = false;
        mbVexpand                           = false;
        mbExpand                            = false;
        mbFill                              = true;
        mbSecondary                         = false;
        mbNonHomogeneous                    = false;
        static bool bDoubleBuffer = getenv("VCL_DOUBLEBUFFERING_FORCE_ENABLE");
        mbDoubleBufferingRequested = bDoubleBuffer; // when we are not sure, assume it cannot do double-buffering via RenderContext
        mpLOKNotifier                       = nullptr;
        mnLOKWindowId                       = 0;
        mbLOKParentNotifier                 = false;
    }

    WindowImpl::~WindowImpl()
    {
        mpChildClipRegion.reset();
        mpAccessibleInfos.reset();
    }

    ImplWinData::ImplWinData() :
        mnCursorExtWidth(0),
        mbVertical(false),
        mnCompositionCharRects(0),
        mnTrackFlags(ShowTrackFlags::NONE),
        mnIsTopWindow(sal_uInt16(~0)), // not initialized yet, 0/1 will indicate TopWindow (see IsTopWindow())
        mbMouseOver(false),
        mbEnableNativeWidget(false)
    {
    }

    ImplWinData::~ImplWinData()
    {
        mpCompositionCharRects.reset();
    }

    ImplFrameData::ImplFrameData( vcl::Window *pWindow )
    {
        ImplSVData* pSVData = ImplGetSVData();
        assert (pSVData->maWinData.mpFirstFrame.get() != pWindow);
        mpNextFrame        = pSVData->maWinData.mpFirstFrame;
        pSVData->maWinData.mpFirstFrame = pWindow;
        mpFirstOverlap     = nullptr;
        mpFocusWin         = nullptr;
        mpMouseMoveWin     = nullptr;
        mpMouseDownWin     = nullptr;
        mxFontCollection   = pSVData->maGDIData.mxScreenFontList;
        mxFontCache        = pSVData->maGDIData.mxScreenFontCache;
        mnFocusId          = nullptr;
        mnMouseMoveId      = nullptr;
        mnLastMouseX       = -1;
        mnLastMouseY       = -1;
        mnBeforeLastMouseX = -1;
        mnBeforeLastMouseY = -1;
        mnFirstMouseX      = -1;
        mnFirstMouseY      = -1;
        mnLastMouseWinX    = -1;
        mnLastMouseWinY    = -1;
        mnModalMode        = 0;
        mnMouseDownTime    = 0;
        mnClickCount       = 0;
        mnFirstMouseCode   = 0;
        mnMouseCode        = 0;
        mnMouseMode        = MouseEventModifiers::NONE;
        mbHasFocus         = false;
        mbInMouseMove      = false;
        mbMouseIn          = false;
        mbStartDragCalled  = false;
        mbNeedSysWindow    = false;
        mbMinimized        = false;
        mbStartFocusState  = false;
        mbInSysObjFocusHdl = false;
        mbInSysObjToTopHdl = false;
        mbSysObjFocus      = false;
        maPaintIdle.SetPriority( TaskPriority::REPAINT );
        maPaintIdle.SetInvokeHandler( LINK( pWindow, vcl::Window, ImplHandlePaintHdl ) );
        maPaintIdle.SetDebugName( "vcl::Window maPaintIdle" );
        maResizeIdle.SetPriority( TaskPriority::RESIZE );
        maResizeIdle.SetInvokeHandler( LINK( pWindow, vcl::Window, ImplHandleResizeTimerHdl ) );
        maResizeIdle.SetDebugName( "vcl::Window maResizeIdle" );
        mbInternalDragGestureRecognizer = false;
        mbInBufferedPaint = false;
        mnDPIX = 96;
        mnDPIY = 96;
    }

    namespace vcl {

    bool Window::AcquireGraphics() const
    {
        DBG_TESTSOLARMUTEX();

        if ( mpGraphics )
            return true;

        mbInitLineColor     = true;
        mbInitFillColor     = true;
        mbInitFont          = true;
        mbInitTextColor     = true;
        mbInitClipRegion    = true;

        ImplSVData* pSVData = ImplGetSVData();

        mpGraphics = mpWindowImpl->mpFrame->AcquireGraphics();
        // try harder if no wingraphics was available directly
        if ( !mpGraphics )
        {
            // find another output device in the same frame
            OutputDevice* pReleaseOutDev = pSVData->maGDIData.mpLastWinGraphics;
            while ( pReleaseOutDev )
            {
                if ( static_cast<vcl::Window*>(pReleaseOutDev)->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame )
                    break;
                pReleaseOutDev = pReleaseOutDev->mpPrevGraphics;
            }

            if ( pReleaseOutDev )
            {
                // steal the wingraphics from the other outdev
                mpGraphics = pReleaseOutDev->mpGraphics;
                pReleaseOutDev->ReleaseGraphics( false );
            }
            else
            {
                // if needed retry after releasing least recently used wingraphics
                while ( !mpGraphics )
                {
                    if ( !pSVData->maGDIData.mpLastWinGraphics )
                        break;
                    pSVData->maGDIData.mpLastWinGraphics->ReleaseGraphics();
                    mpGraphics = mpWindowImpl->mpFrame->AcquireGraphics();
                }
            }
        }

        // update global LRU list of wingraphics
        if ( mpGraphics )
        {
            mpNextGraphics = pSVData->maGDIData.mpFirstWinGraphics;
            pSVData->maGDIData.mpFirstWinGraphics = const_cast<vcl::Window*>(this);
            if ( mpNextGraphics )
                mpNextGraphics->mpPrevGraphics = const_cast<vcl::Window*>(this);
            if ( !pSVData->maGDIData.mpLastWinGraphics )
                pSVData->maGDIData.mpLastWinGraphics = const_cast<vcl::Window*>(this);
        }

        if ( mpGraphics )
        {
            mpGraphics->SetXORMode( (RasterOp::Invert == meRasterOp) || (RasterOp::Xor == meRasterOp) );
            mpGraphics->setAntiAliasB2DDraw(bool(mnAntialiasing & AntialiasingFlags::EnableB2dDraw));
        }

        return mpGraphics != nullptr;
    }

    void Window::ReleaseGraphics( bool bRelease )
    {
        DBG_TESTSOLARMUTEX();

        if ( !mpGraphics )
            return;

        // release the fonts of the physically released graphics device
        if( bRelease )
            ImplReleaseFonts();

        ImplSVData* pSVData = ImplGetSVData();

        vcl::Window* pWindow = this;

        if ( bRelease )
            pWindow->mpWindowImpl->mpFrame->ReleaseGraphics( mpGraphics );
        // remove from global LRU list of window graphics
        if ( mpPrevGraphics )
            mpPrevGraphics->mpNextGraphics = mpNextGraphics;
        else
            pSVData->maGDIData.mpFirstWinGraphics = mpNextGraphics;
        if ( mpNextGraphics )
            mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
        else
            pSVData->maGDIData.mpLastWinGraphics = mpPrevGraphics;

        mpGraphics      = nullptr;
        mpPrevGraphics  = nullptr;
        mpNextGraphics  = nullptr;
    }

    static sal_Int32 CountDPIScaleFactor(sal_Int32 nDPI)
    {
    #ifndef MACOSX
        // Setting of HiDPI is unfortunately all only a heuristic; and to add
        // insult to an injury, the system is constantly lying to us about
        // the DPI and whatnot
        // eg. fdo#77059 - set the value from which we do consider the
        // screen hi-dpi to greater than 168
        if (nDPI > 216)      // 96 * 2   + 96 / 4
            return 250;
        else if (nDPI > 168) // 96 * 2   - 96 / 4
            return 200;
        else if (nDPI > 120) // 96 * 1.5 - 96 / 4
            return 150;
    #else
        (void)nDPI;
    #endif

        return 100;
    }

    void Window::ImplInit( vcl::Window* pParent, WinBits nStyle, SystemParentData* pSystemParentData )
    {
        SAL_WARN_IF( !mpWindowImpl->mbFrame && !pParent && GetType() != WindowType::FIXEDIMAGE, "vcl.window",
            "Window::Window(): pParent == NULL" );

        ImplSVData* pSVData = ImplGetSVData();
        vcl::Window*     pRealParent = pParent;

        // inherit 3D look
        if ( !mpWindowImpl->mbOverlapWin && pParent && (pParent->GetStyle() & WB_3DLOOK) )
            nStyle |= WB_3DLOOK;

        // create border window if necessary
        if ( !mpWindowImpl->mbFrame && !mpWindowImpl->mbBorderWin && !mpWindowImpl->mpBorderWindow
             && (nStyle & (WB_BORDER | WB_SYSTEMCHILDWINDOW) ) )
        {
            BorderWindowStyle nBorderTypeStyle = BorderWindowStyle::NONE;
            if( nStyle & WB_SYSTEMCHILDWINDOW )
            {
                // handle WB_SYSTEMCHILDWINDOW
                // these should be analogous to a top level frame; meaning they
                // should have a border window with style BorderWindowStyle::Frame
                // which controls their size
                nBorderTypeStyle |= BorderWindowStyle::Frame;
                nStyle |= WB_BORDER;
            }
            VclPtrInstance<ImplBorderWindow> pBorderWin( pParent, nStyle & (WB_BORDER | WB_DIALOGCONTROL | WB_NODIALOGCONTROL), nBorderTypeStyle );
            static_cast<vcl::Window*>(pBorderWin)->mpWindowImpl->mpClientWindow = this;
            pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
            mpWindowImpl->mpBorderWindow  = pBorderWin;
            pParent = mpWindowImpl->mpBorderWindow;
        }
        else if( !mpWindowImpl->mbFrame && ! pParent )
        {
            mpWindowImpl->mbOverlapWin  = true;
            mpWindowImpl->mbFrame = true;
        }

        // insert window in list
        ImplInsertWindow( pParent );
        mpWindowImpl->mnStyle = nStyle;

        if( pParent && ! mpWindowImpl->mbFrame )
            mbEnableRTL = AllSettings::GetLayoutRTL();

        // test for frame creation
        if ( mpWindowImpl->mbFrame )
        {
            // create frame
            SalFrameStyleFlags nFrameStyle = SalFrameStyleFlags::NONE;

            if ( nStyle & WB_MOVEABLE )
                nFrameStyle |= SalFrameStyleFlags::MOVEABLE;
            if ( nStyle & WB_SIZEABLE )
                nFrameStyle |= SalFrameStyleFlags::SIZEABLE;
            if ( nStyle & WB_CLOSEABLE )
                nFrameStyle |= SalFrameStyleFlags::CLOSEABLE;
            if ( nStyle & WB_APP )
                nFrameStyle |= SalFrameStyleFlags::DEFAULT;
            // check for undecorated floating window
            if( // 1. floating windows that are not moveable/sizeable (only closeable allowed)
                ( !(nFrameStyle & ~SalFrameStyleFlags::CLOSEABLE) &&
                ( mpWindowImpl->mbFloatWin || ((GetType() == WindowType::BORDERWINDOW) && static_cast<ImplBorderWindow*>(this)->mbFloatWindow) || (nStyle & WB_SYSTEMFLOATWIN) ) ) ||
                // 2. borderwindows of floaters with ownerdraw decoration
                ((GetType() == WindowType::BORDERWINDOW) && static_cast<ImplBorderWindow*>(this)->mbFloatWindow && (nStyle & WB_OWNERDRAWDECORATION) ) )
            {
                nFrameStyle = SalFrameStyleFlags::FLOAT;
                if( nStyle & WB_OWNERDRAWDECORATION )
                    nFrameStyle |= (SalFrameStyleFlags::OWNERDRAWDECORATION | SalFrameStyleFlags::NOSHADOW);
            }
            else if( mpWindowImpl->mbFloatWin )
                nFrameStyle |= SalFrameStyleFlags::TOOLWINDOW;

            if( nStyle & WB_INTROWIN )
                nFrameStyle |= SalFrameStyleFlags::INTRO;
            if( nStyle & WB_TOOLTIPWIN )
                nFrameStyle |= SalFrameStyleFlags::TOOLTIP;

            if( nStyle & WB_NOSHADOW )
                nFrameStyle |= SalFrameStyleFlags::NOSHADOW;

            if( nStyle & WB_SYSTEMCHILDWINDOW )
                nFrameStyle |= SalFrameStyleFlags::SYSTEMCHILD;

            switch (mpWindowImpl->mnType)
            {
                case WindowType::DIALOG:
                case WindowType::TABDIALOG:
                case WindowType::MODALDIALOG:
                case WindowType::MODELESSDIALOG:
                case WindowType::MESSBOX:
                case WindowType::INFOBOX:
                case WindowType::WARNINGBOX:
                case WindowType::ERRORBOX:
                case WindowType::QUERYBOX:
                    nFrameStyle |= SalFrameStyleFlags::DIALOG;
                    break;
                default:
                    break;
            }

            SalFrame* pParentFrame = nullptr;
            if ( pParent )
                pParentFrame = pParent->mpWindowImpl->mpFrame;
            SalFrame* pFrame;
            if ( pSystemParentData )
                pFrame = pSVData->mpDefInst->CreateChildFrame( pSystemParentData, nFrameStyle | SalFrameStyleFlags::PLUG );
            else
                pFrame = pSVData->mpDefInst->CreateFrame( pParentFrame, nFrameStyle );
            if ( !pFrame )
            {
                // do not abort but throw an exception, may be the current thread terminates anyway (plugin-scenario)
                throw RuntimeException(
                    "Could not create system window!",
                    Reference< XInterface >() );
            }

            pFrame->SetCallback( this, ImplWindowFrameProc );

            // set window frame data
            mpWindowImpl->mpFrameData     = new ImplFrameData( this );
            mpWindowImpl->mpFrame         = pFrame;
            mpWindowImpl->mpFrameWindow   = this;
            mpWindowImpl->mpOverlapWindow = this;

            if (!(nStyle & WB_DEFAULTWIN) && mpWindowImpl->mbDoubleBufferingRequested)
                RequestDoubleBuffering(true);

            if ( pRealParent && IsTopWindow() )
            {
                ImplWinData* pParentWinData = pRealParent->ImplGetWinData();
                pParentWinData->maTopWindowChildren.emplace_back(this );
            }
        }

        // init data
        mpWindowImpl->mpRealParent = pRealParent;

        // #99318: make sure fontcache and list is available before call to SetSettings
        mxFontCollection = mpWindowImpl->mpFrameData->mxFontCollection;
        mxFontCache = mpWindowImpl->mpFrameData->mxFontCache;

        if ( mpWindowImpl->mbFrame )
        {
            if ( pParent )
            {
                mpWindowImpl->mpFrameData->mnDPIX     = pParent->mpWindowImpl->mpFrameData->mnDPIX;
                mpWindowImpl->mpFrameData->mnDPIY     = pParent->mpWindowImpl->mpFrameData->mnDPIY;
            }
            else
            {
                OutputDevice *pOutDev = GetOutDev();
                if ( pOutDev->AcquireGraphics() )
                {
                    mpGraphics->GetResolution( mpWindowImpl->mpFrameData->mnDPIX, mpWindowImpl->mpFrameData->mnDPIY );
                }
            }

            // add ownerdraw decorated frame windows to list in the top-most frame window
            // so they can be hidden on lose focus
            if( nStyle & WB_OWNERDRAWDECORATION )
                ImplGetOwnerDrawList().emplace_back(this );

            // delay settings initialization until first "real" frame
            // this relies on the IntroWindow not needing any system settings
            if ( !pSVData->maAppData.mbSettingsInit &&
                 ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN))
                 )
            {
                // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings
                ImplUpdateGlobalSettings( *pSVData->maAppData.mpSettings );
                OutputDevice::SetSettings( *pSVData->maAppData.mpSettings );
                pSVData->maAppData.mbSettingsInit = true;
            }

            // If we create a Window with default size, query this
            // size directly, because we want resize all Controls to
            // the correct size before we display the window
            if ( nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_APP) )
                mpWindowImpl->mpFrame->GetClientSize( mnOutWidth, mnOutHeight );
        }
        else
        {
            if ( pParent )
            {
                if ( !ImplIsOverlapWindow() )
                {
                    mpWindowImpl->mbDisabled          = pParent->mpWindowImpl->mbDisabled;
                    mpWindowImpl->mbInputDisabled     = pParent->mpWindowImpl->mbInputDisabled;
                    mpWindowImpl->meAlwaysInputMode   = pParent->mpWindowImpl->meAlwaysInputMode;
                }

                if (!utl::ConfigManager::IsFuzzing())
                    OutputDevice::SetSettings( pParent->GetSettings() );
            }

        }

        // setup the scale factor for Hi-DPI displays
        mnDPIScalePercentage = CountDPIScaleFactor(mpWindowImpl->mpFrameData->mnDPIY);
        mnDPIX = mpWindowImpl->mpFrameData->mnDPIX;
        mnDPIY = mpWindowImpl->mpFrameData->mnDPIY;

        if (!utl::ConfigManager::IsFuzzing())
        {
            const StyleSettings& rStyleSettings = mxSettings->GetStyleSettings();
            maFont = rStyleSettings.GetAppFont();

            if ( nStyle & WB_3DLOOK )
            {
                SetTextColor( rStyleSettings.GetButtonTextColor() );
                SetBackground( Wallpaper( rStyleSettings.GetFaceColor() ) );
            }
            else
            {
                SetTextColor( rStyleSettings.GetWindowTextColor() );
                SetBackground( Wallpaper( rStyleSettings.GetWindowColor() ) );
            }
        }
        else
        {
            maFont = GetDefaultFont( DefaultFontType::FIXED, LANGUAGE_ENGLISH_US, GetDefaultFontFlags::NONE );
        }

        ImplPointToLogic(*this, maFont);

        (void)ImplUpdatePos();

        // calculate app font res (except for the Intro Window or the default window)
        if ( mpWindowImpl->mbFrame && !pSVData->maGDIData.mnAppFontX && ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN)) )
            ImplInitAppFontData( this );

        if ( GetAccessibleParentWindow()  && GetParent() != Application::GetDefDialogParent() )
            GetAccessibleParentWindow()->CallEventListeners( VclEventId::WindowChildCreated, this );
    }

    void Window::ImplInitAppFontData( vcl::Window const * pWindow )
    {
        ImplSVData* pSVData = ImplGetSVData();
        long nTextHeight = pWindow->GetTextHeight();
        long nTextWidth = pWindow->approximate_char_width() * 8;
        long nSymHeight = nTextHeight*4;
        // Make the basis wider if the font is too narrow
        // such that the dialog looks symmetrical and does not become too narrow.
        // Add some extra space when the dialog has the same width,
        // as a little more space is better.
        if ( nSymHeight > nTextWidth )
            nTextWidth = nSymHeight;
        else if ( nSymHeight+5 > nTextWidth )
            nTextWidth = nSymHeight+5;
        pSVData->maGDIData.mnAppFontX = nTextWidth * 10 / 8;
        pSVData->maGDIData.mnAppFontY = nTextHeight * 10;

    #ifdef MACOSX
        // FIXME: this is currently only on OS X, check with other
        // platforms
        if( pSVData->maNWFData.mbNoFocusRects )
        {
            // try to find out whether there is a large correction
            // of control sizes, if yes, make app font scalings larger
            // so dialog positioning is not completely off
            ImplControlValue aControlValue;
            tools::Rectangle aCtrlRegion( Point(), Size( nTextWidth < 10 ? 10 : nTextWidth, nTextHeight < 10 ? 10 : nTextHeight ) );
            tools::Rectangle aBoundingRgn( aCtrlRegion );
            tools::Rectangle aContentRgn( aCtrlRegion );
            if( pWindow->GetNativeControlRegion( ControlType::Editbox, ControlPart::Entire, aCtrlRegion,
                                                 ControlState::ENABLED, aControlValue,
                                                 aBoundingRgn, aContentRgn ) )
            {
                // comment: the magical +6 is for the extra border in bordered
                // (which is the standard) edit fields
                if( aContentRgn.GetHeight() - nTextHeight > (nTextHeight+4)/4 )
                    pSVData->maGDIData.mnAppFontY = (aContentRgn.GetHeight()-4) * 10;
            }
        }
    #endif
    }

    ImplWinData* Window::ImplGetWinData() const
    {
        if ( !mpWindowImpl->mpWinData )
        {
            static const char* pNoNWF = getenv( "SAL_NO_NWF" );

            const_cast<vcl::Window*>(this)->mpWindowImpl->mpWinData = new ImplWinData;
            mpWindowImpl->mpWinData->mbEnableNativeWidget = !(pNoNWF && *pNoNWF); // true: try to draw this control with native theme API
        }

        return mpWindowImpl->mpWinData;
    }

    void Window::CopyDeviceArea( SalTwoRect& aPosAry, bool bWindowInvalidate )
    {
        if (aPosAry.mnSrcWidth == 0 || aPosAry.mnSrcHeight == 0 || aPosAry.mnDestWidth == 0 || aPosAry.mnDestHeight == 0)
            return;

        if (bWindowInvalidate)
        {
            const tools::Rectangle aSrcRect(Point(aPosAry.mnSrcX, aPosAry.mnSrcY),
                    Size(aPosAry.mnSrcWidth, aPosAry.mnSrcHeight));

            ImplMoveAllInvalidateRegions(aSrcRect,
                    aPosAry.mnDestX-aPosAry.mnSrcX,
                    aPosAry.mnDestY-aPosAry.mnSrcY,
                    false);

            mpGraphics->CopyArea(aPosAry.mnDestX, aPosAry.mnDestY,
                    aPosAry.mnSrcX, aPosAry.mnSrcY,
                    aPosAry.mnSrcWidth, aPosAry.mnSrcHeight,
                    this);

            return;
        }

        OutputDevice::CopyDeviceArea(aPosAry, bWindowInvalidate);
    }

    SalGraphics* Window::ImplGetFrameGraphics() const
    {
        if ( mpWindowImpl->mpFrameWindow->mpGraphics )
        {
            mpWindowImpl->mpFrameWindow->mbInitClipRegion = true;
        }
        else
        {
            OutputDevice* pFrameWinOutDev = mpWindowImpl->mpFrameWindow;
            if ( ! pFrameWinOutDev->AcquireGraphics() )
            {
                return nullptr;
            }
        }
        mpWindowImpl->mpFrameWindow->mpGraphics->ResetClipRegion();
        return mpWindowImpl->mpFrameWindow->mpGraphics;
    }

    void Window::ImplSetReallyVisible()
    {
        // #i43594# it is possible that INITSHOW was never send, because the visibility state changed between
        // ImplCallInitShow() and ImplSetReallyVisible() when called from Show()
        // mbReallyShown is a useful indicator
        if( !mpWindowImpl->mbReallyShown )
            ImplCallInitShow();

        bool bBecameReallyVisible = !mpWindowImpl->mbReallyVisible;

        mbDevOutput     = true;
        mpWindowImpl->mbReallyVisible = true;
        mpWindowImpl->mbReallyShown   = true;

        // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
        // For this, the data member of the event must not be NULL.
        // Previously, we did this in Window::Show, but there some events got lost in certain situations. Now
        // we're doing it when the visibility really changes
        if( bBecameReallyVisible && ImplIsAccessibleCandidate() )
            CallEventListeners( VclEventId::WindowShow, this );
            // TODO. It's kind of a hack that we're re-using the VclEventId::WindowShow. Normally, we should
            // introduce another event which explicitly triggers the Accessibility implementations.

        vcl::Window* pWindow = mpWindowImpl->mpFirstOverlap;
        while ( pWindow )
        {
            if ( pWindow->mpWindowImpl->mbVisible )
                pWindow->ImplSetReallyVisible();
            pWindow = pWindow->mpWindowImpl->mpNext;
        }

        pWindow = mpWindowImpl->mpFirstChild;
        while ( pWindow )
        {
            if ( pWindow->mpWindowImpl->mbVisible )
                pWindow->ImplSetReallyVisible();
            pWindow = pWindow->mpWindowImpl->mpNext;
        }
    }

    void Window::ImplInitResolutionSettings()
    {
        // recalculate AppFont-resolution and DPI-resolution
        if (mpWindowImpl->mbFrame)
        {
            mnDPIX = mpWindowImpl->mpFrameData->mnDPIX;
            mnDPIY = mpWindowImpl->mpFrameData->mnDPIY;

            // setup the scale factor for Hi-DPI displays
            mnDPIScalePercentage = CountDPIScaleFactor(mpWindowImpl->mpFrameData->mnDPIY);
            const StyleSettings& rStyleSettings = mxSettings->GetStyleSettings();
            SetPointFont(*this, rStyleSettings.GetAppFont());
        }
        else if ( mpWindowImpl->mpParent )
        {
            mnDPIX  = mpWindowImpl->mpParent->mnDPIX;
            mnDPIY  = mpWindowImpl->mpParent->mnDPIY;
            mnDPIScalePercentage = mpWindowImpl->mpParent->mnDPIScalePercentage;
        }

        // update the recalculated values for logical units
        // and also tools belonging to the values
        if (IsMapModeEnabled())
        {
            MapMode aMapMode = GetMapMode();
            SetMapMode();
            SetMapMode( aMapMode );
        }
    }

    void Window::ImplPointToLogic(vcl::RenderContext const & rRenderContext, vcl::Font& rFont) const
    {
        Size aSize = rFont.GetFontSize();

        if (aSize.Width())
        {
            aSize.setWidth( aSize.Width() * ( mpWindowImpl->mpFrameData->mnDPIX) );
            aSize.AdjustWidth(72 / 2 );
            aSize.setWidth( aSize.Width() / 72 );
        }
        aSize.setHeight( aSize.Height() * ( mpWindowImpl->mpFrameData->mnDPIY) );
        aSize.AdjustHeight(72/2 );
        aSize.setHeight( aSize.Height() / 72 );

        if (rRenderContext.IsMapModeEnabled())
            aSize = rRenderContext.PixelToLogic(aSize);

        rFont.SetFontSize(aSize);
    }

    void Window::ImplLogicToPoint(vcl::RenderContext const & rRenderContext, vcl::Font& rFont) const
    {
        Size aSize = rFont.GetFontSize();

        if (rRenderContext.IsMapModeEnabled())
            aSize = rRenderContext.LogicToPixel(aSize);

        if (aSize.Width())
        {
            aSize.setWidth( aSize.Width() * 72 );
            aSize.AdjustWidth(mpWindowImpl->mpFrameData->mnDPIX / 2 );
            aSize.setWidth( aSize.Width() / ( mpWindowImpl->mpFrameData->mnDPIX) );
        }
        aSize.setHeight( aSize.Height() * 72 );
        aSize.AdjustHeight(mpWindowImpl->mpFrameData->mnDPIY / 2 );
        aSize.setHeight( aSize.Height() / ( mpWindowImpl->mpFrameData->mnDPIY) );

        rFont.SetFontSize(aSize);
    }

    bool Window::ImplUpdatePos()
    {
        bool bSysChild = false;

        if ( ImplIsOverlapWindow() )
        {
            mnOutOffX  = mpWindowImpl->mnX;
            mnOutOffY  = mpWindowImpl->mnY;
        }
        else
        {
            vcl::Window* pParent = ImplGetParent();

            mnOutOffX  = mpWindowImpl->mnX + pParent->mnOutOffX;
            mnOutOffY  = mpWindowImpl->mnY + pParent->mnOutOffY;
        }

        VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
        while ( pChild )
        {
            if ( pChild->ImplUpdatePos() )
                bSysChild = true;
            pChild = pChild->mpWindowImpl->mpNext;
        }

        if ( mpWindowImpl->mpSysObj )
            bSysChild = true;

        return bSysChild;
    }

    void Window::ImplUpdateSysObjPos()
    {
        if ( mpWindowImpl->mpSysObj )
            mpWindowImpl->mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight );

        VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
        while ( pChild )
        {
            pChild->ImplUpdateSysObjPos();
            pChild = pChild->mpWindowImpl->mpNext;
        }
    }

    void Window::ImplPosSizeWindow( long nX, long nY,
                                    long nWidth, long nHeight, PosSizeFlags nFlags )
    {
        bool    bNewPos         = false;
        bool    bNewSize        = false;
        bool    bCopyBits       = false;
        long    nOldOutOffX     = mnOutOffX;
        long    nOldOutOffY     = mnOutOffY;
        long    nOldOutWidth    = mnOutWidth;
        long    nOldOutHeight   = mnOutHeight;
        std::unique_ptr<vcl::Region> pOverlapRegion;
        std::unique_ptr<vcl::Region> pOldRegion;

        if ( IsReallyVisible() )
        {
            tools::Rectangle aOldWinRect( Point( nOldOutOffX, nOldOutOffY ),
                                   Size( nOldOutWidth, nOldOutHeight ) );
            pOldRegion.reset( new vcl::Region( aOldWinRect ) );
            if ( mpWindowImpl->mbWinRegion )
                pOldRegion->Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );

            if ( mnOutWidth && mnOutHeight && !mpWindowImpl->mbPaintTransparent &&
                 !mpWindowImpl->mbInitWinClipRegion && !mpWindowImpl->maWinClipRegion.IsEmpty() &&
                 !HasPaintEvent() )
                bCopyBits = true;
        }

        bool bnXRecycled = false; // avoid duplicate mirroring in RTL case
        if ( nFlags & PosSizeFlags::Width )
        {
            if(!( nFlags & PosSizeFlags::X ))
            {
                nX = mpWindowImpl->mnX;
                nFlags |= PosSizeFlags::X;
                bnXRecycled = true; // we're using a mnX which was already mirrored in RTL case
            }

            if ( nWidth < 0 )
                nWidth = 0;
            if ( nWidth != mnOutWidth )
            {
                mnOutWidth = nWidth;
                bNewSize = true;
                bCopyBits = false;
            }
        }
        if ( nFlags & PosSizeFlags::Height )
        {
            if ( nHeight < 0 )
                nHeight = 0;
            if ( nHeight != mnOutHeight )
            {
                mnOutHeight = nHeight;
                bNewSize = true;
                bCopyBits = false;
            }
        }

        if ( nFlags & PosSizeFlags::X )
        {
            long nOrgX = nX;
            Point aPtDev( Point( nX+mnOutOffX, 0 ) );
            OutputDevice *pOutDev = GetOutDev();
            if( pOutDev->HasMirroredGraphics() )
            {
                aPtDev.setX( mpGraphics->mirror2( aPtDev.X(), this ) );

                // #106948# always mirror our pos if our parent is not mirroring, even
                // if we are also not mirroring
                // RTL: check if parent is in different coordinates
                if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
                {
                    nX = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - nX;
                }
                /* #i99166# An LTR window in RTL UI that gets sized only would be
                   expected to not moved its upper left point
                */
                if( bnXRecycled )
                {
                    if( ImplIsAntiparallel() )
                    {
                        aPtDev.setX( mpWindowImpl->mnAbsScreenX );
                        nOrgX = mpWindowImpl->maPos.X();
                    }
                }
            }
            else if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
            {
                // mirrored window in LTR UI
                nX = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - nX;
            }

            // check maPos as well, as it could have been changed for client windows (ImplCallMove())
            if ( mpWindowImpl->mnAbsScreenX != aPtDev.X() || nX != mpWindowImpl->mnX || nOrgX != mpWindowImpl->maPos.X() )
            {
                if ( bCopyBits && !pOverlapRegion )
                {
                    pOverlapRegion.reset( new vcl::Region() );
                    ImplCalcOverlapRegion( tools::Rectangle( Point( mnOutOffX, mnOutOffY ),
                                                      Size( mnOutWidth, mnOutHeight ) ),
                                           *pOverlapRegion, false, true );
                }
                mpWindowImpl->mnX = nX;
                mpWindowImpl->maPos.setX( nOrgX );
                mpWindowImpl->mnAbsScreenX = aPtDev.X();
                bNewPos = true;
            }
        }
        if ( nFlags & PosSizeFlags::Y )
        {
            // check maPos as well, as it could have been changed for client windows (ImplCallMove())
            if ( nY != mpWindowImpl->mnY || nY != mpWindowImpl->maPos.Y() )
            {
                if ( bCopyBits && !pOverlapRegion )
                {
                    pOverlapRegion.reset( new vcl::Region() );
                    ImplCalcOverlapRegion( tools::Rectangle( Point( mnOutOffX, mnOutOffY ),
                                                      Size( mnOutWidth, mnOutHeight ) ),
                                           *pOverlapRegion, false, true );
                }
                mpWindowImpl->mnY = nY;
                mpWindowImpl->maPos.setY( nY );
                bNewPos = true;
            }
        }

        if ( bNewPos || bNewSize )
        {
            bool bUpdateSysObjPos = false;
            if ( bNewPos )
                bUpdateSysObjPos = ImplUpdatePos();

            // the borderwindow always specifies the position for its client window
            if ( mpWindowImpl->mpBorderWindow )
                mpWindowImpl->maPos = mpWindowImpl->mpBorderWindow->mpWindowImpl->maPos;

            if ( mpWindowImpl->mpClientWindow )
            {
                mpWindowImpl->mpClientWindow->ImplPosSizeWindow( mpWindowImpl->mpClientWindow->mpWindowImpl->mnLeftBorder,
                                                   mpWindowImpl->mpClientWindow->mpWindowImpl->mnTopBorder,
                                                   mnOutWidth-mpWindowImpl->mpClientWindow->mpWindowImpl->mnLeftBorder-mpWindowImpl->mpClientWindow->mpWindowImpl->mnRightBorder,
                                                   mnOutHeight-mpWindowImpl->mpClientWindow->mpWindowImpl->mnTopBorder-mpWindowImpl->mpClientWindow->mpWindowImpl->mnBottomBorder,
                                                   PosSizeFlags::X | PosSizeFlags::Y |
                                                   PosSizeFlags::Width | PosSizeFlags::Height );
                // If we have a client window, then this is the position
                // of the Application's floating windows
                mpWindowImpl->mpClientWindow->mpWindowImpl->maPos = mpWindowImpl->maPos;
                if ( bNewPos )
                {
                    if ( mpWindowImpl->mpClientWindow->IsVisible() )
                    {
                        mpWindowImpl->mpClientWindow->ImplCallMove();
                    }
                    else
                    {
                        mpWindowImpl->mpClientWindow->mpWindowImpl->mbCallMove = true;
                    }
                }
            }

            // Move()/Resize() will be called only for Show(), such that
            // at least one is called before Show()
            if ( IsVisible() )
            {
                if ( bNewPos )
                {
                    ImplCallMove();
                }
                if ( bNewSize )
                {
                    ImplCallResize();
                }
            }
            else
            {
                if ( bNewPos )
                    mpWindowImpl->mbCallMove = true;
                if ( bNewSize )
                    mpWindowImpl->mbCallResize = true;
            }

            bool bUpdateSysObjClip = false;
            if ( IsReallyVisible() )
            {
                if ( bNewPos || bNewSize )
                {
                    // set Clip-Flag
                    bUpdateSysObjClip = !ImplSetClipFlag( true );
                }

                // invalidate window content ?
                if ( bNewPos || (mnOutWidth > nOldOutWidth) || (mnOutHeight > nOldOutHeight) )
                {
                    if ( bNewPos )
                    {
                        bool bInvalidate = false;
                        bool bParentPaint = true;
                        if ( !ImplIsOverlapWindow() )
                            bParentPaint = mpWindowImpl->mpParent->IsPaintEnabled();
                        if ( bCopyBits && bParentPaint && !HasPaintEvent() )
                        {
                            Point aPoint( mnOutOffX, mnOutOffY );
                            vcl::Region aRegion( tools::Rectangle( aPoint,
                                                       Size( mnOutWidth, mnOutHeight ) ) );
                            if ( mpWindowImpl->mbWinRegion )
                                aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
                            ImplClipBoundaries( aRegion, false, true );
                            if ( !pOverlapRegion->IsEmpty() )
                            {
                                pOverlapRegion->Move( mnOutOffX-nOldOutOffX, mnOutOffY-nOldOutOffY );
                                aRegion.Exclude( *pOverlapRegion );
                            }
                            if ( !aRegion.IsEmpty() )
                            {
                                // adapt Paint areas
                                ImplMoveAllInvalidateRegions( tools::Rectangle( Point( nOldOutOffX, nOldOutOffY ),
                                                                         Size( nOldOutWidth, nOldOutHeight ) ),
                                                              mnOutOffX-nOldOutOffX, mnOutOffY-nOldOutOffY,
                                                              true );
                                SalGraphics* pGraphics = ImplGetFrameGraphics();
                                if ( pGraphics )
                                {

                                    OutputDevice *pOutDev = GetOutDev();
                                    const bool bSelectClipRegion = pOutDev->SelectClipRegion( aRegion, pGraphics );
                                    if ( bSelectClipRegion )
                                    {
                                        pGraphics->CopyArea( mnOutOffX, mnOutOffY,
                                                             nOldOutOffX, nOldOutOffY,
                                                             nOldOutWidth, nOldOutHeight,
                                                             this );
                                    }
                                    else
                                        bInvalidate = true;
                                }
                                else
                                    bInvalidate = true;
                                if ( !bInvalidate )
                                {
                                    if ( !pOverlapRegion->IsEmpty() )
                                        ImplInvalidateFrameRegion( pOverlapRegion.get(), InvalidateFlags::Children );
                                }
                            }
                            else
                                bInvalidate = true;
                        }
                        else
                            bInvalidate = true;
                        if ( bInvalidate )
                            ImplInvalidateFrameRegion( nullptr, InvalidateFlags::Children );
                    }
                    else
                    {
                        Point aPoint( mnOutOffX, mnOutOffY );
                        vcl::Region aRegion( tools::Rectangle( aPoint,
                                                   Size( mnOutWidth, mnOutHeight ) ) );
                        aRegion.Exclude( *pOldRegion );
                        if ( mpWindowImpl->mbWinRegion )
                            aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
                        ImplClipBoundaries( aRegion, false, true );
                        if ( !aRegion.IsEmpty() )
                            ImplInvalidateFrameRegion( &aRegion, InvalidateFlags::Children );
                    }
                }

                // invalidate Parent or Overlaps
                if ( bNewPos ||
                     (mnOutWidth < nOldOutWidth) || (mnOutHeight < nOldOutHeight) )
                {
                    vcl::Region aRegion( *pOldRegion );
                    if ( !mpWindowImpl->mbPaintTransparent )
                        ImplExcludeWindowRegion( aRegion );
                    ImplClipBoundaries( aRegion, false, true );
                    if ( !aRegion.IsEmpty() && !mpWindowImpl->mpBorderWindow )
                        ImplInvalidateParentFrameRegion( aRegion );
                }
            }

            // adapt system objects
            if ( bUpdateSysObjClip )
                ImplUpdateSysObjClip();
            if ( bUpdateSysObjPos )
                ImplUpdateSysObjPos();
            if ( bNewSize && mpWindowImpl->mpSysObj )
                mpWindowImpl->mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight );
        }
    }

    void Window::ImplNewInputContext()
    {
        ImplSVData* pSVData = ImplGetSVData();
        vcl::Window*     pFocusWin = pSVData->maWinData.mpFocusWin;
        if ( !pFocusWin )
            return;

        // Is InputContext changed?
        const InputContext& rInputContext = pFocusWin->GetInputContext();
        if ( rInputContext == pFocusWin->mpWindowImpl->mpFrameData->maOldInputContext )
            return;

        pFocusWin->mpWindowImpl->mpFrameData->maOldInputContext = rInputContext;

        SalInputContext         aNewContext;
        const vcl::Font&        rFont = rInputContext.GetFont();
        const OUString&         rFontName = rFont.GetFamilyName();
        rtl::Reference<LogicalFontInstance> pFontInstance;
        aNewContext.mpFont = nullptr;
        if (!rFontName.isEmpty())
        {
            OutputDevice *pFocusWinOutDev = pFocusWin->GetOutDev();
            Size aSize = pFocusWinOutDev->ImplLogicToDevicePixel( rFont.GetFontSize() );
            if ( !aSize.Height() )
            {
                // only set default sizes if the font height in logical
                // coordinates equals 0
                if ( rFont.GetFontSize().Height() )
                    aSize.setHeight( 1 );
                else
                    aSize.setHeight( (12*pFocusWin->mnDPIY)/72 );
            }
            pFontInstance = pFocusWin->mxFontCache->GetFontInstance( pFocusWin->mxFontCollection.get(),
                             rFont, aSize, static_cast<float>(aSize.Height()) );
            if ( pFontInstance )
                aNewContext.mpFont = pFontInstance;
        }
        aNewContext.meLanguage  = rFont.GetLanguage();
        aNewContext.mnOptions   = rInputContext.GetOptions();
        pFocusWin->ImplGetFrame()->SetInputContext( &aNewContext );
    }

    void Window::doLazyDelete()
    {
        SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(this);
        DockingWindow* pDockWin = dynamic_cast<DockingWindow*>(this);
        if( pSysWin || ( pDockWin && pDockWin->IsFloatingMode() ) )
        {
            Show( false );
            SetParent( ImplGetDefaultWindow() );
        }
        vcl::LazyDeletor::Delete( this );
    }

    KeyIndicatorState Window::GetIndicatorState() const
    {
        return mpWindowImpl->mpFrame->GetIndicatorState();
    }

    void Window::SimulateKeyPress( sal_uInt16 nKeyCode ) const
    {
        mpWindowImpl->mpFrame->SimulateKeyPress(nKeyCode);
    }

    void Window::KeyInput( const KeyEvent& rKEvt )
    {
        KeyCode cod = rKEvt.GetKeyCode ();
        bool accel = ImplGetSVData()->maNWFData.mbEnableAccel;
        bool autoacc = ImplGetSVData()->maNWFData.mbAutoAccel;

        // do not respond to accelerators unless Alt is held */
        if (cod.GetCode () >= 0x200 && cod.GetCode () <= 0x219)
        {
            if (!accel) return;
            if (autoacc && cod.GetModifier () != KEY_MOD2) return;
        }

        NotifyEvent aNEvt( MouseNotifyEvent::KEYINPUT, this, &rKEvt );
        if ( !CompatNotify( aNEvt ) )
            mpWindowImpl->mbKeyInput = true;
    }

    void Window::KeyUp( const KeyEvent& rKEvt )
    {
        NotifyEvent aNEvt( MouseNotifyEvent::KEYUP, this, &rKEvt );
        if ( !CompatNotify( aNEvt ) )
            mpWindowImpl->mbKeyUp = true;
    }

    void Window::Draw( OutputDevice*, const Point&, const Size&, DrawFlags )
    {
    }

    void Window::Move() {}

    void Window::Resize() {}

    void Window::Activate() {}

    void Window::Deactivate() {}

    void Window::GetFocus()
    {
        if ( HasFocus() && mpWindowImpl->mpLastFocusWindow && !(mpWindowImpl->mnDlgCtrlFlags & DialogControlFlags::WantFocus) )
        {
            VclPtr<vcl::Window> xWindow(this);
            mpWindowImpl->mpLastFocusWindow->GrabFocus();
            if( xWindow->IsDisposed() )
                return;
        }

        NotifyEvent aNEvt( MouseNotifyEvent::GETFOCUS, this );
        CompatNotify( aNEvt );
    }

    void Window::LoseFocus()
    {
        NotifyEvent aNEvt( MouseNotifyEvent::LOSEFOCUS, this );
        CompatNotify( aNEvt );
    }

    void Window::SetHelpHdl(const Link<vcl::Window&, bool>& rLink)
    {
        mpWindowImpl->maHelpRequestHdl = rLink;
    }

    void Window::RequestHelp( const HelpEvent& rHEvt )
    {
        // if Balloon-Help is requested, show the balloon
        // with help text set
        if ( rHEvt.GetMode() & HelpEventMode::BALLOON )
        {
            OUString rStr = GetHelpText();
            if ( rStr.isEmpty() )
                rStr = GetQuickHelpText();
            if ( rStr.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() )
                ImplGetParent()->RequestHelp( rHEvt );
            else
            {
                Point aPos = GetPosPixel();
                if ( ImplGetParent() && !ImplIsOverlapWindow() )
                    aPos = OutputToScreenPixel(Point(0, 0));
                tools::Rectangle   aRect( aPos, GetSizePixel() );

                Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), aRect, rStr );
            }
        }
        else if ( rHEvt.GetMode() & HelpEventMode::QUICK )
        {
            const OUString& rStr = GetQuickHelpText();
            if ( rStr.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() )
                ImplGetParent()->RequestHelp( rHEvt );
            else
            {
                Point aPos = GetPosPixel();
                if ( ImplGetParent() && !ImplIsOverlapWindow() )
                    aPos = OutputToScreenPixel(Point(0, 0));
                tools::Rectangle   aRect( aPos, GetSizePixel() );
                OUString      aHelpText;
                if ( !rStr.isEmpty() )
                    aHelpText = GetHelpText();
                Help::ShowQuickHelp( this, aRect, rStr, aHelpText, QuickHelpFlags::CtrlText );
            }
        }
        else if (!mpWindowImpl->maHelpRequestHdl.IsSet() || mpWindowImpl->maHelpRequestHdl.Call(*this))
        {
            OUString aStrHelpId( OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8 ) );
            if ( aStrHelpId.isEmpty() && ImplGetParent() )
                ImplGetParent()->RequestHelp( rHEvt );
            else
            {
                Help* pHelp = Application::GetHelp();
                if ( pHelp )
                {
                    if( !aStrHelpId.isEmpty() )
                        pHelp->Start( aStrHelpId, this );
                    else
                        pHelp->Start( OOO_HELP_INDEX, this );
                }
            }
        }
    }

    void Window::Command( const CommandEvent& rCEvt )
    {
        CallEventListeners( VclEventId::WindowCommand, const_cast<CommandEvent *>(&rCEvt) );

        NotifyEvent aNEvt( MouseNotifyEvent::COMMAND, this, &rCEvt );
        if ( !CompatNotify( aNEvt ) )
            mpWindowImpl->mbCommand = true;
    }

    void Window::Tracking( const TrackingEvent& rTEvt )
    {

        ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
        if( pWrapper )
            pWrapper->Tracking( rTEvt );
    }

    void Window::StateChanged(StateChangedType eType)
    {
        switch (eType)
        {
            //stuff that doesn't invalidate the layout
            case StateChangedType::ControlForeground:
            case StateChangedType::ControlBackground:
            case StateChangedType::UpdateMode:
            case StateChangedType::ReadOnly:
            case StateChangedType::Enable:
            case StateChangedType::State:
            case StateChangedType::Data:
            case StateChangedType::InitShow:
            case StateChangedType::ControlFocus:
                break;
            //stuff that does invalidate the layout
            default:
                queue_resize(eType);
                break;
        }
    }

    void Window::SetStyle( WinBits nStyle )
    {
        if ( mpWindowImpl && mpWindowImpl->mnStyle != nStyle )
        {
            mpWindowImpl->mnPrevStyle = mpWindowImpl->mnStyle;
            mpWindowImpl->mnStyle = nStyle;
            CompatStateChanged( StateChangedType::Style );
        }
    }

    void Window::SetExtendedStyle( WindowExtendedStyle nExtendedStyle )
    {

        if ( mpWindowImpl->mnExtendedStyle != nExtendedStyle )
        {
            vcl::Window* pWindow = ImplGetBorderWindow();
            if( ! pWindow )
                pWindow = this;
            if( pWindow->mpWindowImpl->mbFrame )
            {
                SalExtStyle nExt = 0;
                if( nExtendedStyle & WindowExtendedStyle::Document )
                    nExt |= SAL_FRAME_EXT_STYLE_DOCUMENT;
                if( nExtendedStyle & WindowExtendedStyle::DocModified )
                    nExt |= SAL_FRAME_EXT_STYLE_DOCMODIFIED;

                pWindow->ImplGetFrame()->SetExtendedFrameStyle( nExt );
            }
            mpWindowImpl->mnExtendedStyle = nExtendedStyle;
            CompatStateChanged( StateChangedType::ExtendedStyle );
        }
    }

    void Window::SetBorderStyle( WindowBorderStyle nBorderStyle )
    {

        if ( mpWindowImpl->mpBorderWindow )
        {
            if( nBorderStyle == WindowBorderStyle::REMOVEBORDER &&
                ! mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame &&
                mpWindowImpl->mpBorderWindow->mpWindowImpl->mpParent
                )
            {
                // this is a little awkward: some controls (e.g. svtools ProgressBar)
                // cannot avoid getting constructed with WB_BORDER but want to disable
                // borders in case of NWF drawing. So they need a method to remove their border window
                VclPtr<vcl::Window> pBorderWin = mpWindowImpl->mpBorderWindow;
                // remove us as border window's client
                pBorderWin->mpWindowImpl->mpClientWindow = nullptr;
                mpWindowImpl->mpBorderWindow = nullptr;
                mpWindowImpl->mpRealParent = pBorderWin->mpWindowImpl->mpParent;
                // reparent us above the border window
                SetParent( pBorderWin->mpWindowImpl->mpParent );
                // set us to the position and size of our previous border
                Point aBorderPos( pBorderWin->GetPosPixel() );
                Size aBorderSize( pBorderWin->GetSizePixel() );
                setPosSizePixel( aBorderPos.X(), aBorderPos.Y(), aBorderSize.Width(), aBorderSize.Height() );
                // release border window
                pBorderWin.disposeAndClear();

                // set new style bits
                SetStyle( GetStyle() & (~WB_BORDER) );
            }
            else
            {
                if ( mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW )
                    static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetBorderStyle( nBorderStyle );
                else
                    mpWindowImpl->mpBorderWindow->SetBorderStyle( nBorderStyle );
            }
        }
    }

    WindowBorderStyle Window::GetBorderStyle() const
    {

        if ( mpWindowImpl->mpBorderWindow )
        {
            if ( mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW )
                return static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->GetBorderStyle();
            else
                return mpWindowImpl->mpBorderWindow->GetBorderStyle();
        }

        return WindowBorderStyle::NONE;
    }

    long Window::CalcTitleWidth() const
    {

        if ( mpWindowImpl->mpBorderWindow )
        {
            if ( mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW )
                return static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->CalcTitleWidth();
            else
                return mpWindowImpl->mpBorderWindow->CalcTitleWidth();
        }
        else if ( mpWindowImpl->mbFrame && (mpWindowImpl->mnStyle & WB_MOVEABLE) )
        {
            // we guess the width for frame windows as we do not know the
            // border of external dialogs
            const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
            vcl::Font aFont = GetFont();
            const_cast<vcl::Window*>(this)->SetPointFont(*const_cast<Window*>(this), rStyleSettings.GetTitleFont());
            long nTitleWidth = GetTextWidth( GetText() );
            const_cast<vcl::Window*>(this)->SetFont( aFont );
            nTitleWidth += rStyleSettings.GetTitleHeight() * 3;
            nTitleWidth += rStyleSettings.GetBorderSize() * 2;
            nTitleWidth += 10;
            return nTitleWidth;
        }

        return 0;
    }

    void Window::SetInputContext( const InputContext& rInputContext )
    {

        mpWindowImpl->maInputContext = rInputContext;
        if ( !mpWindowImpl->mbInFocusHdl && HasFocus() )
            ImplNewInputContext();
    }

    void Window::PostExtTextInputEvent(VclEventId nType, const OUString& rText)
    {
        switch (nType)
        {
        case VclEventId::ExtTextInput:
        {
            std::unique_ptr<ExtTextInputAttr[]> pAttr(new ExtTextInputAttr[rText.getLength()]);
            for (int i = 0; i < rText.getLength(); ++i) {
                pAttr[i] = ExtTextInputAttr::Underline;
            }
            SalExtTextInputEvent aEvent { rText, pAttr.get(), rText.getLength(), EXTTEXTINPUT_CURSOR_OVERWRITE };
            ImplWindowFrameProc(this, SalEvent::ExtTextInput, &aEvent);
        }
        break;
        case VclEventId::EndExtTextInput:
            ImplWindowFrameProc(this, SalEvent::EndExtTextInput, nullptr);
            break;
        default:
            assert(false);
        }
    }

    void Window::EndExtTextInput()
    {
        if ( mpWindowImpl->mbExtTextInput )
            ImplGetFrame()->EndExtTextInput( EndExtTextInputFlags::Complete );
    }

    void Window::SetCursorRect( const tools::Rectangle* pRect, long nExtTextInputWidth )
    {

        ImplWinData* pWinData = ImplGetWinData();
        if ( pWinData->mpCursorRect )
        {
            if ( pRect )
                pWinData->mpCursorRect = *pRect;
            else
                pWinData->mpCursorRect.reset();
        }
        else
        {
            if ( pRect )
                pWinData->mpCursorRect = *pRect;
        }

        pWinData->mnCursorExtWidth = nExtTextInputWidth;

    }

    const tools::Rectangle* Window::GetCursorRect() const
    {

        ImplWinData* pWinData = ImplGetWinData();
        return pWinData->mpCursorRect ? &*pWinData->mpCursorRect : nullptr;
    }

    long Window::GetCursorExtTextInputWidth() const
    {

        ImplWinData* pWinData = ImplGetWinData();
        return pWinData->mnCursorExtWidth;
    }

    void Window::SetCompositionCharRect( const tools::Rectangle* pRect, long nCompositionLength, bool bVertical ) {

        ImplWinData* pWinData = ImplGetWinData();
        pWinData->mpCompositionCharRects.reset();
        pWinData->mbVertical = bVertical;
        pWinData->mnCompositionCharRects = nCompositionLength;
        if ( pRect && (nCompositionLength > 0) )
        {
            pWinData->mpCompositionCharRects.reset( new tools::Rectangle[nCompositionLength] );
            for (long i = 0; i < nCompositionLength; ++i)
                pWinData->mpCompositionCharRects[i] = pRect[i];
        }
    }

    void Window::CollectChildren(::std::vector<vcl::Window *>& rAllChildren )
    {
        rAllChildren.push_back( this );

        VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
        while ( pChild )
        {
            pChild->CollectChildren( rAllChildren );
            pChild = pChild->mpWindowImpl->mpNext;
        }
    }

    void Window::SetPointFont(vcl::RenderContext& rRenderContext, const vcl::Font& rFont)
    {
        vcl::Font aFont = rFont;
        ImplPointToLogic(rRenderContext, aFont);
        rRenderContext.SetFont(aFont);
    }

    vcl::Font Window::GetPointFont(vcl::RenderContext const & rRenderContext) const
    {
        vcl::Font aFont = rRenderContext.GetFont();
        ImplLogicToPoint(rRenderContext, aFont);
        return aFont;
    }

    void Window::Show(bool bVisible, ShowFlags nFlags)
    {
        if ( IsDisposed() || mpWindowImpl->mbVisible == bVisible )
            return;

        VclPtr<vcl::Window> xWindow(this);

        bool bRealVisibilityChanged = false;
        mpWindowImpl->mbVisible = bVisible;

        if ( !bVisible )
        {
            ImplHideAllOverlaps();
            if( xWindow->IsDisposed() )
                return;

            if ( mpWindowImpl->mpBorderWindow )
            {
                bool bOldUpdate = mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate;
                if ( mpWindowImpl->mbNoParentUpdate )
                    mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = true;
                mpWindowImpl->mpBorderWindow->Show( false, nFlags );
                mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = bOldUpdate;
            }
            else if ( mpWindowImpl->mbFrame )
            {
                mpWindowImpl->mbSuppressAccessibilityEvents = true;
                mpWindowImpl->mpFrame->Show( false );
            }

            CompatStateChanged( StateChangedType::Visible );

            if ( mpWindowImpl->mbReallyVisible )
            {
                if ( mpWindowImpl->mbInitWinClipRegion )
                    ImplInitWinClipRegion();

                vcl::Region aInvRegion = mpWindowImpl->maWinClipRegion;

                if( xWindow->IsDisposed() )
                    return;

                bRealVisibilityChanged = mpWindowImpl->mbReallyVisible;
                ImplResetReallyVisible();
                ImplSetClipFlag();

                if ( ImplIsOverlapWindow() && !mpWindowImpl->mbFrame )
                {
                    // convert focus
                    if ( !(nFlags & ShowFlags::NoFocusChange) && HasChildPathFocus() )
                    {
                        if ( mpWindowImpl->mpOverlapWindow->IsEnabled() &&
                             mpWindowImpl->mpOverlapWindow->IsInputEnabled() &&
                             ! mpWindowImpl->mpOverlapWindow->IsInModalMode()
                             )
                            mpWindowImpl->mpOverlapWindow->GrabFocus();
                    }
                }

                if ( !mpWindowImpl->mbFrame )
                {
                    if( mpWindowImpl->mpWinData && mpWindowImpl->mpWinData->mbEnableNativeWidget )
                    {
                        /*
                        * #i48371# native theming: some themes draw outside the control
                        * area we tell them to (bad thing, but we cannot do much about it ).
                        * On hiding these controls they get invalidated with their window rectangle
                        * which leads to the parts outside the control area being left and not
                        * invalidated. Workaround: invalidate an area on the parent, too
                        */
                        const int workaround_border = 5;
                        tools::Rectangle aBounds( aInvRegion.GetBoundRect() );
                        aBounds.AdjustLeft( -workaround_border );
                        aBounds.AdjustTop( -workaround_border );
                        aBounds.AdjustRight(workaround_border );
                        aBounds.AdjustBottom(workaround_border );
                        aInvRegion = aBounds;
                    }
                    if ( !mpWindowImpl->mbNoParentUpdate && !(nFlags & ShowFlags::NoParentUpdate) )
                    {
                        if ( !aInvRegion.IsEmpty() )
                            ImplInvalidateParentFrameRegion( aInvRegion );
                    }
                    ImplGenerateMouseMove();
                }
            }
        }
        else
        {
            // inherit native widget flag for form controls
            // required here, because frames never show up in the child hierarchy - which should be fixed....
            // eg, the drop down of a combobox which is a system floating window
            if( mpWindowImpl->mbFrame && GetParent() && GetParent()->IsCompoundControl() &&
                GetParent()->IsNativeWidgetEnabled() != IsNativeWidgetEnabled() &&
                !(GetStyle() & WB_TOOLTIPWIN) )
            {
                EnableNativeWidget( GetParent()->IsNativeWidgetEnabled() );
            }

            if ( mpWindowImpl->mbCallMove )
            {
                ImplCallMove();
            }
            if ( mpWindowImpl->mbCallResize )
            {
                ImplCallResize();
            }

            CompatStateChanged( StateChangedType::Visible );

            vcl::Window* pTestParent;
            if ( ImplIsOverlapWindow() )
                pTestParent = mpWindowImpl->mpOverlapWindow;
            else
                pTestParent = ImplGetParent();
            if ( mpWindowImpl->mbFrame || pTestParent->mpWindowImpl->mbReallyVisible )
            {
                // if a window becomes visible, send all child windows a StateChange,
                // such that these can initialise themselves
                ImplCallInitShow();

                // If it is a SystemWindow it automatically pops up on top of
                // all other windows if needed.
                if ( ImplIsOverlapWindow() && !(nFlags & ShowFlags::NoActivate) )
                {
                    ImplStartToTop(( nFlags & ShowFlags::ForegroundTask ) ? ToTopFlags::ForegroundTask : ToTopFlags::NONE );
                    ImplFocusToTop( ToTopFlags::NONE, false );
                }

                // adjust mpWindowImpl->mbReallyVisible
                bRealVisibilityChanged = !mpWindowImpl->mbReallyVisible;
                ImplSetReallyVisible();

                // assure clip rectangles will be recalculated
                ImplSetClipFlag();

                if ( !mpWindowImpl->mbFrame )
                {
                    InvalidateFlags nInvalidateFlags = InvalidateFlags::Children;
                    if( ! IsPaintTransparent() )
                        nInvalidateFlags |= InvalidateFlags::NoTransparent;
                    ImplInvalidate( nullptr, nInvalidateFlags );
                    ImplGenerateMouseMove();
                }
            }

            if ( mpWindowImpl->mpBorderWindow )
                mpWindowImpl->mpBorderWindow->Show( true, nFlags );
            else if ( mpWindowImpl->mbFrame )
            {
                // #106431#, hide SplashScreen
                ImplSVData* pSVData = ImplGetSVData();
                if ( !pSVData->mpIntroWindow )
                {
                    // The right way would be just to call this (not even in the 'if')
                    GetpApp()->InitFinished();
                }
                else if ( !ImplIsWindowOrChild( pSVData->mpIntroWindow ) )
                {
                    // ... but the VCL splash is broken, and it needs this
                    // (for ./soffice .uno:NewDoc)
                    pSVData->mpIntroWindow->Hide();
                }

                //SAL_WARN_IF( mpWindowImpl->mbSuppressAccessibilityEvents, "vcl", "Window::Show() - Frame reactivated");
                mpWindowImpl->mbSuppressAccessibilityEvents = false;

                mpWindowImpl->mbPaintFrame = true;
                if (!Application::GetSettings().GetMiscSettings().GetPseudoHeadless())
                {
                    bool bNoActivate(nFlags & (ShowFlags::NoActivate|ShowFlags::NoFocusChange));
                    mpWindowImpl->mpFrame->Show( true, bNoActivate );
                }
                if( xWindow->IsDisposed() )
                    return;

                // Query the correct size of the window, if we are waiting for
                // a system resize
                if ( mpWindowImpl->mbWaitSystemResize )
                {
                    long nOutWidth;
                    long nOutHeight;
                    mpWindowImpl->mpFrame->GetClientSize( nOutWidth, nOutHeight );
                    ImplHandleResize( this, nOutWidth, nOutHeight );
                }

                if (mpWindowImpl->mpFrameData->mpBuffer && mpWindowImpl->mpFrameData->mpBuffer->GetOutputSizePixel() != GetOutputSizePixel())
                    // Make sure that the buffer size matches the window size, even if no resize was needed.
                    mpWindowImpl->mpFrameData->mpBuffer->SetOutputSizePixel(GetOutputSizePixel());
            }

            if( xWindow->IsDisposed() )
                return;

            ImplShowAllOverlaps();
        }

        if( xWindow->IsDisposed() )
            return;

        // the SHOW/HIDE events also serve as indicators to send child creation/destroy events to the access bridge
        // However, the access bridge only uses this event if the data member is not NULL (it's kind of a hack that
        // we re-use the SHOW/HIDE events this way, with this particular semantics).
        // Since #104887#, the notifications for the access bridge are done in Impl(Set|Reset)ReallyVisible. Here, we
        // now only notify with a NULL data pointer, for all other clients except the access bridge.
        if ( !bRealVisibilityChanged )
            CallEventListeners( mpWindowImpl->mbVisible ? VclEventId::WindowShow : VclEventId::WindowHide );
        if( xWindow->IsDisposed() )
            return;

    }

    Size Window::GetSizePixel() const
    {
        if (!mpWindowImpl)
        {
            SAL_WARN("vcl.layout", "WTF no windowimpl");
            return Size(0,0);
        }

        // #i43257# trigger pending resize handler to assure correct window sizes
        if( mpWindowImpl->mpFrameData->maResizeIdle.IsActive() )
        {
            VclPtr<vcl::Window> xWindow( const_cast<Window*>(this) );
            mpWindowImpl->mpFrameData->maResizeIdle.Stop();
            mpWindowImpl->mpFrameData->maResizeIdle.Invoke( nullptr );
            if( xWindow->IsDisposed() )
                return Size(0,0);
        }

        return Size( mnOutWidth+mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
                     mnOutHeight+mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder );
    }

    void Window::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
                                   sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
    {
        rLeftBorder     = mpWindowImpl->mnLeftBorder;
        rTopBorder      = mpWindowImpl->mnTopBorder;
        rRightBorder    = mpWindowImpl->mnRightBorder;
        rBottomBorder   = mpWindowImpl->mnBottomBorder;
    }

    void Window::Enable( bool bEnable, bool bChild )
    {
        if ( IsDisposed() )
            return;

        if ( !bEnable )
        {
            // the tracking mode will be stopped or the capture will be stolen
            // when a window is disabled,
            if ( IsTracking() )
                EndTracking( TrackingEventFlags::Cancel );
            if ( IsMouseCaptured() )
                ReleaseMouse();
            // try to pass focus to the next control
            // if the window has focus and is contained in the dialog control
            // mpWindowImpl->mbDisabled should only be set after a call of ImplDlgCtrlNextWindow().
            // Otherwise ImplDlgCtrlNextWindow() should be used
            if ( HasFocus() )
                ImplDlgCtrlNextWindow();
        }

        if ( mpWindowImpl->mpBorderWindow )
        {
            mpWindowImpl->mpBorderWindow->Enable( bEnable, false );
            if ( (mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW) &&
                 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->mpMenuBarWindow )
                static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->mpMenuBarWindow->Enable( bEnable );
        }

        // #i56102# restore app focus win in case the
        // window was disabled when the frame focus changed
        ImplSVData* pSVData = ImplGetSVData();
        if( bEnable &&
            pSVData->maWinData.mpFocusWin == nullptr &&
            mpWindowImpl->mpFrameData->mbHasFocus &&
            mpWindowImpl->mpFrameData->mpFocusWin == this )
            pSVData->maWinData.mpFocusWin = this;

        if ( mpWindowImpl->mbDisabled != !bEnable )
        {
            mpWindowImpl->mbDisabled = !bEnable;
            if ( mpWindowImpl->mpSysObj )
                mpWindowImpl->mpSysObj->Enable( bEnable && !mpWindowImpl->mbInputDisabled );
            CompatStateChanged( StateChangedType::Enable );

            CallEventListeners( bEnable ? VclEventId::WindowEnabled : VclEventId::WindowDisabled );
        }

        if ( bChild )
        {
            VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
            while ( pChild )
            {
                pChild->Enable( bEnable, bChild );
                pChild = pChild->mpWindowImpl->mpNext;
            }
        }

        if ( IsReallyVisible() )
            ImplGenerateMouseMove();
    }

    void Window::SetCallHandlersOnInputDisabled( bool bCall )
    {
        mpWindowImpl->mbCallHandlersDuringInputDisabled = bCall;

        VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
        while ( pChild )
        {
            pChild->SetCallHandlersOnInputDisabled( bCall );
            pChild = pChild->mpWindowImpl->mpNext;
        }
    }

    bool Window::IsCallHandlersOnInputDisabled() const
    {
        return mpWindowImpl->mbCallHandlersDuringInputDisabled;
    }

    void Window::EnableInput( bool bEnable, bool bChild )
    {
        if (!mpWindowImpl)
            return;

        bool bNotify = (bEnable != mpWindowImpl->mbInputDisabled);
        if ( mpWindowImpl->mpBorderWindow )
        {
            mpWindowImpl->mpBorderWindow->EnableInput( bEnable, false );
            if ( (mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW) &&
                 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->mpMenuBarWindow )
                static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->mpMenuBarWindow->EnableInput( bEnable );
        }

        if ( (! bEnable && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled) ||
             (  bEnable && mpWindowImpl->meAlwaysInputMode != AlwaysInputDisabled) )
        {
            // automatically stop the tracking mode or steal capture
            // if the window is disabled
            if ( !bEnable )
            {
                if ( IsTracking() )
                    EndTracking( TrackingEventFlags::Cancel );
                if ( IsMouseCaptured() )
                    ReleaseMouse();
            }

            if ( mpWindowImpl->mbInputDisabled != !bEnable )
            {
                mpWindowImpl->mbInputDisabled = !bEnable;
                if ( mpWindowImpl->mpSysObj )
                    mpWindowImpl->mpSysObj->Enable( !mpWindowImpl->mbDisabled && bEnable );
            }
        }

        // #i56102# restore app focus win in case the
        // window was disabled when the frame focus changed
        ImplSVData* pSVData = ImplGetSVData();
        if( bEnable &&
            pSVData->maWinData.mpFocusWin == nullptr &&
            mpWindowImpl->mpFrameData->mbHasFocus &&
            mpWindowImpl->mpFrameData->mpFocusWin == this )
            pSVData->maWinData.mpFocusWin = this;

        if ( bChild )
        {
            VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
            while ( pChild )
            {
                pChild->EnableInput( bEnable, bChild );
                pChild = pChild->mpWindowImpl->mpNext;
            }
        }

        if ( IsReallyVisible() )
            ImplGenerateMouseMove();

        // #104827# notify parent
        if ( bNotify )
        {
            NotifyEvent aNEvt( bEnable ? MouseNotifyEvent::INPUTENABLE : MouseNotifyEvent::INPUTDISABLE, this );
            CompatNotify( aNEvt );
        }
    }

    void Window::EnableInput( bool bEnable, const vcl::Window* pExcludeWindow )
    {
        if (!mpWindowImpl)
            return;

        EnableInput( bEnable );

        // pExecuteWindow is the first Overlap-Frame --> if this
        // shouldn't be the case, than this must be changed in dialog.cxx
        if( pExcludeWindow )
            pExcludeWindow = pExcludeWindow->ImplGetFirstOverlapWindow();
        vcl::Window* pSysWin = mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mpFirstOverlap;
        while ( pSysWin )
        {
            // Is Window in the path from this window
            if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pSysWin, true ) )
            {
                // Is Window not in the exclude window path or not the
                // exclude window, than change the status
                if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( pSysWin, true ) )
                    pSysWin->EnableInput( bEnable );
            }
            pSysWin = pSysWin->mpWindowImpl->mpNextOverlap;
        }

        // enable/disable floating system windows as well
        vcl::Window* pFrameWin = ImplGetSVData()->maWinData.mpFirstFrame;
        while ( pFrameWin )
        {
            if( pFrameWin->ImplIsFloatingWindow() )
            {
                // Is Window in the path from this window
                if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pFrameWin, true ) )
                {
                    // Is Window not in the exclude window path or not the
                    // exclude window, than change the status
                    if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( pFrameWin, true ) )
                        pFrameWin->EnableInput( bEnable );
                }
            }
            pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame;
        }

        // the same for ownerdraw floating windows
        if( mpWindowImpl->mbFrame )
        {
            ::std::vector< VclPtr<vcl::Window> >& rList = mpWindowImpl->mpFrameData->maOwnerDrawList;
            for (auto const& elem : rList)
            {
                // Is Window in the path from this window
                if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( elem, true ) )
                {
                    // Is Window not in the exclude window path or not the
                    // exclude window, than change the status
                    if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( elem, true ) )
                        elem->EnableInput( bEnable );
                }
            }
        }
    }

    void Window::AlwaysEnableInput( bool bAlways, bool bChild )
    {

        if ( mpWindowImpl->mpBorderWindow )
            mpWindowImpl->mpBorderWindow->AlwaysEnableInput( bAlways, false );

        if( bAlways && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled )
        {
            mpWindowImpl->meAlwaysInputMode = AlwaysInputEnabled;

            if ( bAlways )
                EnableInput( true, false );
        }
        else if( ! bAlways && mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled )
        {
            mpWindowImpl->meAlwaysInputMode = AlwaysInputNone;
        }

        if ( bChild )
        {
            VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
            while ( pChild )
            {
                pChild->AlwaysEnableInput( bAlways, bChild );
                pChild = pChild->mpWindowImpl->mpNext;
            }
        }
    }

    void Window::AlwaysDisableInput( bool bAlways, bool bChild )
    {

        if ( mpWindowImpl->mpBorderWindow )
            mpWindowImpl->mpBorderWindow->AlwaysDisableInput( bAlways, false );

        if( bAlways && mpWindowImpl->meAlwaysInputMode != AlwaysInputDisabled )
        {
            mpWindowImpl->meAlwaysInputMode = AlwaysInputDisabled;

            if ( bAlways )
                EnableInput( false, false );
        }
        else if( ! bAlways && mpWindowImpl->meAlwaysInputMode == AlwaysInputDisabled )
        {
            mpWindowImpl->meAlwaysInputMode = AlwaysInputNone;
        }

        if ( bChild )
        {
            VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
            while ( pChild )
            {
                pChild->AlwaysDisableInput( bAlways, bChild );
                pChild = pChild->mpWindowImpl->mpNext;
            }
        }
    }

    void Window::SetActivateMode( ActivateModeFlags nMode )
    {

        if ( mpWindowImpl->mpBorderWindow )
            mpWindowImpl->mpBorderWindow->SetActivateMode( nMode );

        if ( mpWindowImpl->mnActivateMode != nMode )
        {
            mpWindowImpl->mnActivateMode = nMode;

            // possibly trigger Deactivate/Activate
            if ( mpWindowImpl->mnActivateMode != ActivateModeFlags::NONE )
            {
                if ( (mpWindowImpl->mbActive || (GetType() == WindowType::BORDERWINDOW)) &&
                     !HasChildPathFocus( true ) )
                {
                    mpWindowImpl->mbActive = false;
                    Deactivate();
                }
            }
            else
            {
                if ( !mpWindowImpl->mbActive || (GetType() == WindowType::BORDERWINDOW) )
                {
                    mpWindowImpl->mbActive = true;
                    Activate();
                }
            }
        }
    }

    void Window::setPosSizePixel( long nX, long nY,
                                  long nWidth, long nHeight, PosSizeFlags nFlags )
    {
        bool bHasValidSize = !mpWindowImpl->mbDefSize;

        if ( nFlags & PosSizeFlags::Pos )
            mpWindowImpl->mbDefPos = false;
        if ( nFlags & PosSizeFlags::Size )
            mpWindowImpl->mbDefSize = false;

        // The top BorderWindow is the window which is to be positioned
        VclPtr<vcl::Window> pWindow = this;
        while ( pWindow->mpWindowImpl->mpBorderWindow )
            pWindow = pWindow->mpWindowImpl->mpBorderWindow;

        if ( pWindow->mpWindowImpl->mbFrame )
        {
            // Note: if we're positioning a frame, the coordinates are interpreted
            // as being the top-left corner of the window's client area and NOT
            // as the position of the border ! (due to limitations of several UNIX window managers)
            long nOldWidth  = pWindow->mnOutWidth;

            if ( !(nFlags & PosSizeFlags::Width) )
                nWidth = pWindow->mnOutWidth;
            if ( !(nFlags & PosSizeFlags::Height) )
                nHeight = pWindow->mnOutHeight;

            sal_uInt16 nSysFlags=0;
            VclPtr<vcl::Window> pParent = GetParent();
            VclPtr<vcl::Window> pWinParent = pWindow->GetParent();

            if( nFlags & PosSizeFlags::Width )
                nSysFlags |= SAL_FRAME_POSSIZE_WIDTH;
            if( nFlags & PosSizeFlags::Height )
                nSysFlags |= SAL_FRAME_POSSIZE_HEIGHT;
            if( nFlags & PosSizeFlags::X )
            {
                nSysFlags |= SAL_FRAME_POSSIZE_X;
                if( pWinParent && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) )
                {
                    nX += pWinParent->mnOutOffX;
                }
                if( pParent && pParent->ImplIsAntiparallel() )
                {
                    tools::Rectangle aRect( Point ( nX, nY ), Size( nWidth, nHeight ) );
                    const OutputDevice *pParentOutDev = pParent->GetOutDev();
                    pParentOutDev->ReMirror( aRect );
                    nX = aRect.Left();
                }
            }
            if( !(nFlags & PosSizeFlags::X) && bHasValidSize && pWindow->mpWindowImpl->mpFrame->maGeometry.nWidth )
            {
                // RTL: make sure the old right aligned position is not changed
                // system windows will always grow to the right
                if ( pWinParent )
                {
                    OutputDevice *pParentOutDev = pWinParent->GetOutDev();
                    if( pParentOutDev->HasMirroredGraphics() )
                    {
                        long myWidth = nOldWidth;
                        if( !myWidth )
                            myWidth = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nWidth;
                        if( !myWidth )
                            myWidth = nWidth;
                        nFlags |= PosSizeFlags::X;
                        nSysFlags |= SAL_FRAME_POSSIZE_X;
                        nX = pWinParent->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX - mpWindowImpl->mpFrame->GetUnmirroredGeometry().nLeftDecoration +
                            pWinParent->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nWidth - myWidth - 1 - mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX;
                        if(!(nFlags & PosSizeFlags::Y))
                        {
                            nFlags |= PosSizeFlags::Y;
                            nSysFlags |= SAL_FRAME_POSSIZE_Y;
                            nY = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nY - pWinParent->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nY -
                                mpWindowImpl->mpFrame->GetUnmirroredGeometry().nTopDecoration;
                        }
                    }
                }
            }
            if( nFlags & PosSizeFlags::Y )
            {
                nSysFlags |= SAL_FRAME_POSSIZE_Y;
                if( pWinParent && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) )
                {
                    nY += pWinParent->mnOutOffY;
                }
            }

            if( nSysFlags & (SAL_FRAME_POSSIZE_WIDTH|SAL_FRAME_POSSIZE_HEIGHT) )
            {
                // check for min/max client size and adjust size accordingly
                // otherwise it may happen that the resize event is ignored, i.e. the old size remains
                // unchanged but ImplHandleResize() is called with the wrong size
                SystemWindow *pSystemWindow = dynamic_cast< SystemWindow* >( pWindow.get() );
                if( pSystemWindow )
                {
                    Size aMinSize = pSystemWindow->GetMinOutputSizePixel();
                    Size aMaxSize = pSystemWindow->GetMaxOutputSizePixel();
                    if( nWidth < aMinSize.Width() )
                        nWidth = aMinSize.Width();
                    if( nHeight < aMinSize.Height() )
                        nHeight = aMinSize.Height();

                    if( nWidth > aMaxSize.Width() )
                        nWidth = aMaxSize.Width();
                    if( nHeight > aMaxSize.Height() )
                        nHeight = aMaxSize.Height();
                }
            }

            pWindow->mpWindowImpl->mpFrame->SetPosSize( nX, nY, nWidth, nHeight, nSysFlags );

            // Resize should be called directly. If we haven't
            // set the correct size, we get a second resize from
            // the system with the correct size. This can be happened
            // if the size is to small or to large.
            ImplHandleResize( pWindow, nWidth, nHeight );
        }
        else
        {
            pWindow->ImplPosSizeWindow( nX, nY, nWidth, nHeight, nFlags );
            if ( IsReallyVisible() )
                ImplGenerateMouseMove();
        }
    }

    Point Window::GetPosPixel() const
    {
        return mpWindowImpl->maPos;
    }

    tools::Rectangle Window::GetDesktopRectPixel() const
    {
        tools::Rectangle rRect;
        mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrame->GetWorkArea( rRect );
        return rRect;
    }

    Point Window::OutputToScreenPixel( const Point& rPos ) const
    {
        // relative to top level parent
        return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY );
    }

    Point Window::ScreenToOutputPixel( const Point& rPos ) const
    {
        // relative to top level parent
        return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY );
    }

    long Window::ImplGetUnmirroredOutOffX()
    {
        // revert mnOutOffX changes that were potentially made in ImplPosSizeWindow
        long offx = mnOutOffX;
        OutputDevice *pOutDev = GetOutDev();
        if( pOutDev->HasMirroredGraphics() )
        {
            if( mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
            {
                if ( !ImplIsOverlapWindow() )
                    offx -= mpWindowImpl->mpParent->mnOutOffX;

                offx = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - offx;

                if ( !ImplIsOverlapWindow() )
                    offx += mpWindowImpl->mpParent->mnOutOffX;

            }
        }
        return offx;
    }

    // normalized screen pixel are independent of mirroring
    Point Window::OutputToNormalizedScreenPixel( const Point& rPos ) const
    {
        // relative to top level parent
        long offx = const_cast<vcl::Window*>(this)->ImplGetUnmirroredOutOffX();
        return Point( rPos.X()+offx, rPos.Y()+mnOutOffY );
    }

    Point Window::NormalizedScreenToOutputPixel( const Point& rPos ) const
    {
        // relative to top level parent
        long offx = const_cast<vcl::Window*>(this)->ImplGetUnmirroredOutOffX();
        return Point( rPos.X()-offx, rPos.Y()-mnOutOffY );
    }

    Point Window::OutputToAbsoluteScreenPixel( const Point& rPos ) const
    {
        // relative to the screen
        Point p = OutputToScreenPixel( rPos );
        SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
        p.AdjustX(g.nX );
        p.AdjustY(g.nY );
        return p;
    }

    Point Window::AbsoluteScreenToOutputPixel( const Point& rPos ) const
    {
        // relative to the screen
        Point p = ScreenToOutputPixel( rPos );
        SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
        p.AdjustX( -(g.nX) );
        p.AdjustY( -(g.nY) );
        return p;
    }

    tools::Rectangle Window::ImplOutputToUnmirroredAbsoluteScreenPixel( const tools::Rectangle &rRect ) const
    {
        // this method creates unmirrored screen coordinates to be compared with the desktop
        // and is used for positioning of RTL popup windows correctly on the screen
        SalFrameGeometry g = mpWindowImpl->mpFrame->GetUnmirroredGeometry();

        Point p1 = OutputToScreenPixel( rRect.TopRight() );
        p1.setX( g.nX+g.nWidth-p1.X() );
        p1.AdjustY(g.nY );

        Point p2 = OutputToScreenPixel( rRect.BottomLeft() );
        p2.setX( g.nX+g.nWidth-p2.X() );
        p2.AdjustY(g.nY );

        return tools::Rectangle( p1, p2 );
    }

    tools::Rectangle Window::GetWindowExtentsRelative( vcl::Window *pRelativeWindow ) const
    {
        // with decoration
        return ImplGetWindowExtentsRelative( pRelativeWindow, false );
    }

    tools::Rectangle Window::GetClientWindowExtentsRelative() const
    {
        // without decoration
        return ImplGetWindowExtentsRelative( nullptr, true );
    }

    tools::Rectangle Window::ImplGetWindowExtentsRelative( vcl::Window *pRelativeWindow, bool bClientOnly ) const
    {
        SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
        // make sure we use the extent of our border window,
        // otherwise we miss a few pixels
        const vcl::Window *pWin = (!bClientOnly && mpWindowImpl->mpBorderWindow) ? mpWindowImpl->mpBorderWindow : this;

        Point aPos( pWin->OutputToScreenPixel( Point(0,0) ) );
        aPos.AdjustX(g.nX );
        aPos.AdjustY(g.nY );
        Size aSize ( pWin->GetSizePixel() );
        // #104088# do not add decoration to the workwindow to be compatible to java accessibility api
        if( !bClientOnly && (mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame && GetType() != WindowType::WORKWINDOW)) )
        {
            aPos.AdjustX( -sal_Int32(g.nLeftDecoration) );
            aPos.AdjustY( -sal_Int32(g.nTopDecoration) );
            aSize.AdjustWidth(g.nLeftDecoration + g.nRightDecoration );
            aSize.AdjustHeight(g.nTopDecoration + g.nBottomDecoration );
        }
        if( pRelativeWindow )
        {
            // #106399# express coordinates relative to borderwindow
            vcl::Window *pRelWin = (!bClientOnly && pRelativeWindow->mpWindowImpl->mpBorderWindow) ? pRelativeWindow->mpWindowImpl->mpBorderWindow.get() : pRelativeWindow;
            aPos = pRelWin->AbsoluteScreenToOutputPixel( aPos );
        }
        return tools::Rectangle( aPos, aSize );
    }

    void Window::Scroll( long nHorzScroll, long nVertScroll, ScrollFlags nFlags )
    {

        ImplScroll( tools::Rectangle( Point( mnOutOffX, mnOutOffY ),
                               Size( mnOutWidth, mnOutHeight ) ),
                    nHorzScroll, nVertScroll, nFlags & ~ScrollFlags::Clip );
    }

    void Window::Scroll( long nHorzScroll, long nVertScroll,
                         const tools::Rectangle& rRect, ScrollFlags nFlags )
    {
        OutputDevice *pOutDev = GetOutDev();
        tools::Rectangle aRect = pOutDev->ImplLogicToDevicePixel( rRect );
        aRect.Intersection( tools::Rectangle( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ) );
        if ( !aRect.IsEmpty() )
            ImplScroll( aRect, nHorzScroll, nVertScroll, nFlags );
    }

    void Window::Flush()
    {
        if (mpWindowImpl)
        {
            const tools::Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
            mpWindowImpl->mpFrame->Flush( aWinRect );
        }
    }

    void Window::SetUpdateMode( bool bUpdate )
    {
        if (mpWindowImpl)
        {
            mpWindowImpl->mbNoUpdate = !bUpdate;
            CompatStateChanged( StateChangedType::UpdateMode );
        }
    }

    void Window::GrabFocus()
    {
        ImplGrabFocus( GetFocusFlags::NONE );
    }

    bool Window::HasFocus() const
    {
        return (this == ImplGetSVData()->maWinData.mpFocusWin);
    }

    void Window::GrabFocusToDocument()
    {
        ImplGrabFocusToDocument(GetFocusFlags::NONE);
    }

    void Window::SetFakeFocus( bool bFocus )
    {
        ImplGetWindowImpl()->mbFakeFocusSet = bFocus;
    }

    bool Window::HasChildPathFocus( bool bSystemWindow ) const
    {

        vcl::Window* pFocusWin = ImplGetSVData()->maWinData.mpFocusWin;
        if ( pFocusWin )
            return ImplIsWindowOrChild( pFocusWin, bSystemWindow );
        return false;
    }

    void Window::SetCursor( vcl::Cursor* pCursor )
    {

        if ( mpWindowImpl->mpCursor != pCursor )
        {
            if ( mpWindowImpl->mpCursor )
                mpWindowImpl->mpCursor->ImplHide();
            mpWindowImpl->mpCursor = pCursor;
            if ( pCursor )
                pCursor->ImplShow();
        }
    }

    void Window::SetText( const OUString& rStr )
    {
        if (!mpWindowImpl || rStr == mpWindowImpl->maText)
            return;

        OUString oldTitle( mpWindowImpl->maText );
        mpWindowImpl->maText = rStr;

        if ( mpWindowImpl->mpBorderWindow )
            mpWindowImpl->mpBorderWindow->SetText( rStr );
        else if ( mpWindowImpl->mbFrame )
            mpWindowImpl->mpFrame->SetTitle( rStr );

        CallEventListeners( VclEventId::WindowFrameTitleChanged, &oldTitle );

        // #107247# needed for accessibility
        // The VclEventId::WindowFrameTitleChanged is (mis)used to notify accessible name changes.
        // Therefore a window, which is labeled by this window, must also notify an accessible
        // name change.
        if ( IsReallyVisible() )
        {
            vcl::Window* pWindow = GetAccessibleRelationLabelFor();
            if ( pWindow && pWindow != this )
                pWindow->CallEventListeners( VclEventId::WindowFrameTitleChanged, &oldTitle );
        }

        CompatStateChanged( StateChangedType::Text );
    }

    OUString Window::GetText() const
    {

        return mpWindowImpl->maText;
    }

    OUString Window::GetDisplayText() const
    {

        return GetText();
    }

    const Wallpaper& Window::GetDisplayBackground() const
    {
        // FIXME: fix issue 52349, need to fix this really in
        // all NWF enabled controls
        const ToolBox* pTB = dynamic_cast<const ToolBox*>(this);
        if( pTB )
        {
            if( IsNativeWidgetEnabled() )
                return pTB->ImplGetToolBoxPrivateData()->maDisplayBackground;
        }

        if( !IsBackground() )
        {
            if( mpWindowImpl->mpParent )
                return mpWindowImpl->mpParent->GetDisplayBackground();
        }

        const Wallpaper& rBack = GetBackground();
        if( ! rBack.IsBitmap() &&
            ! rBack.IsGradient() &&
            rBack.GetColor()== COL_TRANSPARENT &&
            mpWindowImpl->mpParent )
                return mpWindowImpl->mpParent->GetDisplayBackground();
        return rBack;
    }

    const OUString& Window::GetHelpText() const
    {
        OUString aStrHelpId( OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8 ) );
        bool bStrHelpId = !aStrHelpId.isEmpty();

        if ( !mpWindowImpl->maHelpText.getLength() && bStrHelpId )
        {
            if ( !IsDialog() && (mpWindowImpl->mnType != WindowType::TABPAGE) && (mpWindowImpl->mnType != WindowType::FLOATINGWINDOW) )
            {
                Help* pHelp = Application::GetHelp();
                if ( pHelp )
                {
                    mpWindowImpl->maHelpText = pHelp->GetHelpText(aStrHelpId, this);
                    mpWindowImpl->mbHelpTextDynamic = false;
                }
            }
        }
        else if( mpWindowImpl->mbHelpTextDynamic && bStrHelpId )
        {
            static const char* pEnv = getenv( "HELP_DEBUG" );
            if( pEnv && *pEnv )
            {
                OUString aTxt = mpWindowImpl->maHelpText + "\n------------------\n" + aStrHelpId;
                mpWindowImpl->maHelpText = aTxt;
            }
            mpWindowImpl->mbHelpTextDynamic = false;
        }

        //Fallback to Window::GetAccessibleDescription without reentry to GetHelpText()
        if (mpWindowImpl->maHelpText.isEmpty() && mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleDescription)
            return *mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
        return mpWindowImpl->maHelpText;
    }

    void Window::SetWindowPeer( Reference< css::awt::XWindowPeer > const & xPeer, VCLXWindow* pVCLXWindow  )
    {
        if (!mpWindowImpl)
            return;

        // be safe against re-entrance: first clear the old ref, then assign the new one
        mpWindowImpl->mxWindowPeer.clear();
        mpWindowImpl->mxWindowPeer = xPeer;

        mpWindowImpl->mpVCLXWindow = pVCLXWindow;
    }

    Reference< css::awt::XWindowPeer > Window::GetComponentInterface( bool bCreate )
    {
        if ( !mpWindowImpl->mxWindowPeer.is() && bCreate )
        {
            UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
            if ( pWrapper )
                mpWindowImpl->mxWindowPeer = pWrapper->GetWindowInterface( this );
        }
        return mpWindowImpl->mxWindowPeer;
    }

    void Window::SetComponentInterface( Reference< css::awt::XWindowPeer > const & xIFace )
    {
        UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
        SAL_WARN_IF( !pWrapper, "vcl.window", "SetComponentInterface: No Wrapper!" );
        if ( pWrapper )
            pWrapper->SetWindowInterface( this, xIFace );
    }

    typedef std::map<vcl::LOKWindowId, VclPtr<vcl::Window>> LOKWindowsMap;

    namespace {

    LOKWindowsMap& GetLOKWindowsMap()
    {
        // never use this in the desktop case
        assert(comphelper::LibreOfficeKit::isActive());

        // Map to remember the LOKWindowId <-> Window binding.
        static std::unique_ptr<LOKWindowsMap> s_pLOKWindowsMap;

        if (!s_pLOKWindowsMap)
            s_pLOKWindowsMap.reset(new LOKWindowsMap);

        return *s_pLOKWindowsMap.get();
    }

    }

    void Window::SetLOKNotifier(const vcl::ILibreOfficeKitNotifier* pNotifier, bool bParent)
    {
        // don't allow setting this twice
        assert(mpWindowImpl->mpLOKNotifier == nullptr);
        assert(pNotifier);

        if (!bParent)
        {
            // Counter to be able to have unique id's for each window.
            static vcl::LOKWindowId sLastLOKWindowId = 1;

            // assign the LOK window id
            assert(mpWindowImpl->mnLOKWindowId == 0);
            mpWindowImpl->mnLOKWindowId = sLastLOKWindowId++;
            GetLOKWindowsMap().insert(std::map<vcl::LOKWindowId, VclPtr<vcl::Window>>::value_type(mpWindowImpl->mnLOKWindowId, this));
        }
        else
            mpWindowImpl->mbLOKParentNotifier = true;

        mpWindowImpl->mpLOKNotifier = pNotifier;
    }

    VclPtr<Window> Window::FindLOKWindow(vcl::LOKWindowId nWindowId)
    {
        const auto it = GetLOKWindowsMap().find(nWindowId);
        if (it != GetLOKWindowsMap().end())
            return it->second;

        return VclPtr<Window>();
    }

    void Window::ReleaseLOKNotifier()
    {
        // unregister the LOK window binding
        if (mpWindowImpl->mnLOKWindowId > 0)
            GetLOKWindowsMap().erase(mpWindowImpl->mnLOKWindowId);

        mpWindowImpl->mpLOKNotifier = nullptr;
        mpWindowImpl->mnLOKWindowId = 0;
    }

    const vcl::ILibreOfficeKitNotifier* Window::GetLOKNotifier() const
    {
        return mpWindowImpl->mpLOKNotifier;
    }

    vcl::LOKWindowId Window::GetLOKWindowId() const
    {
        return mpWindowImpl->mnLOKWindowId;
    }

    VclPtr<vcl::Window> Window::GetParentWithLOKNotifier()
    {
        VclPtr<vcl::Window> pWindow(this);

        while (pWindow && !pWindow->GetLOKNotifier())
            pWindow = pWindow->GetParent();

        return pWindow;
    }

    void Window::ImplCallDeactivateListeners( vcl::Window *pNew )
    {
        // no deactivation if the newly activated window is my child
        if ( !pNew || !ImplIsChild( pNew ) )
        {
            VclPtr<vcl::Window> xWindow(this);
            CallEventListeners( VclEventId::WindowDeactivate, pNew );
            if( xWindow->IsDisposed() )
                return;

            // #100759#, avoid walking the wrong frame's hierarchy
            //           eg, undocked docking windows (ImplDockFloatWin)
            if ( ImplGetParent() && mpWindowImpl->mpFrameWindow == ImplGetParent()->mpWindowImpl->mpFrameWindow )
                ImplGetParent()->ImplCallDeactivateListeners( pNew );
        }
    }

    void Window::ImplCallActivateListeners( vcl::Window *pOld )
    {
        // no activation if the old active window is my child
        if ( !pOld || !ImplIsChild( pOld ) )
        {
            VclPtr<vcl::Window> xWindow(this);
            CallEventListeners( VclEventId::WindowActivate, pOld );
            if( xWindow->IsDisposed() )
                return;

            if ( ImplGetParent() )
                ImplGetParent()->ImplCallActivateListeners( pOld );
            else if( (mpWindowImpl->mnStyle & WB_INTROWIN) == 0 )
            {
                // top level frame reached: store hint for DefModalDialogParent
                ImplGetSVData()->maWinData.mpActiveApplicationFrame = mpWindowImpl->mpFrameWindow;
            }
        }
    }

    void Window::SetClipboard(Reference<XClipboard> const & xClipboard)
    {
        if (mpWindowImpl->mpFrameData)
            mpWindowImpl->mpFrameData->mxClipboard = xClipboard;
    }

    Reference< XClipboard > Window::GetClipboard()
    {

        if( mpWindowImpl->mpFrameData )
        {
            if( ! mpWindowImpl->mpFrameData->mxClipboard.is() )
            {
                try
                {
                    mpWindowImpl->mpFrameData->mxClipboard
                        = css::datatransfer::clipboard::SystemClipboard::create(
                            comphelper::getProcessComponentContext());
                }
                catch (DeploymentException & e)
                {
                    SAL_WARN("vcl.window", "ignoring " << e);
                }
            }

            return mpWindowImpl->mpFrameData->mxClipboard;
        }

        return static_cast < XClipboard * > (nullptr);
    }

    Reference< XClipboard > Window::GetPrimarySelection()
    {

        if( mpWindowImpl->mpFrameData )
        {
            if( ! mpWindowImpl->mpFrameData->mxSelection.is() )
            {
                try
                {
                    Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );

    #if HAVE_FEATURE_X11
                    // A hack, making the primary selection available as an instance
                    // of the SystemClipboard service on X11:
                    Sequence< Any > args(1);
                    args[0] <<= OUString("PRIMARY");
                    mpWindowImpl->mpFrameData->mxSelection.set(
                        (xContext->getServiceManager()->
                         createInstanceWithArgumentsAndContext(
                             "com.sun.star.datatransfer.clipboard.SystemClipboard",
                             args, xContext)),
                        UNO_QUERY_THROW);
    #else
                    static Reference< XClipboard > s_xSelection(
                        xContext->getServiceManager()->createInstanceWithContext( "com.sun.star.datatransfer.clipboard.GenericClipboard", xContext ), UNO_QUERY );

                    mpWindowImpl->mpFrameData->mxSelection = s_xSelection;
    #endif
                }
                catch (RuntimeException & e)
                {
                    SAL_WARN("vcl.window", "ignoring " << e);
                }
            }

            return mpWindowImpl->mpFrameData->mxSelection;
        }

        return static_cast < XClipboard * > (nullptr);
    }

    void Window::RecordLayoutData( vcl::ControlLayoutData* pLayout, const tools::Rectangle& rRect )
    {
        assert(mpOutDevData);
        mpOutDevData->mpRecordLayout = pLayout;
        mpOutDevData->maRecordRect = rRect;
        Paint(*this, rRect);
        mpOutDevData->mpRecordLayout = nullptr;
    }

    void Window::DrawSelectionBackground( const tools::Rectangle& rRect,
                                          sal_uInt16 highlight,
                                          bool bChecked,
                                          bool bDrawBorder
                                          )
    {
        if( rRect.IsEmpty() )
            return;

        const StyleSettings& rStyles = GetSettings().GetStyleSettings();

        // colors used for item highlighting
        Color aSelectionBorderCol( rStyles.GetHighlightColor() );
        Color aSelectionFillCol( aSelectionBorderCol );

        bool bDark = rStyles.GetFaceColor().IsDark();
        bool bBright = ( rStyles.GetFaceColor() == COL_WHITE );

        int c1 = aSelectionBorderCol.GetLuminance();
        int c2 = GetDisplayBackground().GetColor().GetLuminance();

        if( !bDark && !bBright && abs( c2-c1 ) < 75 )
        {
            // contrast too low
            sal_uInt16 h,s,b;
            aSelectionFillCol.RGBtoHSB( h, s, b );
            if( b > 50 )    b -= 40;
            else            b += 40;
            aSelectionFillCol = Color::HSBtoRGB( h, s, b );
            aSelectionBorderCol = aSelectionFillCol;
        }

        tools::Rectangle aRect( rRect );
        Color oldFillCol = GetFillColor();
        Color oldLineCol = GetLineColor();

        if( bDrawBorder )
            SetLineColor( bDark ? COL_WHITE : ( bBright ? COL_BLACK : aSelectionBorderCol ) );
        else
            SetLineColor();

        sal_uInt16 nPercent = 0;
        if( !highlight )
        {
            if( bDark )
                aSelectionFillCol = COL_BLACK;
            else
                nPercent = 80;  // just checked (light)
        }
        else
        {
            if( bChecked && highlight == 2 )
            {
                if( bDark )
                    aSelectionFillCol = COL_LIGHTGRAY;
                else if ( bBright )
                {
                    aSelectionFillCol = COL_BLACK;
                    SetLineColor( COL_BLACK );
                    nPercent = 0;
                }
                else
                    nPercent = 20;          // selected, pressed or checked ( very dark )
            }
            else if( bChecked || highlight == 1 )
            {
                if( bDark )
                    aSelectionFillCol = COL_GRAY;
                else if ( bBright )
                {
                    aSelectionFillCol = COL_BLACK;
                    SetLineColor( COL_BLACK );
                    nPercent = 0;
                }
                else
                    nPercent = 35;          // selected, pressed or checked ( very dark )
            }
            else
            {
                if( bDark )
                    aSelectionFillCol = COL_LIGHTGRAY;
                else if ( bBright )
                {
                    aSelectionFillCol = COL_BLACK;
                    SetLineColor( COL_BLACK );
                    if( highlight == 3 )
                        nPercent = 80;
                    else
                        nPercent = 0;
                }
                else
                    nPercent = 70;          // selected ( dark )
            }
        }

        SetFillColor( aSelectionFillCol );

        if( bDark )
        {
            DrawRect( aRect );
        }
        else
        {
            tools::Polygon aPoly( aRect );
            tools::PolyPolygon aPolyPoly( aPoly );
            DrawTransparent( aPolyPoly, nPercent );
        }

        SetFillColor( oldFillCol );
        SetLineColor( oldLineCol );
    }

    bool Window::IsScrollable() const
    {
        // check for scrollbars
        VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
        while( pChild )
        {
            if( pChild->GetType() == WindowType::SCROLLBAR )
                return true;
            else
                pChild = pChild->mpWindowImpl->mpNext;
        }
        return false;
    }

    void Window::ImplMirrorFramePos( Point &pt ) const
    {
        pt.setX( mpWindowImpl->mpFrame->maGeometry.nWidth-1-pt.X() );
    }

    // frame based modal counter (dialogs are not modal to the whole application anymore)
    bool Window::IsInModalMode() const
    {
        return (mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mnModalMode != 0);
    }

    void Window::IncModalCount()
    {
        vcl::Window* pFrameWindow = mpWindowImpl->mpFrameWindow;
        vcl::Window* pParent = pFrameWindow;
        while( pFrameWindow )
        {
            pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode++;
            while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow )
            {
                pParent = pParent->GetParent();
            }
            pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow.get() : nullptr;
        }
    }
    void Window::DecModalCount()
    {
        vcl::Window* pFrameWindow = mpWindowImpl->mpFrameWindow;
        vcl::Window* pParent = pFrameWindow;
        while( pFrameWindow )
        {
            pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode--;
            while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow )
            {
                pParent = pParent->GetParent();
            }
            pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow.get() : nullptr;
        }
    }

    void Window::ImplIsInTaskPaneList( bool mbIsInTaskList )
    {
        mpWindowImpl->mbIsInTaskPaneList = mbIsInTaskList;
    }

    void Window::ImplNotifyIconifiedState( bool bIconified )
    {
        mpWindowImpl->mpFrameWindow->CallEventListeners( bIconified ? VclEventId::WindowMinimize : VclEventId::WindowNormalize );
        // #109206# notify client window as well to have toolkit topwindow listeners notified
        if( mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow && mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow )
            mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow->CallEventListeners( bIconified ? VclEventId::WindowMinimize : VclEventId::WindowNormalize );
    }

    bool Window::HasActiveChildFrame()
    {
        bool bRet = false;
        vcl::Window *pFrameWin = ImplGetSVData()->maWinData.mpFirstFrame;
        while( pFrameWin )
        {
            if( pFrameWin != mpWindowImpl->mpFrameWindow )
            {
                bool bDecorated = false;
                VclPtr< vcl::Window > pChildFrame = pFrameWin->ImplGetWindow();
                // #i15285# unfortunately WB_MOVEABLE is the same as WB_TABSTOP which can
                // be removed for ToolBoxes to influence the keyboard accessibility
                // thus WB_MOVEABLE is no indicator for decoration anymore
                // but FloatingWindows carry this information in their TitleType...
                // TODO: avoid duplicate WinBits !!!
                if( pChildFrame && pChildFrame->ImplIsFloatingWindow() )
                    bDecorated = static_cast<FloatingWindow*>(pChildFrame.get())->GetTitleType() != FloatWinTitleType::NONE;
                if( bDecorated || (pFrameWin->mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE) ) )
                    if( pChildFrame && pChildFrame->IsVisible() && pChildFrame->IsActive() )
                    {
                        if( ImplIsChild( pChildFrame, true ) )
                        {
                            bRet = true;
                            break;
                        }
                    }
            }
            pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame;
        }
        return bRet;
    }

    LanguageType Window::GetInputLanguage() const
    {
        return mpWindowImpl->mpFrame->GetInputLanguage();
    }

    void Window::EnableNativeWidget( bool bEnable )
    {
        static const char* pNoNWF = getenv( "SAL_NO_NWF" );
        if( pNoNWF && *pNoNWF )
            bEnable = false;

        if( bEnable != ImplGetWinData()->mbEnableNativeWidget )
        {
            ImplGetWinData()->mbEnableNativeWidget = bEnable;

            // send datachanged event to allow for internal changes required for NWF
            // like clipmode, transparency, etc.
            DataChangedEvent aDCEvt( DataChangedEventType::SETTINGS, mxSettings.get(), AllSettingsFlags::STYLE );
            CompatDataChanged( aDCEvt );

            // sometimes the borderwindow is queried, so keep it in sync
            if( mpWindowImpl->mpBorderWindow )
                mpWindowImpl->mpBorderWindow->ImplGetWinData()->mbEnableNativeWidget = bEnable;
        }

        // push down, useful for compound controls
        VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
        while( pChild )
        {
            pChild->EnableNativeWidget( bEnable );
            pChild = pChild->mpWindowImpl->mpNext;
        }
    }

    bool Window::IsNativeWidgetEnabled() const
    {
        return ImplGetWinData()->mbEnableNativeWidget;
    }

    Reference< css::rendering::XCanvas > Window::ImplGetCanvas( bool bSpriteCanvas ) const
    {
        // try to retrieve hard reference from weak member
        Reference< css::rendering::XCanvas > xCanvas( mpWindowImpl->mxCanvas );

        // canvas still valid? Then we're done.
        if( xCanvas.is() )
            return xCanvas;

        Sequence< Any > aArg(6);

        // Feed any with operating system's window handle

        // common: first any is VCL pointer to window (for VCL canvas)
        aArg[ 0 ] <<= reinterpret_cast<sal_Int64>(this);
        aArg[ 1 ] = GetSystemDataAny();
        aArg[ 2 ] <<= css::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight );
        aArg[ 3 ] <<= mpWindowImpl->mbAlwaysOnTop;
        aArg[ 4 ] <<= Reference< css::awt::XWindow >(
                                 const_cast<vcl::Window*>(this)->GetComponentInterface(),
                                 UNO_QUERY );
        aArg[ 5 ] = GetSystemGfxDataAny();

        Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();

        // Create canvas instance with window handle

        static vcl::DeleteUnoReferenceOnDeinit<XMultiComponentFactory> xStaticCanvasFactory(
            css::rendering::CanvasFactory::create( xContext ) );
        Reference<XMultiComponentFactory> xCanvasFactory(xStaticCanvasFactory.get());

        if(xCanvasFactory.is())
        {
    #ifdef _WIN32
            // see #140456# - if we're running on a multiscreen setup,
            // request special, multi-screen safe sprite canvas
            // implementation (not DX5 canvas, as it cannot cope with
            // surfaces spanning multiple displays). Note: canvas
            // (without sprite) stays the same)
            const sal_uInt32 nDisplay = static_cast< WinSalFrame* >( mpWindowImpl->mpFrame )->mnDisplay;
            if( nDisplay >= Application::GetScreenCount() )
            {
                xCanvas.set( xCanvasFactory->createInstanceWithArgumentsAndContext(
                                     bSpriteCanvas ?
                                     OUString( "com.sun.star.rendering.SpriteCanvas.MultiScreen" ) :
                                     OUString( "com.sun.star.rendering.Canvas.MultiScreen" ),
                                     aArg,
                                     xContext ),
                                 UNO_QUERY );

            }
            else
            {
    #endif
                xCanvas.set( xCanvasFactory->createInstanceWithArgumentsAndContext(
                                 bSpriteCanvas ?
                                 OUString( "com.sun.star.rendering.SpriteCanvas" ) :
                                 OUString( "com.sun.star.rendering.Canvas" ),
                                 aArg,
                                 xContext ),
                             UNO_QUERY );

    #ifdef _WIN32
            }
    #endif
            mpWindowImpl->mxCanvas = xCanvas;
        }

        // no factory??? Empty reference, then.
        return xCanvas;
    }

    Reference< css::rendering::XCanvas > Window::GetCanvas() const
    {
        return ImplGetCanvas( false );
    }

    Reference< css::rendering::XSpriteCanvas > Window::GetSpriteCanvas() const
    {
        Reference< css::rendering::XSpriteCanvas > xSpriteCanvas(
            ImplGetCanvas( true ), UNO_QUERY );
        return xSpriteCanvas;
    }

    OUString Window::GetSurroundingText() const
    {
      return OUString();
    }

    Selection Window::GetSurroundingTextSelection() const
    {
      return Selection( 0, 0 );
    }

    bool Window::UsePolyPolygonForComplexGradient()
    {
        return meRasterOp != RasterOp::OverPaint;
    }

    void Window::ApplySettings(vcl::RenderContext& /*rRenderContext*/)
    {
    }

    const SystemEnvData* Window::GetSystemData() const
    {

        return mpWindowImpl->mpFrame ? mpWindowImpl->mpFrame->GetSystemData() : nullptr;
    }

    Any Window::GetSystemDataAny() const
    {
        Any aRet;
        const SystemEnvData* pSysData = GetSystemData();
        if( pSysData )
        {
            Sequence< sal_Int8 > aSeq( reinterpret_cast<sal_Int8 const *>(pSysData), pSysData->nSize );
            aRet <<= aSeq;
        }
        return aRet;
    }

    bool Window::SupportsDoubleBuffering() const
    {
        return mpWindowImpl->mpFrameData->mpBuffer;
    }

    void Window::RequestDoubleBuffering(bool bRequest)
    {
        if (bRequest)
        {
            mpWindowImpl->mpFrameData->mpBuffer = VclPtrInstance<VirtualDevice>();
            // Make sure that the buffer size matches the frame size.
            mpWindowImpl->mpFrameData->mpBuffer->SetOutputSizePixel(mpWindowImpl->mpFrameWindow->GetOutputSizePixel());
        }
        else
            mpWindowImpl->mpFrameData->mpBuffer.reset();
    }

    /*
     * The rational here is that we moved destructors to
     * dispose and this altered a lot of code paths, that
     * are better left unchanged for now.
     */
    #define COMPAT_BODY(method,args) \
        if (!mpWindowImpl || mpWindowImpl->mbInDispose) \
            Window::method args; \
        else \
            method args;

    void Window::CompatGetFocus()
    {
        COMPAT_BODY(GetFocus,())
    }

    void Window::CompatLoseFocus()
    {
        COMPAT_BODY(LoseFocus,())
    }

    void Window::CompatStateChanged( StateChangedType nStateChange )
    {
        COMPAT_BODY(StateChanged,(nStateChange))
    }

    void Window::CompatDataChanged( const DataChangedEvent& rDCEvt )
    {
        COMPAT_BODY(DataChanged,(rDCEvt))
    }

    bool Window::CompatPreNotify( NotifyEvent& rNEvt )
    {
        if (!mpWindowImpl || mpWindowImpl->mbInDispose)
            return Window::PreNotify( rNEvt );
        else
            return PreNotify( rNEvt );
    }

    bool Window::CompatNotify( NotifyEvent& rNEvt )
    {
        if (!mpWindowImpl || mpWindowImpl->mbInDispose)
            return Window::EventNotify( rNEvt );
        else
            return EventNotify( rNEvt );
    }

    void Window::set_id(const OUString& rID)
    {
        mpWindowImpl->maID = rID;
    }

    const OUString& Window::get_id() const
    {
        return mpWindowImpl->maID;
    }

    FactoryFunction Window::GetUITestFactory() const
    {
        return WindowUIObject::create;
    }

    } /* namespace vcl */

    /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

↑ V595 The 'pOverlapWindow' pointer was utilized before it was verified against nullptr. Check lines: 461, 466.

↑ V614 The 'pOverlapRegion' smart pointer is utilized immediately after being declared or reset. It is suspicious that no value was assigned to it.

↑ V547 Expression 'bAlways' is always true.

↑ V547 Expression 'bAlways' is always true.

↑ V581 The conditional expressions of the 'if' statements situated alongside each other are identical. Check lines: 869, 879.

↑ V560 A part of conditional expression is always true: !pOverlapRegion.