Subject: bug#46184: 28.0.50; child-frame-border-width of 0 falls back to internla-border-width

From: martin rudalics <[email-masked]>
Date: Sat, 30 Jan 2021 16:26:07 +0100

> (make-frame `(
 > 	      (parent-frame . ,(window-frame))
 > 	      (child-frame-border-width . 0)
 > 	      (internal-border-width . 200)))
 >
 > I would expect the border width to only fall back if
 > child-frame-border-width is nil, since 0 is a useful setting.

It's not entirely trivial to do that (frame parameters are a pain in
this regard) but please have a look at the attached patch (tested on a
GTK build only).  Alexander, please have a look too.

Thanks, martin
diff --git a/src/frame.c b/src/frame.c
index a2167ce1e4..d4a560af38 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -898,6 +898,7 @@ make_frame (bool mini_p)
   f->no_accept_focus = false;
   f->z_group = z_group_none;
   f->tooltip = false;
+  f->child_frame_border_width = -1;
   f->last_tab_bar_item = -1;
 #ifndef HAVE_EXT_TOOL_BAR
   f->last_tool_bar_item = -1;
@@ -3547,7 +3548,12 @@ DEFUN ("frame-child-frame-border-width", Fframe_child_frame_border_width, Sframe
        doc: /* Return width of FRAME's child-frame border in pixels.  */)
   (Lisp_Object frame)
 {
-  return make_fixnum (FRAME_CHILD_FRAME_BORDER_WIDTH (decode_any_frame (frame)));
+  int width = FRAME_CHILD_FRAME_BORDER_WIDTH (decode_any_frame (frame));
+
+  if (width < 0)
+    return make_fixnum (FRAME_INTERNAL_BORDER_WIDTH (decode_any_frame (frame)));
+  else
+    return make_fixnum (FRAME_CHILD_FRAME_BORDER_WIDTH (decode_any_frame (frame)));
 }

 DEFUN ("frame-internal-border-width", Fframe_internal_border_width, Sframe_internal_border_width, 0, 1, 0,
@@ -4311,7 +4317,9 @@ gui_report_frame_params (struct frame *f, Lisp_Object *alistptr)
   store_in_alist (alistptr, Qborder_width,
 		  make_fixnum (f->border_width));
   store_in_alist (alistptr, Qchild_frame_border_width,
-		  make_fixnum (FRAME_CHILD_FRAME_BORDER_WIDTH (f)));
+		  (FRAME_CHILD_FRAME_BORDER_WIDTH (f) >= 0
+		   ? make_fixnum (FRAME_CHILD_FRAME_BORDER_WIDTH (f))
+		   : Qnil));
   store_in_alist (alistptr, Qinternal_border_width,
 		  make_fixnum (FRAME_INTERNAL_BORDER_WIDTH (f)));
   store_in_alist (alistptr, Qright_divider_width,
diff --git a/src/frame.h b/src/frame.h
index 9b0852c7b9..07e4f38803 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -1449,11 +1449,11 @@ FRAME_CHILD_FRAME_BORDER_WIDTH (struct frame *f)
 FRAME_INTERNAL_BORDER_WIDTH (struct frame *f)
 {
 #ifdef HAVE_WINDOW_SYSTEM
-  return FRAME_PARENT_FRAME(f)
-    ? (f->child_frame_border_width
-       ? FRAME_CHILD_FRAME_BORDER_WIDTH(f)
-       : frame_dimension (f->internal_border_width))
-    : frame_dimension (f->internal_border_width);
+  return (FRAME_PARENT_FRAME(f)
+	  ? (FRAME_CHILD_FRAME_BORDER_WIDTH(f) >= 0
+	     ? FRAME_CHILD_FRAME_BORDER_WIDTH(f)
+	     : frame_dimension (f->internal_border_width))
+	  : frame_dimension (f->internal_border_width));
 #else
   return frame_dimension (f->internal_border_width);
 #endif
diff --git a/src/nsfns.m b/src/nsfns.m
index c383e2f7ec..7e759422e4 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -691,7 +691,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
 ns_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
   int old_width = FRAME_CHILD_FRAME_BORDER_WIDTH (f);
-  int new_width = check_int_nonnegative (arg);
+  int new_width = check_integer_range (arg, -1, INT_MAX);

   if (new_width == old_width)
     return;
diff --git a/src/w32fns.c b/src/w32fns.c
index 7519c752b6..9b9671db05 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1561,8 +1561,8 @@ w32_clear_under_internal_border (struct frame *f)
 static void
 w32_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
-  int argval = check_integer_range (arg, INT_MIN, INT_MAX);
-  int border = max (argval, 0);
+  int argval = check_integer_range (arg, -1, INT_MAX);
+  int border = max (argval, -1);

   if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f))
     {
diff --git a/src/xfns.c b/src/xfns.c
index cac41ee485..8a01edecdb 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -1803,7 +1803,7 @@ x_change_tool_bar_height (struct frame *f, int height)
 static void
 x_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
-  int border = check_int_nonnegative (arg);
+  int border = check_integer_range (arg, -1, INT_MAX);

   if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f))
     {
@@ -3934,12 +3934,7 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,

     }

-  gui_default_parameter (f, parms, Qchild_frame_border_width,
-#ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets.  */
-			 make_fixnum (0),
-#else
-			 make_fixnum (1),
-#endif
+  gui_default_parameter (f, parms, Qchild_frame_border_width, make_fixnum (-1),
 			 "childFrameBorderWidth", "childFrameBorderWidth",
 			 RES_TYPE_NUMBER);
   gui_default_parameter (f, parms, Qinternal_border_width,