Skip to content

Commit 899b0f1

Browse files
committed
macOS: check conflicts for menu shortcuts and clear the default one
Similar to #11396, if one is setting `keybind=cmd+option+h=goto_split:left`, the shortcut for "Hide Others" should be cleared out
1 parent 8d44349 commit 899b0f1

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

macos/Sources/Ghostty/Ghostty.MenuShortcutManager.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ extension Ghostty {
4242
configuredShortcuts.removeAll()
4343

4444
updateShortcutRecursively(in: menu, config: config)
45+
46+
checkConflictsRecursively(in: menu)
4547
}
4648
}
4749
}
@@ -118,6 +120,21 @@ private extension Ghostty.MenuShortcutManager {
118120
}
119121
menu.update()
120122
}
123+
124+
/// Shortcuts in Ghostty configuration should have higher priority than default shortcuts
125+
///
126+
/// We run this to do a final check for every menu item
127+
func checkConflictsRecursively(in menu: NSMenu?) {
128+
guard let menu else {
129+
return
130+
}
131+
132+
for item in menu.items {
133+
checkConflicts(item: item)
134+
checkConflictsRecursively(in: item.submenu)
135+
}
136+
menu.update()
137+
}
121138
}
122139

123140
// MARK: - Process a single menu item
@@ -186,6 +203,22 @@ private extension Ghostty.MenuShortcutManager {
186203
item.keyEquivalent = key.keyEquivalent
187204
item.keyEquivalentModifierMask = key.modifierFlags
188205
}
206+
207+
func checkConflicts(item: NSMenuItem) {
208+
guard
209+
let key = MenuShortcutKey(item),
210+
// There should be an existing shortcut first
211+
let existed = configuredShortcuts[key],
212+
// Then we check if the action is the same
213+
existed != item.action
214+
else {
215+
return
216+
}
217+
// User configured shortcut has conflicts with default one,
218+
// clear the default one
219+
item.keyEquivalent = ""
220+
item.keyEquivalentModifierMask = []
221+
}
189222
}
190223

191224
extension Ghostty.MenuShortcutManager {

macos/Tests/Ghostty/MenuShortcutManagerTests.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ struct MenuShortcutManagerTests {
6161
}
6262

6363
@Test
64-
func unreferencedItemShouldBeResetIfUnbound() async throws {
64+
func unreferencedItemShouldBeResetIfOverrodeOrUnbound() async throws {
6565
let config = try TemporaryConfig("keybind=super+h=goto_split:left")
6666

6767
let hideItem = NSMenuItem(title: "Hide Ghostty", action: "hide:", keyEquivalent: "h")
@@ -100,5 +100,16 @@ struct MenuShortcutManagerTests {
100100

101101
#expect(goToLeftItem.keyEquivalent == "l")
102102
#expect(goToLeftItem.keyEquivalentModifierMask == .command)
103+
104+
try config.reload("""
105+
keybind=super+l=goto_split:left
106+
""")
107+
await manager.resetRegisteredGhosttyActions()
108+
await manager.register(action: "goto_split:left", menuItem: goToLeftItem)
109+
110+
await manager.updateShortcut(in: menu, config: config)
111+
112+
#expect(hideItem.keyEquivalent == "h")
113+
#expect(hideItem.keyEquivalentModifierMask == .command)
103114
}
104115
}

0 commit comments

Comments
 (0)