Commit Graph

13193 Commits

Author SHA1 Message Date
Mitchell Hashimoto
fc9b578ef4 apprt/gtk: hook up search-changed to start a search 2025-11-30 07:23:10 -08:00
Mitchell Hashimoto
0d32e7d814 apprt/gtk: escape to stop search and hide overlay 2025-11-30 07:23:09 -08:00
Mitchell Hashimoto
778b49c9a1 apprt/gtk: hook up start_search/end_search to set active state 2025-11-30 07:23:09 -08:00
Mitchell Hashimoto
027e5d631a config: default search keybindings for Linux 2025-11-30 07:23:09 -08:00
Mitchell Hashimoto
548d1f0300 apprt/gtk: search overlay UI 2025-11-30 07:23:09 -08:00
Mitchell Hashimoto
832883b600 apprt/gtk: move surface event controllers, block events from revealers 2025-11-30 07:23:09 -08:00
Mitchell Hashimoto
4fef41bc83 terminal: renderstate needs to reset highlights on dirty (#9759)
This fixes memory corruption where future matches on a fully dirty row
would write highlights out of bounds. It was easy to reproduce in debug
by searching for `$` in `ghostty +boo`
2025-11-30 07:22:54 -08:00
Tim Culverhouse
a58e33c06b PageList: preserve size.cols in adjustCapacity after column shrink
When columns shrink during resize-without-reflow, page.size.cols is
updated but page.capacity.cols retains the old larger value. When
adjustCapacity later runs (e.g., to expand style/grapheme storage),
it was creating a new page using page.capacity which has the stale
column count, causing size.cols to revert to the old value.

This caused a crash in render.zig where an assertion checks that
page.size.cols matches PageList.cols.

Fix by explicitly copying page.size.cols to the new page after
creation, matching how size.rows is already handled.

Amp-Thread-ID: https://ampcode.com/threads/T-976bc49a-7bfd-40bd-bbbb-38f66fc925ff
Co-authored-by: Amp <amp@ampcode.com>
2025-11-30 07:20:54 -08:00
Mitchell Hashimoto
d7087627d7 terminal: renderstate needs to reset highlights on dirty
This fixes memory corruption where future matches on a fully dirty row
would write highlights out of bounds. It was easy to reproduce in debug
by searching for `$` in `ghostty +boo`
2025-11-30 07:18:42 -08:00
Mitchell Hashimoto
73be3abf00 Update iTerm2 colorschemes (#9755)
Upstream release:
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20251124-150533-2b326a8
2025-11-29 20:56:10 -08:00
mitchellh
643c5e00a0 deps: Update iTerm2 color schemes 2025-11-30 00:16:02 +00:00
Mitchell Hashimoto
3754a94cb5 Allow list-theme action with --plain to sort with --color argument (#9748)
not an accepted issue
https://github.com/ghostty-org/ghostty/discussions/9745 but it seemed
simple enough to add, pretty much copies how the previewer sorts based
on color

This allows --color argument to work when using --plain to sort the list
returned
2025-11-29 14:02:57 -08:00
Mitchell Hashimoto
7f950cc892 search: handle soft-wrapped lines in sliding window properly (#9753)
Fixes #9752
2025-11-29 10:56:11 -08:00
Mitchell Hashimoto
10f19ebdc3 search: handle soft-wrapped lines in sliding window properly
Fixes #9752
2025-11-29 07:32:06 -08:00
Mitchell Hashimoto
2fd48b433d macos: window-width/height is accurate even with other widgets (#9747)
Fixes #2660

Rather than calculate our window frame size based on various chrome
calculations, we now utilize SwiftUI layouts and view intrinsic content
sizes with `setContentSize` to setup our content size ignoring all our
other widgets.

I'm sure there's some edge cases I'm missing here but this should be a
whole lot more reliable on the whole.
2025-11-29 06:56:18 -08:00
rhodes-b
351dd2ea51 allow list themes --plain to accept --color flag 2025-11-28 19:26:11 -06:00
Mitchell Hashimoto
c75bade896 macos: window-width/height is accurate even with other widgets
Fixes #2660

Rather than calculate our window frame size based on various chrome
calculations, we now utilize SwiftUI layouts and view intrinsic content
sizes with `setContentSize` to setup our content size ignoring all our
other widgets.

I'm sure there's some edge cases I'm missing here but this should be a
whole lot more reliable on the whole.
2025-11-28 13:32:03 -08:00
Mitchell Hashimoto
9baf37a9b2 macOS: fix toggle_visibility behaviour with tabbed windows (#9742)
This fixes regression of #5690, which kind of comes from #9576. 

05b42919d5 (before #9576) has weird
behaviours too: restored windows are not properly focused. With this pr,
we only order `selectedWindow` front so we won't mess up with its
selection and focused state and the order of the tab group.


https://github.com/user-attachments/assets/8c3b120e-4077-4cb5-8ed3-9b46522e2f8e
2025-11-28 06:23:58 -08:00
Lukas
94f88c8b54 macOS: fix toggle_visibility behaviour with tabbed windows
This fixes regression of #5690, which kind of comes from #9576. 05b42919d5 (before #9576) has weird behaviours too, restored windows are not properly focused. With this pr, we only order `selectedWindow` front so we won't mess up with its selection state and the order of the tab group.
2025-11-28 10:14:07 +01:00
Mitchell Hashimoto
199119967b Remove unused imports (#9736)
Done with AI:
https://ampcode.com/threads/T-07890fd7-5d5c-462a-8d50-ba7ac6565796

I'm reviewing it now, but if builds pass we're probably fine.
2025-11-27 13:52:28 -08:00
Mitchell Hashimoto
dbfc3eb679 Remove unused imports 2025-11-27 13:37:53 -08:00
Mitchell Hashimoto
d8aeffe1e9 macos: add hover styles to search buttons, cursor changes (#9734)
https://github.com/user-attachments/assets/72a561b5-f863-48c9-97cb-414ed89a8e3f
2025-11-27 13:22:02 -08:00
Mitchell Hashimoto
5c1679209d macos: add hover styles to search buttons, cursor changes 2025-11-27 13:01:51 -08:00
Mitchell Hashimoto
4ff0e0c9d2 input: remove the unused end search entry in the palette 2025-11-27 07:21:59 -08:00
Mitchell Hashimoto
14899591ce terminal: PageList search should halt when pin becomes garbage (#9722)
This means that the pin we're using to track our position in the
PageList was part of a node that got reused/recycled at some point. We
can't make any meaningful guarantees about the state of the PageList.

This only happens with scrollback pruning so we can treat it as a
complete search.
2025-11-26 16:48:30 -08:00
Mitchell Hashimoto
842becbcaf terminal: PageList search should halt when pin becomes garbage
This means that the pin we're using to track our position in the
PageList was part of a node that got reused/recycled at some point. We
can't make any meaningful guarantees about the state of the PageList.

This only happens with scrollback pruning so we can treat it as a
complete search.
2025-11-26 16:36:44 -08:00
Mitchell Hashimoto
c199a8fe7e terminal: RenderState must consider first row in dirty page dirty (#9719)
Fixes #9718
2025-11-26 13:24:05 -08:00
Mitchell Hashimoto
b96b55ebde terminal: RenderState must consider first row in dirty page dirty 2025-11-26 13:20:16 -08:00
Mitchell Hashimoto
e64ae2e966 macOS: refine Search UI (#9717)
- fix search dragging animation when corner is not changed
- use ConcentricRectangle on Tahoe


https://github.com/user-attachments/assets/64c294a7-70bd-484d-b153-4aa2d734b1a7
2025-11-26 12:36:24 -08:00
Lukas
dc08d057fe macOS: use ConcentricRectangle on Tahoe 2025-11-26 21:00:14 +01:00
Lukas
cbcd52846c macOS: fix search dragging animation when corner is not changed 2025-11-26 21:00:14 +01:00
Mitchell Hashimoto
48d11b1ce4 fix(macos): use strings' utf-8 lengths for libghostty calls (#9715)
Swift conveniently converts strings to UTF-8 encoded cstrings when
passing them to external functions, however our libghostty functions
also take a length and we were using String.count for that, which
returns the number of _characters_ not the byte length, which caused
searches with multi-byte characters to get truncated.

I went ahead and changed _all_ invocations that pass a string length to
use the utf-8 byte length even if the string is comptime-known and all
ASCII, just so that it's proper and if someone copies one of the calls
in the future for user-inputted data they don't reproduce this bug.

ref:
https://developer.apple.com/documentation/swift/string/count
https://developer.apple.com/documentation/swift/stringprotocol/lengthofbytes(using:)
2025-11-26 11:16:36 -08:00
Qwerasd
4b01163c79 fix(macos): use strings' utf-8 lengths for libghostty calls
Swift conveniently converts strings to UTF-8 encoded cstrings when
passing them to external functions, however our libghostty functions
also take a length and we were using String.count for that, which
returns the number of _characters_ not the byte length, which caused
searches with multi-byte characters to get truncated.

I went ahead and changed _all_ invocations that pass a string length to
use the utf-8 byte length even if the string is comptime-known and all
ASCII, just so that it's proper and if someone copies one of the calls
in the future for user-inputted data they don't reproduce this bug.

ref:
https://developer.apple.com/documentation/swift/string/count
https://developer.apple.com/documentation/swift/stringprotocol/lengthofbytes(using:)
2025-11-26 12:00:58 -07:00
Mitchell Hashimoto
d213091452 renderer: manual selection should take priority over search matches (#9714)
Previously it was impossible to select a search match. Well, it was
selecting but it wasn't showing that it was selected.
2025-11-26 10:30:42 -08:00
Mitchell Hashimoto
9206b3dc9b renderer: manual selection should take priority over search matches
Previously it was impossible to select a search match. Well, it was
selecting but it wasn't showing that it was selected.
2025-11-26 10:28:28 -08:00
Mitchell Hashimoto
3305455902 macOS: move search result counter inside text field (#9713)
Move the search result counter inside the search text field using an
overlay, preventing layout shift when results appear.

**Before:** The counter appeared as a separate element in the HStack,
causing the text field to shift when results loaded.

**After:** The counter is overlaid inside the text field on the right
side with reserved padding, eliminating layout shift.

---

**AI Disclosure: The was entirely authored with Claude Code,
specifically with Claude Opus 4.5.**
2025-11-26 10:07:15 -08:00
Mitchell Hashimoto
d85fc62774 search: reset selected match when the needle changes 2025-11-26 10:04:28 -08:00
avarayr
f5b923573d macOS: move search result counter inside text field
Move the search result counter (e.g. "1/30") inside the search text
field using an overlay, preventing layout shift when results appear.

This PR was authored with Claude Code.
2025-11-26 13:04:05 -05:00
Mitchell Hashimoto
71a2dad929 macOS Search GUI (#9709)
#189 for macOS

This adds a search GUI for macOS, including macOS-standard menu bar
items, and keybindings that match other native macOS applications such
as Terminal app, Safari, and others. This introduces a new keybinding
action `start_search` to start a blank search for GUIs.

This PR also resolves a number of minor issues found in the search
subsystem and renderer related to search from prior PRs. This should
result in overall improved search stability. **Please note there are
still known issues (bottom of this PR).**

> [!WARNING]
>
> **A note on stability:** I know a lot of people are eager to have this
feature, and I'm excited
> for this feature to soon be available in tip releases. But note that
new features like this are
> always filled with performance issues, bugs, crashes, etc. That's the
point of tip releases:
> to find and address these before wider availability. We will do our
best to respond rapidly to
> major issues found in tip, but don't expect perfect functionality
immediately!

## Demo


https://github.com/user-attachments/assets/3b81752e-d7e5-4875-9864-92497333b23e

> [!NOTE]
>
> You can drag the search window to any of the four corners if its
getting in the way of reading the terminal.

## Known Issues

TODO prior to this PR merging:

- [x] Single-byte search terms cause a crash since our sliding window
can't handle it. This PR temporarily requires search terms with length
2+ before starting a search to avoid it. 😄
- [x] The way `ScreenSearch` prunes history is fundamental unsafe. With
a rapidly growing screen that could reach history limits and an active
search at the same time, Ghostty is almost guaranteed to crash
currently. The workaround is to not search actively scrolling screens
(new data) for now.
2025-11-26 09:09:55 -08:00
Mitchell Hashimoto
5b4394d211 macos: end_search for ending search 2025-11-26 08:57:24 -08:00
Mitchell Hashimoto
c51170da9c add end_search binding 2025-11-26 08:50:06 -08:00
Mitchell Hashimoto
f7b14a0142 macos: debounce search requests with length less than 3 2025-11-26 08:50:06 -08:00
Mitchell Hashimoto
339abf97f7 macos: can allow single char searches now 2025-11-26 08:50:06 -08:00
Mitchell Hashimoto
f91080a165 terminal: fix single-character search crashes 2025-11-26 08:50:06 -08:00
Mitchell Hashimoto
f252db1f1c terminal: handle pruning history for when active area removes it 2025-11-26 08:50:06 -08:00
Mitchell Hashimoto
330ce07d48 terminal: fix moving selection on history changing 2025-11-26 08:50:06 -08:00
Mitchell Hashimoto
ad755b0e3d core: always send start_search for refocus 2025-11-26 08:50:05 -08:00
Mitchell Hashimoto
1bb2d4f1c2 macos: only end search if we previously had one 2025-11-26 08:50:05 -08:00
Mitchell Hashimoto
48acc90983 terminal: search should reload active area if dirty 2025-11-26 08:50:05 -08:00
Mitchell Hashimoto
93656fca5a macos: show progerss correctly for search 2025-11-26 08:50:05 -08:00