-
Notifications
You must be signed in to change notification settings - Fork 637
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support selection foreground being cell foreground #5219
base: main
Are you sure you want to change the base?
Conversation
I like this patch. A couple of minor things, when there are inverted cells, this patch shows the original foreground, rather than the inverted foreground. If you compare to Terminal.app, it will always show the inverted foreground when selecting inverted cells. Additionally, very oddly, the theme's If any example code could help, here is my personal patch (from the 1.0.1 tag) that demonstrates equivalence with Terminal.app selection & cursor behavior, with the exception that I have a custom theme with no diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig
index b37f440f..a2ef6c16 100644
--- a/src/renderer/Metal.zig
+++ b/src/renderer/Metal.zig
@@ -2435,8 +2435,17 @@ fn rebuildCells(
if (selected and !self.config.invert_selection_fg_bg) {
// If we don't have invert selection fg/bg set
// then we just use the selection foreground if
- // set, otherwise the default bg color.
- break :fg self.config.selection_foreground orelse self.background_color orelse self.default_background_color;
+ // set, otherwise the existing fg color.
+ if (style.flags.inverse) {
+ break :fg self.config.selection_foreground orelse bg_style orelse self.background_color orelse self.default_background_color;
+ } else {
+ break :fg self.config.selection_foreground orelse fg_style;
+ }
+ // Except, all themes set selection_foreground! We
+ // want a theme that doesn't set
+ // selection_foreground. We could always force
+ // fg_style, but that isn't a general solution
+ //break :fg fg_style;
}
// Whether we need to use the bg color as our fg color:
@@ -2671,8 +2680,14 @@ fn rebuildCells(
break :blk sty.bg(screen.cursor.page_cell, color_palette) orelse self.background_color orelse self.default_background_color;
} else if (self.config.cursor_text) |txt|
txt
- else
- self.background_color orelse self.default_background_color;
+ else base: {
+ const sty = screen.cursor.page_pin.style(screen.cursor.page_cell);
+ if (sty.flags.inverse) {
+ break :base sty.bg(screen.cursor.page_cell, color_palette) orelse self.background_color orelse self.default_background_color;
+ } else {
+ break :base sty.fg(color_palette, self.config.bold_is_bright) orelse self.foreground_color orelse self.default_foreground_color;
+ }
+ };
self.uniforms.cursor_color = .{
uniform_color.r, |
@kjmph Thanks for catching the inverted cell issue, it should hopefully be fixed now. I've also made |
Oh!!! The cursor wiping out the foreground is a problem upstream, it isn't a regression with this patch. I bet most people allow the shell integration for cursors and because it is a bar, don't notice the color mishap. Will have to open a ticket unless you want to fix it in this patch too? |
To me, changing As for the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work for a first time contributor :) This is imo a nice simplification of some of this code which was starting to get a bit hairy.
This PR makes selection-invert-fg-bg
and cursor-invert-fg-bg
no-ops, which is a breaking change. I'll leave it to Mitchell to determine how to approach that, but at the least the doc strings for those options should be updated to indicate that they no longer do anything.
src/renderer/Metal.zig
Outdated
// Otherwise, use the foreground color. | ||
self.foreground_color orelse self.default_foreground_color; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation looks off here, run this through zig fmt
if you haven't already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
zig fmt
didn't change anything so I just moved the comment somewhere else, hopefully it still makes sense
const sty = screen.cursor.page_pin.style(screen.cursor.page_cell); | ||
const fg_style = sty.fg(color_palette, self.config.bold_is_bright) orelse self.foreground_color orelse self.default_foreground_color; | ||
const bg_style = sty.bg(screen.cursor.page_cell, color_palette) orelse self.background_color orelse self.default_background_color; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's probably not a big deal, but we are computing these styles even if they're not needed when the cursor color is set to an explicit style. I don't think there is a significant runtime cost though. If we wanted to avoid that we could first check to see if the enum has the .color
tag and only compute the styles if it does not (this would be a perfect use case for ziglang/zig#12863)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a check before these calls which should skip them if the union has the .color
tag
/// Specified as either hex (`#RRGGBB` or `RRGGBB`), a named X11 color, | ||
/// `cell-foreground` to match the cell foreground color, or `cell-background` | ||
/// to match the cell background color. | ||
@"cursor-color": ?DynamicColor = null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not for this PR (and maybe never), but I wonder if we should unify the terminology for cursor and selection, so that instead of cursor-text
and cursor-color
we use cursor-foreground
and cursor-background
.
…mputation to avoid unnecssary invocations
Hello, just wondering, does this allow me to configure ghostty to behave like gnome-terminal?/ 2025-01-27T13_55_47.mp4Left ist gnome-terminal and right is ghostty. What I specifically want, is that the blinking cursor block has the same background color as the foreground of the text and the foreground to be the inverted foreground-color of the text (at least that's what I can figure is what gnome-terminal does) |
@cwrau The PR looks like it could match gnome-terminal, but I don't have your precise setup. Here is the best replication I can draw: But again, I'm using I think you would want a Then, set the config:
That should match gnome terminal in your example. See attached video: cursor_test.mp4Patch: diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig
index b37f440f..db41d413 100644
--- a/src/renderer/Metal.zig
+++ b/src/renderer/Metal.zig
@@ -2435,8 +2435,17 @@ fn rebuildCells(
if (selected and !self.config.invert_selection_fg_bg) {
// If we don't have invert selection fg/bg set
// then we just use the selection foreground if
- // set, otherwise the default bg color.
- break :fg self.config.selection_foreground orelse self.background_color orelse self.default_background_color;
+ // set, otherwise the existing fg color.
+ if (style.flags.inverse) {
+ break :fg self.config.selection_foreground orelse bg_style orelse self.background_color orelse self.default_background_color;
+ } else {
+ break :fg self.config.selection_foreground orelse fg_style;
+ }
+ // Except, all themes set selection_foreground! We
+ // want a theme that doesn't set
+ // selection_foreground. We could always force
+ // fg_style, but that isn't a general solution
+ //break :fg fg_style;
}
// Whether we need to use the bg color as our fg color:
@@ -2638,7 +2647,11 @@ fn rebuildCells(
const cursor_color = self.cursor_color orelse self.default_cursor_color orelse color: {
if (self.cursor_invert) {
const sty = screen.cursor.page_pin.style(screen.cursor.page_cell);
- break :color sty.fg(color_palette, self.config.bold_is_bright) orelse self.foreground_color orelse self.default_foreground_color;
+ if (sty.flags.inverse) {
+ break :color sty.bg(screen.cursor.page_cell, color_palette) orelse self.background_color orelse self.default_background_color;
+ } else {
+ break :color sty.fg(color_palette, self.config.bold_is_bright) orelse self.foreground_color orelse self.default_foreground_color;
+ }
} else {
break :color self.foreground_color orelse self.default_foreground_color;
}
@@ -2668,11 +2681,21 @@ fn rebuildCells(
const uniform_color = if (self.cursor_invert) blk: {
const sty = screen.cursor.page_pin.style(screen.cursor.page_cell);
- break :blk sty.bg(screen.cursor.page_cell, color_palette) orelse self.background_color orelse self.default_background_color;
+ if (sty.flags.inverse) {
+ break :blk sty.fg(color_palette, self.config.bold_is_bright) orelse self.foreground_color orelse self.default_foreground_color;
+ } else {
+ break :blk sty.bg(screen.cursor.page_cell, color_palette) orelse self.background_color orelse self.default_background_color;
+ }
} else if (self.config.cursor_text) |txt|
txt
- else
- self.background_color orelse self.default_background_color;
+ else base: {
+ const sty = screen.cursor.page_pin.style(screen.cursor.page_cell);
+ if (sty.flags.inverse) {
+ break :base sty.bg(screen.cursor.page_cell, color_palette) orelse self.background_color orelse self.default_background_color;
+ } else {
+ break :base sty.fg(color_palette, self.config.bold_is_bright) orelse self.foreground_color orelse self.default_foreground_color;
+ }
+ };
self.uniforms.cursor_color = .{
uniform_color.r, |
Actually, I stand corrected, with this PR, I can get close to gnome-terminal @cwrau:
But the foreground colors look saturated incorrectly? (see the S and the E here:) |
Amazing! Looking forward to this PR 😁 |
This resolves #2685.
Changes
SelectionColor
tagged union that can take aColor
,cell-foreground
, orcell-background
invert_selection_fg_bg
during rendering as suggested in the issueDemo
macOS:
demo.mov
Ubuntu:
demo2.mov
Any feedback would be helpful, I'm sure there's a lot of room for improvement here.