Skip to content

Commit 4126de8

Browse files
committed
Add support for disabling menu item images. Issue 12780
1 parent ea1a0f3 commit 4126de8

File tree

9 files changed

+78
-19
lines changed

9 files changed

+78
-19
lines changed

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@
1919
- Don't include AI-generated markdown files (summaries, plans, etc.) in commits — only ship code.
2020
- Avoid duplicate expressions; hoist shared computations into a named `const` before branching.
2121
- Don't change defaults silently.
22+
- Use [iTermUserDefaults userDefaults] instead of [NSUserDefaults standardUserDefaults]

Interfaces/PreferencePanel.xib

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,7 @@ CA
14181418
<outlet property="_flashTabBarInFullscreenWhenSwitchingTabs" destination="Esq-U7-Af7" id="PoL-qW-T0f"/>
14191419
<outlet property="_hideActivityIndicator" destination="5374" id="Q4E-FF-5Zc"/>
14201420
<outlet property="_hideMenuBarInFullscreen" destination="awA-hH-ziY" id="CDd-B7-fbl"/>
1421+
<outlet property="_hideMenuItemIcons" destination="8jj-nE-deG" id="Olu-rG-WKK"/>
14211422
<outlet property="_hideScrollbar" destination="4561" id="I02-gk-NqP"/>
14221423
<outlet property="_hideTab" destination="4462" id="GTv-bn-7th"/>
14231424
<outlet property="_hideTabNumber" destination="4446" id="PIE-R6-5sO"/>
@@ -8486,11 +8487,11 @@ You can choose to define the characters considered part of a word with a regular
84868487
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
84878488
<subviews>
84888489
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Wsp-9H-Fsm" customClass="iTermPreferencesInnerTabContainerView">
8489-
<rect key="frame" x="47" y="173" width="496" height="158"/>
8490+
<rect key="frame" x="47" y="147" width="496" height="184"/>
84908491
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
84918492
<subviews>
84928493
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="awA-hH-ziY">
8493-
<rect key="frame" x="144" y="58" width="306" height="18"/>
8494+
<rect key="frame" x="144" y="84" width="306" height="18"/>
84948495
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
84958496
<string key="toolTip">For this setting to take effect you must disable "Native full screen windows" in Settings &gt; General. If this setting is enabled, the menu bar will remain visible. This is useful for multi-monitor systems.</string>
84968497
<buttonCell key="cell" type="check" title="Auto-hide menu bar in non-native fullscreen" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="MM6-3I-2ep">
@@ -8502,7 +8503,7 @@ You can choose to define the characters considered part of a word with a regular
85028503
</connections>
85038504
</button>
85048505
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zde-kb-c7t">
8505-
<rect key="frame" x="144" y="38" width="337" height="18"/>
8506+
<rect key="frame" x="144" y="64" width="337" height="18"/>
85068507
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
85078508
<string key="toolTip">This is useful if you only use iTerm2 with a hotkey window. The preference is disabled if no dedicated hotkey window is defined since it would be impossible to get to iTerm2 when it has no windows and no hotkey is defined.</string>
85088509
<buttonCell key="cell" type="check" title="Exclude from Dock and ⌘-Tab Application Switcher" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="90f-c6-lvp">
@@ -8514,7 +8515,7 @@ You can choose to define the characters considered part of a word with a regular
85148515
</connections>
85158516
</button>
85168517
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ThU-HR-f8F">
8517-
<rect key="frame" x="90" y="140" width="50" height="16"/>
8518+
<rect key="frame" x="90" y="166" width="50" height="16"/>
85188519
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
85198520
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Theme:" id="uhj-9S-l8R">
85208521
<font key="font" metaFont="system"/>
@@ -8523,7 +8524,7 @@ You can choose to define the characters considered part of a word with a regular
85238524
</textFieldCell>
85248525
</textField>
85258526
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Cjh-dQ-HBQ">
8526-
<rect key="frame" x="144" y="79" width="191" height="26"/>
8527+
<rect key="frame" x="144" y="105" width="191" height="26"/>
85278528
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
85288529
<popUpButtonCell key="cell" type="push" title="Top" bezelStyle="rounded" alignment="left" lineBreakMode="clipping" state="on" borderStyle="borderAndBezel" inset="2" arrowPosition="arrowAtCenter" preferredEdge="maxY" selectedItem="7BM-xw-fbE" id="9o6-qH-zo0" userLabel="Tab Style">
85298530
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@@ -8542,7 +8543,7 @@ You can choose to define the characters considered part of a word with a regular
85428543
</connections>
85438544
</popUpButton>
85448545
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4463">
8545-
<rect key="frame" x="144" y="106" width="191" height="26"/>
8546+
<rect key="frame" x="144" y="132" width="191" height="26"/>
85468547
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
85478548
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="clipping" borderStyle="borderAndBezel" inset="2" arrowPosition="arrowAtCenter" preferredEdge="maxY" id="4495">
85488549
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@@ -8561,7 +8562,7 @@ You can choose to define the characters considered part of a word with a regular
85618562
</connections>
85628563
</popUpButton>
85638564
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uFJ-bZ-kag">
8564-
<rect key="frame" x="144" y="133" width="191" height="26"/>
8565+
<rect key="frame" x="144" y="159" width="191" height="26"/>
85658566
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
85668567
<popUpButtonCell key="cell" type="push" title="Regular" bezelStyle="rounded" alignment="left" lineBreakMode="clipping" state="on" borderStyle="borderAndBezel" tag="4" inset="2" arrowPosition="arrowAtCenter" preferredEdge="maxY" selectedItem="ZNW-QH-Lff" id="dAw-Fo-tf4" userLabel="Tab Style">
85678568
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@@ -8586,7 +8587,7 @@ You can choose to define the characters considered part of a word with a regular
85868587
</connections>
85878588
</popUpButton>
85888589
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ghv-jZ-ql9">
8589-
<rect key="frame" x="18" y="86" width="122" height="16"/>
8590+
<rect key="frame" x="18" y="112" width="122" height="16"/>
85908591
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
85918592
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Status bar location:" id="jtG-zd-rvL">
85928593
<font key="font" metaFont="system"/>
@@ -8595,7 +8596,7 @@ You can choose to define the characters considered part of a word with a regular
85958596
</textFieldCell>
85968597
</textField>
85978598
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="sxm-tG-syy">
8598-
<rect key="frame" x="35" y="113" width="105" height="16"/>
8599+
<rect key="frame" x="35" y="139" width="105" height="16"/>
85998600
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
86008601
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Tab bar location:" id="jnA-10-c4D">
86018602
<font key="font" metaFont="system"/>
@@ -8604,7 +8605,7 @@ You can choose to define the characters considered part of a word with a regular
86048605
</textFieldCell>
86058606
</textField>
86068607
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wjs-vG-qf2">
8607-
<rect key="frame" x="163" y="18" width="334" height="18"/>
8608+
<rect key="frame" x="163" y="44" width="334" height="18"/>
86088609
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
86098610
<string key="toolTip">This is useful if you only use iTerm2 with a hotkey window. The preference is disabled if no dedicated hotkey window is defined since it would be impossible to get to iTerm2 when it has no windows and no hotkey is defined.</string>
86108611
<buttonCell key="cell" type="check" title="…but only if all windows are hotkey windows" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="9Nh-nh-0mQ">
@@ -8616,6 +8617,18 @@ You can choose to define the characters considered part of a word with a regular
86168617
<action selector="settingChanged:" target="wvi-ET-SJJ" id="3mP-qK-BRO"/>
86178618
</connections>
86188619
</button>
8620+
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8jj-nE-deG">
8621+
<rect key="frame" x="144" y="20" width="306" height="18"/>
8622+
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
8623+
<string key="toolTip">For this setting to take effect you must disable "Native full screen windows" in Settings &gt; General. If this setting is enabled, the menu bar will remain visible. This is useful for multi-monitor systems.</string>
8624+
<buttonCell key="cell" type="check" title="Hide menu item icons" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="tBM-DH-v7M">
8625+
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
8626+
<font key="font" metaFont="system"/>
8627+
</buttonCell>
8628+
<connections>
8629+
<action selector="settingChanged:" target="wvi-ET-SJJ" id="A31-UC-br9"/>
8630+
</connections>
8631+
</button>
86198632
</subviews>
86208633
</customView>
86218634
</subviews>
@@ -9881,7 +9894,7 @@ instead of the system keyboard.</string>
98819894
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
98829895
<clipView key="contentView" id="N1C-ir-dI5">
98839896
<rect key="frame" x="1" y="1" width="238" height="377"/>
9884-
<autoresizingMask key="autoresizingMask"/>
9897+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
98859898
<subviews>
98869899
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnResizing="NO" autosaveColumns="NO" typeSelect="NO" id="5562">
98879900
<rect key="frame" x="0.0" y="0.0" width="238" height="377"/>

sources/AppearancePreferencesViewController.m

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ @implementation AppearancePreferencesViewController {
111111
IBOutlet NSTextField *_topBottomMarginsLabel;
112112
IBOutlet NSTextField *_topBottomMargins;
113113
IBOutlet NSStepper *_topBottomMarginsStepper;
114+
115+
IBOutlet NSButton *_hideMenuItemIcons;
114116
}
115117

116118
- (void)awakeFromNib {
@@ -400,6 +402,13 @@ - (void)awakeFromNib {
400402
type:kPreferenceInfoTypeCheckbox];
401403
info.onChange = ^() { [weakSelf postRefreshNotification]; };
402404

405+
info = [self defineControl:_hideMenuItemIcons
406+
key:kPreferenceKeyMenuActionImages
407+
relatedView:nil
408+
type:kPreferenceInfoTypeInvertedCheckbox];
409+
if (@available(macOS 26, *)) {} else {
410+
_hideMenuItemIcons.enabled = NO;
411+
}
403412
[self updateProxyIconEnabled];
404413
}
405414

sources/MainMenuMangler.swift

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class MainMenuMangler: NSObject {
1313
@objc static let instance = MainMenuMangler()
1414
private weak var observedWindow: NSWindow?
1515
private var web: NSMenuItem?
16+
private let defaultsObserver = iTermUserDefaultsObserver()
1617

1718
// Track if the application is terminating to avoid accessing deallocated objects
1819
private var isTerminating = false
@@ -23,6 +24,10 @@ class MainMenuMangler: NSObject {
2324
// Store conflicting menu items that need their key equivalents restored
2425
private var conflictingMenuItems: [(menuItem: NSMenuItem, keyEquivalent: String, modifierMask: NSEvent.ModifierFlags)] = []
2526

27+
@objc static var menuActionImagesEnabled: Bool {
28+
iTermPreferences.bool(forKey: kPreferenceKeyMenuActionImages)
29+
}
30+
2631
private let iconMap = [
2732
// iTerm2 menu
2833
"Show Tip of the Day": "lightbulb",
@@ -320,9 +325,19 @@ class MainMenuMangler: NSObject {
320325

321326
@available(macOS 26, *)
322327
@objc func setIcons() {
323-
// Find all menu items by traversing the main menu
324-
if let mainMenu = NSApp.mainMenu {
328+
defaultsObserver.observeKey(kPreferenceKeyMenuActionImages) { [weak self] in
329+
self?.updateIcons()
330+
}
331+
updateIcons()
332+
}
333+
334+
@available(macOS 26, *)
335+
private func updateIcons() {
336+
guard let mainMenu = NSApp.mainMenu else { return }
337+
if MainMenuMangler.menuActionImagesEnabled {
325338
setIcons(map: iconMap, in: mainMenu)
339+
} else {
340+
removeIcons(in: mainMenu)
326341
}
327342
}
328343

@@ -376,6 +391,17 @@ class MainMenuMangler: NSObject {
376391
}
377392
}
378393

394+
private func removeIcons(in menu: NSMenu) {
395+
for item in menu.items {
396+
if !item.isSeparatorItem {
397+
item.image = nil
398+
}
399+
if item.hasSubmenu, let submenu = item.submenu {
400+
removeIcons(in: submenu)
401+
}
402+
}
403+
}
404+
379405
@objc func start(web: NSMenuItem) {
380406
self.web = web
381407

sources/iTermController.m

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -878,8 +878,10 @@ - (void)_addBookmarksForTag:(NSString*)tag
878878
action:openAllSelector
879879
keyEquivalent:@""];
880880
if (@available(macOS 26, *)) {
881-
aMenuItem.image = [NSImage imageWithSystemSymbolName:@"person.3.sequence"
882-
accessibilityDescription:nil];
881+
if (iTermMainMenuMangler.menuActionImagesEnabled) {
882+
aMenuItem.image = [NSImage imageWithSystemSymbolName:@"person.3.sequence"
883+
accessibilityDescription:nil];
884+
}
883885
}
884886
unsigned int modifierMask = NSEventModifierFlagCommand | NSEventModifierFlagControl;
885887
[aMenuItem setKeyEquivalentModifierMask:modifierMask];

sources/iTermPreferences.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ extern NSString *const kPreferenceKeySnippets;
347347

348348
extern NSString *const kPreferenceKeyDisableTransparencyForKeyWindow;
349349
extern NSString *const kPreferenceKeyNeverBlockSystemShutdown;
350+
extern NSString *const kPreferenceKeyMenuActionImages;
350351

351352
extern NSString *const iTermDefaultAIPrompt;
352353

sources/iTermPreferences.m

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@
212212
NSString *const kPreferenceKeyHTMLTabTitles = @"HTMLTabTitles";
213213
NSString *const kPreferenceKeyDisableTransparencyForKeyWindow = @"DisableTransparencyForKeyWindow";
214214
NSString *const kPreferenceKeyNeverBlockSystemShutdown = @"NeverBlockSystemShutdown";
215+
NSString *const kPreferenceKeyMenuActionImages = @"NSMenuEnableActionImages";
215216

216217
NSString *const kPreferenceKeyOpenAIAPIKey = @"NoSyncOpenAIAPIKey"; // deprecated
217218
NSString *const kPreferenceKeyAIAPIKey = @"NoUserDefaultAIAPIKey";
@@ -668,7 +669,9 @@ + (NSDictionary *)defaultValueMap {
668669
kPreferenceKeyHTMLTabTitles: @NO,
669670

670671
kPreferenceKeyDisableTransparencyForKeyWindow: @NO,
671-
kPreferenceKeyNeverBlockSystemShutdown: @NO
672+
kPreferenceKeyNeverBlockSystemShutdown: @NO,
673+
674+
kPreferenceKeyMenuActionImages: @YES,
672675
};
673676
}
674677
return dict;

0 commit comments

Comments
 (0)