From 9b6a3be99339bcefcc49b7791b7b9761d24e6093 Mon Sep 17 00:00:00 2001 From: Aaron Ruan Date: Tue, 6 Jan 2026 22:15:19 +0800 Subject: [PATCH 1/5] macOS: Selection for Find feature Adds the `selection_for_search` action, with Cmd+E keybind by default. This action inputs the currently selected text into the search field without changing focus, matching standard macOS behavior. --- include/ghostty.h | 9 ++++- macos/Sources/App/macOS/AppDelegate.swift | 2 ++ macos/Sources/App/macOS/MainMenu.xib | 11 ++++-- .../Terminal/BaseTerminalController.swift | 6 +++- macos/Sources/Ghostty/Ghostty.Action.swift | 12 +++++++ macos/Sources/Ghostty/Ghostty.App.swift | 35 +++++++++++++++++++ macos/Sources/Ghostty/Package.swift | 1 + .../Ghostty/Surface View/SurfaceView.swift | 11 +++++- .../Surface View/SurfaceView_AppKit.swift | 8 +++++ src/Surface.zig | 9 +++++ src/apprt/action.zig | 19 ++++++++++ src/config/Config.zig | 6 ++++ src/input/Binding.zig | 4 +++ src/input/command.zig | 6 ++++ 14 files changed, 134 insertions(+), 5 deletions(-) diff --git a/include/ghostty.h b/include/ghostty.h index 0ad15cf69..726b368e7 100644 --- a/include/ghostty.h +++ b/include/ghostty.h @@ -810,6 +810,11 @@ typedef struct { ssize_t selected; } ghostty_action_search_selected_s; +// apprt.action.SelectionForSearch +typedef struct { + const char* text; +} ghostty_action_selection_for_search_s; + // terminal.Scrollbar typedef struct { uint64_t total; @@ -878,11 +883,12 @@ typedef enum { GHOSTTY_ACTION_SHOW_ON_SCREEN_KEYBOARD, GHOSTTY_ACTION_COMMAND_FINISHED, GHOSTTY_ACTION_START_SEARCH, + GHOSTTY_ACTION_SELECTION_FOR_SEARCH, GHOSTTY_ACTION_END_SEARCH, GHOSTTY_ACTION_SEARCH_TOTAL, GHOSTTY_ACTION_SEARCH_SELECTED, GHOSTTY_ACTION_READONLY, - } ghostty_action_tag_e; +} ghostty_action_tag_e; typedef union { ghostty_action_split_direction_e new_split; @@ -919,6 +925,7 @@ typedef union { ghostty_action_progress_report_s progress_report; ghostty_action_command_finished_s command_finished; ghostty_action_start_search_s start_search; + ghostty_action_selection_for_search_s selection_for_search; ghostty_action_search_total_s search_total; ghostty_action_search_selected_s search_selected; ghostty_action_readonly_e readonly; diff --git a/macos/Sources/App/macOS/AppDelegate.swift b/macos/Sources/App/macOS/AppDelegate.swift index 57bfba828..c365fb935 100644 --- a/macos/Sources/App/macOS/AppDelegate.swift +++ b/macos/Sources/App/macOS/AppDelegate.swift @@ -46,6 +46,7 @@ class AppDelegate: NSObject, @IBOutlet private var menuSelectAll: NSMenuItem? @IBOutlet private var menuFindParent: NSMenuItem? @IBOutlet private var menuFind: NSMenuItem? + @IBOutlet private var menuSelectionForFind: NSMenuItem? @IBOutlet private var menuFindNext: NSMenuItem? @IBOutlet private var menuFindPrevious: NSMenuItem? @IBOutlet private var menuHideFindBar: NSMenuItem? @@ -615,6 +616,7 @@ class AppDelegate: NSObject, syncMenuShortcut(config, action: "paste_from_selection", menuItem: self.menuPasteSelection) syncMenuShortcut(config, action: "select_all", menuItem: self.menuSelectAll) syncMenuShortcut(config, action: "start_search", menuItem: self.menuFind) + syncMenuShortcut(config, action: "selection_for_search", menuItem: self.menuSelectionForFind) syncMenuShortcut(config, action: "search:next", menuItem: self.menuFindNext) syncMenuShortcut(config, action: "search:previous", menuItem: self.menuFindPrevious) diff --git a/macos/Sources/App/macOS/MainMenu.xib b/macos/Sources/App/macOS/MainMenu.xib index a321061dd..248063f89 100644 --- a/macos/Sources/App/macOS/MainMenu.xib +++ b/macos/Sources/App/macOS/MainMenu.xib @@ -1,8 +1,8 @@ - + - + @@ -58,6 +58,7 @@ + @@ -262,6 +263,12 @@ + + + + + + diff --git a/macos/Sources/Features/Terminal/BaseTerminalController.swift b/macos/Sources/Features/Terminal/BaseTerminalController.swift index fb86ce8f7..a4e0da7ee 100644 --- a/macos/Sources/Features/Terminal/BaseTerminalController.swift +++ b/macos/Sources/Features/Terminal/BaseTerminalController.swift @@ -1383,7 +1383,11 @@ class BaseTerminalController: NSWindowController, @IBAction func find(_ sender: Any) { focusedSurface?.find(sender) } - + + @IBAction func selectionForFind(_ sender: Any) { + focusedSurface?.selectionForFind(sender) + } + @IBAction func findNext(_ sender: Any) { focusedSurface?.findNext(sender) } diff --git a/macos/Sources/Ghostty/Ghostty.Action.swift b/macos/Sources/Ghostty/Ghostty.Action.swift index 91f1491dd..c04c7d958 100644 --- a/macos/Sources/Ghostty/Ghostty.Action.swift +++ b/macos/Sources/Ghostty/Ghostty.Action.swift @@ -128,6 +128,18 @@ extension Ghostty.Action { } } + struct SelectionForSearch { + let text: String? + + init(c: ghostty_action_selection_for_search_s) { + if let contentCString = c.text { + self.text = String(cString: contentCString) + } else { + self.text = nil + } + } + } + enum PromptTitle { case surface case tab diff --git a/macos/Sources/Ghostty/Ghostty.App.swift b/macos/Sources/Ghostty/Ghostty.App.swift index 4e9166168..69788c194 100644 --- a/macos/Sources/Ghostty/Ghostty.App.swift +++ b/macos/Sources/Ghostty/Ghostty.App.swift @@ -621,6 +621,9 @@ extension Ghostty { case GHOSTTY_ACTION_START_SEARCH: startSearch(app, target: target, v: action.action.start_search) + case GHOSTTY_ACTION_SELECTION_FOR_SEARCH: + selectionForSearch(app, target: target, v: action.action.selection_for_search) + case GHOSTTY_ACTION_END_SEARCH: endSearch(app, target: target) @@ -1881,6 +1884,38 @@ extension Ghostty { } } + private static func selectionForSearch( + _ app: ghostty_app_t, + target: ghostty_target_s, + v: ghostty_action_selection_for_search_s + ) { + switch (target.tag) { + case GHOSTTY_TARGET_APP: + Ghostty.logger.warning("selection_for_search does nothing with an app target") + return + + case GHOSTTY_TARGET_SURFACE: + guard let surface = target.target.surface else { return } + guard let surfaceView = self.surfaceView(from: surface) else { return } + + let selectionForSearch = Ghostty.Action.SelectionForSearch(c: v) + DispatchQueue.main.async { + if surfaceView.searchState != nil, let text = selectionForSearch.text { + NotificationCenter.default.post( + name: .ghosttySelectionForSearch, + object: surfaceView, + userInfo: [ + "text": text + ] + ) + } + } + + default: + assertionFailure() + } + } + private static func endSearch( _ app: ghostty_app_t, target: ghostty_target_s) { diff --git a/macos/Sources/Ghostty/Package.swift b/macos/Sources/Ghostty/Package.swift index aa62c16f7..dbe9c173b 100644 --- a/macos/Sources/Ghostty/Package.swift +++ b/macos/Sources/Ghostty/Package.swift @@ -406,6 +406,7 @@ extension Notification.Name { /// Focus the search field static let ghosttySearchFocus = Notification.Name("com.mitchellh.ghostty.searchFocus") + static let ghosttySelectionForSearch = Notification.Name("com.mitchellh.ghostty.selectionForSearch") } // NOTE: I am moving all of these to Notification.Name extensions over time. This diff --git a/macos/Sources/Ghostty/Surface View/SurfaceView.swift b/macos/Sources/Ghostty/Surface View/SurfaceView.swift index c224d373e..b3717d4c5 100644 --- a/macos/Sources/Ghostty/Surface View/SurfaceView.swift +++ b/macos/Sources/Ghostty/Surface View/SurfaceView.swift @@ -475,7 +475,16 @@ extension Ghostty { } .onReceive(NotificationCenter.default.publisher(for: .ghosttySearchFocus)) { notification in guard notification.object as? SurfaceView === surfaceView else { return } - isSearchFieldFocused = true + DispatchQueue.main.async { + isSearchFieldFocused = true + } + } + .onReceive(NotificationCenter.default.publisher(for: .ghosttySelectionForSearch)) { notification in + guard notification.object as? SurfaceView === surfaceView else { return } + if let userInfo = notification.userInfo, let text = userInfo["text"] as? String { + searchState.needle = text + // We do not focus the textfield after the action to match macOS behavior + } } .background( GeometryReader { barGeo in diff --git a/macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift b/macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift index 7f33df45a..1fc43ac82 100644 --- a/macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift +++ b/macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift @@ -1519,6 +1519,14 @@ extension Ghostty { } } + @IBAction func selectionForFind(_ sender: Any?) { + guard let surface = self.surface else { return } + let action = "selection_for_search" + if (!ghostty_surface_binding_action(surface, action, UInt(action.lengthOfBytes(using: .utf8)))) { + AppDelegate.logger.warning("action failed action=\(action)") + } + } + @IBAction func findNext(_ sender: Any?) { guard let surface = self.surface else { return } let action = "search:next" diff --git a/src/Surface.zig b/src/Surface.zig index 43ee440c2..68cf46045 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -5163,6 +5163,15 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool ); }, + .selection_for_search => { + const selection = try self.selectionString(self.alloc) orelse return false; + return try self.rt_app.performAction( + .{ .surface = self }, + .selection_for_search, + .{ .text = selection }, + ); + }, + .end_search => { // We only return that this was performed if we actually // stopped a search, but we also send the apprt end_search so diff --git a/src/apprt/action.zig b/src/apprt/action.zig index 25fc6f08a..7fdaabf08 100644 --- a/src/apprt/action.zig +++ b/src/apprt/action.zig @@ -316,6 +316,9 @@ pub const Action = union(Key) { /// Start the search overlay with an optional initial needle. start_search: StartSearch, + /// Input the selected text into the search field. + selection_for_search: SelectionForSearch, + /// End the search overlay, clearing the search state and hiding it. end_search, @@ -389,6 +392,7 @@ pub const Action = union(Key) { show_on_screen_keyboard, command_finished, start_search, + selection_for_search, end_search, search_total, search_selected, @@ -914,3 +918,18 @@ pub const SearchSelected = struct { }; } }; + +pub const SelectionForSearch = struct { + text: [:0]const u8, + + // Sync with: ghostty_action_selection_for_search_s + pub const C = extern struct { + text: [*:0]const u8, + }; + + pub fn cval(self: SelectionForSearch) C { + return .{ + .text = self.text.ptr, + }; + } +}; diff --git a/src/config/Config.zig b/src/config/Config.zig index 88f3d5375..698831ec1 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -6585,6 +6585,12 @@ pub const Keybinds = struct { .start_search, .{ .performable = true }, ); + try self.set.putFlags( + alloc, + .{ .key = .{ .unicode = 'e' }, .mods = .{ .super = true } }, + .selection_for_search, + .{ .performable = true }, + ); try self.set.putFlags( alloc, .{ .key = .{ .unicode = 'f' }, .mods = .{ .super = true, .shift = true } }, diff --git a/src/input/Binding.zig b/src/input/Binding.zig index d5b24c61b..0ef5208bc 100644 --- a/src/input/Binding.zig +++ b/src/input/Binding.zig @@ -368,6 +368,9 @@ pub const Action = union(enum) { /// If a previous search is active, it is replaced. search: []const u8, + /// Input the selected text into the search field. + selection_for_search, + /// Navigate the search results. If there is no active search, this /// is not performed. navigate_search: NavigateSearch, @@ -1284,6 +1287,7 @@ pub const Action = union(enum) { .cursor_key, .search, .navigate_search, + .selection_for_search, .start_search, .end_search, .reset, diff --git a/src/input/command.zig b/src/input/command.zig index f089112db..3fc7b29f6 100644 --- a/src/input/command.zig +++ b/src/input/command.zig @@ -189,6 +189,12 @@ fn actionCommands(action: Action.Key) []const Command { .description = "Start a search if one isn't already active.", }}, + .selection_for_search => comptime &.{.{ + .action = .selection_for_search, + .title = "Selection for Search", + .description = "Input the selected text into the search field.", + }}, + .end_search => comptime &.{.{ .action = .end_search, .title = "End Search", From 8e28f58b428d8062ea70cb139793480bb1796d78 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 6 Jan 2026 14:08:34 -0800 Subject: [PATCH 2/5] rename the selection search binding, unify into start_search action --- include/ghostty.h | 7 ---- macos/Sources/App/macOS/AppDelegate.swift | 2 +- macos/Sources/Ghostty/Ghostty.Action.swift | 12 ------- macos/Sources/Ghostty/Ghostty.App.swift | 35 ------------------- .../Surface View/SurfaceView_AppKit.swift | 2 +- src/Surface.zig | 6 ++-- src/apprt/action.zig | 17 --------- src/config/Config.zig | 2 +- src/input/Binding.zig | 8 +++-- src/input/command.zig | 8 ++--- 10 files changed, 15 insertions(+), 84 deletions(-) diff --git a/include/ghostty.h b/include/ghostty.h index 726b368e7..5fc3a7433 100644 --- a/include/ghostty.h +++ b/include/ghostty.h @@ -810,11 +810,6 @@ typedef struct { ssize_t selected; } ghostty_action_search_selected_s; -// apprt.action.SelectionForSearch -typedef struct { - const char* text; -} ghostty_action_selection_for_search_s; - // terminal.Scrollbar typedef struct { uint64_t total; @@ -883,7 +878,6 @@ typedef enum { GHOSTTY_ACTION_SHOW_ON_SCREEN_KEYBOARD, GHOSTTY_ACTION_COMMAND_FINISHED, GHOSTTY_ACTION_START_SEARCH, - GHOSTTY_ACTION_SELECTION_FOR_SEARCH, GHOSTTY_ACTION_END_SEARCH, GHOSTTY_ACTION_SEARCH_TOTAL, GHOSTTY_ACTION_SEARCH_SELECTED, @@ -925,7 +919,6 @@ typedef union { ghostty_action_progress_report_s progress_report; ghostty_action_command_finished_s command_finished; ghostty_action_start_search_s start_search; - ghostty_action_selection_for_search_s selection_for_search; ghostty_action_search_total_s search_total; ghostty_action_search_selected_s search_selected; ghostty_action_readonly_e readonly; diff --git a/macos/Sources/App/macOS/AppDelegate.swift b/macos/Sources/App/macOS/AppDelegate.swift index c365fb935..c0886607c 100644 --- a/macos/Sources/App/macOS/AppDelegate.swift +++ b/macos/Sources/App/macOS/AppDelegate.swift @@ -616,7 +616,7 @@ class AppDelegate: NSObject, syncMenuShortcut(config, action: "paste_from_selection", menuItem: self.menuPasteSelection) syncMenuShortcut(config, action: "select_all", menuItem: self.menuSelectAll) syncMenuShortcut(config, action: "start_search", menuItem: self.menuFind) - syncMenuShortcut(config, action: "selection_for_search", menuItem: self.menuSelectionForFind) + syncMenuShortcut(config, action: "search_selection", menuItem: self.menuSelectionForFind) syncMenuShortcut(config, action: "search:next", menuItem: self.menuFindNext) syncMenuShortcut(config, action: "search:previous", menuItem: self.menuFindPrevious) diff --git a/macos/Sources/Ghostty/Ghostty.Action.swift b/macos/Sources/Ghostty/Ghostty.Action.swift index c04c7d958..91f1491dd 100644 --- a/macos/Sources/Ghostty/Ghostty.Action.swift +++ b/macos/Sources/Ghostty/Ghostty.Action.swift @@ -128,18 +128,6 @@ extension Ghostty.Action { } } - struct SelectionForSearch { - let text: String? - - init(c: ghostty_action_selection_for_search_s) { - if let contentCString = c.text { - self.text = String(cString: contentCString) - } else { - self.text = nil - } - } - } - enum PromptTitle { case surface case tab diff --git a/macos/Sources/Ghostty/Ghostty.App.swift b/macos/Sources/Ghostty/Ghostty.App.swift index 69788c194..4e9166168 100644 --- a/macos/Sources/Ghostty/Ghostty.App.swift +++ b/macos/Sources/Ghostty/Ghostty.App.swift @@ -621,9 +621,6 @@ extension Ghostty { case GHOSTTY_ACTION_START_SEARCH: startSearch(app, target: target, v: action.action.start_search) - case GHOSTTY_ACTION_SELECTION_FOR_SEARCH: - selectionForSearch(app, target: target, v: action.action.selection_for_search) - case GHOSTTY_ACTION_END_SEARCH: endSearch(app, target: target) @@ -1884,38 +1881,6 @@ extension Ghostty { } } - private static func selectionForSearch( - _ app: ghostty_app_t, - target: ghostty_target_s, - v: ghostty_action_selection_for_search_s - ) { - switch (target.tag) { - case GHOSTTY_TARGET_APP: - Ghostty.logger.warning("selection_for_search does nothing with an app target") - return - - case GHOSTTY_TARGET_SURFACE: - guard let surface = target.target.surface else { return } - guard let surfaceView = self.surfaceView(from: surface) else { return } - - let selectionForSearch = Ghostty.Action.SelectionForSearch(c: v) - DispatchQueue.main.async { - if surfaceView.searchState != nil, let text = selectionForSearch.text { - NotificationCenter.default.post( - name: .ghosttySelectionForSearch, - object: surfaceView, - userInfo: [ - "text": text - ] - ) - } - } - - default: - assertionFailure() - } - } - private static func endSearch( _ app: ghostty_app_t, target: ghostty_target_s) { diff --git a/macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift b/macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift index 1fc43ac82..a5ba62571 100644 --- a/macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift +++ b/macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift @@ -1521,7 +1521,7 @@ extension Ghostty { @IBAction func selectionForFind(_ sender: Any?) { guard let surface = self.surface else { return } - let action = "selection_for_search" + let action = "search_selection" if (!ghostty_surface_binding_action(surface, action, UInt(action.lengthOfBytes(using: .utf8)))) { AppDelegate.logger.warning("action failed action=\(action)") } diff --git a/src/Surface.zig b/src/Surface.zig index 68cf46045..1f3e4da8b 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -5163,12 +5163,12 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool ); }, - .selection_for_search => { + .search_selection => { const selection = try self.selectionString(self.alloc) orelse return false; return try self.rt_app.performAction( .{ .surface = self }, - .selection_for_search, - .{ .text = selection }, + .start_search, + .{ .needle = selection }, ); }, diff --git a/src/apprt/action.zig b/src/apprt/action.zig index 7fdaabf08..f00ab16ef 100644 --- a/src/apprt/action.zig +++ b/src/apprt/action.zig @@ -316,9 +316,6 @@ pub const Action = union(Key) { /// Start the search overlay with an optional initial needle. start_search: StartSearch, - /// Input the selected text into the search field. - selection_for_search: SelectionForSearch, - /// End the search overlay, clearing the search state and hiding it. end_search, @@ -392,7 +389,6 @@ pub const Action = union(Key) { show_on_screen_keyboard, command_finished, start_search, - selection_for_search, end_search, search_total, search_selected, @@ -919,17 +915,4 @@ pub const SearchSelected = struct { } }; -pub const SelectionForSearch = struct { - text: [:0]const u8, - // Sync with: ghostty_action_selection_for_search_s - pub const C = extern struct { - text: [*:0]const u8, - }; - - pub fn cval(self: SelectionForSearch) C { - return .{ - .text = self.text.ptr, - }; - } -}; diff --git a/src/config/Config.zig b/src/config/Config.zig index 698831ec1..ef6132912 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -6588,7 +6588,7 @@ pub const Keybinds = struct { try self.set.putFlags( alloc, .{ .key = .{ .unicode = 'e' }, .mods = .{ .super = true } }, - .selection_for_search, + .search_selection, .{ .performable = true }, ); try self.set.putFlags( diff --git a/src/input/Binding.zig b/src/input/Binding.zig index 0ef5208bc..08f5fdf7c 100644 --- a/src/input/Binding.zig +++ b/src/input/Binding.zig @@ -368,8 +368,10 @@ pub const Action = union(enum) { /// If a previous search is active, it is replaced. search: []const u8, - /// Input the selected text into the search field. - selection_for_search, + /// Start a search for the current text selection. If there is no + /// selection, this does nothing. If a search is already active, this + /// changes the search terms. + search_selection, /// Navigate the search results. If there is no active search, this /// is not performed. @@ -1287,7 +1289,7 @@ pub const Action = union(enum) { .cursor_key, .search, .navigate_search, - .selection_for_search, + .search_selection, .start_search, .end_search, .reset, diff --git a/src/input/command.zig b/src/input/command.zig index 3fc7b29f6..d6d2b0247 100644 --- a/src/input/command.zig +++ b/src/input/command.zig @@ -189,10 +189,10 @@ fn actionCommands(action: Action.Key) []const Command { .description = "Start a search if one isn't already active.", }}, - .selection_for_search => comptime &.{.{ - .action = .selection_for_search, - .title = "Selection for Search", - .description = "Input the selected text into the search field.", + .search_selection => comptime &.{.{ + .action = .search_selection, + .title = "Search Selection", + .description = "Start a search for the current text selection.", }}, .end_search => comptime &.{.{ From f07d600e43d10b67b596b2739440d2679a8754b9 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 6 Jan 2026 14:12:26 -0800 Subject: [PATCH 3/5] macos: start_search with needle changes needle --- macos/Sources/Ghostty/Ghostty.App.swift | 8 ++++++-- src/apprt/action.zig | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/macos/Sources/Ghostty/Ghostty.App.swift b/macos/Sources/Ghostty/Ghostty.App.swift index 4e9166168..959f78197 100644 --- a/macos/Sources/Ghostty/Ghostty.App.swift +++ b/macos/Sources/Ghostty/Ghostty.App.swift @@ -1869,11 +1869,15 @@ extension Ghostty { let startSearch = Ghostty.Action.StartSearch(c: v) DispatchQueue.main.async { - if surfaceView.searchState != nil { - NotificationCenter.default.post(name: .ghosttySearchFocus, object: surfaceView) + if let searchState = surfaceView.searchState { + if let needle = startSearch.needle, !needle.isEmpty { + searchState.needle = needle + } } else { surfaceView.searchState = Ghostty.SurfaceView.SearchState(from: startSearch) } + + NotificationCenter.default.post(name: .ghosttySearchFocus, object: surfaceView) } default: diff --git a/src/apprt/action.zig b/src/apprt/action.zig index f00ab16ef..4dd9d2994 100644 --- a/src/apprt/action.zig +++ b/src/apprt/action.zig @@ -313,7 +313,9 @@ pub const Action = union(Key) { /// A command has finished, command_finished: CommandFinished, - /// Start the search overlay with an optional initial needle. + /// Start the search overlay with an optional initial needle. If the + /// search is already active and the needle is non-empty, update the + /// current search needle and focus the search input. start_search: StartSearch, /// End the search overlay, clearing the search state and hiding it. From 05a41c77726bea3b3bb6271d60b006ad4ec02733 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 6 Jan 2026 14:20:30 -0800 Subject: [PATCH 4/5] macos: clean up menu --- macos/Sources/App/macOS/MainMenu.xib | 13 +++++++------ macos/Sources/Ghostty/Package.swift | 1 - .../Sources/Ghostty/Surface View/SurfaceView.swift | 7 ------- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/macos/Sources/App/macOS/MainMenu.xib b/macos/Sources/App/macOS/MainMenu.xib index 248063f89..aa9aca952 100644 --- a/macos/Sources/App/macOS/MainMenu.xib +++ b/macos/Sources/App/macOS/MainMenu.xib @@ -263,12 +263,6 @@ - - - - - - @@ -288,6 +282,13 @@ + + + + + + + diff --git a/macos/Sources/Ghostty/Package.swift b/macos/Sources/Ghostty/Package.swift index dbe9c173b..aa62c16f7 100644 --- a/macos/Sources/Ghostty/Package.swift +++ b/macos/Sources/Ghostty/Package.swift @@ -406,7 +406,6 @@ extension Notification.Name { /// Focus the search field static let ghosttySearchFocus = Notification.Name("com.mitchellh.ghostty.searchFocus") - static let ghosttySelectionForSearch = Notification.Name("com.mitchellh.ghostty.selectionForSearch") } // NOTE: I am moving all of these to Notification.Name extensions over time. This diff --git a/macos/Sources/Ghostty/Surface View/SurfaceView.swift b/macos/Sources/Ghostty/Surface View/SurfaceView.swift index b3717d4c5..5609f36b7 100644 --- a/macos/Sources/Ghostty/Surface View/SurfaceView.swift +++ b/macos/Sources/Ghostty/Surface View/SurfaceView.swift @@ -479,13 +479,6 @@ extension Ghostty { isSearchFieldFocused = true } } - .onReceive(NotificationCenter.default.publisher(for: .ghosttySelectionForSearch)) { notification in - guard notification.object as? SurfaceView === surfaceView else { return } - if let userInfo = notification.userInfo, let text = userInfo["text"] as? String { - searchState.needle = text - // We do not focus the textfield after the action to match macOS behavior - } - } .background( GeometryReader { barGeo in Color.clear.onAppear { From 3ba4f17f0df0b284016470ac7635a289b95aef5a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 6 Jan 2026 14:21:39 -0800 Subject: [PATCH 5/5] zig fmt --- src/apprt/action.zig | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/apprt/action.zig b/src/apprt/action.zig index 4dd9d2994..78f4bef54 100644 --- a/src/apprt/action.zig +++ b/src/apprt/action.zig @@ -916,5 +916,3 @@ pub const SearchSelected = struct { }; } }; - -