1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-26 07:33:47 +00:00

Fixes in window size functions around Bug#16430 and Bug#16470.

* window.c (Fwindow_pixel_width, Fwindow_pixel_height)
(Fwindow_mode_line_height, Fwindow_header_line_height)
(Fwindow_right_divider_width, Fwindow_bottom_divider_width):
Minor doc-string adjustments.
(Fwindow_total_height, Fwindow_total_width): New argument ROUND.
Rewrite doc-strings.
(window_body_height, window_body_width): Do not count partially
visible lines/columns when PIXELWISE is nil (Bug#16470).
(Qfloor, Qceiling): New symbols.
* window.el (window-total-size, window-size): New argument
ROUND.
(window--min-delta-1, window-min-delta, window--max-delta-1): Be
more conservative when calculating the numbers of lines or
columns a window can shrink (Bug#16430).
(fit-window-to-buffer): Simplify code.
* term.el (term-window-width): Call window-body-width again.
This commit is contained in:
Martin Rudalics 2014-01-22 11:29:23 +01:00
parent 29f5e020a2
commit 6cb4da45dc
5 changed files with 157 additions and 90 deletions

View File

@ -1,3 +1,14 @@
2014-01-22 Martin Rudalics <rudalics@gmx.at>
Fixes in window size functions around Bug#16430 and Bug#16470.
* window.el (window-total-size, window-size): New argument
ROUND.
(window--min-delta-1, window-min-delta, window--max-delta-1): Be
more conservative when calculating the numbers of lines or
columns a window can shrink (Bug#16430).
(fit-window-to-buffer): Simplify code.
* term.el (term-window-width): Call window-body-width again.
2014-01-22 Glenn Morris <rgm@gnu.org>
* image.el (image-format-suffixes): Doc fix.

View File

@ -975,9 +975,8 @@ is buffer-local."
(display-graphic-p)
overflow-newline-into-fringe
(/= (frame-parameter nil 'right-fringe) 0))
;; Call window-text-width instead of window-width (Bug#16470).
(window-text-width)
(1- (window-text-width))))
(window-body-width)
(1- (window-body-width))))
(put 'term-mode 'mode-class 'special)

View File

@ -1013,18 +1013,21 @@ FRAME defaults to the selected frame."
(window--atom-check frame))
;;; Window sizes.
(defun window-total-size (&optional window horizontal)
(defun window-total-size (&optional window horizontal round)
"Return the total height or width of WINDOW.
WINDOW must be a valid window and defaults to the selected one.
If HORIZONTAL is omitted or nil, return the total height of
WINDOW, in lines, like `window-total-height'. Otherwise return
the total width, in columns, like `window-total-width'."
(if horizontal
(window-total-width window)
(window-total-height window)))
the total width, in columns, like `window-total-width'.
(defun window-size (&optional window horizontal pixelwise)
Optional argument ROUND is handled as for `window-total-height'
and `window-total-width'."
(if horizontal
(window-total-width window round)
(window-total-height window round)))
(defun window-size (&optional window horizontal pixelwise round)
"Return the height or width of WINDOW.
WINDOW must be a valid window and defaults to the selected one.
@ -1033,14 +1036,18 @@ WINDOW, in lines, like `window-total-height'. Otherwise return
the total width, in columns, like `window-total-width'.
Optional argument PIXELWISE means return the pixel size of WINDOW
like `window-pixel-height' and `window-pixel-width'."
like `window-pixel-height' and `window-pixel-width'.
Optional argument ROUND is ignored if PIXELWISE is non-nil and
handled as for `window-total-height' and `window-total-width'
otherwise."
(if horizontal
(if pixelwise
(window-pixel-width window)
(window-total-width window))
(window-total-width window round))
(if pixelwise
(window-pixel-height window)
(window-total-height window))))
(window-total-height window round))))
(defvar window-size-fixed nil
"Non-nil in a buffer means windows displaying the buffer are fixed-size.
@ -1316,7 +1323,7 @@ WINDOW can be resized in the desired direction. The function
(unless (eq sub window)
(setq delta
(min delta
(- (window-size sub horizontal pixelwise)
(- (window-size sub horizontal pixelwise 'floor)
(window-min-size
sub horizontal ignore pixelwise)))))
(setq sub (window-right sub))))
@ -1356,7 +1363,7 @@ at least one other window can be enlarged appropriately.
Optional argument PIXELWISE non-nil means return number of pixels
by which WINDOW can be shrunk."
(setq window (window-normalize-window window))
(let ((size (window-size window horizontal pixelwise))
(let ((size (window-size window horizontal pixelwise 'floor))
(minimum (window-min-size window horizontal ignore pixelwise)))
(cond
(nodown
@ -1393,7 +1400,7 @@ by which WINDOW can be shrunk."
(t
(setq delta
(+ delta
(- (window-size sub horizontal pixelwise)
(- (window-size sub horizontal pixelwise 'floor)
(window-min-size
sub horizontal ignore pixelwise))))))
(setq sub (window-right sub))))
@ -7131,8 +7138,7 @@ accessible position."
(window-bottom-divider-width)))
;; Round height.
(unless pixelwise
(setq height (+ (/ height char-height)
(if (zerop (% height char-height)) 0 1))))
(setq height (/ (+ height char-height -1) char-height)))
(unless (= height total-height)
(window-resize-no-error
window
@ -7185,8 +7191,7 @@ accessible position."
(if pixelwise char-height 1))))
(window-right-divider-width))))
(unless pixelwise
(setq width (+ (/ width char-width)
(if (zerop (% width char-width)) 0 1))))
(setq width (/ (+ width char-width -1) char-width)))
(unless (= width body-width)
(window-resize-no-error
window

View File

@ -1,3 +1,16 @@
2014-01-22 Martin Rudalics <rudalics@gmx.at>
Fixes in window size functions around Bug#16430 and Bug#16470.
* window.c (Fwindow_pixel_width, Fwindow_pixel_height)
(Fwindow_mode_line_height, Fwindow_header_line_height)
(Fwindow_right_divider_width, Fwindow_bottom_divider_width):
Minor doc-string adjustments.
(Fwindow_total_height, Fwindow_total_width): New argument ROUND.
Rewrite doc-strings.
(window_body_height, window_body_width): Do not count partially
visible lines/columns when PIXELWISE is nil (Bug#16470).
(Qfloor, Qceiling): New symbols.
2014-01-21 Eli Zaretskii <eliz@gnu.org>
* w32fns.c (unwind_create_frame): Avoid crashing inside assertion

View File

@ -54,6 +54,7 @@ static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertic
static Lisp_Object Qwindow_pixel_to_total;
static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of;
static Lisp_Object Qfloor, Qceiling;
static int displayed_window_lines (struct window *);
static int count_windows (struct window *);
@ -682,7 +683,7 @@ selected one. */)
}
DEFUN ("window-pixel-width", Fwindow_pixel_width, Swindow_pixel_width, 0, 1, 0,
doc: /* Return the pixel width of window WINDOW.
doc: /* Return the width of window WINDOW in pixels.
WINDOW must be a valid window and defaults to the selected one.
The return value includes the fringes and margins of WINDOW as well as
@ -695,7 +696,7 @@ spanned by its children. */)
}
DEFUN ("window-pixel-height", Fwindow_pixel_height, Swindow_pixel_height, 0, 1, 0,
doc: /* Return the pixel height of window WINDOW.
doc: /* Return the height of window WINDOW in pixels.
WINDOW must be a valid window and defaults to the selected one.
The return value includes the mode line and header line, if any. If
@ -706,34 +707,77 @@ screen areas spanned by its children. */)
return make_number (decode_valid_window (window)->pixel_height);
}
DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 1, 0,
doc: /* Return the total height, in lines, of window WINDOW.
DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 2, 0,
doc: /* Return the height of window WINDOW in lines.
WINDOW must be a valid window and defaults to the selected one.
The return value includes the mode line and header line, if any.
If WINDOW is an internal window, the total height is the height
of the screen areas spanned by its children.
The return value includes the heights of WINDOW's mode and header line
and its bottom divider, if any. If WINDOW is an internal window, the
total height is the height of the screen areas spanned by its children.
On a graphical display, this total height is reported as an
integer multiple of the default character height. */)
(Lisp_Object window)
If WINDOW's pixel height is not an integral multiple of its frame's
character height, the number of lines occupied by WINDOW is rounded
internally. This is done in a way such that, if WINDOW is a parent
window, the sum of the total heights of all its children internally
equals the total height of WINDOW.
If the optional argument ROUND is `ceiling', return the smallest integer
larger than WINDOW's pixel height divided by the character height of
WINDOW's frame. ROUND `floor' means to return the largest integer
smaller than WINDOW's pixel height divided by the character height of
WINDOW's frame. Any other value of ROUND means to return the internal
total height of WINDOW. */)
(Lisp_Object window, Lisp_Object round)
{
return make_number (decode_valid_window (window)->total_lines);
struct window *w = decode_valid_window (window);
if (! EQ (round, Qfloor) && ! EQ (round, Qceiling))
return make_number (w->total_lines);
else
{
int unit = FRAME_LINE_HEIGHT (WINDOW_XFRAME (w));
return make_number (EQ (round, Qceiling)
? ((w->pixel_height + unit - 1) /unit)
: (w->pixel_height / unit));
}
}
DEFUN ("window-total-width", Fwindow_total_width, Swindow_total_width, 0, 1, 0,
doc: /* Return the total width, in columns, of window WINDOW.
DEFUN ("window-total-width", Fwindow_total_width, Swindow_total_width, 0, 2, 0,
doc: /* Return the total width of window WINDOW in columns.
WINDOW must be a valid window and defaults to the selected one.
The return value includes any vertical dividers or scroll bars
belonging to WINDOW. If WINDOW is an internal window, the total width
is the width of the screen areas spanned by its children.
The return value includes the widths of WINDOW's fringes, margins,
scroll bars and its right divider, if any. If WINDOW is an internal
window, the total width is the width of the screen areas spanned by its
children.
On a graphical display, this total width is reported as an
integer multiple of the default character width. */)
(Lisp_Object window)
If WINDOW's pixel width is not an integral multiple of its frame's
character width, the number of lines occupied by WINDOW is rounded
internally. This is done in a way such that, if WINDOW is a parent
window, the sum of the total widths of all its children internally
equals the total width of WINDOW.
If the optional argument ROUND is `ceiling', return the smallest integer
larger than WINDOW's pixel width divided by the character width of
WINDOW's frame. ROUND `floor' means to return the largest integer
smaller than WINDOW's pixel width divided by the character width of
WINDOW's frame. Any other value of ROUND means to return the internal
total width of WINDOW. */)
(Lisp_Object window, Lisp_Object round)
{
return make_number (decode_valid_window (window)->total_cols);
struct window *w = decode_valid_window (window);
if (! EQ (round, Qfloor) && ! EQ (round, Qceiling))
return make_number (w->total_cols);
else
{
int unit = FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
return make_number (EQ (round, Qceiling)
? ((w->pixel_width + unit - 1) /unit)
: (w->pixel_width / unit));
}
}
DEFUN ("window-new-total", Fwindow_new_total, Swindow_new_total, 0, 1, 0,
@ -811,62 +855,58 @@ WINDOW must be a valid window and defaults to the selected one. */)
return make_number (decode_valid_window (window)->top_line);
}
/* Return the number of lines of W's body. Don't count any mode or
header line of W. */
/* Return the number of lines/pixels of W's body. Don't count any mode
or header line or horizontal divider of W. Rounds down to nearest
integer when not working pixelwise. */
static int
window_body_height (struct window *w, bool pixelwise)
{
int pixels = (w->pixel_height
- WINDOW_BOTTOM_DIVIDER_WIDTH (w)
int height = (w->pixel_height
- WINDOW_HEADER_LINE_HEIGHT (w)
- WINDOW_MODE_LINE_HEIGHT (w));
int unit = FRAME_LINE_HEIGHT (WINDOW_XFRAME (w));
- WINDOW_MODE_LINE_HEIGHT (w)
- WINDOW_BOTTOM_DIVIDER_WIDTH (w));
return pixelwise ? pixels : ((pixels + unit - 1) / unit);
return pixelwise ? height : height / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w));
}
/* Return the number of columns of W's body. Don't count columns
occupied by the scroll bar or the vertical bar separating W from its
right sibling. On window-systems don't count fringes or display
margins either. */
/* Return the number of columns/pixels of W's body. Don't count columns
occupied by the scroll bar or the divider/vertical bar separating W
from its right sibling or margins. On window-systems don't count
fringes either. Round down to nearest integer when not working
pixelwise. */
int
window_body_width (struct window *w, bool pixelwise)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
int pixels = (w->pixel_width
- WINDOW_RIGHT_DIVIDER_WIDTH (w)
- (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
? WINDOW_SCROLL_BAR_AREA_WIDTH (w)
: ((!FRAME_WINDOW_P (f)
&& !WINDOW_RIGHTMOST_P (w)
&& !WINDOW_RIGHT_DIVIDER_WIDTH (w)
&& !WINDOW_FULL_WIDTH_P (w))
/* According to Eli this is either 1 or 0. */
? 1 : 0))
int width = (w->pixel_width
- WINDOW_RIGHT_DIVIDER_WIDTH (w)
- (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
? WINDOW_SCROLL_BAR_AREA_WIDTH (w)
: ((!FRAME_WINDOW_P (f)
&& !WINDOW_RIGHTMOST_P (w)
&& !WINDOW_RIGHT_DIVIDER_WIDTH (w))
/* A vertical bar is either 1 or 0. */
? 1 : 0))
- WINDOW_MARGINS_WIDTH (w)
- (FRAME_WINDOW_P (f)
? WINDOW_FRINGES_WIDTH (w)
: 0));
int unit = FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
return pixelwise ? pixels : ((pixels + unit - 1) / unit);
return pixelwise ? width : width / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
}
DEFUN ("window-body-height", Fwindow_body_height, Swindow_body_height, 0, 2, 0,
doc: /* Return the height, in lines, of WINDOW's text area.
WINDOW must be a live window and defaults to the selected one.
doc: /* Return the height of WINDOW's text area.
WINDOW must be a live window and defaults to the selected one. Optional
argument PIXELWISE non-nil means return the height of WINDOW's text area
in pixels. The return value does not include the mode line or header
line or any horizontal divider.
Optional argument PIXELWISE non-nil means return the height in pixels.
The returned height does not include the mode line or header line. On a
graphical display, the height is expressed as an integer multiple of the
default character height if PIXELWISE is nil.
If PIXELWISE is nil and a line at the bottom of the text area is only
partially visible, that counts as a whole line; to exclude
partially-visible lines, use `window-text-height'. */)
If PIXELWISE is nil, return the largest integer smaller than WINDOW's
pixel height divided by the character height of WINDOW's frame. This
means that if a line at the bottom of the text area is only partially
visible, that line is not counted. */)
(Lisp_Object window, Lisp_Object pixelwise)
{
return make_number (window_body_height (decode_live_window (window),
@ -874,19 +914,16 @@ partially-visible lines, use `window-text-height'. */)
}
DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 2, 0,
doc: /* Return the width, in columns, of WINDOW's text area.
WINDOW must be a live window and defaults to the selected one.
doc: /* Return the width of WINDOW's text area.
WINDOW must be a live window and defaults to the selected one. Optional
argument PIXELWISE non-nil means return the width in pixels. The return
value does not include any vertical dividers, fringes or marginal areas,
or scroll bars.
Optional argument PIXELWISE non-nil means return the width in pixels.
The return value does not include any vertical dividers, fringe or
marginal areas, or scroll bars. On a graphical display, the width is
expressed as an integer multiple of the default character width if
PIXELWISE is nil.
If PIXELWISE is nil and a column at the right of the text area is only
partially visible, that counts as a whole column; to exclude
partially-visible columns, use `window-text-width'. */)
If PIXELWISE is nil, return the largest integer smaller than WINDOW's
pixel width divided by the character width of WINDOW's frame. This
means that if a column at the right of the text area is only partially
visible, that column is not counted. */)
(Lisp_Object window, Lisp_Object pixelwise)
{
return make_number (window_body_width (decode_live_window (window),
@ -895,7 +932,7 @@ partially-visible columns, use `window-text-width'. */)
DEFUN ("window-mode-line-height", Fwindow_mode_line_height,
Swindow_mode_line_height, 0, 1, 0,
doc: /* Return the height in pixel of WINDOW's mode-line.
doc: /* Return the height in pixels of WINDOW's mode-line.
WINDOW must be a live window and defaults to the selected one. */)
(Lisp_Object window)
{
@ -904,7 +941,7 @@ WINDOW must be a live window and defaults to the selected one. */)
DEFUN ("window-header-line-height", Fwindow_header_line_height,
Swindow_header_line_height, 0, 1, 0,
doc: /* Return the height in pixel of WINDOW's header-line.
doc: /* Return the height in pixels of WINDOW's header-line.
WINDOW must be a live window and defaults to the selected one. */)
(Lisp_Object window)
{
@ -913,7 +950,7 @@ WINDOW must be a live window and defaults to the selected one. */)
DEFUN ("window-right-divider-width", Fwindow_right_divider_width,
Swindow_right_divider_width, 0, 1, 0,
doc: /* Return the width of WINDOW's right divider.
doc: /* Return the width in pixels of WINDOW's right divider.
WINDOW must be a live window and defaults to the selected one. */)
(Lisp_Object window)
{
@ -922,7 +959,7 @@ WINDOW must be a live window and defaults to the selected one. */)
DEFUN ("window-bottom-divider-width", Fwindow_bottom_divider_width,
Swindow_bottom_divider_width, 0, 1, 0,
doc: /* Return the width of WINDOW's bottom divider.
doc: /* Return the width in pixels of WINDOW's bottom divider.
WINDOW must be a live window and defaults to the selected one. */)
(Lisp_Object window)
{
@ -7101,6 +7138,8 @@ syms_of_window (void)
DEFSYM (Qabove, "above");
DEFSYM (Qbelow, "below");
DEFSYM (Qclone_of, "clone-of");
DEFSYM (Qfloor, "floor");
DEFSYM (Qceiling, "ceiling");
staticpro (&Vwindow_list);