macos: search input starts the search up

pull/9709/head
Mitchell Hashimoto 2025-11-25 12:34:46 -08:00
parent 081d73d850
commit 5ee000f58f
No known key found for this signature in database
GPG Key ID: 523D5DC389D273BC
3 changed files with 17 additions and 9 deletions

View File

@ -391,7 +391,6 @@ extension Ghostty {
struct SurfaceSearchOverlay: View { struct SurfaceSearchOverlay: View {
let surfaceView: SurfaceView let surfaceView: SurfaceView
@Binding var searchState: SurfaceView.SearchState? @Binding var searchState: SurfaceView.SearchState?
@State private var searchText: String = ""
@State private var corner: Corner = .topRight @State private var corner: Corner = .topRight
@State private var dragOffset: CGSize = .zero @State private var dragOffset: CGSize = .zero
@State private var barSize: CGSize = .zero @State private var barSize: CGSize = .zero
@ -402,7 +401,10 @@ extension Ghostty {
var body: some View { var body: some View {
GeometryReader { geo in GeometryReader { geo in
HStack(spacing: 8) { HStack(spacing: 8) {
TextField("Search", text: $searchText) TextField("Search", text: Binding(
get: { searchState?.needle ?? "" },
set: { searchState?.needle = $0 }
))
.textFieldStyle(.plain) .textFieldStyle(.plain)
.frame(width: 180) .frame(width: 180)
.padding(.horizontal, 8) .padding(.horizontal, 8)
@ -436,9 +438,6 @@ extension Ghostty {
.cornerRadius(8) .cornerRadius(8)
.shadow(radius: 4) .shadow(radius: 4)
.onAppear { .onAppear {
if let needle = searchState?.needle {
searchText = needle
}
isSearchFieldFocused = true isSearchFieldFocused = true
} }
.onReceive(NotificationCenter.default.publisher(for: .ghosttySearchFocus)) { notification in .onReceive(NotificationCenter.default.publisher(for: .ghosttySearchFocus)) { notification in

View File

@ -1,4 +1,5 @@
import AppKit import AppKit
import Combine
import SwiftUI import SwiftUI
import CoreText import CoreText
import UserNotifications import UserNotifications
@ -67,15 +68,23 @@ extension Ghostty {
// The current search state. When non-nil, the search overlay should be shown. // The current search state. When non-nil, the search overlay should be shown.
@Published var searchState: SearchState? = nil { @Published var searchState: SearchState? = nil {
didSet { didSet {
// If the search state becomes nil, we need to make sure we're stopping if let searchState {
// the search internally. searchNeedleCancellable = searchState.$needle.sink { [weak self] needle in
if searchState == nil { guard let surface = self?.surface else { return }
let action = "search:\(needle)"
ghostty_surface_binding_action(surface, action, UInt(action.count))
}
} else {
searchNeedleCancellable = nil
guard let surface = self.surface else { return } guard let surface = self.surface else { return }
let action = "search:" let action = "search:"
ghostty_surface_binding_action(surface, action, UInt(action.count)) ghostty_surface_binding_action(surface, action, UInt(action.count))
} }
} }
} }
// Cancellable for search state needle changes
private var searchNeedleCancellable: AnyCancellable?
// The time this surface last became focused. This is a ContinuousClock.Instant // The time this surface last became focused. This is a ContinuousClock.Instant
// on supported platforms. // on supported platforms.

View File

@ -4879,7 +4879,7 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
.start_search => if (self.search == null) { .start_search => if (self.search == null) {
// To save resources, we don't actually start a search here, // To save resources, we don't actually start a search here,
// we just notify teh apprt. The real thread will start when // we just notify the apprt. The real thread will start when
// the first needles are set. // the first needles are set.
_ = try self.rt_app.performAction( _ = try self.rt_app.performAction(
.{ .surface = self }, .{ .surface = self },