Fixes#5022
The CSI SGR sequence (CSI m) is unique in that its the only CSI sequence
that allows colons as delimiters between some parameters, and the colon
vs. semicolon changes the semantics of the parameters.
Previously, Ghostty assumed that an SGR sequence was either all colons
or all semicolons, and would change its behavior based on the first
delimiter it encountered.
This is incorrect. It is perfectly valid for an SGR sequence to have
both colons and semicolons as delimiters. For example, Kakoune sends the
following:
;4:3;38;2;175;175;215;58:2::190:80:70m
This is equivalent to:
- unset (0)
- curly underline (4:3)
- foreground color (38;2;175;175;215)
- underline color (58:2::190:80:70)
This commit changes the behavior of Ghostty to track the delimiter per
parameter, rather than per sequence. It also updates the SGR parser to
be more robust and handle the various edge cases that can occur. Tests
were added for the new cases.
Fixes#5022
The CSI SGR sequence (CSI m) is unique in that its the only CSI sequence
that allows colons as delimiters between some parameters, and the colon
vs. semicolon changes the semantics of the parameters.
Previously, Ghostty assumed that an SGR sequence was either all colons
or all semicolons, and would change its behavior based on the first
delimiter it encountered.
This is incorrect. It is perfectly valid for an SGR sequence to have
both colons and semicolons as delimiters. For example, Kakoune sends
the following:
;4:3;38;2;175;175;215;58:2::190:80:70m
This is equivalent to:
- unset (0)
- curly underline (4:3)
- foreground color (38;2;175;175;215)
- underline color (58:2::190:80:70)
This commit changes the behavior of Ghostty to track the delimiter per
parameter, rather than per sequence. It also updates the SGR parser to
be more robust and handle the various edge cases that can occur. Tests
were added for the new cases.
Previously, the logic navigated to the second-to-last tab instead of the
last tab due to an off-by-one error. This updates the implementation so
that the index calculation to accurately target the last tab.
In the `gotoLastTab` method there was a decrement in the number of max
number of tabs and another increment in the `goToTab` method to get the
actual tab index.
Fixes#3345
Piggybacking on the logic introduced PR
https://github.com/ghostty-org/ghostty/pull/3997, this patch prevents
mouse motion events with the same cursor position triggered by the
window title updating from un-hiding the mouse even when
`mouse-hide-while-typing` config item is true.
Two major changes:
1. Hiding uses `NSApp.hide` which hides all windows, preserves tabs, and
yields focus to the next app.
2. Unhiding manually tracks and brings forward only the windows we hid.
Proper focus should be retained.
There's one behavioral change here. Before this patch, if
`gtk-titlebar=false` we _never_ created a headerbar. This explicitly
contradicted the comments in the source, and the documentation for
`gtk-titlebar` imply that if a window starts out without a titlebar it
can be brought back later with the `toggle_window_decorations` keybind
action.
After this patch, a headerbar is always created, but if
`gtk-titlebar=false` or `window-decoration=false` it's immediately
hidden.
I'm not sure how this interacts with the current SSD/CSD detection that
seems to happen when running Ghostty on non-Gnome DEs so it'll be
important to get #4724 merged (plus any follow ups) to enable more
explicit control of SSD/CSD.
Fixes: https://github.com/ghostty-org/ghostty/issues/4634#issuecomment-2573469532
This commit fixes two issues:
1. `libghostty` must not override ctrl+key inputs if we are in a preedit
state. This allows thigs like `ctrl+h` to work properly in an IME.
2. On macOS, when an IME commits text, we strip the control modifier
from the key event we send to libghostty. This is a bit of a hack but
this avoids triggering special ctrl+key handling.
A "size-limit" function has been implemented for GTK which calls
gtk_widget_set_size_request() to set the minimum widget/window size.
Without
this function, it's left to GTK to set the minimum size which is usually
a lot larger than the documented 10x4 cell minimum size. This doesn't
fix the
issue completely as GTK retains the final say in how small a window can
be
but it gets closer.
Resolves: #4836
A "size-limit" function has been implemented for GTK which calls
gtk_widget_set_size_request() to set the minimum widget/window size. Without
this function, it's left to GTK to set the minimum size which is usually
a lot larger than the documented 10x4 cell minimum size. This doesn't fix the
issue completely as GTK retains the final say in how small a window can be
but it gets closer.
Resolves: #4836
## Description
This PR implements the `copy_url_to_clipboard` keybind action. This
action allows users to copy URLs directly to the clipboard without
needing to select them first.
### Features
- Works with both regex-matched URLs and OSC8 hyperlinks
- Copies only the URL portion, not the surrounding text
- Respects the `clipboard_trim_trailing_spaces` configuration
- Provides clear error feedback
- Follows the same patterns as other clipboard operations
https://github.com/user-attachments/assets/c9c82e3d-dfc5-4171-b367-d6799305d87f
Resolves https://github.com/ghostty-org/ghostty/issues/4633
This produces the following keybind, which I believe was intended.
> keybind = cmd+backspace=text:\x15
Matches the cmd+left and cmd+right which are a few lines up.
#3679#3646