]> git.eshelyaron.com Git - emacs.git/commitdiff
Fixes in window size functions around Bug#16430 and Bug#16470.
authorMartin Rudalics <rudalics@gmx.at>
Wed, 22 Jan 2014 10:29:23 +0000 (11:29 +0100)
committerMartin Rudalics <rudalics@gmx.at>
Wed, 22 Jan 2014 10:29:23 +0000 (11:29 +0100)
* 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.

lisp/ChangeLog
lisp/term.el
lisp/window.el
src/ChangeLog
src/window.c

index 974cd2223efe63b9de3206e584be1726e943da38..d0b8d646323f00475222e37e4e8113429e142b6a 100644 (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.
index 87898bac39faee6969fb480de4fb6335398ec37d..97108c330a8e4e8be19f07095e6e8a2e9228da5e 100644 (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))))
 
 \f
 (put 'term-mode 'mode-class 'special)
index 9bc929109d48f597fd8c2fea1075f15640aa7a68..1845fdd8e7b687139a5cfcca16069fdcbb7224b0 100644 (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'."
+the total width, in columns, like `window-total-width'.
+
+Optional argument ROUND is handled as for `window-total-height'
+and `window-total-width'."
   (if horizontal
-      (window-total-width window)
-    (window-total-height window)))
+      (window-total-width window round)
+    (window-total-height window round)))
 
-(defun window-size (&optional window horizontal pixelwise)
+(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
index eb05786e3fa659f2ab5d5dbcf3b04f337652372e..a9822e56acd8afe2793bbb30c3827b7b904ae096 100644 (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
index bd319f5be8f39a1d86429682ddfd9a3fc36c68d1..60ec913ebbfa2bc7159fb46e0971baa92c5754c8 100644 (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.  */)
 }
 \f
 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.
-
-On a graphical display, this total width is reported as an
-integer multiple of the default character width.  */)
-  (Lisp_Object window)
+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.
+
+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.
-
-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'.  */)
+       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.
+
+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.
-
-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'.  */)
+       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.
+
+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);