Allow displaying tool bar on the bottom of the frame

* 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 (Fw32_frame_geometry): Report tool bar position
correctly.
(w32_clear_under_internal_border): Subtract bottom margins
prior to 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 clearing bottom border.

* 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.
This commit is contained in:
Po Lu 2023-06-21 10:04:31 +08:00
parent bc6068fe94
commit db6de49f23
16 changed files with 347 additions and 133 deletions

View file

@ -523,7 +523,8 @@ Height | | | Height | | | Height
| | | |<--+--- 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 @@ tool bar but not that of the menu bar (Lucid, Motif, MS-Windows) or
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 @@ native frame of @var{frame}).
@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 @@ whenever the tool bar wraps (@pxref{Frame Layout}).
@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

View file

@ -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

View file

@ -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));

View file

@ -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.

View file

@ -205,11 +205,9 @@ struct frame
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 @@ default_pixels_per_inch_y (void)
#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 @@ IMAGE_OPT_FROM_ID (struct frame *f, int id)
#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 @@ IMAGE_OPT_FROM_ID (struct frame *f, int id)
#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 @@ IMAGE_OPT_FROM_ID (struct frame *f, int id)
#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 @@ IMAGE_OPT_FROM_ID (struct frame *f, int id)
#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. */

View file

@ -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,9 @@ 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;
int internal_border_width, tab_bar_height;
int tool_bar_height, tab_bar_width;
f = decode_window_system_frame (frame);
parent = FRAME_PARENT_FRAME (f);
@ -1473,6 +1488,31 @@ 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_x + internal_border_width;
inner_top = native_y + internal_border_width;
inner_right = (native_x + FRAME_PIXEL_WIDTH (f)
- internal_border_width);
inner_bottom = (native_y + 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);
/* 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 +1522,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),
@ -1506,13 +1539,18 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
Fcons (Qmenu_bar_external, Qnil),
Fcons (Qmenu_bar_size,
Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f)
- (FRAME_INTERNAL_BORDER_WIDTH (f) * 2)),
- (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)),
- (FRAME_INTERNAL_BORDER_WIDTH (f)
* 2)),
make_fixnum (FRAME_TOOL_BAR_HEIGHT (f)))),
Fcons (Qinternal_border_width,
make_fixnum (FRAME_INTERNAL_BORDER_WIDTH (f))));

View file

@ -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 ();

View file

@ -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,

View file

@ -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);
}
}

View file

@ -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 @@ menu bar or tool bar of FRAME. */)
? 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 @@ The coordinates X and Y are interpreted in pixels relative to a position
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 @@ The current page setup can be obtained using `x-get-page-setup'. */)
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:

View file

@ -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 ();

View file

@ -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
@ -8993,7 +9026,9 @@ and width values are in pixels.
: 0),
make_fixnum (tab_bar_height))),
Fcons (Qtool_bar_external, Qnil),
Fcons (Qtool_bar_position, tool_bar_height ? Qtop : Qnil),
Fcons (Qtool_bar_position, (tool_bar_height
? FRAME_TOOL_BAR_POSITION (f)
: Qnil)),
Fcons (Qtool_bar_size,
Fcons (make_fixnum
(tool_bar_height
@ -9084,10 +9119,11 @@ menu bar or tool bar of FRAME. */)
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 +10592,7 @@ frame_parm_handler w32_frame_parm_handlers[] =
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,

View file

@ -4828,10 +4828,9 @@ values. */)
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)
{

View file

@ -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;

View file

@ -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 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
}
/* 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. */

View file

@ -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