Resolves: tdf#120632 consider submenus on restoring focus from menu

additionally to the menu having focus, if a submenu of that menu has
focus, then restore the focus when the whole hierarchy execution ends
return focus to the toplevel menu's saved focus widget

Change-Id: Iefd467fb1ba67ffd0a303505a893d2453e0ffbb3
Reviewed-on: https://gerrit.libreoffice.org/66132
Tested-by: Xisco Faulí <xiscofauli@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/vcl/source/window/menufloatingwindow.cxx b/vcl/source/window/menufloatingwindow.cxx
index ea4cb3b..5ba39b5 100644
--- a/vcl/source/window/menufloatingwindow.cxx
+++ b/vcl/source/window/menufloatingwindow.cxx
@@ -401,6 +401,16 @@ void MenuFloatingWindow::Start()
        GetParent()->IncModalCount();
}

bool MenuFloatingWindow::MenuInHierarchyHasFocus() const
{
    if (HasChildPathFocus())
        return true;
    PopupMenu* pSub = GetActivePopup();
    if (!pSub)
        return false;
    return pSub->ImplGetFloatingWindow()->HasChildPathFocus();
}

void MenuFloatingWindow::End()
{
    if (!bInExecute)
@@ -412,7 +422,7 @@ void MenuFloatingWindow::End()
    // restore focus to previous window if we still have the focus
    VclPtr<vcl::Window> xFocusId(xSaveFocusId);
    xSaveFocusId = nullptr;
    if (HasChildPathFocus() && xFocusId != nullptr)
    if (xFocusId != nullptr && MenuInHierarchyHasFocus())
    {
        ImplGetSVData()->maWinData.mbNoDeactivate = false;
        Window::EndSaveFocus(xFocusId);
diff --git a/vcl/source/window/menufloatingwindow.hxx b/vcl/source/window/menufloatingwindow.hxx
index 9888cd2..c091b46 100644
--- a/vcl/source/window/menufloatingwindow.hxx
+++ b/vcl/source/window/menufloatingwindow.hxx
@@ -121,6 +121,8 @@ public:

    void SetPosInParent( sal_uInt16 nPos ) { nPosInParent = nPos; }

    bool MenuInHierarchyHasFocus() const;

    virtual css::uno::Reference<css::accessibility::XAccessible> CreateAccessible() override;
};