tdf#149805 tdf#151677 tdf#152217 tdf#154043 tdf#153458 tdf#153800 Revert "VCL expect

... correct frame size for native menubars"

This reverts

    commit afc828b9833b7a612369e95606ba56d41ef2c369
    Date:   Sat May 28 23:47:21 2022 +0200

        VCL expect correct frame size for native menubars

        ... and renove the wrong framesize hack in the Qt backend

because it caused several regressions and unfortunately
the commit also doesn't fix all of the bugs mentioned
in its commit message (while some previous patch sets of the
change did address more, yet had other issues, s.a. the discussion
in the commit's Gerrit change [1]).

While e.g. the drag and drop issues reported in tdf#153458
and tdf#153800 could be fixed by translating the event position
using `mapToParent()` (as is done in
`QtWidget::fillSalAbstractMouseEvent` with the above commit
in place), I currently don't see how to address the other
issues and the overall direction of the change is not fully
clear to me at this point. (There are also other pending changes
in the relation change still pending in Gerrit that would presumably
need more work/analysis.)

After all, it seems the best way forward to revert the
commit for now.

This also reverts the follow-up commit

    commit 25da92004038c03c0feedf373e8038e7ee3e0c37
    Date:   Thu Jul 21 11:33:02 2022 +0200

        Make JunitTest_toolkit_unoapi_1 succeed again on macOS

that fixed a test failure introduced by the above commit.

Luckily, there seem to be no follow-up commits that
depend on this and the commits can be reverted cleanly
without the need to resolve any conflicts manually.

This reverts commit 25da92004038c03c0feedf373e8038e7ee3e0c37.
This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369.

[1] https://gerrit.libreoffice.org/c/core/+/135082

Change-Id: I4c099ad7de8cbbad10da391ede4770d8c748fbde
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149495
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx
index bb0ef8c..abad985 100644
--- a/include/vcl/menu.hxx
+++ b/include/vcl/menu.hxx
@@ -179,8 +179,6 @@ protected:

    SAL_DLLPRIVATE void ImplFillLayoutData() const;
    SAL_DLLPRIVATE SalMenu* ImplGetSalMenu() { return mpSalMenu.get(); }
    // convenience function; just returns the SalMenu*, if HasNativeMenuBar() is true
    SAL_DLLPRIVATE SalMenu* GetNativeMenuBar();
    SAL_DLLPRIVATE OUString ImplGetHelpText( sal_uInt16 nItemId ) const;

    // returns native check and option menu symbol height in rCheckHeight and rRadioHeight
diff --git a/vcl/inc/osx/salmenu.h b/vcl/inc/osx/salmenu.h
index 274d1ec..597180c 100644
--- a/vcl/inc/osx/salmenu.h
+++ b/vcl/inc/osx/salmenu.h
@@ -55,7 +55,7 @@ public:
    AquaSalMenu( bool bMenuBar );
    virtual ~AquaSalMenu() override;

    virtual bool HasNativeMenuBar() override;
    virtual bool VisibleMenuBar() override;

    virtual void InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) override;
    virtual void RemoveItem( unsigned nPos ) override;
diff --git a/vcl/inc/qt5/QtFrame.hxx b/vcl/inc/qt5/QtFrame.hxx
index 40954f6..963572ca 100644
--- a/vcl/inc/qt5/QtFrame.hxx
+++ b/vcl/inc/qt5/QtFrame.hxx
@@ -131,6 +131,7 @@ class VCLPLUG_QT_PUBLIC QtFrame : public QObject, public SalFrame
    bool isMinimized() const;
    bool isMaximized() const;
    void SetWindowStateImpl(Qt::WindowStates eState);
    int menuBarOffset() const;

    void fixICCCMwindowGroup();

@@ -145,8 +146,6 @@ public:
    QtMainWindow* GetTopLevelWindow() const { return m_pTopLevel; }
    QWidget* asChild() const;
    qreal devicePixelRatioF() const;
    QPoint mapToParent(const QPoint&) const;
    QPoint mapFromParent(const QPoint&) const;

    void Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 nExtentsWidth,
                sal_Int32 nExtentsHeight) const;
diff --git a/vcl/inc/qt5/QtMenu.hxx b/vcl/inc/qt5/QtMenu.hxx
index 6bb0dbc..a1b7768 100644
--- a/vcl/inc/qt5/QtMenu.hxx
+++ b/vcl/inc/qt5/QtMenu.hxx
@@ -69,15 +69,14 @@ private:
public:
    QtMenu(bool bMenuBar);

    virtual bool HasNativeMenuBar() override;
    virtual int GetMenuBarHeight() const override;
    virtual void ShowMenuBar(bool bVisible) override;
    virtual bool VisibleMenuBar() override; // must return TRUE to actually DISPLAY native menu bars

    virtual void InsertItem(SalMenuItem* pSalMenuItem, unsigned nPos) override;
    virtual void RemoveItem(unsigned nPos) override;
    virtual void SetSubMenu(SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned nPos) override;
    virtual void SetFrame(const SalFrame* pFrame) override;
    const QtFrame* GetFrame() const;
    virtual void ShowMenuBar(bool bVisible) override;
    virtual bool ShowNativePopupMenu(FloatingWindow* pWin, const tools::Rectangle& rRect,
                                     FloatWinPopupFlags nFlags) override;
    QtMenu* GetTopLevel();
@@ -96,6 +95,7 @@ public:
    virtual bool AddMenuBarButton(const SalMenuButtonItem&) override;
    virtual void RemoveMenuBarButton(sal_uInt16 nId) override;
    virtual tools::Rectangle GetMenuBarButtonRectPixel(sal_uInt16 nId, SalFrame*) override;
    virtual int GetMenuBarHeight() const override;

    void SetMenu(Menu* pMenu) { mpVCLMenu = pMenu; }
    Menu* GetMenu() { return mpVCLMenu; }
diff --git a/vcl/inc/qt5/QtPainter.hxx b/vcl/inc/qt5/QtPainter.hxx
index 755a51f60..9702a19 100644
--- a/vcl/inc/qt5/QtPainter.hxx
+++ b/vcl/inc/qt5/QtPainter.hxx
@@ -34,26 +34,34 @@ class QtPainter final : public QPainter
public:
    QtPainter(QtGraphicsBackend& rGraphics, bool bPrepareBrush = false,
              sal_uInt8 nTransparency = 255);
    ~QtPainter();
    ~QtPainter()
    {
        if (m_rGraphics.m_pFrame && !m_aRegion.isEmpty())
            m_rGraphics.m_pFrame->GetQWidget()->update(m_aRegion);
    }

    void update(int nx, int ny, int nw, int nh)
    {
        if (m_rGraphics.m_pFrame)
            m_aRegion += QRect(nx, ny, nw, nh);
            m_aRegion += scaledQRect({ nx, ny, nw, nh }, 1 / m_rGraphics.devicePixelRatioF());
    }

    void update(const QRect& rRect)
    {
        if (m_rGraphics.m_pFrame)
            m_aRegion += rRect;
            m_aRegion += scaledQRect(rRect, 1 / m_rGraphics.devicePixelRatioF());
    }

    void update(const QRectF& rRectF) { update(rRectF.toAlignedRect()); }
    void update(const QRectF& rRectF)
    {
        if (m_rGraphics.m_pFrame)
            update(scaledQRect(rRectF.toAlignedRect(), 1 / m_rGraphics.devicePixelRatioF()));
    }

    void update()
    {
        if (m_rGraphics.m_pFrame)
            m_aRegion += m_rGraphics.m_pFrame->GetQWidget()->geometry();
            m_aRegion += m_rGraphics.m_pFrame->GetQWidget()->rect();
    }
};

diff --git a/vcl/inc/qt5/QtTools.hxx b/vcl/inc/qt5/QtTools.hxx
index 694a075..9b4239a 100644
--- a/vcl/inc/qt5/QtTools.hxx
+++ b/vcl/inc/qt5/QtTools.hxx
@@ -69,11 +69,6 @@ inline QRect scaledQRect(const QRect& rRect, const qreal fScale)
                 ceil(rRect.height() * fScale));
}

inline QSize scaledQSize(const QSize& rSize, const qreal fScale)
{
    return QSize(ceil(rSize.width() * fScale), ceil(rSize.height() * fScale));
}

inline tools::Rectangle toRectangle(const QRect& rRect)
{
    return tools::Rectangle(rRect.left(), rRect.top(), rRect.right(), rRect.bottom());
diff --git a/vcl/inc/salmenu.hxx b/vcl/inc/salmenu.hxx
index 50c1e9f..975df93 100644
--- a/vcl/inc/salmenu.hxx
+++ b/vcl/inc/salmenu.hxx
@@ -60,18 +60,9 @@ class VCL_PLUGIN_PUBLIC SalMenu
public:
    virtual ~SalMenu();

    /**
     * Return true, if the implementation supports a native menu bar
     * (or wants to suppress LO's menu bar, like on Mac).
     *
     * You might need to implement the matching SalFrame::SetMenu.
     **/
    virtual bool HasNativeMenuBar() = 0;
    /** Return the height of the native menu bar. Must return 0, if it's hidden. */
    virtual int GetMenuBarHeight() const;
    /** Change visibility of the native menu bar. */
    virtual void ShowMenuBar(bool);

    virtual bool VisibleMenuBar() = 0;  // must return true to actually DISPLAY native menu bars
                                            // otherwise only menu messages are processed (eg, OLE on Windows)
    virtual void ShowMenuBar( bool ) {}
    virtual void InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) = 0;
    virtual void RemoveItem( unsigned nPos ) = 0;
    virtual void SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned nPos ) = 0;
@@ -100,6 +91,8 @@ public:
    // but rectangle cannot be determined
    virtual tools::Rectangle GetMenuBarButtonRectPixel( sal_uInt16 i_nItemId, SalFrame* i_pReferenceFrame );

    virtual int GetMenuBarHeight() const;

    virtual void ApplyPersona();
};

diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index fc8ab76..2b18466 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -71,8 +71,8 @@ public:
    GtkSalMenu( bool bMenuBar );
    virtual ~GtkSalMenu() override;

    virtual bool HasNativeMenuBar() override;
    virtual void ShowMenuBar(bool bVisible) override;
    virtual bool                VisibleMenuBar() override;   // must return TRUE to actually DISPLAY native menu bars
                                                    // otherwise only menu messages are processed (eg, OLE on Windows)

    virtual void                InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) override;
    virtual void                RemoveItem( unsigned nPos ) override;
@@ -112,6 +112,7 @@ public:
    static void                 Activate(const gchar* pMenuCommand);
    static void                 Deactivate(const gchar* pMenuCommand);
    void                        EnableUnity(bool bEnable);
    virtual void                ShowMenuBar( bool bVisible ) override;
    bool                        PrepUpdate() const;
    virtual void                Update() override;  // Update this menu only.
    // Update full menu hierarchy from this menu.
@@ -138,6 +139,7 @@ public:
    virtual tools::Rectangle GetMenuBarButtonRectPixel( sal_uInt16 i_nItemId, SalFrame* i_pReferenceFrame ) override;
    virtual bool CanGetFocus() const override;
    virtual bool TakeFocus() override;
    virtual int GetMenuBarHeight() const override;
    virtual void ApplyPersona() override;
};

diff --git a/vcl/inc/win/salmenu.h b/vcl/inc/win/salmenu.h
index 96dc275..7058d9c 100644
--- a/vcl/inc/win/salmenu.h
+++ b/vcl/inc/win/salmenu.h
@@ -28,7 +28,8 @@ class WinSalMenu : public SalMenu
public:
    WinSalMenu();
    virtual ~WinSalMenu() override;
    virtual bool HasNativeMenuBar() override;
    virtual bool VisibleMenuBar() override;  // must return TRUE to actually DISPLAY native menu bars
                            // otherwise only menu messages are processed (eg, OLE on Windows)

    virtual void InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) override;
    virtual void RemoveItem( unsigned nPos ) override;
diff --git a/vcl/osx/salmenu.cxx b/vcl/osx/salmenu.cxx
index c7dfc46..bc2c5be 100644
--- a/vcl/osx/salmenu.cxx
+++ b/vcl/osx/salmenu.cxx
@@ -448,7 +448,7 @@ void AquaSalMenu::removeFallbackMenuItem( NSMenuItem* pOldItem )
    }
}

bool AquaSalMenu::HasNativeMenuBar()
bool AquaSalMenu::VisibleMenuBar()
{
    return true;
}
diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx
index 5517584..4bdd36e 100644
--- a/vcl/qt5/QtFrame.cxx
+++ b/vcl/qt5/QtFrame.cxx
@@ -249,16 +249,8 @@ QtFrame::~QtFrame()
void QtFrame::Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 nExtentsWidth,
                     sal_Int32 nExtentsHeight) const
{
    QRect aParentUpdateRect(scaledQRect(QRect(nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight),
                                        1 / devicePixelRatioF()));
    if (!m_pTopLevel)
        m_pQWidget->update(aParentUpdateRect);
    else
    {
        QRect aIntersectedRect(aParentUpdateRect.intersected(m_pQWidget->geometry()));
        if (!aIntersectedRect.isEmpty())
            m_pQWidget->update(aIntersectedRect.translated(-m_pQWidget->geometry().topLeft()));
    }
    m_pQWidget->update(scaledQRect(QRect(nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight),
                                   1 / devicePixelRatioF()));
}

SalGraphics* QtFrame::AcquireGraphics()
@@ -272,7 +264,7 @@ SalGraphics* QtFrame::AcquireGraphics()
    {
        if (!m_pSvpGraphics)
        {
            QSize aSize = asChild()->size() * devicePixelRatioF();
            QSize aSize = m_pQWidget->size() * devicePixelRatioF();
            m_pSvpGraphics.reset(new QtSvpGraphics(this));
            m_pSurface.reset(
                cairo_image_surface_create(CAIRO_FORMAT_ARGB32, aSize.width(), aSize.height()));
@@ -289,7 +281,7 @@ SalGraphics* QtFrame::AcquireGraphics()
        {
            m_pQtGraphics.reset(new QtGraphics(this));
            m_pQImage.reset(
                new QImage(asChild()->size() * devicePixelRatioF(), Qt_DefaultFormat32));
                new QImage(m_pQWidget->size() * devicePixelRatioF(), Qt_DefaultFormat32));
            m_pQImage->fill(Qt::transparent);
            m_pQtGraphics->ChangeQImage(m_pQImage.get());
        }
@@ -455,25 +447,32 @@ void QtFrame::SetMaxClientSize(tools::Long nWidth, tools::Long nHeight)
    }
}

int QtFrame::menuBarOffset() const
{
    QtMainWindow* pTopLevel = m_pParent->GetTopLevelWindow();
    if (pTopLevel && pTopLevel->menuBar() && pTopLevel->menuBar()->isVisible())
        return round(pTopLevel->menuBar()->geometry().height() * devicePixelRatioF());
    return 0;
}

void QtFrame::SetDefaultPos()
{
    if (!m_bDefaultPos)
        return;

    QWidget* const pChildWin = asChild()->window();
    QPoint aPos;

    // center on parent or screen
    // center on parent
    if (m_pParent)
    {
        const qreal fRatio = devicePixelRatioF();
        QWidget* const pParentWin = m_pParent->asChild()->window();
        aPos = (pParentWin->rect().center() - pChildWin->rect().center()) * devicePixelRatioF();
        QWidget* const pChildWin = asChild()->window();
        QPoint aPos = (pParentWin->rect().center() - pChildWin->rect().center()) * fRatio;
        aPos.ry() -= menuBarOffset();
        SetPosSize(aPos.x(), aPos.y(), 0, 0, SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y);
        assert(!m_bDefaultPos);
    }
    else
        aPos = windowHandle()->screen()->availableGeometry().center() - pChildWin->rect().center();

    SetPosSize(aPos.x(), aPos.y(), 0, 0, SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y);
    assert(!m_bDefaultPos);
        m_bDefaultPos = false;
}

Size QtFrame::CalcDefaultSize()
@@ -567,11 +566,10 @@ void QtFrame::SetPosSize(tools::Long nX, tools::Long nY, tools::Long nWidth, too
    {
        const SalFrameGeometry& aParentGeometry = m_pParent->maGeometry;
        if (QGuiApplication::isRightToLeft())
            nX = aParentGeometry.x() + aParentGeometry.width() - nX - maGeometry.width()
                 - aParentGeometry.rightDecoration() - 1;
            nX = aParentGeometry.x() + aParentGeometry.width() - nX - maGeometry.width() - 1;
        else
            nX += aParentGeometry.x() + aParentGeometry.leftDecoration();
        nY += aParentGeometry.y() + aParentGeometry.topDecoration();
            nX += aParentGeometry.x();
        nY += aParentGeometry.y() + menuBarOffset();
    }

    if (!(nFlags & SAL_FRAME_POSSIZE_X))
@@ -589,8 +587,8 @@ void QtFrame::SetPosSize(tools::Long nX, tools::Long nY, tools::Long nWidth, too

void QtFrame::GetClientSize(tools::Long& rWidth, tools::Long& rHeight)
{
    rWidth = maGeometry.width();
    rHeight = maGeometry.height();
    rWidth = round(m_pQWidget->width() * devicePixelRatioF());
    rHeight = round(m_pQWidget->height() * devicePixelRatioF());
}

void QtFrame::GetWorkArea(tools::Rectangle& rRect)
@@ -1523,14 +1521,4 @@ void QtFrame::handleDragLeave()
    m_bInDrag = false;
}

QPoint QtFrame::mapToParent(const QPoint& rPos) const
{
    return m_pTopLevel ? m_pQWidget->mapToParent(rPos) : rPos;
}

QPoint QtFrame::mapFromParent(const QPoint& rPos) const
{
    return m_pTopLevel ? m_pQWidget->mapFromParent(rPos) : rPos;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/QtMenu.cxx b/vcl/qt5/QtMenu.cxx
index dd259f3..fe281d6 100644
--- a/vcl/qt5/QtMenu.cxx
+++ b/vcl/qt5/QtMenu.cxx
@@ -59,7 +59,7 @@ QtMenu::QtMenu(bool bMenuBar)
{
}

bool QtMenu::HasNativeMenuBar() { return true; }
bool QtMenu::VisibleMenuBar() { return true; }

void QtMenu::InsertMenuItem(QtMenuItem* pSalMenuItem, unsigned nPos)
{
@@ -849,7 +849,8 @@ int QtMenu::GetMenuBarHeight() const
{
    if (!validateQMenuBar() || mpQMenuBar->isHidden())
        return 0;
    return mpQMenuBar->height() * mpFrame->devicePixelRatioF();

    return mpQMenuBar->height();
}

QtMenuItem::QtMenuItem(const SalItemParams* pItemData)
diff --git a/vcl/qt5/QtPainter.cxx b/vcl/qt5/QtPainter.cxx
index 529a7c5..115b4a82 100644
--- a/vcl/qt5/QtPainter.cxx
+++ b/vcl/qt5/QtPainter.cxx
@@ -56,23 +56,3 @@ QtPainter::QtPainter(QtGraphicsBackend& rGraphics, bool bPrepareBrush, sal_uInt8
    setCompositionMode(rGraphics.m_eCompositionMode);
    setRenderHint(QPainter::Antialiasing, m_rGraphics.getAntiAlias());
}

QtPainter::~QtPainter()
{
    if (!m_rGraphics.m_pFrame || m_aRegion.isEmpty())
        return;

    QWidget* pWidget = m_rGraphics.m_pFrame->GetQWidget();
    QRect aParentUpdateRect(
        scaledQRect(m_aRegion.boundingRect(), 1 / m_rGraphics.devicePixelRatioF()));
    if (!m_rGraphics.m_pFrame->GetTopLevelWindow())
        pWidget->update(m_aRegion);
    else
    {
        QRect aIntersectedRect(aParentUpdateRect.intersected(pWidget->geometry()));
        if (!aIntersectedRect.isEmpty())
            pWidget->update(aIntersectedRect.translated(-pWidget->geometry().topLeft()));
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx
index cc17cc8..83ada78 100644
--- a/vcl/qt5/QtWidget.cxx
+++ b/vcl/qt5/QtWidget.cxx
@@ -82,21 +82,18 @@ void QtWidget::paintEvent(QPaintEvent* pEvent)
        aImage = *m_rFrame.m_pQImage;

    const qreal fRatio = m_rFrame.devicePixelRatioF();
    assert(aImage.size() == scaledQSize(m_rFrame.asChild()->size(), fRatio));
    aImage.setDevicePixelRatio(fRatio);
    QPoint aPos = m_rFrame.mapToParent(pEvent->rect().topLeft());
    QRectF source(aPos * fRatio, scaledQSize(pEvent->rect().size(), fRatio));
    p.drawImage(pEvent->rect().topLeft(), aImage, source);
    QRectF source(pEvent->rect().topLeft() * fRatio, pEvent->rect().size() * fRatio);
    p.drawImage(pEvent->rect(), aImage, source);
}

void QtWidget::resizeEvent(QResizeEvent*)
void QtWidget::resizeEvent(QResizeEvent* pEvent)
{
    // this uses the actual frame size for the double buffering backing store.
    // while children get a resize event before their parents, the size of the
    // frame / window is already updated at this point.
    const qreal fRatio = m_rFrame.devicePixelRatioF();
    const int nWidth = ceil(m_rFrame.asChild()->size().width() * fRatio);
    const int nHeight = ceil(m_rFrame.asChild()->size().height() * fRatio);
    const int nWidth = ceil(pEvent->size().width() * fRatio);
    const int nHeight = ceil(pEvent->size().height() * fRatio);

    m_rFrame.maGeometry.setSize({ nWidth, nHeight });

    if (m_rFrame.m_bUseCairo)
    {
@@ -131,13 +128,6 @@ void QtWidget::resizeEvent(QResizeEvent*)
        }
    }

    const QRect aQtFrameGeometry = m_rFrame.asChild()->frameGeometry();
    const QRect aQtGeometry = m_rFrame.asChild()->geometry();
    m_rFrame.maGeometry.setLeftDecoration(aQtGeometry.left() - aQtFrameGeometry.left());
    m_rFrame.maGeometry.setTopDecoration(aQtGeometry.top() - aQtFrameGeometry.top());
    m_rFrame.maGeometry.setRightDecoration(aQtFrameGeometry.right() - aQtGeometry.right());
    m_rFrame.maGeometry.setBottomDecoration(aQtFrameGeometry.bottom() - aQtGeometry.bottom());
    m_rFrame.maGeometry.setSize({ nWidth, nHeight });
    m_rFrame.CallCallback(SalEvent::Resize, nullptr);
}

@@ -152,7 +142,7 @@ void QtWidget::fillSalAbstractMouseEvent(const QtFrame& rFrame, const QInputEven
                                         SalAbstractMouseEvent& aSalEvent)
{
    const qreal fRatio = rFrame.devicePixelRatioF();
    const Point aPos = toPoint(rFrame.mapToParent(rPos) * fRatio);
    const Point aPos = toPoint(rPos * fRatio);

    aSalEvent.mnX = QGuiApplication::isLeftToRight() ? aPos.X() : round(nWidth * fRatio) - aPos.X();
    aSalEvent.mnY = aPos.Y();
@@ -215,7 +205,7 @@ void QtWidget::mouseMoveEvent(QMouseEvent* pEvent)
void QtWidget::handleMouseEnterLeaveEvents(const QtFrame& rFrame, QEvent* pQEvent)
{
    const qreal fRatio = rFrame.devicePixelRatioF();
    const QWidget* pWidget = rFrame.asChild();
    const QWidget* pWidget = rFrame.GetQWidget();
    const Point aPos = toPoint(pWidget->mapFromGlobal(QCursor::pos()) * fRatio);

    SalMouseEvent aEvent;
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index e4e7676..394a093 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -234,8 +234,6 @@ tools::Rectangle SalMenu::GetMenuBarButtonRectPixel(sal_uInt16, SalFrame*)

int SalMenu::GetMenuBarHeight() const { return 0; }

void SalMenu::ShowMenuBar(bool) {}

void SalMenu::ApplyPersona() {}

SalMenuItem::~SalMenuItem() {}
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index 656fba5..e8facf7 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -2210,11 +2210,6 @@ void Menu::ImplFillLayoutData() const
    }
}

SalMenu* Menu::GetNativeMenuBar()
{
    return mpSalMenu && mpSalMenu->HasNativeMenuBar() ? mpSalMenu.get() : nullptr;
}

tools::Rectangle Menu::GetCharacterBounds( sal_uInt16 nItemID, tools::Long nIndex ) const
{
    tools::Long nItemIndex = -1;
@@ -2448,21 +2443,26 @@ void MenuBar::SetDisplayable( bool bDisplayable )

VclPtr<vcl::Window> MenuBar::ImplCreate(vcl::Window* pParent, vcl::Window* pWindow, MenuBar* pMenu)
{
    // can't this be a static_cast? is there a real possibility, the pWindow is not the MenuBarWindow or nullptr?
    VclPtr<MenuBarWindow> pMenuBarWindow = dynamic_cast<MenuBarWindow*>(pWindow);
    if (!pMenuBarWindow)
        pMenuBarWindow = VclPtr<MenuBarWindow>::Create(pParent);

    pMenu->pStartedFrom = nullptr;
    pMenu->pWindow = pMenuBarWindow;
    pMenuBarWindow->SetMenu(pMenu);
    if (pMenuBarWindow) {
        // This is needed at least on macOS to make the JunitTest_toolkit_unoapi_1
        // toolkit.AccessibleMenu test pass:
        pMenu->ImplCalcSize(pMenuBarWindow);
    {
        pWindow = pMenuBarWindow = VclPtr<MenuBarWindow>::Create( pParent );
    }

    return pMenuBarWindow;
    pMenu->pStartedFrom = nullptr;
    pMenu->pWindow = pWindow;
    pMenuBarWindow->SetMenu(pMenu);
    tools::Long nHeight = pWindow ? pMenu->ImplCalcSize(pWindow).Height() : 0;

    // depending on the native implementation or the displayable flag
    // the menubar windows is suppressed (ie, height=0)
    if (!pMenu->IsDisplayable() || (pMenu->ImplGetSalMenu() && pMenu->ImplGetSalMenu()->VisibleMenuBar()))
    {
        nHeight = 0;
    }

    pMenuBarWindow->SetHeight(nHeight);
    return pWindow;
}

void MenuBar::ImplDestroy( MenuBar* pMenu, bool bDelete )
@@ -2489,7 +2489,7 @@ bool MenuBar::ImplHandleKeyEvent( const KeyEvent& rKEvent )

    // No keyboard processing when system handles the menu.
    SalMenu *pNativeMenu = ImplGetSalMenu();
    if (pNativeMenu && pNativeMenu->HasNativeMenuBar())
    if (pNativeMenu && pNativeMenu->VisibleMenuBar())
    {
        // Except when the event is the F6 cycle pane event and we can put our
        // focus into it (i.e. the gtk3 menubar case but not the mac/unity case
diff --git a/vcl/source/window/menubarwindow.cxx b/vcl/source/window/menubarwindow.cxx
index 552034b..0109bb5 100644
--- a/vcl/source/window/menubarwindow.cxx
+++ b/vcl/source/window/menubarwindow.cxx
@@ -167,43 +167,34 @@ void MenuBarWindow::dispose()
    Window::dispose();
}

void MenuBarWindow::SetMenu(MenuBar* pMenu)
void MenuBarWindow::SetMenu( MenuBar* pMen )
{
    if (pMenu == m_pMenu)
        return;
    m_pMenu = pMenu;

    m_pMenu = pMen;
    KillActivePopup();
    m_nHighlightedItem = ITEMPOS_INVALID;

    if (!pMenu)
    if (pMen)
    {
        LayoutChanged();
        return;
        m_aCloseBtn->ShowItem(ToolBoxItemId(IID_DOCUMENTCLOSE), pMen->HasCloseButton());
        m_aCloseBtn->Show(pMen->HasCloseButton() || !m_aAddButtons.empty());
        m_aFloatBtn->Show(pMen->HasFloatButton());
        m_aHideBtn->Show(pMen->HasHideButton());
    }
    SalMenu* pSalMenu = pMenu->ImplGetSalMenu();
    const bool bHasNativeMenuBar = pSalMenu && pSalMenu->HasNativeMenuBar();
    Invalidate();

    // no menubar window drawing needed in case of a native menu bar
    SetPaintTransparent(bHasNativeMenuBar);
    m_aCloseBtn->ShowItem(ToolBoxItemId(IID_DOCUMENTCLOSE), !bHasNativeMenuBar && pMenu->HasCloseButton());
    m_aCloseBtn->Show(!bHasNativeMenuBar && (pMenu->HasCloseButton() || !m_aAddButtons.empty()));
    m_aFloatBtn->Show(!bHasNativeMenuBar && pMenu->HasFloatButton());
    m_aHideBtn->Show(!bHasNativeMenuBar && pMenu->HasHideButton());

    // connect native popup menu / menubar and show it
    if (pSalMenu)
    // show and connect native menubar
    if( m_pMenu && m_pMenu->ImplGetSalMenu() )
    {
        SalFrame* pFrame = ImplGetFrame();
        assert(pFrame);
        if (bHasNativeMenuBar)
            pFrame->SetMenu(pSalMenu);
        pSalMenu->SetFrame(pFrame);
        if (bHasNativeMenuBar)
            pSalMenu->ShowMenuBar(true);
    }
        if( m_pMenu->ImplGetSalMenu()->VisibleMenuBar() )
            ImplGetFrame()->SetMenu( m_pMenu->ImplGetSalMenu() );

    LayoutChanged();
        m_pMenu->ImplGetSalMenu()->SetFrame( ImplGetFrame() );
        m_pMenu->ImplGetSalMenu()->ShowMenuBar(true);
    }
}

void MenuBarWindow::SetHeight(tools::Long nHeight)
{
    setPosSizePixel(0, 0, 0, nHeight, PosSizeFlags::Height);
}

void MenuBarWindow::ShowButtons( bool bClose, bool bFloat, bool bHide )
@@ -733,8 +724,10 @@ bool MenuBarWindow::HandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu )
    }

    // no key events if native menus
    if (m_pMenu->GetNativeMenuBar())
    if (m_pMenu->ImplGetSalMenu() && m_pMenu->ImplGetSalMenu()->VisibleMenuBar())
    {
        return false;
    }

    if ( nCode == KEY_MENU && !rKEvent.GetKeyCode().IsShift() ) // only F10, not Shift-F10
    {
@@ -869,7 +862,7 @@ void MenuBarWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Recta
    Size aOutputSize = GetOutputSizePixel();

    // no VCL paint if native menus
    if (m_pMenu->GetNativeMenuBar())
    if (m_pMenu->ImplGetSalMenu() && m_pMenu->ImplGetSalMenu()->VisibleMenuBar())
        return;

    // Make sure that all actual rendering happens in one go to avoid flicker.
@@ -1011,24 +1004,22 @@ void MenuBarWindow::LayoutChanged()

    ApplySettings(*GetOutDev());

    // if the font was changed.
    tools::Long nHeight = m_pMenu->ImplCalcSize(this).Height();

    // depending on the native implementation or the displayable flag
    // the menubar windows is suppressed (ie, height=0)
    tools::Long nHeight = 0;
    const bool bHasNativeMenuBar = m_pMenu->GetNativeMenuBar();
    if (bHasNativeMenuBar)
        nHeight = m_pMenu->ImplGetSalMenu()->GetMenuBarHeight();
    else if (static_cast<MenuBar*>(m_pMenu.get())->IsDisplayable())
        nHeight = m_pMenu->ImplCalcSize(this).Height();

    if (!static_cast<MenuBar*>(m_pMenu.get())->IsDisplayable() ||
        (m_pMenu->ImplGetSalMenu() && m_pMenu->ImplGetSalMenu()->VisibleMenuBar()))
    {
        nHeight = 0;
    }
    setPosSizePixel(0, 0, 0, nHeight, PosSizeFlags::Height);
    GetParent()->Resize();
    Invalidate();
    Resize();

    if (!bHasNativeMenuBar)
    {
        Invalidate();
        Resize();
        m_pMenu->ImplKillLayoutData();
    }
    m_pMenu->ImplKillLayoutData();
}

void MenuBarWindow::ApplySettings(vcl::RenderContext& rRenderContext)
@@ -1219,8 +1210,8 @@ bool MenuBarWindow::CanGetFocus() const
       this relies on MenuBar::ImplCreate setting the height of the menubar
       to 0 in this case
    */
    SalMenu *pNativeMenu = m_pMenu ? m_pMenu->GetNativeMenuBar() : nullptr;
    if (pNativeMenu)
    SalMenu *pNativeMenu = m_pMenu ? m_pMenu->ImplGetSalMenu() : nullptr;
    if (pNativeMenu && pNativeMenu->VisibleMenuBar())
        return pNativeMenu->CanGetFocus();
    return GetSizePixel().Height() > 0;
}
diff --git a/vcl/source/window/menubarwindow.hxx b/vcl/source/window/menubarwindow.hxx
index 0a90747..cc7963a 100644
--- a/vcl/source/window/menubarwindow.hxx
+++ b/vcl/source/window/menubarwindow.hxx
@@ -120,6 +120,7 @@ public:
    virtual void    RequestHelp( const HelpEvent& rHEvt ) override;

    void    SetMenu(MenuBar* pMenu);
    void    SetHeight(tools::Long nHeight);
    void    KillActivePopup();
    void    PopupClosed(Menu const * pMenu);
    sal_uInt16 GetHighlightedItem() const { return m_nHighlightedItem; }
diff --git a/vcl/unx/gtk3/gtksalmenu.cxx b/vcl/unx/gtk3/gtksalmenu.cxx
index bb40484..b03db5f 100644
--- a/vcl/unx/gtk3/gtksalmenu.cxx
+++ b/vcl/unx/gtk3/gtksalmenu.cxx
@@ -653,7 +653,7 @@ GtkSalMenu::~GtkSalMenu()
        mpFrame->SetMenu(nullptr);
}

bool GtkSalMenu::HasNativeMenuBar()
bool GtkSalMenu::VisibleMenuBar()
{
    return mbMenuBar && (bUnityMode || mpMenuBarContainerWidget);
}
@@ -1620,6 +1620,11 @@ void GtkSalMenu::GetSystemMenuData( SystemMenuData* )
{
}

int GtkSalMenu::GetMenuBarHeight() const
{
    return mpMenuBarWidget ? gtk_widget_get_allocated_height(mpMenuBarWidget) : 0;
}

/*
 * GtkSalMenuItem
 */
diff --git a/vcl/win/window/salmenu.cxx b/vcl/win/window/salmenu.cxx
index 4b07f23..91a1528 100644
--- a/vcl/win/window/salmenu.cxx
+++ b/vcl/win/window/salmenu.cxx
@@ -115,7 +115,7 @@ WinSalMenu::~WinSalMenu()
    ::DestroyMenu( mhMenu );
}

bool WinSalMenu::HasNativeMenuBar()
bool WinSalMenu::VisibleMenuBar()
{
    // The Win32 implementation never shows a native
    // menubar. Thus, native menus are only visible