mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-09-05 19:08:17 +00:00
macos: menu item symbols for Tahoe
This is recommended for macOS Tahoe and all standard menu items now have associated images. This makes our app look more polished and native for macOS Tahoe. For icon choice, I tried to copy other native macOS apps as much as possible, mostly from Xcode. It looks like a lot of apps aren't updated yet. I'm absolutely open to suggestions for better icons but I think these are a good starting point. One menu change is I moved "reset font size" above "increase font size" which better matches other apps (e.g. Terminal.app).
This commit is contained in:
@@ -93,6 +93,7 @@
|
||||
A5A6F72A2CC41B8900B232A5 /* AppInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A6F7292CC41B8700B232A5 /* AppInfo.swift */; };
|
||||
A5AEB1652D5BE7D000513529 /* LastWindowPosition.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5AEB1642D5BE7BF00513529 /* LastWindowPosition.swift */; };
|
||||
A5B30539299BEAAB0047F10C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A5B30538299BEAAB0047F10C /* Assets.xcassets */; };
|
||||
A5B4EA852DFE691B0022C3A2 /* NSMenuItem+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5B4EA842DFE69140022C3A2 /* NSMenuItem+Extension.swift */; };
|
||||
A5CA378C2D2A4DEB00931030 /* KeyboardLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CA378B2D2A4DE800931030 /* KeyboardLayout.swift */; };
|
||||
A5CA378E2D31D6C300931030 /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CA378D2D31D6C100931030 /* Weak.swift */; };
|
||||
A5CBD0562C9E65B80017A1AE /* DraggableWindowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CBD0552C9E65A50017A1AE /* DraggableWindowView.swift */; };
|
||||
@@ -210,6 +211,7 @@
|
||||
A5B30531299BEAAA0047F10C /* Ghostty.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Ghostty.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A5B30538299BEAAB0047F10C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
A5B3053D299BEAAB0047F10C /* Ghostty.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Ghostty.entitlements; sourceTree = "<group>"; };
|
||||
A5B4EA842DFE69140022C3A2 /* NSMenuItem+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSMenuItem+Extension.swift"; sourceTree = "<group>"; };
|
||||
A5CA378B2D2A4DE800931030 /* KeyboardLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardLayout.swift; sourceTree = "<group>"; };
|
||||
A5CA378D2D31D6C100931030 /* Weak.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Weak.swift; sourceTree = "<group>"; };
|
||||
A5CBD0552C9E65A50017A1AE /* DraggableWindowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraggableWindowView.swift; sourceTree = "<group>"; };
|
||||
@@ -478,6 +480,7 @@
|
||||
A599CDAF2CF103F20049FA26 /* NSAppearance+Extension.swift */,
|
||||
A5A2A3CB2D444AB80033CF96 /* NSApplication+Extension.swift */,
|
||||
A54B0CEA2D0CFB4A00CBEFF8 /* NSImage+Extension.swift */,
|
||||
A5B4EA842DFE69140022C3A2 /* NSMenuItem+Extension.swift */,
|
||||
A52FFF5C2CAB4D05000C6A5B /* NSScreen+Extension.swift */,
|
||||
AEE8B3442B9AA39600260C5E /* NSPasteboard+Extension.swift */,
|
||||
C1F26EA62B738B9900404083 /* NSView+Extension.swift */,
|
||||
@@ -763,6 +766,7 @@
|
||||
A5CDF1952AAFA19600513312 /* ConfigurationErrorsView.swift in Sources */,
|
||||
A55B7BBC29B6FC330055DE60 /* SurfaceView.swift in Sources */,
|
||||
A5333E1C2B5A1CE3008AEFF7 /* CrossKit.swift in Sources */,
|
||||
A5B4EA852DFE691B0022C3A2 /* NSMenuItem+Extension.swift in Sources */,
|
||||
A5874D992DAD751B00E83852 /* CGS.swift in Sources */,
|
||||
A586366B2DF0A98C00E04A10 /* Array+Extension.swift in Sources */,
|
||||
A51544FE2DFB111C009E85D8 /* TitlebarTabsTahoeTerminalWindow.swift in Sources */,
|
||||
|
@@ -166,7 +166,7 @@ class AppDelegate: NSObject,
|
||||
|
||||
// This registers the Ghostty => Services menu to exist.
|
||||
NSApp.servicesMenu = menuServices
|
||||
|
||||
|
||||
// Setup a local event monitor for app-level keyboard shortcuts. See
|
||||
// localEventHandler for more info why.
|
||||
_ = NSEvent.addLocalMonitorForEvents(
|
||||
@@ -242,6 +242,9 @@ class AppDelegate: NSObject,
|
||||
|
||||
ghostty_app_set_color_scheme(app, scheme)
|
||||
}
|
||||
|
||||
// Setup our menu
|
||||
setupMenuImages()
|
||||
}
|
||||
|
||||
func applicationDidBecomeActive(_ notification: Notification) {
|
||||
@@ -392,6 +395,41 @@ class AppDelegate: NSObject,
|
||||
return dockMenu
|
||||
}
|
||||
|
||||
/// Setup all the images for our menu items.
|
||||
private func setupMenuImages() {
|
||||
// Note: This COULD Be done all in the xib file, but I find it easier to
|
||||
// modify this stuff as code.
|
||||
self.menuNewWindow?.setImageIfDesired(systemSymbolName: "macwindow.badge.plus")
|
||||
self.menuNewTab?.setImageIfDesired(systemSymbolName: "macwindow")
|
||||
self.menuSplitRight?.setImageIfDesired(systemSymbolName: "rectangle.righthalf.inset.filled")
|
||||
self.menuSplitLeft?.setImageIfDesired(systemSymbolName: "rectangle.leadinghalf.inset.filled")
|
||||
self.menuSplitUp?.setImageIfDesired(systemSymbolName: "rectangle.tophalf.inset.filled")
|
||||
self.menuSplitDown?.setImageIfDesired(systemSymbolName: "rectangle.bottomhalf.inset.filled")
|
||||
self.menuClose?.setImageIfDesired(systemSymbolName: "xmark")
|
||||
self.menuIncreaseFontSize?.setImageIfDesired(systemSymbolName: "textformat.size.larger")
|
||||
self.menuResetFontSize?.setImageIfDesired(systemSymbolName: "textformat.size")
|
||||
self.menuDecreaseFontSize?.setImageIfDesired(systemSymbolName: "textformat.size.smaller")
|
||||
self.menuCommandPalette?.setImageIfDesired(systemSymbolName: "filemenu.and.selection")
|
||||
self.menuQuickTerminal?.setImageIfDesired(systemSymbolName: "apple.terminal")
|
||||
self.menuChangeTitle?.setImageIfDesired(systemSymbolName: "pencil.line")
|
||||
self.menuTerminalInspector?.setImageIfDesired(systemSymbolName: "scope")
|
||||
self.menuToggleFullScreen?.setImageIfDesired(systemSymbolName: "square.arrowtriangle.4.outward")
|
||||
self.menuToggleVisibility?.setImageIfDesired(systemSymbolName: "eye")
|
||||
self.menuZoomSplit?.setImageIfDesired(systemSymbolName: "arrow.up.left.and.arrow.down.right")
|
||||
self.menuPreviousSplit?.setImageIfDesired(systemSymbolName: "chevron.backward.2")
|
||||
self.menuNextSplit?.setImageIfDesired(systemSymbolName: "chevron.forward.2")
|
||||
self.menuEqualizeSplits?.setImageIfDesired(systemSymbolName: "inset.filled.topleft.topright.bottomleft.bottomright.rectangle")
|
||||
self.menuSelectSplitLeft?.setImageIfDesired(systemSymbolName: "arrow.left")
|
||||
self.menuSelectSplitRight?.setImageIfDesired(systemSymbolName: "arrow.right")
|
||||
self.menuSelectSplitAbove?.setImageIfDesired(systemSymbolName: "arrow.up")
|
||||
self.menuSelectSplitBelow?.setImageIfDesired(systemSymbolName: "arrow.down")
|
||||
self.menuMoveSplitDividerUp?.setImageIfDesired(systemSymbolName: "arrow.up.to.line")
|
||||
self.menuMoveSplitDividerDown?.setImageIfDesired(systemSymbolName: "arrow.down.to.line")
|
||||
self.menuMoveSplitDividerLeft?.setImageIfDesired(systemSymbolName: "arrow.left.to.line")
|
||||
self.menuMoveSplitDividerRight?.setImageIfDesired(systemSymbolName: "arrow.right.to.line")
|
||||
self.menuFloatOnTop?.setImageIfDesired(systemSymbolName: "square.3.layers.3d.top.filled")
|
||||
}
|
||||
|
||||
/// Sync all of our menu item keyboard shortcuts with the Ghostty configuration.
|
||||
private func syncMenuShortcuts(_ config: Ghostty.Config) {
|
||||
guard ghostty.readiness == .ready else { return }
|
||||
|
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23727" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24093.7" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23727"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24093.7"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
@@ -251,18 +251,18 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="View" id="m6z-2H-VW7">
|
||||
<items>
|
||||
<menuItem title="Increase Font Size" id="CIH-ey-Z6x" userLabel="Increase Font Size">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="increaseFontSize:" target="-1" id="361-5E-7PY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Reset Font Size" id="Jah-MY-aLX">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="resetFontSize:" target="-1" id="3dh-T9-IkH"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Increase Font Size" id="CIH-ey-Z6x" userLabel="Increase Font Size">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="increaseFontSize:" target="-1" id="361-5E-7PY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Decrease Font Size" id="kzb-SZ-dOA">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
|
@@ -1281,6 +1281,10 @@ extension Ghostty {
|
||||
|
||||
let menu = NSMenu()
|
||||
|
||||
// We just use a floating var so we can easily setup metadata on each item
|
||||
// in a row without storing it all.
|
||||
var item: NSMenuItem
|
||||
|
||||
// If we have a selection, add copy
|
||||
if self.selectedRange().length > 0 {
|
||||
menu.addItem(withTitle: "Copy", action: #selector(copy(_:)), keyEquivalent: "")
|
||||
@@ -1288,16 +1292,23 @@ extension Ghostty {
|
||||
menu.addItem(withTitle: "Paste", action: #selector(paste(_:)), keyEquivalent: "")
|
||||
|
||||
menu.addItem(.separator())
|
||||
menu.addItem(withTitle: "Split Right", action: #selector(splitRight(_:)), keyEquivalent: "")
|
||||
menu.addItem(withTitle: "Split Left", action: #selector(splitLeft(_:)), keyEquivalent: "")
|
||||
menu.addItem(withTitle: "Split Down", action: #selector(splitDown(_:)), keyEquivalent: "")
|
||||
menu.addItem(withTitle: "Split Up", action: #selector(splitUp(_:)), keyEquivalent: "")
|
||||
item = menu.addItem(withTitle: "Split Right", action: #selector(splitRight(_:)), keyEquivalent: "")
|
||||
item.setImageIfDesired(systemSymbolName: "rectangle.righthalf.inset.filled")
|
||||
item = menu.addItem(withTitle: "Split Left", action: #selector(splitLeft(_:)), keyEquivalent: "")
|
||||
item.setImageIfDesired(systemSymbolName: "rectangle.leadinghalf.inset.filled")
|
||||
item = menu.addItem(withTitle: "Split Down", action: #selector(splitDown(_:)), keyEquivalent: "")
|
||||
item.setImageIfDesired(systemSymbolName: "rectangle.bottomhalf.inset.filled")
|
||||
item = menu.addItem(withTitle: "Split Up", action: #selector(splitUp(_:)), keyEquivalent: "")
|
||||
item.setImageIfDesired(systemSymbolName: "rectangle.tophalf.inset.filled")
|
||||
|
||||
menu.addItem(.separator())
|
||||
menu.addItem(withTitle: "Reset Terminal", action: #selector(resetTerminal(_:)), keyEquivalent: "")
|
||||
menu.addItem(withTitle: "Toggle Terminal Inspector", action: #selector(toggleTerminalInspector(_:)), keyEquivalent: "")
|
||||
item = menu.addItem(withTitle: "Reset Terminal", action: #selector(resetTerminal(_:)), keyEquivalent: "")
|
||||
item.setImageIfDesired(systemSymbolName: "arrow.trianglehead.2.clockwise")
|
||||
item = menu.addItem(withTitle: "Toggle Terminal Inspector", action: #selector(toggleTerminalInspector(_:)), keyEquivalent: "")
|
||||
item.setImageIfDesired(systemSymbolName: "scope")
|
||||
menu.addItem(.separator())
|
||||
menu.addItem(withTitle: "Change Title...", action: #selector(changeTitle(_:)), keyEquivalent: "")
|
||||
item = menu.addItem(withTitle: "Change Title...", action: #selector(changeTitle(_:)), keyEquivalent: "")
|
||||
item.setImageIfDesired(systemSymbolName: "pencil.line")
|
||||
|
||||
return menu
|
||||
}
|
||||
|
11
macos/Sources/Helpers/Extensions/NSMenuItem+Extension.swift
Normal file
11
macos/Sources/Helpers/Extensions/NSMenuItem+Extension.swift
Normal file
@@ -0,0 +1,11 @@
|
||||
import AppKit
|
||||
|
||||
extension NSMenuItem {
|
||||
/// Sets the image property from a symbol if we want images on our menu items.
|
||||
func setImageIfDesired(systemSymbolName symbol: String) {
|
||||
// We only set on macOS 26 when icons on menu items became the norm.
|
||||
if #available(macOS 26, *) {
|
||||
image = NSImage(systemSymbolName: symbol, accessibilityDescription: title)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user