Skip to content
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

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

dal-liu
Copy link

@dal-liu dal-liu commented Jan 19, 2025

This resolves #2685.

Changes

  • Created SelectionColor tagged union that can take a Color, cell-foreground, or cell-background
  • Used the new union to implement the feature for Metal and OpenGL
  • Removed the use of invert_selection_fg_bg during rendering as suggested in the issue

Demo

macOS:

demo.mov

Ubuntu:

demo2.mov

Any feedback would be helpful, I'm sure there's a lot of room for improvement here.

@kjmph
Copy link

kjmph commented Jan 20, 2025

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 cursor-text seems to not be honored with this patch, unless this is a main vs 1.0.1 change?

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 selection-foreground specified. I also made a change to cursor rendering so that the cell-foreground is used. Can we support cell-foreground with cursor-text as well?

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 exisitng 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,

@dal-liu
Copy link
Author

dal-liu commented Jan 22, 2025

@kjmph Thanks for catching the inverted cell issue, it should hopefully be fixed now. I've also made cursor-text and cursor-color accept cell-foreground and cell-background the same way that the selection colors do.

@kjmph
Copy link

kjmph commented Jan 22, 2025

Haha, great improvement! Except for two things. 1) If the cursor-color is cell-foreground then it wipes out the cell's text. If cursor-color is cell-background then it can't be seen because it blends in. I think it wise to remove the support from cursor-color since it will lead people astray into odd configuration territory. 2) The cursor foreground is wiped out with inverted cells. I don't understand why that happens with your PR, unless it exists in the upstream main branch? I'm personally working on the 1.0.1 tag.

Here is an image showing this patch (and cursor-text = cell-foreground) with inverted cells:
Screenshot 2025-01-21 at 10 43 44 PM

Here is an image showing the patch I shared against 1.0.1 with inverted cells:
Screenshot 2025-01-21 at 10 44 10 PM

I'll give a test against main.

@kjmph
Copy link

kjmph commented Jan 22, 2025

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?

@dal-liu
Copy link
Author

dal-liu commented Jan 22, 2025

To me, changing cursor-color to accept cell colors makes sense since we should have more control over the colors, plus it was suggested in the original issue as well. That being said, if a 3rd opinion disagrees then I'll gladly revert the changes, so I will leave it for now.

As for the cursor-text thing, it's definitely worth opening a discussion about it.

Copy link
Member

@gpanders gpanders left a 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.

Comment on lines +2819 to +2820
// Otherwise, use the foreground color.
self.foreground_color orelse self.default_foreground_color;
Copy link
Member

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.

Comment on lines +2807 to +2809
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;
Copy link
Member

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)

/// 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,
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support selection foreground being cell foreground
3 participants