/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwindowsmenu.h"
#include "qwindowscontext.h"
#include "qwindowswindow.h"

#include <QtGui/qwindow.h>
#include <QtCore/qdebug.h>
#include <QtCore/qvariant.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qpointer.h>

#include <algorithm>

QT_BEGIN_NAMESPACE

/*!
    \class QWindowsMenuBar
    \brief Windows native menu bar

    \list
    \li \l{https://msdn.microsoft.com/de-de/library/windows/desktop/ms647553(v=vs.85).aspx#_win32_Menu_Creation_Functions},
         \e{About Menus}
    \endlist

    \note The destruction order of the QWindowsMenu/Item/Bar instances is
    arbitrary depending on whether the application is Qt Quick or
    Qt Widgets, either the containers or the items might be deleted first.

    \internal
    \ingroup qt-lighthouse-win
*/

static uint nextId = 1;

// Find a QPlatformMenu[Item]* in a vector of QWindowsMenu[Item], where
// QVector::indexOf() cannot be used since it wants a QWindowsMenu[Item]*
template <class Derived, class Needle>
static int indexOf(const QVector<Derived *> &v, const Needle *needle)
{
    for (int i = 0, size = v.size(); i < size; ++i) {
        if (v.at(i) == needle)
            return i;
    }
    return -1;
}

// Helper for inserting a QPlatformMenu[Item]* into a vector of QWindowsMenu[Item].
template <class Derived, class Base>
static int insertBefore(QVector<Derived *> *v, Base *newItemIn, const Base *before = nullptr)
{
    int index = before ? indexOf(*v, before) : -1;
    if (index != -1) {
        v->insert(index, static_cast<Derived *>(newItemIn));
    } else {
        index = v->size();
        v->append(static_cast<Derived *>(newItemIn));
    }
    return index;
}

static inline const wchar_t *qStringToWChar(const QString &s)
{
    return reinterpret_cast<const wchar_t *>(s.utf16());
}

// Traverse menu and return the item for which predicate
// "bool Function(QWindowsMenuItem *)" returns true
template <class Predicate>
static QWindowsMenuItem *traverseMenuItems(const QWindowsMenu *menu, Predicate p)
{
    const QWindowsMenu::MenuItems &items = menu->menuItems();
    for (QWindowsMenuItem *item : items) {
        if (p(item))
            return item;
        if (item->subMenu()) {
            if (QWindowsMenuItem *subMenuItem = traverseMenuItems(item->subMenu(), p))
                return subMenuItem;
        }
    }
    return nullptr;
}

// Traverse menu bar return the item for which predicate
// "bool Function(QWindowsMenuItem *)" returns true
template <class Predicate>
static QWindowsMenuItem *traverseMenuItems(const QWindowsMenuBar *menuBar, Predicate p)
{
    const QWindowsMenuBar::Menus &menus = menuBar->menus();
    for (QWindowsMenu *menu : menus) {
        if (QWindowsMenuItem *item = traverseMenuItems(menu, p))
            return item;
    }
    return nullptr;
}

template <class Menu /* Menu[Bar] */>
static QWindowsMenuItem *findMenuItemById(const Menu *menu, uint id)
{
    return traverseMenuItems(menu, [id] (const QWindowsMenuItem *i) { return i->id() == id; });
}

// Traverse menu and return the menu for which predicate
// "bool Function(QWindowsMenu *)" returns true
template <class Predicate>
static QWindowsMenu *traverseMenus(const QWindowsMenu *menu, Predicate p)
{
    const QWindowsMenu::MenuItems &items = menu->menuItems();
    for (QWindowsMenuItem *item : items) {
        if (QWindowsMenu *subMenu = item->subMenu()) {
            if (p(subMenu))
                return subMenu;
            if (QWindowsMenu *menu = traverseMenus(subMenu, p))
                return menu;
        }
    }
    return nullptr;
}

// Traverse menu bar return the item for which
// function "bool Function(QWindowsMenu *)" returns true
template <class Predicate>
static QWindowsMenu *traverseMenus(const QWindowsMenuBar *menuBar, Predicate p)
{
    const QWindowsMenuBar::Menus &menus = menuBar->menus();
    for (QWindowsMenu *menu : menus) {
            if (p(menu))
                return menu;
        if (QWindowsMenu *subMenu = traverseMenus(menu, p))
            return subMenu;
    }
    return nullptr;
}

template <class Menu /* Menu[Bar] */>
static QWindowsMenu *findMenuByHandle(const Menu *menu, HMENU hMenu)
{
    return traverseMenus(menu, [hMenu] (const QWindowsMenu *i) { return i->menuHandle() == hMenu; });
}

template <class MenuType>
static int findNextVisibleEntry(const QVector<MenuType *> &entries, int pos)
{
    for (int i = pos, size = entries.size(); i < size; ++i) {
        if (entries.at(i)->isVisible())
            return i;
    }
    return -1;
}

static inline void menuItemInfoInit(MENUITEMINFO &menuItemInfo)
{
    memset(&menuItemInfo, 0, sizeof(MENUITEMINFO));
    menuItemInfo.cbSize = sizeof(MENUITEMINFO);
}

static inline void menuItemInfoSetText(MENUITEMINFO &menuItemInfo, const QString &text)
{
    menuItemInfoInit(menuItemInfo);
    menuItemInfo.fMask = MIIM_STRING;
    menuItemInfo.dwTypeData = const_cast<wchar_t *>(qStringToWChar(text));
    menuItemInfo.cch = UINT(text.size());
}

static UINT menuItemState(HMENU hMenu, UINT uItem, BOOL fByPosition)
{
    MENUITEMINFO menuItemInfo;
    menuItemInfoInit(menuItemInfo);
    menuItemInfo.fMask = MIIM_STATE;
    return GetMenuItemInfo(hMenu, uItem, fByPosition, &menuItemInfo) == TRUE ? menuItemInfo.fState : 0;
}

static void menuItemSetState(HMENU hMenu, UINT uItem, BOOL fByPosition, UINT flags)
{
    MENUITEMINFO menuItemInfo;
    menuItemInfoInit(menuItemInfo);
    menuItemInfo.fMask = MIIM_STATE;
    menuItemInfo.fState = flags;
    SetMenuItemInfo(hMenu, uItem, fByPosition, &menuItemInfo);
}

static void menuItemSetChangeState(HMENU hMenu, UINT uItem, BOOL fByPosition,
                                   bool value, UINT trueState, UINT falseState)
{
     const UINT oldState = menuItemState(hMenu, uItem, fByPosition);
     UINT newState = oldState;
     if (value) {
         newState |= trueState;
         newState &= ~falseState;
     } else {
         newState &= ~trueState;
         newState |= falseState;
     }
     if (oldState != newState)
         menuItemSetState(hMenu, uItem, fByPosition, newState);
}

// ------------ QWindowsMenuItem
QWindowsMenuItem::QWindowsMenuItem(QWindowsMenu *parentMenu)
    : m_parentMenu(parentMenu)
    , m_id(0)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << static_cast<const void *>(this)
        << "parentMenu=" << parentMenu;
}

QWindowsMenuItem::~QWindowsMenuItem()
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << static_cast<const void *>(this);
    removeFromMenu();
    freeBitmap();
}

void QWindowsMenuItem::freeBitmap()
{
    if (m_hbitmap) {
        DeleteObject(m_hbitmap);
        m_hbitmap = nullptr;
    }
}

void QWindowsMenuItem::setIcon(const QIcon &icon)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << '(' << icon << ')' << this;
    if (m_icon.cacheKey() == icon.cacheKey())
        return;
    m_icon = icon;
    if (m_parentMenu != nullptr)
        updateBitmap();
}

Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = 0);

void QWindowsMenuItem::updateBitmap()
{
    freeBitmap();
    if (!m_icon.isNull()) {
        const int size = m_iconSize ? m_iconSize : GetSystemMetrics(SM_CYMENUCHECK);
        m_hbitmap = qt_pixmapToWinHBITMAP(m_icon.pixmap(QSize(size, size)), 1);
    }
    MENUITEMINFO itemInfo;
    menuItemInfoInit(itemInfo);
    itemInfo.fMask = MIIM_BITMAP;
    itemInfo.hbmpItem = m_hbitmap;
    SetMenuItemInfo(parentMenuHandle(), m_id, FALSE, &itemInfo);
}

void QWindowsMenuItem::setText(const QString &text)
{
    qCDebug(lcQpaMenus).nospace().noquote()
        << __FUNCTION__ << "(\"" << text << "\") " << this;
    if (m_text == text)
        return;
    m_text = text;
    if (m_parentMenu != nullptr)
        updateText();
}

void QWindowsMenuItem::updateText()
{
    MENUITEMINFO menuItemInfo;
    const QString &text = nativeText();
    menuItemInfoSetText(menuItemInfo, text);
    SetMenuItemInfo(parentMenuHandle(), m_id, FALSE, &menuItemInfo);
}

void QWindowsMenuItem::setMenu(QPlatformMenu *menuIn)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << '(' << menuIn << ')' << this;
    if (menuIn == m_subMenu)
        return;
    const uint oldId = m_id;
    if (menuIn != nullptr) { // Set submenu
        m_subMenu = static_cast<QWindowsMenu *>(menuIn);
        m_subMenu->setAsItemSubMenu(this);
        m_id = m_subMenu->id();
        if (m_parentMenu != nullptr) {
            ModifyMenu(m_parentMenu->menuHandle(), oldId, MF_BYCOMMAND | MF_POPUP,
                       m_id, qStringToWChar(m_text));
        }
        return;
    }
    // Clear submenu
    m_subMenu = nullptr;
    if (m_parentMenu != nullptr) {
        m_id = nextId++;
        ModifyMenu(m_parentMenu->menuHandle(), oldId, MF_BYCOMMAND,
                   m_id, qStringToWChar(m_text));
    } else {
        m_id = 0;
    }
}

void QWindowsMenuItem::setVisible(bool isVisible)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << '(' << isVisible << ')' << this;
    if (m_visible == isVisible)
        return;
    m_visible = isVisible;
    if (m_parentMenu == nullptr)
        return;
    // Windows menu items do not implement settable visibility, we need to work
    // around by removing the item from the menu. It will be kept in the list.
    if (isVisible)
        insertIntoMenuHelper(m_parentMenu, false, m_parentMenu->menuItems().indexOf(this));
    else
        RemoveMenu(parentMenuHandle(), m_id, MF_BYCOMMAND);
}

void QWindowsMenuItem::setIsSeparator(bool isSeparator)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << '(' << isSeparator << ')' << this;
    if (m_separator == isSeparator)
        return;
    m_separator = isSeparator;
    if (m_parentMenu == nullptr)
        return;
    MENUITEMINFO menuItemInfo;
    menuItemInfoInit(menuItemInfo);
    menuItemInfo.fMask = MIIM_FTYPE;
    menuItemInfo.fType = isSeparator ? MFT_SEPARATOR : MFT_STRING;
    SetMenuItemInfo(parentMenuHandle(), m_id, FALSE, &menuItemInfo);
}

void QWindowsMenuItem::setCheckable(bool checkable)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << '(' << checkable << ')' << this;
    if (m_checkable == checkable)
        return;
    m_checkable = checkable;
    if (m_parentMenu == nullptr)
        return;
    UINT state = menuItemState(parentMenuHandle(), m_id, FALSE);
    if (m_checkable)
        state |= m_checked ? MF_CHECKED : MF_UNCHECKED;
    else
        state &= ~(MF_CHECKED | MF_UNCHECKED);
    menuItemSetState(parentMenuHandle(), m_id, FALSE, state);
}

void QWindowsMenuItem::setChecked(bool isChecked)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << '(' << isChecked << ')' << this;
    if (m_checked == isChecked)
        return;
    m_checked = isChecked;
    // Convenience: Allow to set checkable by calling setChecked(true) for
    // Quick Controls 1
    if (isChecked)
        m_checkable = true;
    if (m_parentMenu == nullptr || !m_checkable)
        return;
    menuItemSetChangeState(parentMenuHandle(), m_id, FALSE, m_checked, MF_CHECKED, MF_UNCHECKED);
}

#if QT_CONFIG(shortcut)
void QWindowsMenuItem::setShortcut(const QKeySequence &shortcut)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << '(' << shortcut << ')' << this;
    if (m_shortcut == shortcut)
        return;
    m_shortcut = shortcut;
    if (m_parentMenu != nullptr)
        updateText();
}
#endif

void QWindowsMenuItem::setEnabled(bool enabled)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << '(' << enabled << ')' << this;
    if (m_enabled == enabled)
        return;
    m_enabled = enabled;
    if (m_parentMenu != nullptr)
        menuItemSetChangeState(parentMenuHandle(), m_id, FALSE, m_enabled, MF_ENABLED, MF_GRAYED);
}

void QWindowsMenuItem::setIconSize(int size)
{
    if (m_iconSize == size)
        return;
    m_iconSize = size;
    if (m_parentMenu != nullptr)
        updateBitmap();
}

HMENU QWindowsMenuItem::parentMenuHandle() const
{
    return m_parentMenu ? m_parentMenu->menuHandle() : nullptr;
}

UINT QWindowsMenuItem::state() const
{
    if (m_separator)
        return MF_SEPARATOR;
    UINT result = MF_STRING | (m_enabled ? MF_ENABLED : MF_GRAYED);
    if (m_subMenu != nullptr)
        result |= MF_POPUP;
    if (m_checkable)
        result |= m_checked ? MF_CHECKED : MF_UNCHECKED;
    if (QGuiApplication::layoutDirection() == Qt::RightToLeft)
        result |= MFT_RIGHTORDER;
    return result;
}

QString QWindowsMenuItem::nativeText() const
{
    QString result = m_text;
#if QT_CONFIG(shortcut)
    if (!m_shortcut.isEmpty()) {
        result += QLatin1Char('\t');
        result += m_shortcut.toString(QKeySequence::NativeText);
    }
#endif
    return result;
}

void QWindowsMenuItem::insertIntoMenu(QWindowsMenu *menu, bool append, int index)
{
    if (m_id == 0 && m_subMenu == nullptr)
        m_id = nextId++;
    insertIntoMenuHelper(menu, append, index);
    m_parentMenu = menu;
}

void QWindowsMenuItem::insertIntoMenuHelper(QWindowsMenu *menu, bool append, int index)
{
    const QString &text = nativeText();

    UINT_PTR idBefore = 0;
    if (!append) {
        // Skip over self (either newly inserted or when called from setVisible()
        const int nextIndex = findNextVisibleEntry(menu->menuItems(), index + 1);
        if (nextIndex != -1)
            idBefore = menu->menuItems().at(nextIndex)->id();
    }

    if (idBefore)
        InsertMenu(menu->menuHandle(), idBefore, state(), m_id, qStringToWChar(text));
    else
        AppendMenu(menu->menuHandle(), state(), m_id, qStringToWChar(text));

    updateBitmap();
}

bool QWindowsMenuItem::removeFromMenu()
{
    if (QWindowsMenu *parentMenu = m_parentMenu) {
        m_parentMenu = nullptr;
        RemoveMenu(parentMenu->menuHandle(), m_id, MF_BYCOMMAND);
        parentMenu->notifyRemoved(this);
        return true;
    }
    return false;
}

// ------------ QWindowsMenu

QWindowsMenu::QWindowsMenu() : QWindowsMenu(nullptr, CreateMenu())
{
}

QWindowsMenu::QWindowsMenu(QWindowsMenu *parentMenu, HMENU menu)
    : m_parentMenu(parentMenu)
    , m_hMenu(menu)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << static_cast<const void *>(this)
        << "parentMenu=" << parentMenu << "HMENU=" << m_hMenu;
}

QWindowsMenu::~QWindowsMenu()
{
    qCDebug(lcQpaMenus).noquote().nospace() << __FUNCTION__
      << " \"" <<m_text << "\", " << static_cast<const void *>(this);
    for (int i = m_menuItems.size() - 1; i>= 0; --i)
        m_menuItems.at(i)->removeFromMenu();
    removeFromParent();
    DestroyMenu(m_hMenu);
}

void QWindowsMenu::insertMenuItem(QPlatformMenuItem *menuItemIn, QPlatformMenuItem *before)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << '(' << menuItemIn << ", before=" << before << ')' << this;
    auto *menuItem = static_cast<QWindowsMenuItem *>(menuItemIn);
    const int index = insertBefore(&m_menuItems, menuItemIn, before);
    const bool append = index == m_menuItems.size() - 1;
    menuItem->insertIntoMenu(this, append, index);
}

void QWindowsMenu::removeMenuItem(QPlatformMenuItem *menuItemIn)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << '(' << menuItemIn << ')' << this;
    static_cast<QWindowsMenuItem *>(menuItemIn)->removeFromMenu();
}

void QWindowsMenu::setText(const QString &text)
{
    qCDebug(lcQpaMenus).nospace().noquote()
        << __FUNCTION__ << "(\"" << text << "\") " << this;
    if (m_text == text)
        return;
    m_text = text;
    if (!m_visible)
        return;
    const HMENU ph = parentHandle();
    if (ph == nullptr)
        return;
    MENUITEMINFO menuItemInfo;
    menuItemInfoSetText(menuItemInfo, m_text);
    SetMenuItemInfo(ph, id(), FALSE, &menuItemInfo);
}

void QWindowsMenu::setIcon(const QIcon &icon)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << '(' << icon << ')' << this;
    m_icon = icon;
}

void QWindowsMenu::setEnabled(bool enabled)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << '(' << enabled << ')' << this;
    if (m_enabled == enabled)
        return;
    m_enabled = enabled;
    if (!m_visible)
        return;
    if (const HMENU ph = parentHandle())
        menuItemSetChangeState(ph, id(), FALSE, m_enabled, MF_ENABLED, MF_GRAYED);
}

QWindowsMenuItem *QWindowsMenu::itemForSubMenu(const QWindowsMenu *subMenu) const
{
    const auto it = std::find_if(m_menuItems.cbegin(), m_menuItems.cend(),
                                 [subMenu] (const QWindowsMenuItem *i) { return i->subMenu() == subMenu; });
    return it != m_menuItems.cend() ? *it : nullptr;
}

void QWindowsMenu::insertIntoMenuBar(QWindowsMenuBar *bar, bool append, int index)
{
    UINT_PTR idBefore = 0;
    if (!append) {
        // Skip over self (either newly inserted or when called from setVisible()
        const int nextIndex = findNextVisibleEntry(bar->menus(), index + 1);
        if (nextIndex != -1)
            idBefore = bar->menus().at(nextIndex)->id();
    }
    m_parentMenuBar = bar;
    m_parentMenu = nullptr;
    if (idBefore)
        InsertMenu(bar->menuBarHandle(), idBefore, MF_POPUP | MF_BYCOMMAND, id(), qStringToWChar(m_text));
    else
        AppendMenu(bar->menuBarHandle(), MF_POPUP, id(), qStringToWChar(m_text));
}

bool QWindowsMenu::removeFromParent()
{
    if (QWindowsMenuBar *bar = m_parentMenuBar) {
        m_parentMenuBar = nullptr;
        bar->notifyRemoved(this);
        return RemoveMenu(bar->menuBarHandle(), id(), MF_BYCOMMAND) == TRUE;
    }
    if (QWindowsMenu *menu = m_parentMenu) {
         m_parentMenu = nullptr;
         QWindowsMenuItem *item = menu->itemForSubMenu(this);
         if (item)
             item->setMenu(nullptr);
         return item != nullptr;
    }
    return false;
}

void QWindowsMenu::setVisible(bool visible)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << '(' << visible << ')' << this;
    if (m_visible == visible)
        return;
    m_visible = visible;
    const HMENU ph = parentHandle();
    if (ph == nullptr)
        return;
    // Windows menus do not implement settable visibility, we need to work
    // around by removing the menu from the parent. It will be kept in the list.
    if (visible) {
        if (m_parentMenuBar)
            insertIntoMenuBar(m_parentMenuBar, false, m_parentMenuBar->menus().indexOf(this));
    } else {
        RemoveMenu(ph, id(), MF_BYCOMMAND);
    }
    if (m_parentMenuBar)
        m_parentMenuBar->redraw();
}

QPlatformMenuItem *QWindowsMenu::menuItemAt(int position) const
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << position;
    return position >= 0 && position < m_menuItems.size()
        ? m_menuItems.at(position) : nullptr;
}

QPlatformMenuItem *QWindowsMenu::menuItemForTag(quintptr tag) const
{
    return traverseMenuItems(this, [tag] (const QPlatformMenuItem *i) { return i->tag() == tag; });
}

QPlatformMenuItem *QWindowsMenu::createMenuItem() const
{
    QPlatformMenuItem *result = new QWindowsMenuItem;
    qCDebug(lcQpaMenus) << __FUNCTION__ << this << "returns" << result;
    return result;
}

QPlatformMenu *QWindowsMenu::createSubMenu() const
{
    QPlatformMenu *result = new QWindowsMenu;
    qCDebug(lcQpaMenus) << __FUNCTION__ << this << "returns" << result;
    return result;
}

void QWindowsMenu::setAsItemSubMenu(QWindowsMenuItem *item)
{
    m_parentMenu = item->parentMenu();
}

HMENU QWindowsMenu::parentMenuHandle() const
{
    return m_parentMenu ? m_parentMenu->menuHandle() : nullptr;
}

HMENU QWindowsMenu::parentMenuBarHandle() const
{
    return m_parentMenuBar ? m_parentMenuBar->menuBarHandle() : nullptr;
}

HMENU QWindowsMenu::parentHandle() const
{
    if (m_parentMenuBar)
        return m_parentMenuBar->menuBarHandle();
    if (m_parentMenu)
      return m_parentMenu->menuHandle();
    return nullptr;
}

// --------------- QWindowsPopupMenu

static QPointer<QWindowsPopupMenu> lastShownPopupMenu;

QWindowsPopupMenu::QWindowsPopupMenu() : QWindowsMenu(nullptr, CreatePopupMenu())
{
}

void QWindowsPopupMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect,
                                  const QPlatformMenuItem *item)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << '>' << this << parentWindow << targetRect << item;
    const auto *window = static_cast<const QWindowsBaseWindow *>(parentWindow->handle());
    const QPoint globalPos = window->mapToGlobal(targetRect.topLeft());
    trackPopupMenu(window->handle(), globalPos.x(), globalPos.y());
}

bool QWindowsPopupMenu::trackPopupMenu(HWND windowHandle, int x, int y)
{
    lastShownPopupMenu = this;
    // Emulate Show()/Hide() signals. Could be implemented by catching the
    // WM_EXITMENULOOP, WM_ENTERMENULOOP messages; but they do not carry
    // information telling which menu was opened.
    emit aboutToShow();
    const bool result =
        TrackPopupMenu(menuHandle(),
                          QGuiApplication::layoutDirection() == Qt::RightToLeft ? UINT(TPM_RIGHTALIGN) : UINT(0),
                          x, y, 0, windowHandle, nullptr) == TRUE;
    emit aboutToHide();
    return result;
}

bool QWindowsPopupMenu::notifyTriggered(uint id)
{
    QPlatformMenuItem *result = lastShownPopupMenu.isNull()
        ? nullptr
        : findMenuItemById(lastShownPopupMenu.data(), id);
    if (result != nullptr) {
        qCDebug(lcQpaMenus) << __FUNCTION__ << "id=" << id;
        emit result->activated();
    }
    lastShownPopupMenu = nullptr;
    return result != nullptr;
}

bool QWindowsPopupMenu::notifyAboutToShow(HMENU hmenu)
{
    if (lastShownPopupMenu.isNull())
        return false;
    if (lastShownPopupMenu->menuHandle() == hmenu) {
        emit lastShownPopupMenu->aboutToShow();
        return true;
    }
    if (QWindowsMenu *menu = findMenuByHandle(lastShownPopupMenu.data(), hmenu)) {
        emit menu->aboutToShow();
        return true;
    }
    return false;
}

// --------------- QWindowsMenuBar

QWindowsMenuBar::QWindowsMenuBar() : m_hMenuBar(CreateMenu())
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << static_cast<const void *>(this);
}

QWindowsMenuBar::~QWindowsMenuBar()
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << static_cast<const void *>(this);
    for (int m = m_menus.size() - 1; m >= 0; --m)
        m_menus.at(m)->removeFromParent();
    removeFromWindow();
    DestroyMenu(m_hMenuBar);
}

void QWindowsMenuBar::insertMenu(QPlatformMenu *menuIn, QPlatformMenu *before)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << menuIn << "before=" << before;
    auto *menu = static_cast<QWindowsMenu *>(menuIn);
    const int index = insertBefore(&m_menus, menuIn, before);
    menu->insertIntoMenuBar(this, index == m_menus.size() - 1, index);
}

void QWindowsMenuBar::removeMenu(QPlatformMenu *menu)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ << '(' << menu << ')' << this;
    const int index = indexOf(m_menus, menu);
    if (index != -1)
        m_menus[index]->removeFromParent();
}

// When calling handleReparent() for a QWindow instances that does not have
// a platform window yet, set the menubar as dynamic property to be installed
// on platform window creation.
static const char menuBarPropertyName[] = "_q_windowsNativeMenuBar";

void QWindowsMenuBar::handleReparent(QWindow *newParentWindow)
{
    qCDebug(lcQpaMenus) << __FUNCTION__ <<  '(' << newParentWindow << ')' << this;
    if (newParentWindow == nullptr) {
        removeFromWindow();
        return; // Happens during Quick Controls 1 property setup
    }
    if (QPlatformWindow *platWin = newParentWindow->handle())
        install(static_cast<QWindowsWindow *>(platWin));
    else // Store for later creation, see menuBarOf()
        newParentWindow->setProperty(menuBarPropertyName, QVariant::fromValue<QObject *>(this));
}

QWindowsMenuBar *QWindowsMenuBar::menuBarOf(const QWindow *notYetCreatedWindow)
{
    const QVariant menuBarV = notYetCreatedWindow->property(menuBarPropertyName);
    return menuBarV.canConvert<QObject *>()
        ? qobject_cast<QWindowsMenuBar *>(menuBarV.value<QObject *>()) : nullptr;
}

static inline void forceNcCalcSize(HWND hwnd)
{
    // Force WM_NCCALCSIZE to adjust margin: Does not appear to work?
    SetWindowPos(hwnd, nullptr, 0, 0, 0, 0,
                 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
}

void QWindowsMenuBar::install(QWindowsWindow *window)
{
    const HWND hwnd = window->handle();
    const BOOL result = SetMenu(hwnd, m_hMenuBar);
    if (result) {
        window->setMenuBar(this);
        forceNcCalcSize(hwnd);
    }
}

void QWindowsMenuBar::removeFromWindow()
{
    if (QWindowsWindow *window = platformWindow()) {
        const HWND hwnd = window->handle();
        SetMenu(hwnd, nullptr);
        window->setMenuBar(nullptr);
        forceNcCalcSize(hwnd);
    }
}

QPlatformMenu *QWindowsMenuBar::menuForTag(quintptr tag) const
{
    return traverseMenus(this, [tag] (const QWindowsMenu *m) { return m->tag() == tag; });
}

QPlatformMenu *QWindowsMenuBar::createMenu() const
{
    QPlatformMenu *result = new QWindowsMenu;
    qCDebug(lcQpaMenus) << __FUNCTION__ << this << "returns" << result;
    return result;
}

bool QWindowsMenuBar::notifyTriggered(uint id)
{
    QPlatformMenuItem *result = findMenuItemById(this, id);
    if (result  != nullptr) {
        qCDebug(lcQpaMenus) << __FUNCTION__ << "id=" << id;
        emit result->activated();
    }
    return result != nullptr;
}

bool QWindowsMenuBar::notifyAboutToShow(HMENU hmenu)
{
    if (QWindowsMenu *menu = findMenuByHandle(this, hmenu)) {
        emit menu->aboutToShow();
        return true;
    }
    return false;
}

QWindowsWindow *QWindowsMenuBar::platformWindow() const
{
    if (const QWindowsContext *ctx = QWindowsContext::instance()) {
        if (QWindowsWindow *w = ctx->findPlatformWindow(this))
            return w;
    }
    return nullptr;
}

void QWindowsMenuBar::redraw() const
{
    if (const QWindowsWindow *window = platformWindow())
        DrawMenuBar(window->handle());
}

#ifndef QT_NO_DEBUG_STREAM

template <class M>  /* Menu[Item] */
static void formatTextSequence(QDebug &d, const QVector<M *> &v)
{
    if (const int size = v.size()) {
        d << '[' << size << "](";
        for (int i = 0; i < size; ++i) {
            if (i)
                d << ", ";
            if (!v.at(i)->isVisible())
                d << "[hidden] ";
            d << '"' << v.at(i)->text() << '"';
        }
        d << ')';
    }
}

void QWindowsMenuItem::formatDebug(QDebug &d) const
{
    if (m_separator)
        d << "separator, ";
    else
        d << '"' << m_text << "\", ";
    d << static_cast<const void *>(this);
    if (m_parentMenu)
        d << ", parentMenu=" << static_cast<const void *>(m_parentMenu);
    if (m_subMenu)
        d << ", subMenu=" << static_cast<const void *>(m_subMenu);
    d << ", tag=" << Qt::showbase << Qt::hex
      << tag() << Qt::noshowbase << Qt::dec << ", id=" << m_id;
#if QT_CONFIG(shortcut)
    if (!m_shortcut.isEmpty())
        d << ", shortcut=" << m_shortcut;
#endif
    if (m_visible)
        d << " [visible]";
    if (m_enabled)
        d << " [enabled]";
    if (m_checkable)
        d << ", checked=" << m_checked;
}

QDebug operator<<(QDebug d, const QPlatformMenuItem *i)
{
    QDebugStateSaver saver(d);
    d.nospace();
    d.noquote();
    d << "QPlatformMenuItem(";
    if (i)
        static_cast<const QWindowsMenuItem *>(i)->formatDebug(d);
    else
        d << '0';
    d << ')';
    return d;
}

void QWindowsMenu::formatDebug(QDebug &d) const
{
    d << '"' << m_text << "\", " << static_cast<const void *>(this)
      << ", handle=" << m_hMenu;
    if (m_parentMenuBar != nullptr)
        d << " [on menubar]";
    if (m_parentMenu != nullptr)
        d << " [on menu]";
    if (tag())
        d << ", tag=" << Qt::showbase << Qt::hex << tag() << Qt::noshowbase << Qt::dec;
    if (m_visible)
        d << " [visible]";
    if (m_enabled)
        d << " [enabled]";
    d <<' ';
    formatTextSequence(d, m_menuItems);
}

void QWindowsMenuBar::formatDebug(QDebug &d) const
{
    d << static_cast<const void *>(this) << ' ';
    formatTextSequence(d, m_menus);
}

QDebug operator<<(QDebug d, const QPlatformMenu *m)
{
    QDebugStateSaver saver(d);
    d.nospace();
    d.noquote();
    if (m) {
        d << m->metaObject()->className() << '(';
        static_cast<const QWindowsMenu *>(m)->formatDebug(d);
        d << ')';
    } else {
        d << "QPlatformMenu(0)";
    }
    return d;
}

QDebug operator<<(QDebug d, const QPlatformMenuBar *mb)
{
    QDebugStateSaver saver(d);
    d.nospace();
    d.noquote();
    d << "QPlatformMenuBar(";
    if (mb)
        static_cast<const QWindowsMenuBar *>(mb)->formatDebug(d);
    else
        d << '0';
    d << ')';
    return d;
}

#endif // !QT_NO_DEBUG_STREAM

QT_END_NAMESPACE
