Subject: Re: bug#62573: 29.0.60; Cursor color not being inverted in emacs-29

From: Daniel Martín <[email-masked]>
Date: Sat, 01 Apr 2023 21:56:33 +0200

Eli Zaretskii <[email-masked]> writes:

>> From: Al Haji-Ali <[email-masked]>
>> Cc: [email-masked]
>> Date: Fri, 31 Mar 2023 22:46:00 +0100
>> 
>> 
>> On 31/03/2023, Eli Zaretskii wrote:
>> > On which platform is that and with what Emacs configuration?  (Using
>> > "M-x report-emacs-bug" would have collected this information
>> > automatically for you.)
>> Apologies, below are the details. I can also add the config of emacs 28.2 if that's helpful.
>> I am not sure what the issue is or how to debug it, so any hints are appreciated.
>> 
>> ---------------------------------------------------------------------------
>> In GNU Emacs 29.0.60 (build 1, aarch64-apple-darwin22.3.0, NS
>>  appkit-2299.40 Version 13.2.1 (Build 22D68)) of 2023-03-22 built on
>>  HW-R9XXWKPJ4D
>> Windowing system distributor 'Apple', version 10.3.2299
>> System Description:  macOS 13.2.1
>
> This is macOS, so I suspect the problem is specific to macOS.  Can
> someone with access to macOS please try reproducing this, and perhaps
> debugging the problem?

This bug is a regression caused by
07715630ad9df9cb681cbadecbaf73fc9c698061.  (Adding Po Lu to the CC.)

>From what I see, the font display refactor removed this code from
src/nsterm.m:

-  face = FACE_FROM_ID_OR_NULL (f, phys_cursor_glyph->face_id);
-  if (face && NS_FACE_BACKGROUND (face)
-      == ns_index_color (FRAME_CURSOR_COLOR (f), f))
-    {
-      [ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), f) set];
-      hollow_color = FRAME_CURSOR_COLOR (f);
-    }
-  else

which seems to be responsible for the cursor color change when the
background face color is the same as the cursor color.  I can't find
that logic in the current code, so I think we miss it from the
refactoring.

I've solved the bug by replicating that logic in the appropriate places,
nsterm.m and macfont.m:

diff --git a/src/macfont.m b/src/macfont.m
index d0cdbcd08c7..d14cf5f9c98 100644
--- a/src/macfont.m
+++ b/src/macfont.m
@@ -2933,9 +2933,15 @@ So we use CTFontDescriptorCreateMatchingFontDescriptor (no
     {
       if (s->hl == DRAW_CURSOR)
         {
-	  CGColorRef colorref = get_cgcolor_from_nscolor (FRAME_CURSOR_COLOR (f), f);
-	  CGContextSetFillColorWithColor (context, colorref);
-	  CGColorRelease (colorref);
+          if (face && NS_FACE_BACKGROUND (face)
+              == [(NSColor*)FRAME_CURSOR_COLOR (f) unsignedLong])
+            CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND (context, face);
+          else
+            {
+              CGColorRef colorref = get_cgcolor_from_nscolor (FRAME_CURSOR_COLOR (f), f);
+              CGContextSetFillColorWithColor (context, colorref);
+              CGColorRelease (colorref);
+            }
         }
       else
         CG_SET_FILL_COLOR_WITH_FACE_BACKGROUND (context, face);
@@ -2949,9 +2955,15 @@ So we use CTFontDescriptorCreateMatchingFontDescriptor (no
       CGContextScaleCTM (context, 1, -1);
       if (s->hl == DRAW_CURSOR)
         {
-	  CGColorRef colorref = get_cgcolor_from_nscolor (FRAME_BACKGROUND_COLOR (f), f);
-	  CGContextSetFillColorWithColor (context, colorref);
-	  CGColorRelease (colorref);
+          if (face && NS_FACE_BACKGROUND (face)
+              == [(NSColor*)FRAME_CURSOR_COLOR (f) unsignedLong])
+            CG_SET_FILL_COLOR_WITH_FACE_BACKGROUND (context, face);
+          else
+            {
+              CGColorRef colorref = get_cgcolor_from_nscolor (FRAME_BACKGROUND_COLOR (f), f);
+              CGContextSetFillColorWithColor (context, colorref);
+              CGColorRelease (colorref);
+            }
         }
       else
         CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND (context, face);
diff --git a/src/nsterm.m b/src/nsterm.m
index 46007ec4fcb..2f31a279bfc 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -3750,14 +3750,17 @@ Function modeled after x_draw_glyph_string_box ().
 	{
           struct face *face = s->face;
           if (!face->stipple)
-	    {
-	      if (s->hl != DRAW_CURSOR)
-		[(NS_FACE_BACKGROUND (face) != 0
-		  ? [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
-		  : FRAME_BACKGROUND_COLOR (s->f)) set];
-	      else
-		[FRAME_CURSOR_COLOR (s->f) set];
-	    }
+            {
+              if (s->hl != DRAW_CURSOR)
+                [(NS_FACE_BACKGROUND (face) != 0
+                  ? [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+                  : FRAME_BACKGROUND_COLOR (s->f)) set];
+              else if (face && NS_FACE_BACKGROUND (face)
+                       == [(NSColor*)FRAME_CURSOR_COLOR (s->f) unsignedLong])
+                [[NSColor colorWithUnsignedLong:NS_FACE_FOREGROUND (face)] set];
+              else
+                [FRAME_CURSOR_COLOR (s->f) set];
+            }
           else
             {
               struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);

Could you give it a try on macOS and GNUstep?  Thank you.