aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-06-21 10:12:18 +0800
committerPo Lu2023-06-21 10:12:18 +0800
commit70cf0d7c6f39a53103cb3f6222cedb8345f5d920 (patch)
tree0c7ab48372d6cb63b9be2c019c3caca2b58240a7 /src
parentaf13157653b05cbd98ea3d7f9b461b37fd69a6e4 (diff)
parentdb6de49f231f863b21547173ce3ac9ab8e5e0d86 (diff)
downloademacs-70cf0d7c6f39a53103cb3f6222cedb8345f5d920.tar.gz
emacs-70cf0d7c6f39a53103cb3f6222cedb8345f5d920.zip
Merge remote-tracking branch 'origin/master' into feature/android
Diffstat (limited to 'src')
-rw-r--r--src/dispnew.c31
-rw-r--r--src/frame.c6
-rw-r--r--src/frame.h83
-rw-r--r--src/haikufns.c82
-rw-r--r--src/haikuterm.c27
-rw-r--r--src/nsfns.m17
-rw-r--r--src/nsterm.m4
-rw-r--r--src/pgtkfns.c16
-rw-r--r--src/pgtkterm.c30
-rw-r--r--src/w32fns.c68
-rw-r--r--src/window.c5
-rw-r--r--src/xdisp.c2
-rw-r--r--src/xfns.c52
-rw-r--r--src/xterm.c30
14 files changed, 326 insertions, 127 deletions
diff --git a/src/dispnew.c b/src/dispnew.c
index 8d039bf9a3d..1e99c7b58bd 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -2224,10 +2224,10 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
2224 2224
2225 w->pixel_top = (FRAME_MENU_BAR_HEIGHT (f) 2225 w->pixel_top = (FRAME_MENU_BAR_HEIGHT (f)
2226 + (!NILP (Vtab_bar_position) 2226 + (!NILP (Vtab_bar_position)
2227 ? FRAME_TOOL_BAR_HEIGHT (f) : 0)); 2227 ? FRAME_TOOL_BAR_TOP_HEIGHT (f) : 0));
2228 w->top_line = (FRAME_MENU_BAR_LINES (f) 2228 w->top_line = (FRAME_MENU_BAR_LINES (f)
2229 + (!NILP (Vtab_bar_position) 2229 + (!NILP (Vtab_bar_position)
2230 ? FRAME_TOOL_BAR_LINES (f) : 0)); 2230 ? FRAME_TOOL_BAR_TOP_LINES (f) : 0));
2231 w->total_cols = FRAME_TOTAL_COLS (f); 2231 w->total_cols = FRAME_TOTAL_COLS (f);
2232 w->pixel_width = (FRAME_PIXEL_WIDTH (f) 2232 w->pixel_width = (FRAME_PIXEL_WIDTH (f)
2233 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); 2233 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
@@ -2256,10 +2256,29 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
2256 2256
2257 w->pixel_left = 0; 2257 w->pixel_left = 0;
2258 w->left_col = 0; 2258 w->left_col = 0;
2259 w->pixel_top = FRAME_MENU_BAR_HEIGHT (f) 2259
2260 + (NILP (Vtab_bar_position) ? FRAME_TAB_BAR_HEIGHT (f) : 0); 2260 /* If the tool bar should be placed at the bottom of the frame,
2261 w->top_line = FRAME_MENU_BAR_LINES (f) 2261 place it there instead, outside the internal border. */
2262 + (NILP (Vtab_bar_position) ? FRAME_TAB_BAR_LINES (f) : 0); 2262
2263 if (EQ (FRAME_TOOL_BAR_POSITION (f), Qbottom))
2264 {
2265 w->pixel_top = (FRAME_PIXEL_HEIGHT (f)
2266 - FRAME_TOOL_BAR_HEIGHT (f));
2267 w->top_line = (FRAME_LINES (f)
2268 - FRAME_TOOL_BAR_LINES (f));
2269 }
2270 else
2271 {
2272 /* Otherwise, place the window at the top of the frame. */
2273
2274 w->pixel_top = (FRAME_MENU_BAR_HEIGHT (f)
2275 + (NILP (Vtab_bar_position)
2276 ? FRAME_TAB_BAR_HEIGHT (f) : 0));
2277 w->top_line = (FRAME_MENU_BAR_LINES (f)
2278 + (NILP (Vtab_bar_position)
2279 ? FRAME_TAB_BAR_LINES (f) : 0));
2280 }
2281
2263 w->total_cols = FRAME_TOTAL_COLS (f); 2282 w->total_cols = FRAME_TOTAL_COLS (f);
2264 w->pixel_width = (FRAME_PIXEL_WIDTH (f) 2283 w->pixel_width = (FRAME_PIXEL_WIDTH (f)
2265 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); 2284 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
diff --git a/src/frame.c b/src/frame.c
index 04ffdd5494d..a2b04a9d99b 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -714,10 +714,10 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
714 ? old_native_height 714 ? old_native_height
715 : max (FRAME_TEXT_TO_PIXEL_HEIGHT (f, new_text_height), 715 : max (FRAME_TEXT_TO_PIXEL_HEIGHT (f, new_text_height),
716 min_inner_height 716 min_inner_height
717 + FRAME_TOP_MARGIN_HEIGHT (f) 717 + FRAME_MARGIN_HEIGHT (f)
718 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f))); 718 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)));
719 new_inner_height = (new_native_height 719 new_inner_height = (new_native_height
720 - FRAME_TOP_MARGIN_HEIGHT (f) 720 - FRAME_MARGIN_HEIGHT (f)
721 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); 721 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
722 new_text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, new_native_height); 722 new_text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, new_native_height);
723 new_text_lines = new_text_height / unit_height; 723 new_text_lines = new_text_height / unit_height;
@@ -944,11 +944,9 @@ make_frame (bool mini_p)
944 f = allocate_frame (); 944 f = allocate_frame ();
945 XSETFRAME (frame, f); 945 XSETFRAME (frame, f);
946 946
947#ifdef USE_GTK
948 /* Initialize Lisp data. Note that allocate_frame initializes all 947 /* Initialize Lisp data. Note that allocate_frame initializes all
949 Lisp data to nil, so do it only for slots which should not be nil. */ 948 Lisp data to nil, so do it only for slots which should not be nil. */
950 fset_tool_bar_position (f, Qtop); 949 fset_tool_bar_position (f, Qtop);
951#endif
952 950
953 /* Initialize non-Lisp data. Note that allocate_frame zeroes out all 951 /* Initialize non-Lisp data. Note that allocate_frame zeroes out all
954 non-Lisp data, so do it only for slots which should not be zero. 952 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 41b4cd444f6..8142dec456b 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -264,11 +264,9 @@ struct frame
264 Lisp_Object current_tool_bar_string; 264 Lisp_Object current_tool_bar_string;
265#endif 265#endif
266 266
267#ifdef USE_GTK
268 /* Where tool bar is, can be left, right, top or bottom. 267 /* Where tool bar is, can be left, right, top or bottom.
269 Except with GTK, the only supported position is `top'. */ 268 Except with GTK, the only supported position is `top'. */
270 Lisp_Object tool_bar_position; 269 Lisp_Object tool_bar_position;
271#endif
272 270
273#if defined (HAVE_XFT) || defined (HAVE_FREETYPE) 271#if defined (HAVE_XFT) || defined (HAVE_FREETYPE)
274 /* List of data specific to font-driver and frame, but common to faces. */ 272 /* List of data specific to font-driver and frame, but common to faces. */
@@ -848,14 +846,9 @@ fset_tool_bar_items (struct frame *f, Lisp_Object val)
848{ 846{
849 f->tool_bar_items = val; 847 f->tool_bar_items = val;
850} 848}
851#ifdef USE_GTK 849
852INLINE void
853fset_tool_bar_position (struct frame *f, Lisp_Object val)
854{
855 f->tool_bar_position = val;
856}
857#endif /* USE_GTK */
858#if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR) 850#if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
851
859INLINE void 852INLINE void
860fset_tool_bar_window (struct frame *f, Lisp_Object val) 853fset_tool_bar_window (struct frame *f, Lisp_Object val)
861{ 854{
@@ -871,7 +864,14 @@ fset_desired_tool_bar_string (struct frame *f, Lisp_Object val)
871{ 864{
872 f->desired_tool_bar_string = val; 865 f->desired_tool_bar_string = val;
873} 866}
874#endif /* HAVE_WINDOW_SYSTEM && !USE_GTK && !HAVE_NS */ 867
868#endif /* HAVE_WINDOW_SYSTEM && !HAVE_EXT_TOOL_BAR */
869
870INLINE void
871fset_tool_bar_position (struct frame *f, Lisp_Object val)
872{
873 f->tool_bar_position = val;
874}
875 875
876INLINE double 876INLINE double
877NUMVAL (Lisp_Object x) 877NUMVAL (Lisp_Object x)
@@ -1064,27 +1064,70 @@ default_pixels_per_inch_y (void)
1064#define FRAME_EXTERNAL_TOOL_BAR(f) false 1064#define FRAME_EXTERNAL_TOOL_BAR(f) false
1065#endif 1065#endif
1066 1066
1067/* This is really supported only with GTK. */ 1067/* Position of F's tool bar; one of Qtop, Qleft, Qright, or
1068#ifdef USE_GTK 1068 Qbottom.
1069
1070 Qleft and Qright are not supported outside GTK+. */
1069#define FRAME_TOOL_BAR_POSITION(f) (f)->tool_bar_position 1071#define FRAME_TOOL_BAR_POSITION(f) (f)->tool_bar_position
1070#else
1071#define FRAME_TOOL_BAR_POSITION(f) ((void) (f), Qtop)
1072#endif
1073 1072
1074/* Size of frame F's internal tool bar in frame lines and pixels. */ 1073/* Size of frame F's internal tool bar in frame lines and pixels. */
1075#define FRAME_TOOL_BAR_LINES(f) (f)->tool_bar_lines 1074#define FRAME_TOOL_BAR_LINES(f) (f)->tool_bar_lines
1076#define FRAME_TOOL_BAR_HEIGHT(f) (f)->tool_bar_height 1075#define FRAME_TOOL_BAR_HEIGHT(f) (f)->tool_bar_height
1077 1076
1077/* Size of F's tool bar if it is placed at the top of the
1078 frame, else 0. */
1079
1080#define FRAME_TOOL_BAR_TOP_HEIGHT(f) \
1081 ((BASE_EQ ((f)->tool_bar_position, Qtop)) \
1082 ? (f)->tool_bar_height : 0)
1083
1084#define FRAME_TOOL_BAR_TOP_LINES(f) \
1085 ((BASE_EQ ((f)->tool_bar_position, Qtop)) \
1086 ? (f)->tool_bar_height : 0)
1087
1088/* Size of F's tool bar if it is placed at the bottom of the
1089 frame. */
1090#define FRAME_TOOL_BAR_BOTTOM_HEIGHT(f) \
1091 ((BASE_EQ ((f)->tool_bar_position, Qbottom)) \
1092 ? (f)->tool_bar_height : 0)
1093
1094#define FRAME_TOOL_BAR_BOTTOM_LINES(f) \
1095 ((BASE_EQ ((f)->tool_bar_position, Qbottom)) \
1096 ? (f)->tool_bar_lines : 0)
1097
1078/* Height of frame F's top margin in frame lines. */ 1098/* Height of frame F's top margin in frame lines. */
1079#define FRAME_TOP_MARGIN(F) \ 1099#define FRAME_TOP_MARGIN(F) \
1080 (FRAME_MENU_BAR_LINES (F) \ 1100 (FRAME_MENU_BAR_LINES (F) \
1081 + FRAME_TAB_BAR_LINES (F) \ 1101 + FRAME_TAB_BAR_LINES (F) \
1082 + FRAME_TOOL_BAR_LINES (F)) 1102 + FRAME_TOOL_BAR_TOP_LINES (F))
1083 1103
1084/* Pixel height of frame F's top margin. */ 1104/* Pixel height of frame F's top margin. */
1105
1085#define FRAME_TOP_MARGIN_HEIGHT(F) \ 1106#define FRAME_TOP_MARGIN_HEIGHT(F) \
1086 (FRAME_MENU_BAR_HEIGHT (F) \ 1107 (FRAME_MENU_BAR_HEIGHT (F) \
1087 + FRAME_TAB_BAR_HEIGHT (F) \ 1108 + FRAME_TAB_BAR_HEIGHT (F) \
1109 + FRAME_TOOL_BAR_TOP_HEIGHT (F))
1110
1111/* Height of F's bottom margin in frame lines. */
1112
1113#define FRAME_BOTTOM_MARGIN(f) \
1114 (FRAME_TOOL_BAR_BOTTOM_LINES (f))
1115
1116/* Pixel height of frame F's bottom margin. */
1117
1118#define FRAME_BOTTOM_MARGIN_HEIGHT(f) \
1119 (FRAME_TOOL_BAR_BOTTOM_HEIGHT (f))
1120
1121/* Size of both vertical margins combined. */
1122
1123#define FRAME_MARGINS(F) \
1124 (FRAME_MENU_BAR_LINES (F) \
1125 + FRAME_TAB_BAR_LINES (F) \
1126 + FRAME_TOOL_BAR_LINES (F))
1127
1128#define FRAME_MARGIN_HEIGHT(F) \
1129 (FRAME_MENU_BAR_HEIGHT (F) \
1130 + FRAME_TAB_BAR_HEIGHT (F) \
1088 + FRAME_TOOL_BAR_HEIGHT (F)) 1131 + FRAME_TOOL_BAR_HEIGHT (F))
1089 1132
1090/* True if frame F is currently visible. */ 1133/* True if frame F is currently visible. */
@@ -1705,7 +1748,7 @@ IMAGE_OPT_FROM_ID (struct frame *f, int id)
1705 1748
1706#define FRAME_PIXEL_HEIGHT_TO_TEXT_LINES(f, height) \ 1749#define FRAME_PIXEL_HEIGHT_TO_TEXT_LINES(f, height) \
1707 (((height) \ 1750 (((height) \
1708 - FRAME_TOP_MARGIN_HEIGHT (f) \ 1751 - FRAME_MARGIN_HEIGHT (f) \
1709 - FRAME_SCROLL_BAR_AREA_HEIGHT (f) \ 1752 - FRAME_SCROLL_BAR_AREA_HEIGHT (f) \
1710 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)) \ 1753 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)) \
1711 / FRAME_LINE_HEIGHT (f)) 1754 / FRAME_LINE_HEIGHT (f))
@@ -1720,7 +1763,7 @@ IMAGE_OPT_FROM_ID (struct frame *f, int id)
1720 1763
1721#define FRAME_TEXT_TO_PIXEL_HEIGHT(f, height) \ 1764#define FRAME_TEXT_TO_PIXEL_HEIGHT(f, height) \
1722 ((height) \ 1765 ((height) \
1723 + FRAME_TOP_MARGIN_HEIGHT (f) \ 1766 + FRAME_MARGIN_HEIGHT (f) \
1724 + FRAME_SCROLL_BAR_AREA_HEIGHT (f) \ 1767 + FRAME_SCROLL_BAR_AREA_HEIGHT (f) \
1725 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)) 1768 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
1726 1769
@@ -1734,7 +1777,7 @@ IMAGE_OPT_FROM_ID (struct frame *f, int id)
1734 1777
1735#define FRAME_PIXEL_TO_TEXT_HEIGHT(f, height) \ 1778#define FRAME_PIXEL_TO_TEXT_HEIGHT(f, height) \
1736 ((height) \ 1779 ((height) \
1737 - FRAME_TOP_MARGIN_HEIGHT (f) \ 1780 - FRAME_MARGIN_HEIGHT (f) \
1738 - FRAME_SCROLL_BAR_AREA_HEIGHT (f) \ 1781 - FRAME_SCROLL_BAR_AREA_HEIGHT (f) \
1739 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)) 1782 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
1740 1783
@@ -1744,7 +1787,7 @@ IMAGE_OPT_FROM_ID (struct frame *f, int id)
1744 1787
1745#define FRAME_INNER_HEIGHT(f) \ 1788#define FRAME_INNER_HEIGHT(f) \
1746 (FRAME_PIXEL_HEIGHT (f) \ 1789 (FRAME_PIXEL_HEIGHT (f) \
1747 - FRAME_TOP_MARGIN_HEIGHT (f) \ 1790 - FRAME_MARGIN_HEIGHT (f) \
1748 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)) 1791 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
1749 1792
1750/* Value is the smallest width of any character in any font on frame F. */ 1793/* 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..8028a73abd1 100644
--- a/src/haikufns.c
+++ b/src/haikufns.c
@@ -263,15 +263,26 @@ haiku_set_tool_bar_position (struct frame *f,
263 Lisp_Object new_value, 263 Lisp_Object new_value,
264 Lisp_Object old_value) 264 Lisp_Object old_value)
265{ 265{
266 Lisp_Object choice = list4 (Qleft, Qright, Qtop, Qbottom); 266 if (!EQ (new_value, Qtop) && !EQ (new_value, Qbottom))
267 error ("Tool bar position must be either `top' or `bottom'");
267 268
268 if (!NILP (Fmemq (new_value, choice))) 269 if (EQ (new_value, old_value))
269 { 270 return;
270 if (!EQ (new_value, Qtop)) 271
271 error ("The only supported tool bar position is top"); 272 /* Set the tool bar position. */
272 } 273 fset_tool_bar_position (f, new_value);
273 else 274
274 wrong_choice (choice, new_value); 275 /* Now reconfigure frame glyphs to place the tool bar at the bottom.
276 While the inner height has not changed, call
277 `resize_frame_windows' to place each of the windows at its new
278 position. */
279
280 adjust_frame_size (f, -1, -1, 3, false, Qtool_bar_position);
281 adjust_frame_glyphs (f);
282 SET_FRAME_GARBAGED (f);
283
284 if (FRAME_HAIKU_WINDOW (f))
285 haiku_clear_under_internal_border (f);
275} 286}
276 287
277static void 288static void
@@ -1436,10 +1447,11 @@ haiku_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval
1436} 1447}
1437 1448
1438/* Return geometric attributes of FRAME. According to the value of 1449/* Return geometric attributes of FRAME. According to the value of
1439 ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the inner 1450 ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the
1440 edges of FRAME, the root window edges of frame (Qroot_edges). Any 1451 inner edges of FRAME, the root window edges of frame (Qroot_edges).
1441 other value means to return the geometry as returned by 1452 Any other value means to return the geometry as returned by
1442 Fx_frame_geometry. */ 1453 Fx_frame_geometry. */
1454
1443static Lisp_Object 1455static Lisp_Object
1444frame_geometry (Lisp_Object frame, Lisp_Object attribute) 1456frame_geometry (Lisp_Object frame, Lisp_Object attribute)
1445{ 1457{
@@ -1448,6 +1460,9 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
1448 int outer_x, outer_y, outer_width, outer_height; 1460 int outer_x, outer_y, outer_width, outer_height;
1449 int right_off, bottom_off, top_off; 1461 int right_off, bottom_off, top_off;
1450 int native_x, native_y; 1462 int native_x, native_y;
1463 int inner_left, inner_top, inner_right, inner_bottom;
1464 int internal_border_width, tab_bar_height;
1465 int tool_bar_height, tab_bar_width;
1451 1466
1452 f = decode_window_system_frame (frame); 1467 f = decode_window_system_frame (frame);
1453 parent = FRAME_PARENT_FRAME (f); 1468 parent = FRAME_PARENT_FRAME (f);
@@ -1473,6 +1488,31 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
1473 native_y -= FRAME_OUTPUT_DATA (parent)->frame_y; 1488 native_y -= FRAME_OUTPUT_DATA (parent)->frame_y;
1474 } 1489 }
1475 1490
1491 internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
1492 inner_left = native_x + internal_border_width;
1493 inner_top = native_y + internal_border_width;
1494 inner_right = (native_x + FRAME_PIXEL_WIDTH (f)
1495 - internal_border_width);
1496 inner_bottom = (native_y + FRAME_PIXEL_HEIGHT (f)
1497 - internal_border_width);
1498
1499 tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
1500 tab_bar_width = (tab_bar_height
1501 ? (FRAME_PIXEL_WIDTH (f) - 2
1502 * internal_border_width)
1503 : 0);
1504 inner_top += tab_bar_height;
1505
1506 tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
1507
1508 /* Subtract or add to the inner dimensions based on the tool bar
1509 position. */
1510
1511 if (EQ (FRAME_TOOL_BAR_POSITION (f), Qtop))
1512 inner_top += tool_bar_height;
1513 else
1514 inner_bottom -= tool_bar_height;
1515
1476 if (EQ (attribute, Qouter_edges)) 1516 if (EQ (attribute, Qouter_edges))
1477 return list4i (outer_x, outer_y, 1517 return list4i (outer_x, outer_y,
1478 outer_x + outer_width, 1518 outer_x + outer_width,
@@ -1482,14 +1522,7 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
1482 native_x + FRAME_PIXEL_WIDTH (f), 1522 native_x + FRAME_PIXEL_WIDTH (f),
1483 native_y + FRAME_PIXEL_HEIGHT (f)); 1523 native_y + FRAME_PIXEL_HEIGHT (f));
1484 else if (EQ (attribute, Qinner_edges)) 1524 else if (EQ (attribute, Qinner_edges))
1485 return list4i (native_x + FRAME_INTERNAL_BORDER_WIDTH (f), 1525 return list4i (inner_left, inner_top, inner_right, inner_bottom);
1486 native_y + FRAME_INTERNAL_BORDER_WIDTH (f)
1487 + FRAME_MENU_BAR_HEIGHT (f) + FRAME_TOOL_BAR_HEIGHT (f),
1488 native_x - FRAME_INTERNAL_BORDER_WIDTH (f)
1489 + FRAME_PIXEL_WIDTH (f),
1490 native_y + FRAME_PIXEL_HEIGHT (f)
1491 - FRAME_INTERNAL_BORDER_WIDTH (f));
1492
1493 else 1526 else
1494 return list (Fcons (Qouter_position, 1527 return list (Fcons (Qouter_position,
1495 Fcons (make_fixnum (outer_x), 1528 Fcons (make_fixnum (outer_x),
@@ -1506,13 +1539,18 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
1506 Fcons (Qmenu_bar_external, Qnil), 1539 Fcons (Qmenu_bar_external, Qnil),
1507 Fcons (Qmenu_bar_size, 1540 Fcons (Qmenu_bar_size,
1508 Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f) 1541 Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f)
1509 - (FRAME_INTERNAL_BORDER_WIDTH (f) * 2)), 1542 - (FRAME_INTERNAL_BORDER_WIDTH (f)
1543 * 2)),
1510 make_fixnum (FRAME_MENU_BAR_HEIGHT (f)))), 1544 make_fixnum (FRAME_MENU_BAR_HEIGHT (f)))),
1545 Fcons (Qtab_bar_size,
1546 Fcons (make_fixnum (tab_bar_width),
1547 make_fixnum (tab_bar_height))),
1511 Fcons (Qtool_bar_external, Qnil), 1548 Fcons (Qtool_bar_external, Qnil),
1512 Fcons (Qtool_bar_position, Qtop), 1549 Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
1513 Fcons (Qtool_bar_size, 1550 Fcons (Qtool_bar_size,
1514 Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f) 1551 Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f)
1515 - (FRAME_INTERNAL_BORDER_WIDTH (f) * 2)), 1552 - (FRAME_INTERNAL_BORDER_WIDTH (f)
1553 * 2)),
1516 make_fixnum (FRAME_TOOL_BAR_HEIGHT (f)))), 1554 make_fixnum (FRAME_TOOL_BAR_HEIGHT (f)))),
1517 Fcons (Qinternal_border_width, 1555 Fcons (Qinternal_border_width,
1518 make_fixnum (FRAME_INTERNAL_BORDER_WIDTH (f)))); 1556 make_fixnum (FRAME_INTERNAL_BORDER_WIDTH (f))));
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)
4165 4165
4166 BView_InvertRect (view, flash_left, 4166 BView_InvertRect (view, flash_left,
4167 (height - flash_height 4167 (height - flash_height
4168 - FRAME_INTERNAL_BORDER_WIDTH (f)), 4168 - FRAME_INTERNAL_BORDER_WIDTH (f)
4169 - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
4169 width, flash_height); 4170 width, flash_height);
4170 } 4171 }
4171 else 4172 else
@@ -4210,7 +4211,8 @@ haiku_flash (struct frame *f)
4210 4211
4211 BView_InvertRect (view, flash_left, 4212 BView_InvertRect (view, flash_left,
4212 (height - flash_height 4213 (height - flash_height
4213 - FRAME_INTERNAL_BORDER_WIDTH (f)), 4214 - FRAME_INTERNAL_BORDER_WIDTH (f)
4215 - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
4214 width, flash_height); 4216 width, flash_height);
4215 } 4217 }
4216 else 4218 else
@@ -4465,14 +4467,16 @@ haiku_clear_under_internal_border (struct frame *f)
4465 int width = FRAME_PIXEL_WIDTH (f); 4467 int width = FRAME_PIXEL_WIDTH (f);
4466 int height = FRAME_PIXEL_HEIGHT (f); 4468 int height = FRAME_PIXEL_HEIGHT (f);
4467 int margin = FRAME_TOP_MARGIN_HEIGHT (f); 4469 int margin = FRAME_TOP_MARGIN_HEIGHT (f);
4468 int face_id = 4470 int bottom_margin = FRAME_BOTTOM_MARGIN_HEIGHT (f);
4469 (FRAME_PARENT_FRAME (f) 4471 int face_id = (FRAME_PARENT_FRAME (f)
4470 ? (!NILP (Vface_remapping_alist) 4472 ? (!NILP (Vface_remapping_alist)
4471 ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID) 4473 ? lookup_basic_face (NULL, f,
4472 : CHILD_FRAME_BORDER_FACE_ID) 4474 CHILD_FRAME_BORDER_FACE_ID)
4473 : (!NILP (Vface_remapping_alist) 4475 : CHILD_FRAME_BORDER_FACE_ID)
4474 ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID) 4476 : (!NILP (Vface_remapping_alist)
4475 : INTERNAL_BORDER_FACE_ID)); 4477 ? lookup_basic_face (NULL, f,
4478 INTERNAL_BORDER_FACE_ID)
4479 : INTERNAL_BORDER_FACE_ID));
4476 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); 4480 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
4477 void *view = FRAME_HAIKU_DRAWABLE (f); 4481 void *view = FRAME_HAIKU_DRAWABLE (f);
4478 4482
@@ -4492,7 +4496,8 @@ haiku_clear_under_internal_border (struct frame *f)
4492 BView_FillRectangle (view, 0, 0, border, height); 4496 BView_FillRectangle (view, 0, 0, border, height);
4493 BView_FillRectangle (view, 0, margin, width, border); 4497 BView_FillRectangle (view, 0, margin, width, border);
4494 BView_FillRectangle (view, width - border, 0, border, height); 4498 BView_FillRectangle (view, width - border, 0, border, height);
4495 BView_FillRectangle (view, 0, height - border, width, border); 4499 BView_FillRectangle (view, 0, height - bottom_margin - border,
4500 width, border);
4496 BView_EndClip (view); 4501 BView_EndClip (view);
4497 BView_draw_unlock (view); 4502 BView_draw_unlock (view);
4498 unblock_input (); 4503 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 @@ ns_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
706 ns_change_tab_bar_height (f, nlines * FRAME_LINE_HEIGHT (f)); 706 ns_change_tab_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
707} 707}
708 708
709
710
711/* Tool bar support. */
709 712
710/* toolbar support */
711static void 713static void
712ns_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) 714ns_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
713{ 715{
@@ -760,7 +762,16 @@ ns_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
760} 762}
761 763
762static void 764static void
763ns_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 765ns_set_tool_bar_position (struct frame *f, Lisp_Object arg,
766 Lisp_Object oldval)
767{
768 if (!EQ (arg, Qtop))
769 error ("Tool bar position must be `top'");
770}
771
772static void
773ns_set_child_frame_border_width (struct frame *f, Lisp_Object arg,
774 Lisp_Object oldval)
764{ 775{
765 int border; 776 int border;
766 777
@@ -1055,7 +1066,7 @@ frame_parm_handler ns_frame_parm_handlers[] =
1055 gui_set_font_backend, /* generic OK */ 1066 gui_set_font_backend, /* generic OK */
1056 gui_set_alpha, 1067 gui_set_alpha,
1057 0, /* x_set_sticky */ 1068 0, /* x_set_sticky */
1058 0, /* x_set_tool_bar_position */ 1069 ns_set_tool_bar_position,
1059 0, /* x_set_inhibit_double_buffering */ 1070 0, /* x_set_inhibit_double_buffering */
1060 ns_set_undecorated, 1071 ns_set_undecorated,
1061 ns_set_parent_frame, 1072 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 @@ ns_clear_under_internal_border (struct frame *f)
2728 int width = FRAME_PIXEL_WIDTH (f); 2728 int width = FRAME_PIXEL_WIDTH (f);
2729 int height = FRAME_PIXEL_HEIGHT (f); 2729 int height = FRAME_PIXEL_HEIGHT (f);
2730 int margin = FRAME_TOP_MARGIN_HEIGHT (f); 2730 int margin = FRAME_TOP_MARGIN_HEIGHT (f);
2731 int bottom_margin = FRAME_BOTTOM_MARGIN_HEIGHT (f);
2731 int face_id = 2732 int face_id =
2732 (FRAME_PARENT_FRAME (f) 2733 (FRAME_PARENT_FRAME (f)
2733 ? (!NILP (Vface_remapping_alist) 2734 ? (!NILP (Vface_remapping_alist)
@@ -2753,7 +2754,8 @@ ns_clear_under_internal_border (struct frame *f)
2753 NSRectFill (NSMakeRect (0, 0, border, height)); 2754 NSRectFill (NSMakeRect (0, 0, border, height));
2754 NSRectFill (NSMakeRect (0, margin, width, border)); 2755 NSRectFill (NSMakeRect (0, margin, width, border));
2755 NSRectFill (NSMakeRect (width - border, 0, border, height)); 2756 NSRectFill (NSMakeRect (width - border, 0, border, height));
2756 NSRectFill (NSMakeRect (0, height - border, width, border)); 2757 NSRectFill (NSMakeRect (0, height - bottom_margin - border,
2758 width, border));
2757 ns_unfocus (f); 2759 ns_unfocus (f);
2758 } 2760 }
2759} 2761}
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)
3451 tab_bar_height = FRAME_TAB_BAR_HEIGHT (f); 3451 tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
3452 tab_bar_width = (tab_bar_height 3452 tab_bar_width = (tab_bar_height
3453 ? native_width - 2 * internal_border_width : 0); 3453 ? native_width - 2 * internal_border_width : 0);
3454 /* inner_top += tab_bar_height; */ 3454 inner_top += tab_bar_height;
3455 3455
3456 /* Construct list. */ 3456 /* Construct list. */
3457 if (EQ (attribute, Qouter_edges)) 3457 if (EQ (attribute, Qouter_edges))
@@ -3564,7 +3564,9 @@ menu bar or tool bar of FRAME. */)
3564 ? type : Qnative_edges)); 3564 ? type : Qnative_edges));
3565} 3565}
3566 3566
3567DEFUN ("pgtk-set-mouse-absolute-pixel-position", Fpgtk_set_mouse_absolute_pixel_position, Spgtk_set_mouse_absolute_pixel_position, 2, 2, 0, 3567DEFUN ("pgtk-set-mouse-absolute-pixel-position",
3568 Fpgtk_set_mouse_absolute_pixel_position,
3569 Spgtk_set_mouse_absolute_pixel_position, 2, 2, 0,
3568 doc: /* Move mouse pointer to absolute pixel position (X, Y). 3570 doc: /* Move mouse pointer to absolute pixel position (X, Y).
3569The coordinates X and Y are interpreted in pixels relative to a position 3571The coordinates X and Y are interpreted in pixels relative to a position
3570\(0, 0) of the selected frame's display. */) 3572\(0, 0) of the selected frame's display. */)
@@ -3583,7 +3585,9 @@ The coordinates X and Y are interpreted in pixels relative to a position
3583 return Qnil; 3585 return Qnil;
3584} 3586}
3585 3587
3586DEFUN ("pgtk-mouse-absolute-pixel-position", Fpgtk_mouse_absolute_pixel_position, Spgtk_mouse_absolute_pixel_position, 0, 0, 0, 3588DEFUN ("pgtk-mouse-absolute-pixel-position",
3589 Fpgtk_mouse_absolute_pixel_position,
3590 Spgtk_mouse_absolute_pixel_position, 0, 0, 0,
3587 doc: /* Return absolute position of mouse cursor in pixels. 3591 doc: /* Return absolute position of mouse cursor in pixels.
3588The position is returned as a cons cell (X . Y) of the 3592The position is returned as a cons cell (X . Y) of the
3589coordinates of the mouse cursor position in pixels relative to a 3593coordinates of the mouse cursor position in pixels relative to a
@@ -3605,7 +3609,8 @@ position (0, 0) of the selected frame's terminal. */)
3605} 3609}
3606 3610
3607 3611
3608DEFUN ("pgtk-page-setup-dialog", Fpgtk_page_setup_dialog, Spgtk_page_setup_dialog, 0, 0, 0, 3612DEFUN ("pgtk-page-setup-dialog", Fpgtk_page_setup_dialog,
3613 Spgtk_page_setup_dialog, 0, 0, 0,
3609 doc: /* Pop up a page setup dialog. 3614 doc: /* Pop up a page setup dialog.
3610The current page setup can be obtained using `x-get-page-setup'. */) 3615The current page setup can be obtained using `x-get-page-setup'. */)
3611 (void) 3616 (void)
@@ -3617,7 +3622,8 @@ The current page setup can be obtained using `x-get-page-setup'. */)
3617 return Qnil; 3622 return Qnil;
3618} 3623}
3619 3624
3620DEFUN ("pgtk-get-page-setup", Fpgtk_get_page_setup, Spgtk_get_page_setup, 0, 0, 0, 3625DEFUN ("pgtk-get-page-setup", Fpgtk_get_page_setup,
3626 Spgtk_get_page_setup, 0, 0, 0,
3621 doc: /* Return the value of the current page setup. 3627 doc: /* Return the value of the current page setup.
3622The return value is an alist containing the following keys: 3628The return value is an alist containing the following keys:
3623 3629
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)
3766 cairo_rectangle (cr, 3766 cairo_rectangle (cr,
3767 flash_left, 3767 flash_left,
3768 (height - flash_height 3768 (height - flash_height
3769 - FRAME_INTERNAL_BORDER_WIDTH (f)), 3769 - FRAME_INTERNAL_BORDER_WIDTH (f)
3770 - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
3770 width, flash_height); 3771 width, flash_height);
3771 cairo_fill (cr); 3772 cairo_fill (cr);
3772 } 3773 }
@@ -4947,14 +4948,16 @@ pgtk_clear_under_internal_border (struct frame *f)
4947 int width = FRAME_PIXEL_WIDTH (f); 4948 int width = FRAME_PIXEL_WIDTH (f);
4948 int height = FRAME_PIXEL_HEIGHT (f); 4949 int height = FRAME_PIXEL_HEIGHT (f);
4949 int margin = FRAME_TOP_MARGIN_HEIGHT (f); 4950 int margin = FRAME_TOP_MARGIN_HEIGHT (f);
4950 int face_id = 4951 int bottom_margin = FRAME_BOTTOM_MARGIN_HEIGHT (f);
4951 (FRAME_PARENT_FRAME (f) 4952 int face_id = (FRAME_PARENT_FRAME (f)
4952 ? (!NILP (Vface_remapping_alist) 4953 ? (!NILP (Vface_remapping_alist)
4953 ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID) 4954 ? lookup_basic_face (NULL, f,
4954 : CHILD_FRAME_BORDER_FACE_ID) 4955 CHILD_FRAME_BORDER_FACE_ID)
4955 : (!NILP (Vface_remapping_alist) 4956 : CHILD_FRAME_BORDER_FACE_ID)
4956 ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID) 4957 : (!NILP (Vface_remapping_alist)
4957 : INTERNAL_BORDER_FACE_ID)); 4958 ? lookup_basic_face (NULL, f,
4959 INTERNAL_BORDER_FACE_ID)
4960 : INTERNAL_BORDER_FACE_ID));
4958 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); 4961 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
4959 4962
4960 block_input (); 4963 block_input ();
@@ -4965,15 +4968,18 @@ pgtk_clear_under_internal_border (struct frame *f)
4965 fill_background_by_face (f, face, 0, 0, border, height); 4968 fill_background_by_face (f, face, 0, 0, border, height);
4966 fill_background_by_face (f, face, width - border, 0, border, 4969 fill_background_by_face (f, face, width - border, 0, border,
4967 height); 4970 height);
4968 fill_background_by_face (f, face, 0, height - border, width, 4971 fill_background_by_face (f, face, 0, (height
4969 border); 4972 - bottom_margin
4973 - border),
4974 width, border);
4970 } 4975 }
4971 else 4976 else
4972 { 4977 {
4973 pgtk_clear_area (f, 0, 0, border, height); 4978 pgtk_clear_area (f, 0, 0, border, height);
4974 pgtk_clear_area (f, 0, margin, width, border); 4979 pgtk_clear_area (f, 0, margin, width, border);
4975 pgtk_clear_area (f, width - border, 0, border, height); 4980 pgtk_clear_area (f, width - border, 0, border, height);
4976 pgtk_clear_area (f, 0, height - border, width, border); 4981 pgtk_clear_area (f, 0, height - bottom_margin - border,
4982 width, border);
4977 } 4983 }
4978 4984
4979 unblock_input (); 4985 unblock_input ();
diff --git a/src/w32fns.c b/src/w32fns.c
index 745f561e6b1..dcf9a212bdd 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1537,14 +1537,16 @@ w32_clear_under_internal_border (struct frame *f)
1537 { 1537 {
1538 int width = FRAME_PIXEL_WIDTH (f); 1538 int width = FRAME_PIXEL_WIDTH (f);
1539 int height = FRAME_PIXEL_HEIGHT (f); 1539 int height = FRAME_PIXEL_HEIGHT (f);
1540 int face_id = 1540 int bottom_margin = FRAME_BOTTOM_MARGIN_HEIGHT (f);
1541 (FRAME_PARENT_FRAME (f) 1541 int face_id = (FRAME_PARENT_FRAME (f)
1542 ? (!NILP (Vface_remapping_alist) 1542 ? (!NILP (Vface_remapping_alist)
1543 ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID) 1543 ? lookup_basic_face (NULL, f,
1544 : CHILD_FRAME_BORDER_FACE_ID) 1544 CHILD_FRAME_BORDER_FACE_ID)
1545 : (!NILP (Vface_remapping_alist) 1545 : CHILD_FRAME_BORDER_FACE_ID)
1546 ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID) 1546 : (!NILP (Vface_remapping_alist)
1547 : INTERNAL_BORDER_FACE_ID)); 1547 ? lookup_basic_face (NULL, f,
1548 INTERNAL_BORDER_FACE_ID)
1549 : INTERNAL_BORDER_FACE_ID));
1548 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); 1550 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
1549 1551
1550 block_input (); 1552 block_input ();
@@ -1554,17 +1556,21 @@ w32_clear_under_internal_border (struct frame *f)
1554 /* Fill border with internal border face. */ 1556 /* Fill border with internal border face. */
1555 unsigned long color = face->background; 1557 unsigned long color = face->background;
1556 1558
1557 w32_fill_area (f, hdc, color, 0, FRAME_TOP_MARGIN_HEIGHT (f), width, border); 1559 w32_fill_area (f, hdc, color, 0, FRAME_TOP_MARGIN_HEIGHT (f),
1560 width, border);
1558 w32_fill_area (f, hdc, color, 0, 0, border, height); 1561 w32_fill_area (f, hdc, color, 0, 0, border, height);
1559 w32_fill_area (f, hdc, color, width - border, 0, border, height); 1562 w32_fill_area (f, hdc, color, width - border, 0, border, height);
1560 w32_fill_area (f, hdc, color, 0, height - border, width, border); 1563 w32_fill_area (f, hdc, color, 0, height - bottom_margin - border,
1564 width, border);
1561 } 1565 }
1562 else 1566 else
1563 { 1567 {
1564 w32_clear_area (f, hdc, 0, FRAME_TOP_MARGIN_HEIGHT (f), width, border); 1568 w32_clear_area (f, hdc, 0, FRAME_TOP_MARGIN_HEIGHT (f),
1569 width, border);
1565 w32_clear_area (f, hdc, 0, 0, border, height); 1570 w32_clear_area (f, hdc, 0, 0, border, height);
1566 w32_clear_area (f, hdc, width - border, 0, border, height); 1571 w32_clear_area (f, hdc, width - border, 0, border, height);
1567 w32_clear_area (f, hdc, 0, height - border, width, border); 1572 w32_clear_area (f, hdc, 0, height - bottom_margin - border,
1573 width, border);
1568 } 1574 }
1569 release_frame_dc (f, hdc); 1575 release_frame_dc (f, hdc);
1570 unblock_input (); 1576 unblock_input ();
@@ -1806,6 +1812,33 @@ w32_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1806 w32_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f)); 1812 w32_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
1807} 1813}
1808 1814
1815static void
1816w32_set_tool_bar_position (struct frame *f,
1817 Lisp_Object new_value,
1818 Lisp_Object old_value)
1819{
1820 if (!EQ (new_value, Qtop) && !EQ (new_value, Qbottom))
1821 error ("Tool bar position must be either `top' or `bottom'");
1822
1823 if (EQ (new_value, old_value))
1824 return;
1825
1826 /* Set the tool bar position. */
1827 fset_tool_bar_position (f, new_value);
1828
1829 /* Now reconfigure frame glyphs to place the tool bar at the
1830 bottom. While the inner height has not changed, call
1831 `resize_frame_windows' to place each of the windows at its
1832 new position. */
1833
1834 adjust_frame_size (f, -1, -1, 3, false, Qtool_bar_position);
1835 adjust_frame_glyphs (f);
1836 SET_FRAME_GARBAGED (f);
1837
1838 if (FRAME_W32_WINDOW (f))
1839 w32_clear_under_internal_border (f);
1840}
1841
1809/* Enable or disable double buffering on frame F. 1842/* Enable or disable double buffering on frame F.
1810 1843
1811 When double buffering is enabled, all drawing happens on a back 1844 When double buffering is enabled, all drawing happens on a back
@@ -8993,7 +9026,9 @@ and width values are in pixels.
8993 : 0), 9026 : 0),
8994 make_fixnum (tab_bar_height))), 9027 make_fixnum (tab_bar_height))),
8995 Fcons (Qtool_bar_external, Qnil), 9028 Fcons (Qtool_bar_external, Qnil),
8996 Fcons (Qtool_bar_position, tool_bar_height ? Qtop : Qnil), 9029 Fcons (Qtool_bar_position, (tool_bar_height
9030 ? FRAME_TOOL_BAR_POSITION (f)
9031 : Qnil)),
8997 Fcons (Qtool_bar_size, 9032 Fcons (Qtool_bar_size,
8998 Fcons (make_fixnum 9033 Fcons (make_fixnum
8999 (tool_bar_height 9034 (tool_bar_height
@@ -9084,10 +9119,11 @@ menu bar or tool bar of FRAME. */)
9084 return list4 (make_fixnum (left + internal_border_width), 9119 return list4 (make_fixnum (left + internal_border_width),
9085 make_fixnum (top 9120 make_fixnum (top
9086 + FRAME_TAB_BAR_HEIGHT (f) 9121 + FRAME_TAB_BAR_HEIGHT (f)
9087 + FRAME_TOOL_BAR_HEIGHT (f) 9122 + FRAME_TOOL_BAR_TOP_HEIGHT (f)
9088 + internal_border_width), 9123 + internal_border_width),
9089 make_fixnum (right - internal_border_width), 9124 make_fixnum (right - internal_border_width),
9090 make_fixnum (bottom - internal_border_width)); 9125 make_fixnum (bottom - internal_border_width
9126 - FRAME_TOOL_BAR_BOTTOM_HEIGHT (f)));
9091 } 9127 }
9092 else 9128 else
9093 return list4 (make_fixnum (left), make_fixnum (top), 9129 return list4 (make_fixnum (left), make_fixnum (top),
@@ -10556,7 +10592,7 @@ frame_parm_handler w32_frame_parm_handlers[] =
10556 gui_set_font_backend, 10592 gui_set_font_backend,
10557 gui_set_alpha, 10593 gui_set_alpha,
10558 0, /* x_set_sticky */ 10594 0, /* x_set_sticky */
10559 0, /* x_set_tool_bar_position */ 10595 w32_set_tool_bar_position,
10560 w32_set_inhibit_double_buffering, 10596 w32_set_inhibit_double_buffering,
10561 w32_set_undecorated, 10597 w32_set_undecorated,
10562 w32_set_parent_frame, 10598 w32_set_parent_frame,
diff --git a/src/window.c b/src/window.c
index b929d63d64e..ea27fdda2a6 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4831,10 +4831,9 @@ values. */)
4831 return Qt; 4831 return Qt;
4832} 4832}
4833 4833
4834/* Resize frame F's windows when F's inner height (inner width if
4835 HORFLAG is true) has been set to SIZE pixels. */
4834 4836
4835/**
4836Resize frame F's windows when F's inner height (inner width if HORFLAG
4837is true) has been set to SIZE pixels. */
4838void 4837void
4839resize_frame_windows (struct frame *f, int size, bool horflag) 4838resize_frame_windows (struct frame *f, int size, bool horflag)
4840{ 4839{
diff --git a/src/xdisp.c b/src/xdisp.c
index 117df85e97e..679f937a9c7 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -37649,7 +37649,7 @@ init_xdisp (void)
37649 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f); 37649 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
37650 r->total_cols = FRAME_COLS (f); 37650 r->total_cols = FRAME_COLS (f);
37651 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f); 37651 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
37652 r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_TOP_MARGIN (f); 37652 r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_MARGINS (f);
37653 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f); 37653 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
37654 37654
37655 m->top_line = FRAME_TOTAL_LINES (f) - 1; 37655 m->top_line = FRAME_TOTAL_LINES (f) - 1;
diff --git a/src/xfns.c b/src/xfns.c
index 057d0436ebe..2046999cf5d 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -807,23 +807,45 @@ x_set_tool_bar_position (struct frame *f,
807 Lisp_Object new_value, 807 Lisp_Object new_value,
808 Lisp_Object old_value) 808 Lisp_Object old_value)
809{ 809{
810 Lisp_Object choice = list4 (Qleft, Qright, Qtop, Qbottom); 810#ifdef USE_GTK
811 Lisp_Object choice;
812
813 choice = list4 (Qleft, Qright, Qtop, Qbottom);
811 814
812 if (!NILP (Fmemq (new_value, choice))) 815 if (!NILP (Fmemq (new_value, choice)))
813 { 816 {
814#ifdef USE_GTK
815 if (!EQ (new_value, old_value)) 817 if (!EQ (new_value, old_value))
816 { 818 {
817 xg_change_toolbar_position (f, new_value); 819 xg_change_toolbar_position (f, new_value);
818 fset_tool_bar_position (f, new_value); 820 fset_tool_bar_position (f, new_value);
819 } 821 }
820#else 822#else /* !USE_GTK */
821 if (!EQ (new_value, Qtop)) 823 if (!EQ (new_value, Qtop) && !EQ (new_value, Qbottom))
822 error ("The only supported tool bar position is top"); 824 error ("Tool bar position must be either `top' or `bottom'");
823#endif 825
826 if (EQ (new_value, old_value))
827 return;
828
829 /* Set the tool bar position. */
830 fset_tool_bar_position (f, new_value);
831
832 /* Now reconfigure frame glyphs to place the tool bar at the
833 bottom. While the inner height has not changed, call
834 `resize_frame_windows' to place each of the windows at its
835 new position. */
836
837 adjust_frame_size (f, -1, -1, 3, false, Qtool_bar_position);
838 adjust_frame_glyphs (f);
839 SET_FRAME_GARBAGED (f);
840
841 if (FRAME_X_WINDOW (f))
842 x_clear_under_internal_border (f);
843#endif /* USE_GTK */
844#ifdef USE_GTK
824 } 845 }
825 else 846 else
826 wrong_choice (choice, new_value); 847 wrong_choice (choice, new_value);
848#endif /* USE_GTK */
827} 849}
828 850
829#ifdef HAVE_XDBE 851#ifdef HAVE_XDBE
@@ -6676,10 +6698,11 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
6676} 6698}
6677 6699
6678/* Return geometric attributes of FRAME. According to the value of 6700/* Return geometric attributes of FRAME. According to the value of
6679 ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the native 6701 ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the
6680 edges of FRAME (Qnative_edges), or the inner edges of frame 6702 native edges of FRAME (Qnative_edges), or the inner edges of frame
6681 (Qinner_edges). Any other value means to return the geometry as 6703 (Qinner_edges). Any other value means to return the geometry as
6682 returned by Fx_frame_geometry. */ 6704 returned by Fx_frame_geometry. */
6705
6683static Lisp_Object 6706static Lisp_Object
6684frame_geometry (Lisp_Object frame, Lisp_Object attribute) 6707frame_geometry (Lisp_Object frame, Lisp_Object attribute)
6685{ 6708{
@@ -6768,8 +6791,8 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
6768 6791
6769 tab_bar_height = FRAME_TAB_BAR_HEIGHT (f); 6792 tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
6770 tab_bar_width = (tab_bar_height 6793 tab_bar_width = (tab_bar_height
6771 ? native_width - 2 * internal_border_width 6794 ? native_width - 2 * internal_border_width
6772 : 0); 6795 : 0);
6773 inner_top += tab_bar_height; 6796 inner_top += tab_bar_height;
6774 6797
6775#ifdef HAVE_EXT_TOOL_BAR 6798#ifdef HAVE_EXT_TOOL_BAR
@@ -6809,7 +6832,14 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
6809 tool_bar_width = (tool_bar_height 6832 tool_bar_width = (tool_bar_height
6810 ? native_width - 2 * internal_border_width 6833 ? native_width - 2 * internal_border_width
6811 : 0); 6834 : 0);
6812 inner_top += tool_bar_height; 6835
6836 /* Subtract or add to the inner dimensions based on the tool bar
6837 position. */
6838
6839 if (EQ (FRAME_TOOL_BAR_POSITION (f), Qtop))
6840 inner_top += tool_bar_height;
6841 else
6842 inner_bottom -= tool_bar_height;
6813#endif 6843#endif
6814 6844
6815 /* Construct list. */ 6845 /* Construct list. */
diff --git a/src/xterm.c b/src/xterm.c
index 37fabc15e3a..3f333f124e6 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -7574,14 +7574,16 @@ x_clear_under_internal_border (struct frame *f)
7574 int width = FRAME_PIXEL_WIDTH (f); 7574 int width = FRAME_PIXEL_WIDTH (f);
7575 int height = FRAME_PIXEL_HEIGHT (f); 7575 int height = FRAME_PIXEL_HEIGHT (f);
7576 int margin = FRAME_TOP_MARGIN_HEIGHT (f); 7576 int margin = FRAME_TOP_MARGIN_HEIGHT (f);
7577 int face_id = 7577 int bottom_margin = FRAME_BOTTOM_MARGIN_HEIGHT (f);
7578 (FRAME_PARENT_FRAME (f) 7578 int face_id = (FRAME_PARENT_FRAME (f)
7579 ? (!NILP (Vface_remapping_alist) 7579 ? (!NILP (Vface_remapping_alist)
7580 ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID) 7580 ? lookup_basic_face (NULL, f,
7581 : CHILD_FRAME_BORDER_FACE_ID) 7581 CHILD_FRAME_BORDER_FACE_ID)
7582 : (!NILP (Vface_remapping_alist) 7582 : CHILD_FRAME_BORDER_FACE_ID)
7583 ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID) 7583 : (!NILP (Vface_remapping_alist)
7584 : INTERNAL_BORDER_FACE_ID)); 7584 ? lookup_basic_face (NULL, f,
7585 INTERNAL_BORDER_FACE_ID)
7586 : INTERNAL_BORDER_FACE_ID));
7585 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); 7587 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
7586 7588
7587 if (face) 7589 if (face)
@@ -7594,7 +7596,8 @@ x_clear_under_internal_border (struct frame *f)
7594 x_fill_rectangle (f, gc, 0, margin, width, border, false); 7596 x_fill_rectangle (f, gc, 0, margin, width, border, false);
7595 x_fill_rectangle (f, gc, 0, 0, border, height, false); 7597 x_fill_rectangle (f, gc, 0, 0, border, height, false);
7596 x_fill_rectangle (f, gc, width - border, 0, border, height, false); 7598 x_fill_rectangle (f, gc, width - border, 0, border, height, false);
7597 x_fill_rectangle (f, gc, 0, height - border, width, border, false); 7599 x_fill_rectangle (f, gc, 0, height - bottom_margin - border,
7600 width, border, false);
7598 XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f)); 7601 XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
7599 } 7602 }
7600 else 7603 else
@@ -7602,7 +7605,8 @@ x_clear_under_internal_border (struct frame *f)
7602 x_clear_area (f, 0, 0, border, height); 7605 x_clear_area (f, 0, 0, border, height);
7603 x_clear_area (f, 0, margin, width, border); 7606 x_clear_area (f, 0, margin, width, border);
7604 x_clear_area (f, width - border, 0, border, height); 7607 x_clear_area (f, width - border, 0, border, height);
7605 x_clear_area (f, 0, height - border, width, border); 7608 x_clear_area (f, 0, height - bottom_margin - border,
7609 width, border);
7606 } 7610 }
7607 } 7611 }
7608} 7612}
@@ -11318,7 +11322,8 @@ XTflash (struct frame *f)
11318 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc, 11322 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
11319 flash_left, 11323 flash_left,
11320 (height - flash_height 11324 (height - flash_height
11321 - FRAME_INTERNAL_BORDER_WIDTH (f)), 11325 - FRAME_INTERNAL_BORDER_WIDTH (f)
11326 - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
11322 width, flash_height); 11327 width, flash_height);
11323 11328
11324 } 11329 }
@@ -11372,7 +11377,8 @@ XTflash (struct frame *f)
11372 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc, 11377 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
11373 flash_left, 11378 flash_left,
11374 (height - flash_height 11379 (height - flash_height
11375 - FRAME_INTERNAL_BORDER_WIDTH (f)), 11380 - FRAME_INTERNAL_BORDER_WIDTH (f)
11381 - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
11376 width, flash_height); 11382 width, flash_height);
11377 } 11383 }
11378 else 11384 else