emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Testing wanted


From: Po Lu
Subject: Testing wanted
Date: Tue, 20 Jun 2023 15:14:47 +0800

Would MS Windows users please perform the following tests on the change
below?

Set `tool-bar-position' to `top' and then `bottom', and verify that the
frame size does not change.  Repeat this with the `fullscreen' parameter
set to fullscreen, fullheight, maximized, and nil.

Set `internal-border-width' to 0, then 10, verifying that that no
residual drawing remains within the internal border, and that the tool
bar contents are not overwritten by the internal border.

Run (frame-edges nil 'inner-edges), verifying that the edge computation
takes the tool bar position into account.

Run (frame-geometry), and verify that `tool-bar-position' is reported
correctly.

Resize the frame so that the tool bar does not fit on one line, and
verify that the frame does not grow as the tool bar starts to wrap.

Thanks in advance.

2023-06-20  Staff User  <staff@G4_A60M>

        * src/xterm.c (x_clear_under_internal_border): Subtract bottom
        margins before clearing bottom border.
        (XTflash): Subtract bottom margins before flashing mini window.

        * src/xfns.c (x_set_tool_bar_position): Allow setting different
        values outside of GTK+.
        (frame_geometry): Adjust inner width and height for tool bars
        placed on the bottom.

        * src/xdisp.c (init_xdisp): Calculate using top margins only.

        * src/window.c (resize_frame_windows): Fix commentary.

        * src/w32fns.c (w32_clear_under_internal_border): Subtract bottom
        margins before clearing bottom border.
        (w32_set_tool_bar_position): New function.
        (Fw32_frame_edges): Subtract bottom tool bar from inner width and
        height.
        (w32_frame_parm_handlers): Add `set_tool_bar_position' parameter
        handler.

        * src/pgtkterm.c (pgtk_flash): Subtract bottom
        margins before clearing bottom border.
        (XTflash): Subtract bottom margins before flashing mini window.

        * src/pgtkfns.c (frame_geometry): Set `inner_top' correctly.
        (Fpgtk_set_mouse_absolute_pixel_position):
        (Fpgtk_mouse_absolute_pixel_position):
        (Fpgtk_page_setup_dialog):
        (Fpgtk_get_page_setup): Wrap lines which cause C Mode to hang.

        * src/nsterm.m (ns_clear_under_internal_border): Subtract bottom
        margins before flashing mini window.

        * src/nsfns.m (ns_set_tool_bar_position): New function.  Error if
        arg is not top.
        (ns_frame_parm_handlers): Add that as the handler for
        `tool-bar-position', to prevent it from being set to an invalid
        value.

        * src/haikuterm.c (haiku_flash): Subtract bottom margins before
        flashing mini window.
        (haiku_clear_under_internal_border): Subtract bottom margins
        before clearing bottom border.

        * src/haikufns.c (haiku_set_tool_bar_position): Allow setting
        values other than `top'.
        (frame_geometry): Take bottom margin into account when calculating
        inner dimensions.

        * src/frame.h (struct frame): Always define `tool_bar_position'.
        (fset_tool_bar_position): Define function everywhere.
        (FRAME_TOOL_BAR_POSITION): Define correctly on all toolkits.
        (FRAME_TOOL_BAR_TOP_HEIGHT):
        (FRAME_TOOL_BAR_TOP_LINES):
        (FRAME_TOOL_BAR_BOTTOM_HEIGHT):
        (FRAME_TOOL_BAR_BOTTOM_LINES): New macros.  Each pair returns the
        tool bar dimensions only if the tool bar position is set
        appropriately.
        (FRAME_TOP_MARGIN, FRAME_TOP_MARGIN_HEIGHT): Only add tool bar
        height if it is placed at the top of the frame.
        (FRAME_BOTTOM_MARGIN, FRAME_BOTTOM_MARGIN_HEIGHT): Add ``bottom
        margins''.
        (FRAME_MARGINS, FRAME_MARGIN_HEIGHT): Move original margin macro
        here.
        (FRAME_PIXEL_HEIGHT_TO_TEXT_LINES):
        (FRAME_TEXT_TO_PIXEL_HEIGHT):
        (FRAME_PIXEL_TO_TEXT_HEIGHT):
        (FRAME_INNER_HEIGHT): Subtract both vertical margins.

        * src/frame.c (adjust_frame_size): Subtract both top and bottom
        margins to determine the inner height.
        (make_frame): Initialize `f->tool_bar_position' unconditionally.

        * src/dispnew.c (adjust_frame_glyphs_for_window_redisplay): Place
        internal tool bar on bottom if requested.

        * doc/lispref/frames.texi (Frame Layout): Describe the possibility
        of the tool bar being placed below the inner area of the frame.
        (Layout Parameters): Describe that `tool-bar-position' is now
        supported almost everywhere.

diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index a8ac9a214f6..67def9b1fda 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -523,7 +523,8 @@ Frame Layout
      | |  | |<--+--- Inner Frame Width ------->| |  | |
      | |  | |   |                              | |  | |
      | |  | |___v______________________________| |  | |
-     | |  |___________ Internal Border __________|  | v
+     | |  |___________ Internal Border __________|  | |
+     | | (4)__________ Bottom Tool Bar __________|  | v
      v |___________ External/Outer Border __________|
            <-------- Native Frame Width -------->
 
@@ -707,6 +708,10 @@ Frame Layout
 those of the menu bar and the tool bar (non-toolkit and text terminal
 frames).
 
+If the native position would otherwise be (2), but the tool bar is
+placed at the bottom of the frame as depicted in (4), the native
+position of the frame becomes that of the tab bar.
+
 The native position of a frame is the reference position for functions
 that set or return the current position of the mouse (@pxref{Mouse
 Position}) and for functions dealing with the position of windows like
@@ -844,8 +849,11 @@ Frame Layout
 
 @item tool-bar-position
 This tells on which side the tool bar on @var{frame} is and can be one
-of @code{left}, @code{top}, @code{right} or @code{bottom}.  The only
-toolkit that currently supports a value other than @code{top} is GTK+.
+of @code{left}, @code{top}, @code{right} or @code{bottom}.
+
+The values @code{left} and @code{bottom} are only supported on builds
+using the GTK+ toolkit; @code{bottom} is supported on all builds other
+than NS, and @code{top} is supported everywhere.
 
 @item tool-bar-size
 A cons of the width and height of the tool bar of @var{frame}.
@@ -1905,9 +1913,11 @@ Layout Parameters
 
 @vindex tool-bar-position@r{, a frame parameter}
 @item tool-bar-position
-The position of the tool bar when Emacs was built with GTK+.  Its value
-can be one of @code{top}, @code{bottom} @code{left}, @code{right}.  The
-default is @code{top}.
+The position of the tool bar.  Its value can be one of @code{top},
+@code{bottom} @code{left}, @code{right}.  The default is @code{top}.
+
+It can be set to @code{bottom} on Emacs built with any toolkit other
+than Nextstep, and @code{left} or @code{right} on builds using GTK+.
 
 @vindex tab-bar-lines@r{, a frame parameter}
 @item tab-bar-lines
diff --git a/etc/NEWS b/etc/NEWS
index 2170323e74a..77ca749ccc3 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -82,6 +82,11 @@ This is used for displaying the time and date components of
 Several symbolic icons are added to "etc/images/symbols", including
 plus, minus, check-mark, start, etc.
 
++++
+** Tool bars can now be placed on the bottom on more systems.
+The 'tool-bar-position' frame parameter can be set to 'bottom' on all
+window systems other than Nextstep.
+
 
 * Editing Changes in Emacs 30.1
 
diff --git a/src/dispnew.c b/src/dispnew.c
index 9133d515ca3..82524d8cb8d 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -2218,10 +2218,10 @@ adjust_frame_glyphs_for_window_redisplay (struct frame 
*f)
 
     w->pixel_top = (FRAME_MENU_BAR_HEIGHT (f)
                    + (!NILP (Vtab_bar_position)
-                      ? FRAME_TOOL_BAR_HEIGHT (f) : 0));
+                      ? FRAME_TOOL_BAR_TOP_HEIGHT (f) : 0));
     w->top_line = (FRAME_MENU_BAR_LINES (f)
                   + (!NILP (Vtab_bar_position)
-                     ? FRAME_TOOL_BAR_LINES (f) : 0));
+                     ? FRAME_TOOL_BAR_TOP_LINES (f) : 0));
     w->total_cols = FRAME_TOTAL_COLS (f);
     w->pixel_width = (FRAME_PIXEL_WIDTH (f)
                       - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
@@ -2250,10 +2250,29 @@ adjust_frame_glyphs_for_window_redisplay (struct frame 
*f)
 
     w->pixel_left = 0;
     w->left_col = 0;
-    w->pixel_top = FRAME_MENU_BAR_HEIGHT (f)
-      + (NILP (Vtab_bar_position) ? FRAME_TAB_BAR_HEIGHT (f) : 0);
-    w->top_line = FRAME_MENU_BAR_LINES (f)
-      + (NILP (Vtab_bar_position) ? FRAME_TAB_BAR_LINES (f) : 0);
+
+    /* If the tool bar should be placed at the bottom of the frame,
+       place it there instead, outside the internal border.  */
+
+    if (EQ (FRAME_TOOL_BAR_POSITION (f), Qbottom))
+      {
+       w->pixel_top = (FRAME_PIXEL_HEIGHT (f)
+                       - FRAME_TOOL_BAR_HEIGHT (f));
+       w->top_line = (FRAME_LINES (f)
+                      - FRAME_TOOL_BAR_LINES (f));
+      }
+    else
+      {
+       /* Otherwise, place the window at the top of the frame.  */
+
+       w->pixel_top = (FRAME_MENU_BAR_HEIGHT (f)
+                       + (NILP (Vtab_bar_position)
+                          ? FRAME_TAB_BAR_HEIGHT (f) : 0));
+       w->top_line = (FRAME_MENU_BAR_LINES (f)
+                      + (NILP (Vtab_bar_position)
+                         ? FRAME_TAB_BAR_LINES (f) : 0));
+      }
+
     w->total_cols = FRAME_TOTAL_COLS (f);
     w->pixel_width = (FRAME_PIXEL_WIDTH (f)
                       - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
diff --git a/src/frame.c b/src/frame.c
index 037914ac9dc..3d140fcfc12 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -710,10 +710,10 @@ adjust_frame_size (struct frame *f, int new_text_width, 
int new_text_height,
                       ? old_native_height
                       : max (FRAME_TEXT_TO_PIXEL_HEIGHT (f, new_text_height),
                              min_inner_height
-                             + FRAME_TOP_MARGIN_HEIGHT (f)
+                             + FRAME_MARGIN_HEIGHT (f)
                              + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)));
   new_inner_height = (new_native_height
-                     - FRAME_TOP_MARGIN_HEIGHT (f)
+                     - FRAME_MARGIN_HEIGHT (f)
                      - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
   new_text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, new_native_height);
   new_text_lines = new_text_height / unit_height;
@@ -940,11 +940,9 @@ make_frame (bool mini_p)
   f = allocate_frame ();
   XSETFRAME (frame, f);
 
-#ifdef USE_GTK
   /* Initialize Lisp data.  Note that allocate_frame initializes all
      Lisp data to nil, so do it only for slots which should not be nil.  */
   fset_tool_bar_position (f, Qtop);
-#endif
 
   /* Initialize non-Lisp data.  Note that allocate_frame zeroes out all
      non-Lisp data, so do it only for slots which should not be zero.
diff --git a/src/frame.h b/src/frame.h
index b95b94c7685..44eefa357fc 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -205,11 +205,9 @@ #define EMACS_FRAME_H
   Lisp_Object current_tool_bar_string;
 #endif
 
-#ifdef USE_GTK
   /* Where tool bar is, can be left, right, top or bottom.
      Except with GTK, the only supported position is `top'.  */
   Lisp_Object tool_bar_position;
-#endif
 
 #if defined (HAVE_XFT) || defined (HAVE_FREETYPE)
   /* List of data specific to font-driver and frame, but common to faces.  */
@@ -782,14 +780,9 @@ fset_tool_bar_items (struct frame *f, Lisp_Object val)
 {
   f->tool_bar_items = val;
 }
-#ifdef USE_GTK
-INLINE void
-fset_tool_bar_position (struct frame *f, Lisp_Object val)
-{
-  f->tool_bar_position = val;
-}
-#endif /* USE_GTK */
+
 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
+
 INLINE void
 fset_tool_bar_window (struct frame *f, Lisp_Object val)
 {
@@ -805,7 +798,14 @@ fset_desired_tool_bar_string (struct frame *f, Lisp_Object 
val)
 {
   f->desired_tool_bar_string = val;
 }
-#endif /* HAVE_WINDOW_SYSTEM && !USE_GTK && !HAVE_NS */
+
+#endif /* HAVE_WINDOW_SYSTEM && !HAVE_EXT_TOOL_BAR */
+
+INLINE void
+fset_tool_bar_position (struct frame *f, Lisp_Object val)
+{
+  f->tool_bar_position = val;
+}
 
 INLINE double
 NUMVAL (Lisp_Object x)
@@ -984,25 +984,68 @@ #define FRAME_EXTERNAL_TOOL_BAR(f) (f)->external_tool_bar
 #define FRAME_EXTERNAL_TOOL_BAR(f) false
 #endif
 
-/* This is really supported only with GTK.  */
-#ifdef USE_GTK
+/* Position of F's tool bar; one of Qtop, Qleft, Qright, or
+   Qbottom.
+
+   Qleft and Qright are not supported outside GTK+.  */
 #define FRAME_TOOL_BAR_POSITION(f) (f)->tool_bar_position
-#else
-#define FRAME_TOOL_BAR_POSITION(f) ((void) (f), Qtop)
-#endif
 
 /* Size of frame F's internal tool bar in frame lines and pixels.  */
 #define FRAME_TOOL_BAR_LINES(f) (f)->tool_bar_lines
 #define FRAME_TOOL_BAR_HEIGHT(f) (f)->tool_bar_height
 
+/* Size of F's tool bar if it is placed at the top of the
+   frame, else 0.  */
+
+#define FRAME_TOOL_BAR_TOP_HEIGHT(f)                   \
+  ((BASE_EQ ((f)->tool_bar_position, Qtop))            \
+   ? (f)->tool_bar_height : 0)
+
+#define FRAME_TOOL_BAR_TOP_LINES(f)                    \
+  ((BASE_EQ ((f)->tool_bar_position, Qtop))            \
+   ? (f)->tool_bar_height : 0)
+
+/* Size of F's tool bar if it is placed at the bottom of the
+   frame.  */
+#define FRAME_TOOL_BAR_BOTTOM_HEIGHT(f)                        \
+  ((BASE_EQ ((f)->tool_bar_position, Qbottom))         \
+   ? (f)->tool_bar_height : 0)
+
+#define FRAME_TOOL_BAR_BOTTOM_LINES(f)                 \
+  ((BASE_EQ ((f)->tool_bar_position, Qbottom))         \
+   ? (f)->tool_bar_lines : 0)
+
 /* Height of frame F's top margin in frame lines.  */
 #define FRAME_TOP_MARGIN(F)                    \
   (FRAME_MENU_BAR_LINES (F)                    \
    + FRAME_TAB_BAR_LINES (F)                   \
-   + FRAME_TOOL_BAR_LINES (F))
+   + FRAME_TOOL_BAR_TOP_LINES (F))
 
 /* Pixel height of frame F's top margin.  */
+
 #define FRAME_TOP_MARGIN_HEIGHT(F)             \
+  (FRAME_MENU_BAR_HEIGHT (F)                   \
+   + FRAME_TAB_BAR_HEIGHT (F)                  \
+   + FRAME_TOOL_BAR_TOP_HEIGHT (F))
+
+/* Height of F's bottom margin in frame lines.  */
+
+#define FRAME_BOTTOM_MARGIN(f)                 \
+  (FRAME_TOOL_BAR_BOTTOM_LINES (f))
+
+/* Pixel height of frame F's bottom margin.  */
+
+#define FRAME_BOTTOM_MARGIN_HEIGHT(f)          \
+  (FRAME_TOOL_BAR_BOTTOM_HEIGHT (f))
+
+/* Size of both vertical margins combined.  */
+
+#define FRAME_MARGINS(F)                       \
+  (FRAME_MENU_BAR_LINES (F)                    \
+   + FRAME_TAB_BAR_LINES (F)                   \
+   + FRAME_TOOL_BAR_LINES (F))
+
+#define FRAME_MARGIN_HEIGHT(F)                 \
   (FRAME_MENU_BAR_HEIGHT (F)                   \
    + FRAME_TAB_BAR_HEIGHT (F)                  \
    + FRAME_TOOL_BAR_HEIGHT (F))
@@ -1625,7 +1668,7 @@ #define FRAME_PIXEL_WIDTH_TO_TEXT_COLS(f, width)          
        \
 
 #define FRAME_PIXEL_HEIGHT_TO_TEXT_LINES(f, height)                    \
   (((height)                                                           \
-    - FRAME_TOP_MARGIN_HEIGHT (f)                                      \
+    - FRAME_MARGIN_HEIGHT (f)                                          \
     - FRAME_SCROLL_BAR_AREA_HEIGHT (f)                                 \
     - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))                             \
    / FRAME_LINE_HEIGHT (f))
@@ -1640,7 +1683,7 @@ #define FRAME_TEXT_TO_PIXEL_WIDTH(f, width)         \
 
 #define FRAME_TEXT_TO_PIXEL_HEIGHT(f, height)       \
   ((height)                                         \
-   + FRAME_TOP_MARGIN_HEIGHT (f)                    \
+   + FRAME_MARGIN_HEIGHT (f)                        \
    + FRAME_SCROLL_BAR_AREA_HEIGHT (f)               \
    + 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
 
@@ -1654,7 +1697,7 @@ #define FRAME_PIXEL_TO_TEXT_WIDTH(f, width)         \
 
 #define FRAME_PIXEL_TO_TEXT_HEIGHT(f, height)          \
   ((height)                                            \
-   - FRAME_TOP_MARGIN_HEIGHT (f)                       \
+   - FRAME_MARGIN_HEIGHT (f)                           \
    - FRAME_SCROLL_BAR_AREA_HEIGHT (f)                  \
    - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
 
@@ -1664,7 +1707,7 @@ #define FRAME_INNER_WIDTH(f)                      \
 
 #define FRAME_INNER_HEIGHT(f)                  \
   (FRAME_PIXEL_HEIGHT (f)                      \
-   - FRAME_TOP_MARGIN_HEIGHT (f)               \
+   - FRAME_MARGIN_HEIGHT (f)                   \
    - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
 
 /* Value is the smallest width of any character in any font on frame F.  */
diff --git a/src/haikufns.c b/src/haikufns.c
index b4e68495a35..d34e7c13abf 100644
--- a/src/haikufns.c
+++ b/src/haikufns.c
@@ -263,15 +263,26 @@ haiku_set_tool_bar_position (struct frame *f,
                             Lisp_Object new_value,
                             Lisp_Object old_value)
 {
-  Lisp_Object choice = list4 (Qleft, Qright, Qtop, Qbottom);
+  if (!EQ (new_value, Qtop) && !EQ (new_value, Qbottom))
+    error ("Tool bar position must be either `top' or `bottom'");
 
-  if (!NILP (Fmemq (new_value, choice)))
-    {
-      if (!EQ (new_value, Qtop))
-       error ("The only supported tool bar position is top");
-    }
-  else
-    wrong_choice (choice, new_value);
+  if (EQ (new_value, old_value))
+    return;
+
+  /* Set the tool bar position.  */
+  fset_tool_bar_position (f, new_value);
+
+  /* Now reconfigure frame glyphs to place the tool bar at the bottom.
+     While the inner height has not changed, call
+     `resize_frame_windows' to place each of the windows at its new
+     position.  */
+
+  adjust_frame_size (f, -1, -1, 3, false, Qtool_bar_position);
+  adjust_frame_glyphs (f);
+  SET_FRAME_GARBAGED (f);
+
+  if (FRAME_HAIKU_WINDOW (f))
+    haiku_clear_under_internal_border (f);
 }
 
 static void
@@ -1436,10 +1447,11 @@ haiku_set_menu_bar_lines (struct frame *f, Lisp_Object 
value, Lisp_Object oldval
 }
 
 /* Return geometric attributes of FRAME.  According to the value of
-   ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the inner
-   edges of FRAME, the root window edges of frame (Qroot_edges).  Any
-   other value means to return the geometry as returned by
+   ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the
+   inner edges of FRAME, the root window edges of frame (Qroot_edges).
+   Any other value means to return the geometry as returned by
    Fx_frame_geometry.  */
+
 static Lisp_Object
 frame_geometry (Lisp_Object frame, Lisp_Object attribute)
 {
@@ -1448,6 +1460,7 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
   int outer_x, outer_y, outer_width, outer_height;
   int right_off, bottom_off, top_off;
   int native_x, native_y;
+  int inner_left, inner_top, inner_right, inner_bottom;
 
   f = decode_window_system_frame (frame);
   parent = FRAME_PARENT_FRAME (f);
@@ -1473,6 +1486,35 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
       native_y -= FRAME_OUTPUT_DATA (parent)->frame_y;
     }
 
+  internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
+  inner_left = native_left + internal_border_width;
+  inner_top = native_top + internal_border_width;
+  inner_right = (native_left + FRAME_PIXEL_WIDTH (f)
+                - internal_border_width);
+  inner_bottom = (native_top + FRAME_PIXEL_HEIGHT (f)
+                 - internal_border_width);
+
+  tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
+  tab_bar_width = (tab_bar_height
+                  ? (FRAME_PIXEL_WIDTH (f) - 2
+                     * internal_border_width)
+                  : 0);
+  inner_top += tab_bar_height;
+
+  tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
+  tool_bar_width = (tool_bar_height
+                   ? (FRAME_PIXEL_WIDTH (f) - 2
+                      * internal_border_width)
+                   : 0);
+
+  /* Subtract or add to the inner dimensions based on the tool bar
+     position.  */
+
+  if (EQ (FRAME_TOOL_BAR_POSITION (f), Qtop))
+    inner_top += tool_bar_height;
+  else
+    inner_bottom -= tool_bar_height;
+
   if (EQ (attribute, Qouter_edges))
     return list4i (outer_x, outer_y,
                   outer_x + outer_width,
@@ -1482,14 +1524,7 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
                   native_x + FRAME_PIXEL_WIDTH (f),
                   native_y + FRAME_PIXEL_HEIGHT (f));
   else if (EQ (attribute, Qinner_edges))
-    return list4i (native_x + FRAME_INTERNAL_BORDER_WIDTH (f),
-                  native_y + FRAME_INTERNAL_BORDER_WIDTH (f)
-                  + FRAME_MENU_BAR_HEIGHT (f) + FRAME_TOOL_BAR_HEIGHT (f),
-                  native_x - FRAME_INTERNAL_BORDER_WIDTH (f)
-                  + FRAME_PIXEL_WIDTH (f),
-                  native_y + FRAME_PIXEL_HEIGHT (f)
-                  - FRAME_INTERNAL_BORDER_WIDTH (f));
-
+    return list4i (inner_left, inner_top, inner_right, inner_bottom);
   else
     return list (Fcons (Qouter_position,
                        Fcons (make_fixnum (outer_x),
@@ -1508,8 +1543,11 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
                        Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f)
                                            - (FRAME_INTERNAL_BORDER_WIDTH (f) 
* 2)),
                               make_fixnum (FRAME_MENU_BAR_HEIGHT (f)))),
+                Fcons (Qtab_bar_size,
+                       Fcons (make_fixnum (tab_bar_width),
+                              make_fixnum (tab_bar_height))),
                 Fcons (Qtool_bar_external, Qnil),
-                Fcons (Qtool_bar_position, Qtop),
+                Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
                 Fcons (Qtool_bar_size,
                        Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f)
                                            - (FRAME_INTERNAL_BORDER_WIDTH (f) 
* 2)),
diff --git a/src/haikuterm.c b/src/haikuterm.c
index 212870064e8..ed28a806ff2 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -4165,7 +4165,8 @@ haiku_flash (struct frame *f)
 
       BView_InvertRect (view, flash_left,
                        (height - flash_height
-                        - FRAME_INTERNAL_BORDER_WIDTH (f)),
+                        - FRAME_INTERNAL_BORDER_WIDTH (f)
+                        - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
                        width, flash_height);
     }
   else
@@ -4210,7 +4211,8 @@ haiku_flash (struct frame *f)
 
       BView_InvertRect (view, flash_left,
                        (height - flash_height
-                        - FRAME_INTERNAL_BORDER_WIDTH (f)),
+                        - FRAME_INTERNAL_BORDER_WIDTH (f)
+                        - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
                        width, flash_height);
     }
   else
@@ -4465,14 +4467,16 @@ haiku_clear_under_internal_border (struct frame *f)
       int width = FRAME_PIXEL_WIDTH (f);
       int height = FRAME_PIXEL_HEIGHT (f);
       int margin = FRAME_TOP_MARGIN_HEIGHT (f);
-      int face_id =
-       (FRAME_PARENT_FRAME (f)
-        ? (!NILP (Vface_remapping_alist)
-           ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
-           : CHILD_FRAME_BORDER_FACE_ID)
-        : (!NILP (Vface_remapping_alist)
-           ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
-           : INTERNAL_BORDER_FACE_ID));
+      int bottom_margin = FRAME_BOTTOM_MARGIN_HEIGHT (f);
+      int face_id = (FRAME_PARENT_FRAME (f)
+                    ? (!NILP (Vface_remapping_alist)
+                       ? lookup_basic_face (NULL, f,
+                                            CHILD_FRAME_BORDER_FACE_ID)
+                       : CHILD_FRAME_BORDER_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);
       void *view = FRAME_HAIKU_DRAWABLE (f);
 
@@ -4492,7 +4496,8 @@ haiku_clear_under_internal_border (struct frame *f)
       BView_FillRectangle (view, 0, 0, border, height);
       BView_FillRectangle (view, 0, margin, width, border);
       BView_FillRectangle (view, width - border, 0, border, height);
-      BView_FillRectangle (view, 0, height - border, width, border);
+      BView_FillRectangle (view, 0, height - bottom_margin - border,
+                          width, border);
       BView_EndClip (view);
       BView_draw_unlock (view);
       unblock_input ();
diff --git a/src/nsfns.m b/src/nsfns.m
index 8804a7df7cf..90159533128 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -706,8 +706,10 @@ Turn the input menu (an NSMenu) into a lisp list for 
tracking on lisp side.
     ns_change_tab_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
 }
 
+
+
+/* Tool bar support.  */
 
-/* toolbar support */
 static void
 ns_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
 {
@@ -760,7 +762,16 @@ Turn the input menu (an NSMenu) into a lisp list for 
tracking on lisp side.
 }
 
 static void
-ns_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object 
oldval)
+ns_set_tool_bar_position (struct frame *f, Lisp_Object arg,
+                         Lisp_Object oldval)
+{
+  if (!EQ (arg, Qtop))
+    error ("Tool bar position must be `top'");
+}
+
+static void
+ns_set_child_frame_border_width (struct frame *f, Lisp_Object arg,
+                                Lisp_Object oldval)
 {
   int border;
 
@@ -1055,7 +1066,7 @@ Turn the input menu (an NSMenu) into a lisp list for 
tracking on lisp side.
   gui_set_font_backend, /* generic OK */
   gui_set_alpha,
   0, /* x_set_sticky */
-  0, /* x_set_tool_bar_position */
+  ns_set_tool_bar_position,
   0, /* x_set_inhibit_double_buffering */
   ns_set_undecorated,
   ns_set_parent_frame,
diff --git a/src/nsterm.m b/src/nsterm.m
index 3e089cc1ff1..8c72bb25df1 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -2728,6 +2728,7 @@ Hide the window (X11 semantics)
       int width = FRAME_PIXEL_WIDTH (f);
       int height = FRAME_PIXEL_HEIGHT (f);
       int margin = FRAME_TOP_MARGIN_HEIGHT (f);
+      int bottom_margin = FRAME_BOTTOM_MARGIN_HEIGHT (f);
       int face_id =
         (FRAME_PARENT_FRAME (f)
          ? (!NILP (Vface_remapping_alist)
@@ -2753,7 +2754,8 @@ Hide the window (X11 semantics)
       NSRectFill (NSMakeRect (0, 0, border, height));
       NSRectFill (NSMakeRect (0, margin, width, border));
       NSRectFill (NSMakeRect (width - border, 0, border, height));
-      NSRectFill (NSMakeRect (0, height - border, width, border));
+      NSRectFill (NSMakeRect (0, height - bottom_margin - border,
+                             width, border));
       ns_unfocus (f);
     }
 }
diff --git a/src/pgtkfns.c b/src/pgtkfns.c
index 801f97d26d2..9cec7243515 100644
--- a/src/pgtkfns.c
+++ b/src/pgtkfns.c
@@ -3451,7 +3451,7 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
   tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
   tab_bar_width = (tab_bar_height
                   ? native_width - 2 * internal_border_width : 0);
-  /* inner_top += tab_bar_height; */
+  inner_top += tab_bar_height;
 
   /* Construct list.  */
   if (EQ (attribute, Qouter_edges))
@@ -3564,7 +3564,9 @@ manager (like the title bar or external borders) as well 
as any external
                                 ? type : Qnative_edges));
 }
 
-DEFUN ("pgtk-set-mouse-absolute-pixel-position", 
Fpgtk_set_mouse_absolute_pixel_position, 
Spgtk_set_mouse_absolute_pixel_position, 2, 2, 0,
+DEFUN ("pgtk-set-mouse-absolute-pixel-position",
+       Fpgtk_set_mouse_absolute_pixel_position,
+       Spgtk_set_mouse_absolute_pixel_position, 2, 2, 0,
        doc: /* Move mouse pointer to absolute pixel position (X, Y).
 The coordinates X and Y are interpreted in pixels relative to a position
 \(0, 0) of the selected frame's display.  */)
@@ -3583,7 +3585,9 @@ DEFUN ("pgtk-set-mouse-absolute-pixel-position", 
Fpgtk_set_mouse_absolute_pixel_
   return Qnil;
 }
 
-DEFUN ("pgtk-mouse-absolute-pixel-position", 
Fpgtk_mouse_absolute_pixel_position, Spgtk_mouse_absolute_pixel_position, 0, 0, 
0,
+DEFUN ("pgtk-mouse-absolute-pixel-position",
+       Fpgtk_mouse_absolute_pixel_position,
+       Spgtk_mouse_absolute_pixel_position, 0, 0, 0,
        doc: /* Return absolute position of mouse cursor in pixels.
 The position is returned as a cons cell (X . Y) of the
 coordinates of the mouse cursor position in pixels relative to a
@@ -3605,7 +3609,8 @@ position (0, 0) of the selected frame's terminal. */)
 }
 
 
-DEFUN ("pgtk-page-setup-dialog", Fpgtk_page_setup_dialog, 
Spgtk_page_setup_dialog, 0, 0, 0,
+DEFUN ("pgtk-page-setup-dialog", Fpgtk_page_setup_dialog,
+       Spgtk_page_setup_dialog, 0, 0, 0,
        doc: /* Pop up a page setup dialog.
 The current page setup can be obtained using `x-get-page-setup'.  */)
   (void)
@@ -3617,7 +3622,8 @@ DEFUN ("pgtk-page-setup-dialog", Fpgtk_page_setup_dialog, 
Spgtk_page_setup_dialo
   return Qnil;
 }
 
-DEFUN ("pgtk-get-page-setup", Fpgtk_get_page_setup, Spgtk_get_page_setup, 0, 
0, 0,
+DEFUN ("pgtk-get-page-setup", Fpgtk_get_page_setup,
+       Spgtk_get_page_setup, 0, 0, 0,
        doc: /* Return the value of the current page setup.
 The return value is an alist containing the following keys:
 
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index 91e4d828f51..dc2d6477bb5 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -3766,7 +3766,8 @@ pgtk_flash (struct frame *f)
       cairo_rectangle (cr,
                       flash_left,
                       (height - flash_height
-                       - FRAME_INTERNAL_BORDER_WIDTH (f)),
+                       - FRAME_INTERNAL_BORDER_WIDTH (f)
+                       - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
                       width, flash_height);
       cairo_fill (cr);
     }
@@ -4947,14 +4948,16 @@ pgtk_clear_under_internal_border (struct frame *f)
       int width = FRAME_PIXEL_WIDTH (f);
       int height = FRAME_PIXEL_HEIGHT (f);
       int margin = FRAME_TOP_MARGIN_HEIGHT (f);
-      int face_id =
-       (FRAME_PARENT_FRAME (f)
-        ? (!NILP (Vface_remapping_alist)
-           ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
-           : CHILD_FRAME_BORDER_FACE_ID)
-        : (!NILP (Vface_remapping_alist)
-           ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
-           : INTERNAL_BORDER_FACE_ID));
+      int bottom_margin = FRAME_BOTTOM_MARGIN_HEIGHT (f);
+      int face_id = (FRAME_PARENT_FRAME (f)
+                    ? (!NILP (Vface_remapping_alist)
+                       ? lookup_basic_face (NULL, f,
+                                            CHILD_FRAME_BORDER_FACE_ID)
+                       : CHILD_FRAME_BORDER_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 ();
@@ -4965,15 +4968,18 @@ pgtk_clear_under_internal_border (struct frame *f)
          fill_background_by_face (f, face, 0, 0, border, height);
          fill_background_by_face (f, face, width - border, 0, border,
                                   height);
-         fill_background_by_face (f, face, 0, height - border, width,
-                                  border);
+         fill_background_by_face (f, face, 0, (height
+                                               - bottom_margin
+                                               - border),
+                                  width, border);
        }
       else
        {
          pgtk_clear_area (f, 0, 0, border, height);
          pgtk_clear_area (f, 0, margin, width, border);
          pgtk_clear_area (f, width - border, 0, border, height);
-         pgtk_clear_area (f, 0, height - border, width, border);
+         pgtk_clear_area (f, 0, height - bottom_margin - border,
+                          width, border);
        }
 
       unblock_input ();
diff --git a/src/w32fns.c b/src/w32fns.c
index 745f561e6b1..c676c25afdc 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1537,14 +1537,16 @@ w32_clear_under_internal_border (struct frame *f)
     {
       int width = FRAME_PIXEL_WIDTH (f);
       int height = FRAME_PIXEL_HEIGHT (f);
-      int face_id =
-       (FRAME_PARENT_FRAME (f)
-        ? (!NILP (Vface_remapping_alist)
-           ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
-           : CHILD_FRAME_BORDER_FACE_ID)
-        : (!NILP (Vface_remapping_alist)
-           ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
-           : INTERNAL_BORDER_FACE_ID));
+      int bottom_margin = FRAME_BOTTOM_MARGIN_HEIGHT (f);
+      int face_id = (FRAME_PARENT_FRAME (f)
+                    ? (!NILP (Vface_remapping_alist)
+                       ? lookup_basic_face (NULL, f,
+                                            CHILD_FRAME_BORDER_FACE_ID)
+                       : CHILD_FRAME_BORDER_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 ();
@@ -1554,17 +1556,21 @@ w32_clear_under_internal_border (struct frame *f)
          /* Fill border with internal border face.  */
          unsigned long color = face->background;
 
-         w32_fill_area (f, hdc, color, 0, FRAME_TOP_MARGIN_HEIGHT (f), width, 
border);
+         w32_fill_area (f, hdc, color, 0, FRAME_TOP_MARGIN_HEIGHT (f),
+                        width, border);
          w32_fill_area (f, hdc, color, 0, 0, border, height);
          w32_fill_area (f, hdc, color, width - border, 0, border, height);
-         w32_fill_area (f, hdc, color, 0, height - border, width, border);
+         w32_fill_area (f, hdc, color, 0, height - bottom_margin - border,
+                        width, border);
        }
       else
        {
-         w32_clear_area (f, hdc, 0, FRAME_TOP_MARGIN_HEIGHT (f), width, 
border);
+         w32_clear_area (f, hdc, 0, FRAME_TOP_MARGIN_HEIGHT (f),
+                         width, border);
          w32_clear_area (f, hdc, 0, 0, border, height);
          w32_clear_area (f, hdc, width - border, 0, border, height);
-         w32_clear_area (f, hdc, 0, height - border, width, border);
+         w32_clear_area (f, hdc, 0, height - bottom_margin - border,
+                         width, border);
        }
       release_frame_dc (f, hdc);
       unblock_input ();
@@ -1806,6 +1812,33 @@ w32_set_tool_bar_lines (struct frame *f, Lisp_Object 
value, Lisp_Object oldval)
   w32_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
 }
 
+static void
+w32_set_tool_bar_position (struct frame *f,
+                          Lisp_Object new_value,
+                          Lisp_Object old_value)
+{
+  if (!EQ (new_value, Qtop) && !EQ (new_value, Qbottom))
+    error ("Tool bar position must be either `top' or `bottom'");
+
+  if (EQ (new_value, old_value))
+    return;
+
+  /* Set the tool bar position.  */
+  fset_tool_bar_position (f, new_value);
+
+  /* Now reconfigure frame glyphs to place the tool bar at the
+     bottom.  While the inner height has not changed, call
+     `resize_frame_windows' to place each of the windows at its
+     new position.  */
+
+  adjust_frame_size (f, -1, -1, 3, false, Qtool_bar_position);
+  adjust_frame_glyphs (f);
+  SET_FRAME_GARBAGED (f);
+
+  if (FRAME_W32_WINDOW (f))
+    w32_clear_under_internal_border (f);
+}
+
 /* Enable or disable double buffering on frame F.
 
    When double buffering is enabled, all drawing happens on a back
@@ -9084,10 +9117,11 @@ manager (like the title bar or external borders) as 
well as any external
          return list4 (make_fixnum (left + internal_border_width),
                        make_fixnum (top
                                     + FRAME_TAB_BAR_HEIGHT (f)
-                                    + FRAME_TOOL_BAR_HEIGHT (f)
+                                    + FRAME_TOOL_BAR_TOP_HEIGHT (f)
                                     + internal_border_width),
                        make_fixnum (right - internal_border_width),
-                       make_fixnum (bottom - internal_border_width));
+                       make_fixnum (bottom - internal_border_width
+                                    - FRAME_TOOL_BAR_BOTTOM_HEIGHT (f)));
        }
       else
        return list4 (make_fixnum (left), make_fixnum (top),
@@ -10556,7 +10590,7 @@ DEFUN ("w32-set-wallpaper", Fw32_set_wallpaper, 
Sw32_set_wallpaper, 1, 1, 0,
   gui_set_font_backend,
   gui_set_alpha,
   0, /* x_set_sticky */
-  0, /* x_set_tool_bar_position */
+  w32_set_tool_bar_position,
   w32_set_inhibit_double_buffering,
   w32_set_undecorated,
   w32_set_parent_frame,
diff --git a/src/window.c b/src/window.c
index e22fea0bb7a..fa024b6d2d8 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4828,10 +4828,9 @@ DEFUN ("window-resize-apply-total", 
Fwindow_resize_apply_total, Swindow_resize_a
   return Qt;
 }
 
+/* Resize frame F's windows when F's inner height (inner width if
+   HORFLAG is true) has been set to SIZE pixels.  */
 
-/**
-Resize frame F's windows when F's inner height (inner width if HORFLAG
-is true) has been set to SIZE pixels.  */
 void
 resize_frame_windows (struct frame *f, int size, bool horflag)
 {
diff --git a/src/xdisp.c b/src/xdisp.c
index 8bcf2acfe04..4a48b93b29e 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -37494,7 +37494,7 @@ init_xdisp (void)
       r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
       r->total_cols = FRAME_COLS (f);
       r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
-      r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
+      r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_MARGINS (f);
       r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
 
       m->top_line = FRAME_TOTAL_LINES (f) - 1;
diff --git a/src/xfns.c b/src/xfns.c
index 234a48c908f..a58e854811b 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -807,23 +807,45 @@ x_set_tool_bar_position (struct frame *f,
                          Lisp_Object new_value,
                          Lisp_Object old_value)
 {
-  Lisp_Object choice = list4 (Qleft, Qright, Qtop, Qbottom);
+#ifdef USE_GTK
+  Lisp_Object choice;
+
+  choice = list4 (Qleft, Qright, Qtop, Qbottom);
 
   if (!NILP (Fmemq (new_value, choice)))
     {
-#ifdef USE_GTK
       if (!EQ (new_value, old_value))
        {
          xg_change_toolbar_position (f, new_value);
          fset_tool_bar_position (f, new_value);
        }
-#else
-      if (!EQ (new_value, Qtop))
-       error ("The only supported tool bar position is top");
-#endif
+#else /* !USE_GTK */
+      if (!EQ (new_value, Qtop) && !EQ (new_value, Qbottom))
+       error ("Tool bar position must be either `top' or `bottom'");
+
+      if (EQ (new_value, old_value))
+       return;
+
+      /* Set the tool bar position.  */
+      fset_tool_bar_position (f, new_value);
+
+      /* Now reconfigure frame glyphs to place the tool bar at the
+        bottom.  While the inner height has not changed, call
+        `resize_frame_windows' to place each of the windows at its
+        new position.  */
+
+      adjust_frame_size (f, -1, -1, 3, false, Qtool_bar_position);
+      adjust_frame_glyphs (f);
+      SET_FRAME_GARBAGED (f);
+
+      if (FRAME_X_WINDOW (f))
+       x_clear_under_internal_border (f);
+#endif /* USE_GTK */
+#ifdef USE_GTK
     }
   else
     wrong_choice (choice, new_value);
+#endif /* USE_GTK */
 }
 
 #ifdef HAVE_XDBE
@@ -6673,10 +6695,11 @@ DEFUN ("x-display-monitor-attributes-list", 
Fx_display_monitor_attributes_list,
 }
 
 /* Return geometric attributes of FRAME.  According to the value of
-   ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the native
-   edges of FRAME (Qnative_edges), or the inner edges of frame
+   ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the
+   native edges of FRAME (Qnative_edges), or the inner edges of frame
    (Qinner_edges).  Any other value means to return the geometry as
    returned by Fx_frame_geometry.  */
+
 static Lisp_Object
 frame_geometry (Lisp_Object frame, Lisp_Object attribute)
 {
@@ -6765,8 +6788,8 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
 
   tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
   tab_bar_width = (tab_bar_height
-                   ? native_width - 2 * internal_border_width
-                   : 0);
+                  ? native_width - 2 * internal_border_width
+                  : 0);
   inner_top += tab_bar_height;
 
 #ifdef HAVE_EXT_TOOL_BAR
@@ -6806,7 +6829,14 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
   tool_bar_width = (tool_bar_height
                    ? native_width - 2 * internal_border_width
                    : 0);
-  inner_top += tool_bar_height;
+
+  /* Subtract or add to the inner dimensions based on the tool bar
+     position.  */
+
+  if (EQ (FRAME_TOOL_BAR_POSITION (f), Qtop))
+    inner_top += tool_bar_height;
+  else
+    inner_bottom -= tool_bar_height;
 #endif
 
   /* Construct list.  */
diff --git a/src/xterm.c b/src/xterm.c
index 0450230efe6..7fb6283c088 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -7574,14 +7574,16 @@ x_clear_under_internal_border (struct frame *f)
       int width = FRAME_PIXEL_WIDTH (f);
       int height = FRAME_PIXEL_HEIGHT (f);
       int margin = FRAME_TOP_MARGIN_HEIGHT (f);
-      int face_id =
-       (FRAME_PARENT_FRAME (f)
-        ? (!NILP (Vface_remapping_alist)
-           ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
-           : CHILD_FRAME_BORDER_FACE_ID)
-        : (!NILP (Vface_remapping_alist)
-           ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
-           : INTERNAL_BORDER_FACE_ID));
+      int bottom_margin = FRAME_BOTTOM_MARGIN_HEIGHT (f);
+      int face_id = (FRAME_PARENT_FRAME (f)
+                    ? (!NILP (Vface_remapping_alist)
+                       ? lookup_basic_face (NULL, f,
+                                            CHILD_FRAME_BORDER_FACE_ID)
+                       : CHILD_FRAME_BORDER_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)
@@ -7594,7 +7596,8 @@ x_clear_under_internal_border (struct frame *f)
          x_fill_rectangle (f, gc, 0, margin, width, border, false);
          x_fill_rectangle (f, gc, 0, 0, border, height, false);
          x_fill_rectangle (f, gc, width - border, 0, border, height, false);
-         x_fill_rectangle (f, gc, 0, height - border, width, border, false);
+         x_fill_rectangle (f, gc, 0, height - bottom_margin - border,
+                           width, border, false);
          XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
        }
       else
@@ -7602,7 +7605,8 @@ x_clear_under_internal_border (struct frame *f)
          x_clear_area (f, 0, 0, border, height);
          x_clear_area (f, 0, margin, width, border);
          x_clear_area (f, width - border, 0, border, height);
-         x_clear_area (f, 0, height - border, width, border);
+         x_clear_area (f, 0, height - bottom_margin - border,
+                       width, border);
        }
     }
 }
@@ -11318,7 +11322,8 @@ XTflash (struct frame *f)
       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
                      flash_left,
                      (height - flash_height
-                      - FRAME_INTERNAL_BORDER_WIDTH (f)),
+                      - FRAME_INTERNAL_BORDER_WIDTH (f)
+                      - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
                      width, flash_height);
 
     }
@@ -11372,7 +11377,8 @@ XTflash (struct frame *f)
       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
                      flash_left,
                      (height - flash_height
-                      - FRAME_INTERNAL_BORDER_WIDTH (f)),
+                      - FRAME_INTERNAL_BORDER_WIDTH (f)
+                      - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
                      width, flash_height);
     }
   else


reply via email to

[Prev in Thread] Current Thread [Next in Thread]