mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-06 07:38:21 +00:00
macos: rename to TabTitleEditor
This commit is contained in:
@@ -190,6 +190,7 @@
|
||||
Helpers/Private/CGS.swift,
|
||||
Helpers/Private/Dock.swift,
|
||||
Helpers/TabGroupCloseCoordinator.swift,
|
||||
Helpers/TabTitleEditor.swift,
|
||||
Helpers/VibrantLayer.m,
|
||||
Helpers/Weak.swift,
|
||||
);
|
||||
|
||||
@@ -37,8 +37,8 @@ class TerminalWindow: NSWindow {
|
||||
/// Sets up our tab context menu
|
||||
private var tabMenuObserver: NSObjectProtocol?
|
||||
|
||||
/// Coordinates inline tab title editing for this host window.
|
||||
private lazy var inlineTabTitleEditingCoordinator = InlineTabTitleEditingCoordinator(
|
||||
/// Handles inline tab title editing for this host window.
|
||||
private lazy var tabTitleEditor = TabTitleEditor(
|
||||
hostWindow: self,
|
||||
delegate: self
|
||||
)
|
||||
@@ -181,7 +181,7 @@ class TerminalWindow: NSWindow {
|
||||
override var canBecomeMain: Bool { return true }
|
||||
|
||||
override func sendEvent(_ event: NSEvent) {
|
||||
if inlineTabTitleEditingCoordinator.handleDoubleClick(event) {
|
||||
if tabTitleEditor.handleDoubleClick(event) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ class TerminalWindow: NSWindow {
|
||||
}
|
||||
|
||||
override func close() {
|
||||
inlineTabTitleEditingCoordinator.finishEditing(commit: true)
|
||||
tabTitleEditor.finishEditing(commit: true)
|
||||
NotificationCenter.default.post(name: Self.terminalWillCloseNotification, object: self)
|
||||
super.close()
|
||||
}
|
||||
@@ -224,7 +224,7 @@ class TerminalWindow: NSWindow {
|
||||
|
||||
@discardableResult
|
||||
func beginInlineTabTitleEdit(for targetWindow: NSWindow) -> Bool {
|
||||
inlineTabTitleEditingCoordinator.beginEditing(for: targetWindow)
|
||||
tabTitleEditor.beginEditing(for: targetWindow)
|
||||
}
|
||||
|
||||
@objc private func renameTabFromContextMenu(_ sender: NSMenuItem) {
|
||||
@@ -794,16 +794,16 @@ private func makeTabColorPaletteView(
|
||||
|
||||
// MARK: - Inline Tab Title Editing
|
||||
|
||||
extension TerminalWindow: InlineTabTitleEditingCoordinatorDelegate {
|
||||
func inlineTabTitleEditingCoordinator(
|
||||
_ coordinator: InlineTabTitleEditingCoordinator,
|
||||
extension TerminalWindow: TabTitleEditorDelegate {
|
||||
func tabTitleEditor(
|
||||
_ editor: TabTitleEditor,
|
||||
canRenameTabFor targetWindow: NSWindow
|
||||
) -> Bool {
|
||||
targetWindow.windowController is BaseTerminalController
|
||||
}
|
||||
|
||||
func inlineTabTitleEditingCoordinator(
|
||||
_ coordinator: InlineTabTitleEditingCoordinator,
|
||||
func tabTitleEditor(
|
||||
_ editor: TabTitleEditor,
|
||||
titleFor targetWindow: NSWindow
|
||||
) -> String {
|
||||
guard let targetController = targetWindow.windowController as? BaseTerminalController else {
|
||||
@@ -813,8 +813,8 @@ extension TerminalWindow: InlineTabTitleEditingCoordinatorDelegate {
|
||||
return targetController.titleOverride ?? targetWindow.title
|
||||
}
|
||||
|
||||
func inlineTabTitleEditingCoordinator(
|
||||
_ coordinator: InlineTabTitleEditingCoordinator,
|
||||
func tabTitleEditor(
|
||||
_ editor: TabTitleEditor,
|
||||
didCommitTitle editedTitle: String,
|
||||
for targetWindow: NSWindow
|
||||
) {
|
||||
@@ -822,8 +822,8 @@ extension TerminalWindow: InlineTabTitleEditingCoordinatorDelegate {
|
||||
targetController.titleOverride = editedTitle.isEmpty ? nil : editedTitle
|
||||
}
|
||||
|
||||
func inlineTabTitleEditingCoordinator(
|
||||
_ coordinator: InlineTabTitleEditingCoordinator,
|
||||
func tabTitleEditor(
|
||||
_ editor: TabTitleEditor,
|
||||
performFallbackRenameFor targetWindow: NSWindow
|
||||
) {
|
||||
guard let targetController = targetWindow.windowController as? BaseTerminalController else { return }
|
||||
|
||||
@@ -1,39 +1,39 @@
|
||||
import AppKit
|
||||
|
||||
/// Delegate used by ``InlineTabTitleEditingCoordinator`` to resolve tab-specific behavior.
|
||||
protocol InlineTabTitleEditingCoordinatorDelegate: AnyObject {
|
||||
/// Delegate used by ``TabTitleEditor`` to resolve tab-specific behavior.
|
||||
protocol TabTitleEditorDelegate: AnyObject {
|
||||
/// Returns whether inline rename should be allowed for the given tab window.
|
||||
func inlineTabTitleEditingCoordinator(
|
||||
_ coordinator: InlineTabTitleEditingCoordinator,
|
||||
func tabTitleEditor(
|
||||
_ editor: TabTitleEditor,
|
||||
canRenameTabFor targetWindow: NSWindow
|
||||
) -> Bool
|
||||
|
||||
/// Returns the current title value to seed into the inline editor.
|
||||
func inlineTabTitleEditingCoordinator(
|
||||
_ coordinator: InlineTabTitleEditingCoordinator,
|
||||
func tabTitleEditor(
|
||||
_ editor: TabTitleEditor,
|
||||
titleFor targetWindow: NSWindow
|
||||
) -> String
|
||||
|
||||
/// Called when inline editing commits a title for a target tab window.
|
||||
func inlineTabTitleEditingCoordinator(
|
||||
_ coordinator: InlineTabTitleEditingCoordinator,
|
||||
func tabTitleEditor(
|
||||
_ editor: TabTitleEditor,
|
||||
didCommitTitle editedTitle: String,
|
||||
for targetWindow: NSWindow
|
||||
)
|
||||
|
||||
/// Called when inline editing could not start and the host should show a fallback flow.
|
||||
func inlineTabTitleEditingCoordinator(
|
||||
_ coordinator: InlineTabTitleEditingCoordinator,
|
||||
func tabTitleEditor(
|
||||
_ editor: TabTitleEditor,
|
||||
performFallbackRenameFor targetWindow: NSWindow
|
||||
)
|
||||
}
|
||||
|
||||
/// Handles inline tab title editing for native AppKit window tabs.
|
||||
final class InlineTabTitleEditingCoordinator: NSObject, NSTextFieldDelegate {
|
||||
final class TabTitleEditor: NSObject, NSTextFieldDelegate {
|
||||
/// Host window containing the tab bar where editing occurs.
|
||||
private weak var hostWindow: NSWindow?
|
||||
/// Delegate that provides and commits title data for target tab windows.
|
||||
private weak var delegate: InlineTabTitleEditingCoordinatorDelegate?
|
||||
private weak var delegate: TabTitleEditorDelegate?
|
||||
|
||||
/// Active inline editor view, if editing is in progress.
|
||||
private weak var inlineTitleEditor: NSTextField?
|
||||
@@ -47,7 +47,7 @@ final class InlineTabTitleEditingCoordinator: NSObject, NSTextFieldDelegate {
|
||||
private var pendingEditWorkItem: DispatchWorkItem?
|
||||
|
||||
/// Creates a coordinator bound to a host window and rename delegate.
|
||||
init(hostWindow: NSWindow, delegate: InlineTabTitleEditingCoordinatorDelegate) {
|
||||
init(hostWindow: NSWindow, delegate: TabTitleEditorDelegate) {
|
||||
self.hostWindow = hostWindow
|
||||
self.delegate = delegate
|
||||
}
|
||||
@@ -57,7 +57,7 @@ final class InlineTabTitleEditingCoordinator: NSObject, NSTextFieldDelegate {
|
||||
func handleDoubleClick(_ event: NSEvent) -> Bool {
|
||||
// We only want double-clicks
|
||||
guard event.type == .leftMouseDown, event.clickCount == 2 else { return false }
|
||||
|
||||
|
||||
// If we don't have a host window to look up the click, we do nothing.
|
||||
guard let hostWindow else { return false }
|
||||
|
||||
@@ -65,7 +65,7 @@ final class InlineTabTitleEditingCoordinator: NSObject, NSTextFieldDelegate {
|
||||
let locationInScreen = hostWindow.convertPoint(toScreen: event.locationInWindow)
|
||||
guard let tabIndex = hostWindow.tabIndex(atScreenPoint: locationInScreen),
|
||||
let targetWindow = hostWindow.tabbedWindows?[safe: tabIndex],
|
||||
delegate?.inlineTabTitleEditingCoordinator(self, canRenameTabFor: targetWindow) == true
|
||||
delegate?.tabTitleEditor(self, canRenameTabFor: targetWindow) == true
|
||||
else { return false }
|
||||
|
||||
// We need to start editing in a separate event loop tick, so set that up.
|
||||
@@ -77,7 +77,7 @@ final class InlineTabTitleEditingCoordinator: NSObject, NSTextFieldDelegate {
|
||||
}
|
||||
|
||||
// Inline editing failed, so trigger fallback rename whatever it is.
|
||||
self.delegate?.inlineTabTitleEditingCoordinator(self, performFallbackRenameFor: targetWindow)
|
||||
self.delegate?.tabTitleEditor(self, performFallbackRenameFor: targetWindow)
|
||||
}
|
||||
|
||||
pendingEditWorkItem = workItem
|
||||
@@ -95,7 +95,7 @@ final class InlineTabTitleEditingCoordinator: NSObject, NSTextFieldDelegate {
|
||||
let tabbedWindows = hostWindow.tabbedWindows,
|
||||
let tabIndex = tabbedWindows.firstIndex(of: targetWindow),
|
||||
let tabButton = hostWindow.tabButtonsInVisualOrder()[safe: tabIndex],
|
||||
delegate?.inlineTabTitleEditingCoordinator(self, canRenameTabFor: targetWindow) == true
|
||||
delegate?.tabTitleEditor(self, canRenameTabFor: targetWindow) == true
|
||||
else { return false }
|
||||
|
||||
// If we have a pending edit, we need to cancel it because we got
|
||||
@@ -108,7 +108,7 @@ final class InlineTabTitleEditingCoordinator: NSObject, NSTextFieldDelegate {
|
||||
let titleLabels = tabButton
|
||||
.descendants(withClassName: "NSTextField")
|
||||
.compactMap { $0 as? NSTextField }
|
||||
let editedTitle = delegate?.inlineTabTitleEditingCoordinator(self, titleFor: targetWindow) ?? targetWindow.title
|
||||
let editedTitle = delegate?.tabTitleEditor(self, titleFor: targetWindow) ?? targetWindow.title
|
||||
let sourceLabel = sourceTabTitleLabel(from: titleLabels, matching: editedTitle)
|
||||
let editorFrame = tabTitleEditorFrame(for: tabButton, sourceLabel: sourceLabel)
|
||||
guard editorFrame.width >= 20, editorFrame.height >= 14 else { return false }
|
||||
@@ -215,7 +215,7 @@ final class InlineTabTitleEditingCoordinator: NSObject, NSTextFieldDelegate {
|
||||
|
||||
// Delegate owns title persistence semantics (including empty-title handling).
|
||||
guard commit, let targetWindow else { return }
|
||||
delegate?.inlineTabTitleEditingCoordinator(self, didCommitTitle: editedTitle, for: targetWindow)
|
||||
delegate?.tabTitleEditor(self, didCommitTitle: editedTitle, for: targetWindow)
|
||||
}
|
||||
|
||||
/// Chooses an editor frame that aligns with the tab title within the tab button.
|
||||
Reference in New Issue
Block a user