Subject: Re: bug#41071: make-frame with internal-border face not working

From: Alan Third <[email-masked]>
Date: Wed, 23 Sep 2020 14:03:27 +0100

On Mon, May 04, 2020 at 03:30:09PM +0800, 王凯 wrote:
> 
> (defface test
>   '((t (:inherit default :background "green")))
>   "Face used by the ivy-posframe."
>   :group 'ivy-posframe)
> 
> (set-face-background
> 'internal-border
> (face-attribute 'test :background)
> (make-frame `((internal-border-width . 100)
>                (parent-frame . ,(window-frame)))))
> 
> (set-face-background
> 'internal-border
> (face-attribute 'test :background)
> (make-frame `((internal-border-width . 100))))
> 
> Eval code above in emacs, internal-border-width works but the
> :background not.

Patch against master attached. It appears to work correctly here, but
I'm slightly concerned it may not work so well on older versions of
macOS, but we'll probably just have to wait and see if anyone
complains.
-- 
Alan Third
>From 5f98e4703791b31ed4b94c16340170777e7a9374 Mon Sep 17 00:00:00 2001
From: Alan Third <[email-masked]>
Date: Wed, 23 Sep 2020 13:57:50 +0100
Subject: [PATCH] Implement internal border colors on NS (bug#41071)

* src/nsterm.m (ns_clear_under_internal_border): New function.
(ns_after_update_window_line): Use the correct background color.
(ns_redisplay_interface): Add ns_clear_under_internal_border.
---
 src/nsterm.m | 64 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 59 insertions(+), 5 deletions(-)

diff --git a/src/nsterm.m b/src/nsterm.m
index 5e5d09f058..4b1cf65964 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -3052,6 +3052,40 @@ so some key presses (TAB) are swallowed by the system.  */
 }

+static void
+ns_clear_under_internal_border (struct frame *f)
+{
+  NSTRACE ("ns_clear_under_internal_border");
+
+  if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
+    {
+      int border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
+      NSView *view = FRAME_NS_VIEW (f);
+      NSRect edge_rect, frame_rect = [view bounds];
+      NSRectEdge edge[] = {NSMinXEdge, NSMinYEdge, NSMaxXEdge, NSMaxYEdge};
+
+      int face_id =
+	!NILP (Vface_remapping_alist)
+	? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
+	: INTERNAL_BORDER_FACE_ID;
+      struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
+
+      if (!face)
+        face = FRAME_DEFAULT_FACE (f);
+
+      ns_focus (f, &frame_rect, 1);
+      [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set];
+      for (int i = 0; i < 4 ; i++)
+        {
+          NSDivideRect (frame_rect, &edge_rect, &frame_rect, border_width, edge[i]);
+
+          NSRectFill (edge_rect);
+        }
+      ns_unfocus (f);
+    }
+}
+
+
 static void
 ns_after_update_window_line (struct window *w, struct glyph_row *desired_row)
 /* --------------------------------------------------------------------------
@@ -3080,12 +3114,32 @@ so some key presses (TAB) are swallowed by the system.  */
 	  height > 0))
     {
       int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
+      int face_id =
+        !NILP (Vface_remapping_alist)
+        ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
+        : INTERNAL_BORDER_FACE_ID;
+      struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
 
       block_input ();
-      ns_clear_frame_area (f, 0, y, width, height);
-      ns_clear_frame_area (f,
-                           FRAME_PIXEL_WIDTH (f) - width,
-                           y, width, height);
+      if (face)
+        {
+          NSRect r = NSMakeRect (0, y, FRAME_PIXEL_WIDTH (f), height);
+          ns_focus (f, &r, 1);
+
+          [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set];
+          NSRectFill (NSMakeRect (0, y, width, height));
+          NSRectFill (NSMakeRect (FRAME_PIXEL_WIDTH (f) - width,
+                                  y, width, height));
+
+          ns_unfocus (f);
+        }
+      else
+        {
+          ns_clear_frame_area (f, 0, y, width, height);
+          ns_clear_frame_area (f,
+                               FRAME_PIXEL_WIDTH (f) - width,
+                               y, width, height);
+        }
       unblock_input ();
     }
 }
@@ -5301,7 +5355,7 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
   ns_draw_glyph_string,
   ns_define_frame_cursor,
   ns_clear_frame_area,
-  0, /* clear_under_internal_border */
+  ns_clear_under_internal_border, /* clear_under_internal_border */
   ns_draw_window_cursor,
   ns_draw_vertical_window_border,
   ns_draw_window_divider,
-- 
2.26.1