From 9db5beae714688e7e80a5386f45cac811ca5c3e3 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 15 Apr 2025 15:58:17 +0200 Subject: [PATCH] macOS: use correct icon pixmaps in native menus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When creating an NSImage from a QIcon to show the icon of the action in native menus, then we so far didn't take the state (on/off) or mode (normal/disabled) of the UI element into account. This resulted in a menu item showing the Normal/Off icon of an action, even if the underlying action was disabled or checked. Icons in menus are not common on macOS, but since we have the information we need in QCocoaMenuItem, we might just as well use it to get the right pixmap from the QIcon (even if that pixmap is generated from the Normal/Off pixmap). Add an overload to our NSImage::imageFromQIcon helpers that takes a mode and state, call that from the existing overload, and use it in QCocoaMenuItem::sync. Pick-to: 6.8 Fixes: QTBUG-135934 Change-Id: Ifce73daf49ce34c874fa5bf652d84b3102a06709 Reviewed-by: Tor Arne Vestbø (cherry picked from commit 84da5450c342655a7e426c5bb07d9accf7a222a1) Reviewed-by: Qt Cherry-pick Bot --- src/gui/painting/qcoregraphics.mm | 10 +++++++++- src/gui/painting/qcoregraphics_p.h | 7 ++++++- src/plugins/platforms/cocoa/qcocoamenuitem.mm | 6 +++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qcoregraphics.mm b/src/gui/painting/qcoregraphics.mm index 40fe5bdd144..ff7f877799b 100644 --- a/src/gui/painting/qcoregraphics.mm +++ b/src/gui/painting/qcoregraphics.mm @@ -122,6 +122,14 @@ QT_END_NAMESPACE } + (instancetype)imageFromQIcon:(const QIcon &)icon withSize:(int)size +{ + return [NSImage imageFromQIcon:icon withSize:0 withMode:QIcon::Normal withState:QIcon::Off]; +} + + ++ (instancetype)imageFromQIcon:(const QIcon &)icon withSize:(int)size withMode:(QIcon::Mode)mode + withState:(QIcon::State)state + { if (icon.isNull()) return nil; @@ -133,7 +141,7 @@ QT_END_NAMESPACE auto nsImage = [[[NSImage alloc] initWithSize:NSZeroSize] autorelease]; for (QSize size : std::as_const(availableSizes)) { - QImage image = icon.pixmap(size).toImage(); + const QImage image = icon.pixmap(size, mode, state).toImage(); if (image.isNull()) continue; diff --git a/src/gui/painting/qcoregraphics_p.h b/src/gui/painting/qcoregraphics_p.h index a35f27a7304..b685b0c96f1 100644 --- a/src/gui/painting/qcoregraphics_p.h +++ b/src/gui/painting/qcoregraphics_p.h @@ -18,8 +18,9 @@ #include #include -#include +#include #include +#include #include @@ -52,6 +53,10 @@ QT_END_NAMESPACE + (instancetype)imageFromQImage:(const QT_PREPEND_NAMESPACE(QImage) &)image; + (instancetype)imageFromQIcon:(const QT_PREPEND_NAMESPACE(QIcon) &)icon; + (instancetype)imageFromQIcon:(const QT_PREPEND_NAMESPACE(QIcon) &)icon withSize:(int)size; ++ (instancetype)imageFromQIcon:(const QT_PREPEND_NAMESPACE(QIcon) &)icon + withSize:(int)size + withMode:(QT_PREPEND_NAMESPACE(QIcon)::Mode)mode + withState:(QT_PREPEND_NAMESPACE(QIcon)::State)state; @end QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index c944e233336..b6033e9cdfc 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -372,7 +372,11 @@ NSMenuItem *QCocoaMenuItem::sync() m_native.keyEquivalentModifierMask = NSEventModifierFlagCommand; } - m_native.image = [NSImage imageFromQIcon:m_icon withSize:m_iconSize]; + const QIcon::Mode mode = m_enabled ? QIcon::Normal : QIcon::Disabled; + const QIcon::State state = m_checked ? QIcon::On : QIcon::Off; + m_native.image = [NSImage imageFromQIcon:m_icon withSize:m_iconSize + withMode:mode + withState:state]; m_native.state = m_checked ? NSControlStateValueOn : NSControlStateValueOff; return m_native;