diff options
| author | Martin Rudalics | 2014-01-22 11:29:23 +0100 |
|---|---|---|
| committer | Martin Rudalics | 2014-01-22 11:29:23 +0100 |
| commit | 6cb4da45dc3d0660a65b29e192e82a37e3ad505c (patch) | |
| tree | 310338ec8e359c9b3923e45b3437996c185a901b /src/window.c | |
| parent | 29f5e020a29c27e2b198069d0fe5ddc30b0a618f (diff) | |
| download | emacs-6cb4da45dc3d0660a65b29e192e82a37e3ad505c.tar.gz emacs-6cb4da45dc3d0660a65b29e192e82a37e3ad505c.zip | |
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.
Diffstat (limited to 'src/window.c')
| -rw-r--r-- | src/window.c | 187 |
1 files changed, 113 insertions, 74 deletions
diff --git a/src/window.c b/src/window.c index bd319f5be8f..60ec913ebbf 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -54,6 +54,7 @@ static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertic | |||
| 54 | static Lisp_Object Qwindow_pixel_to_total; | 54 | static Lisp_Object Qwindow_pixel_to_total; |
| 55 | static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; | 55 | static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; |
| 56 | static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of; | 56 | static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of; |
| 57 | static Lisp_Object Qfloor, Qceiling; | ||
| 57 | 58 | ||
| 58 | static int displayed_window_lines (struct window *); | 59 | static int displayed_window_lines (struct window *); |
| 59 | static int count_windows (struct window *); | 60 | static int count_windows (struct window *); |
| @@ -682,7 +683,7 @@ selected one. */) | |||
| 682 | } | 683 | } |
| 683 | 684 | ||
| 684 | DEFUN ("window-pixel-width", Fwindow_pixel_width, Swindow_pixel_width, 0, 1, 0, | 685 | DEFUN ("window-pixel-width", Fwindow_pixel_width, Swindow_pixel_width, 0, 1, 0, |
| 685 | doc: /* Return the pixel width of window WINDOW. | 686 | doc: /* Return the width of window WINDOW in pixels. |
| 686 | WINDOW must be a valid window and defaults to the selected one. | 687 | WINDOW must be a valid window and defaults to the selected one. |
| 687 | 688 | ||
| 688 | The return value includes the fringes and margins of WINDOW as well as | 689 | The return value includes the fringes and margins of WINDOW as well as |
| @@ -695,7 +696,7 @@ spanned by its children. */) | |||
| 695 | } | 696 | } |
| 696 | 697 | ||
| 697 | DEFUN ("window-pixel-height", Fwindow_pixel_height, Swindow_pixel_height, 0, 1, 0, | 698 | DEFUN ("window-pixel-height", Fwindow_pixel_height, Swindow_pixel_height, 0, 1, 0, |
| 698 | doc: /* Return the pixel height of window WINDOW. | 699 | doc: /* Return the height of window WINDOW in pixels. |
| 699 | WINDOW must be a valid window and defaults to the selected one. | 700 | WINDOW must be a valid window and defaults to the selected one. |
| 700 | 701 | ||
| 701 | The return value includes the mode line and header line, if any. If | 702 | The return value includes the mode line and header line, if any. If |
| @@ -706,34 +707,77 @@ screen areas spanned by its children. */) | |||
| 706 | return make_number (decode_valid_window (window)->pixel_height); | 707 | return make_number (decode_valid_window (window)->pixel_height); |
| 707 | } | 708 | } |
| 708 | 709 | ||
| 709 | DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 1, 0, | 710 | DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 2, 0, |
| 710 | doc: /* Return the total height, in lines, of window WINDOW. | 711 | doc: /* Return the height of window WINDOW in lines. |
| 711 | WINDOW must be a valid window and defaults to the selected one. | 712 | WINDOW must be a valid window and defaults to the selected one. |
| 712 | 713 | ||
| 713 | The return value includes the mode line and header line, if any. | 714 | The return value includes the heights of WINDOW's mode and header line |
| 714 | If WINDOW is an internal window, the total height is the height | 715 | and its bottom divider, if any. If WINDOW is an internal window, the |
| 715 | of the screen areas spanned by its children. | 716 | total height is the height of the screen areas spanned by its children. |
| 716 | 717 | ||
| 717 | On a graphical display, this total height is reported as an | 718 | If WINDOW's pixel height is not an integral multiple of its frame's |
| 718 | integer multiple of the default character height. */) | 719 | character height, the number of lines occupied by WINDOW is rounded |
| 719 | (Lisp_Object window) | 720 | internally. This is done in a way such that, if WINDOW is a parent |
| 721 | window, the sum of the total heights of all its children internally | ||
| 722 | equals the total height of WINDOW. | ||
| 723 | |||
| 724 | If the optional argument ROUND is `ceiling', return the smallest integer | ||
| 725 | larger than WINDOW's pixel height divided by the character height of | ||
| 726 | WINDOW's frame. ROUND `floor' means to return the largest integer | ||
| 727 | smaller than WINDOW's pixel height divided by the character height of | ||
| 728 | WINDOW's frame. Any other value of ROUND means to return the internal | ||
| 729 | total height of WINDOW. */) | ||
| 730 | (Lisp_Object window, Lisp_Object round) | ||
| 720 | { | 731 | { |
| 721 | return make_number (decode_valid_window (window)->total_lines); | 732 | struct window *w = decode_valid_window (window); |
| 733 | |||
| 734 | if (! EQ (round, Qfloor) && ! EQ (round, Qceiling)) | ||
| 735 | return make_number (w->total_lines); | ||
| 736 | else | ||
| 737 | { | ||
| 738 | int unit = FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)); | ||
| 739 | |||
| 740 | return make_number (EQ (round, Qceiling) | ||
| 741 | ? ((w->pixel_height + unit - 1) /unit) | ||
| 742 | : (w->pixel_height / unit)); | ||
| 743 | } | ||
| 722 | } | 744 | } |
| 723 | 745 | ||
| 724 | DEFUN ("window-total-width", Fwindow_total_width, Swindow_total_width, 0, 1, 0, | 746 | DEFUN ("window-total-width", Fwindow_total_width, Swindow_total_width, 0, 2, 0, |
| 725 | doc: /* Return the total width, in columns, of window WINDOW. | 747 | doc: /* Return the total width of window WINDOW in columns. |
| 726 | WINDOW must be a valid window and defaults to the selected one. | 748 | WINDOW must be a valid window and defaults to the selected one. |
| 727 | 749 | ||
| 728 | The return value includes any vertical dividers or scroll bars | 750 | The return value includes the widths of WINDOW's fringes, margins, |
| 729 | belonging to WINDOW. If WINDOW is an internal window, the total width | 751 | scroll bars and its right divider, if any. If WINDOW is an internal |
| 730 | is the width of the screen areas spanned by its children. | 752 | window, the total width is the width of the screen areas spanned by its |
| 731 | 753 | children. | |
| 732 | On a graphical display, this total width is reported as an | 754 | |
| 733 | integer multiple of the default character width. */) | 755 | If WINDOW's pixel width is not an integral multiple of its frame's |
| 734 | (Lisp_Object window) | 756 | character width, the number of lines occupied by WINDOW is rounded |
| 757 | internally. This is done in a way such that, if WINDOW is a parent | ||
| 758 | window, the sum of the total widths of all its children internally | ||
| 759 | equals the total width of WINDOW. | ||
| 760 | |||
| 761 | If the optional argument ROUND is `ceiling', return the smallest integer | ||
| 762 | larger than WINDOW's pixel width divided by the character width of | ||
| 763 | WINDOW's frame. ROUND `floor' means to return the largest integer | ||
| 764 | smaller than WINDOW's pixel width divided by the character width of | ||
| 765 | WINDOW's frame. Any other value of ROUND means to return the internal | ||
| 766 | total width of WINDOW. */) | ||
| 767 | (Lisp_Object window, Lisp_Object round) | ||
| 735 | { | 768 | { |
| 736 | return make_number (decode_valid_window (window)->total_cols); | 769 | struct window *w = decode_valid_window (window); |
| 770 | |||
| 771 | if (! EQ (round, Qfloor) && ! EQ (round, Qceiling)) | ||
| 772 | return make_number (w->total_cols); | ||
| 773 | else | ||
| 774 | { | ||
| 775 | int unit = FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w)); | ||
| 776 | |||
| 777 | return make_number (EQ (round, Qceiling) | ||
| 778 | ? ((w->pixel_width + unit - 1) /unit) | ||
| 779 | : (w->pixel_width / unit)); | ||
| 780 | } | ||
| 737 | } | 781 | } |
| 738 | 782 | ||
| 739 | DEFUN ("window-new-total", Fwindow_new_total, Swindow_new_total, 0, 1, 0, | 783 | 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. */) | |||
| 811 | return make_number (decode_valid_window (window)->top_line); | 855 | return make_number (decode_valid_window (window)->top_line); |
| 812 | } | 856 | } |
| 813 | 857 | ||
| 814 | /* Return the number of lines of W's body. Don't count any mode or | 858 | /* Return the number of lines/pixels of W's body. Don't count any mode |
| 815 | header line of W. */ | 859 | or header line or horizontal divider of W. Rounds down to nearest |
| 816 | 860 | integer when not working pixelwise. */ | |
| 817 | static int | 861 | static int |
| 818 | window_body_height (struct window *w, bool pixelwise) | 862 | window_body_height (struct window *w, bool pixelwise) |
| 819 | { | 863 | { |
| 820 | int pixels = (w->pixel_height | 864 | int height = (w->pixel_height |
| 821 | - WINDOW_BOTTOM_DIVIDER_WIDTH (w) | ||
| 822 | - WINDOW_HEADER_LINE_HEIGHT (w) | 865 | - WINDOW_HEADER_LINE_HEIGHT (w) |
| 823 | - WINDOW_MODE_LINE_HEIGHT (w)); | 866 | - WINDOW_MODE_LINE_HEIGHT (w) |
| 824 | int unit = FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)); | 867 | - WINDOW_BOTTOM_DIVIDER_WIDTH (w)); |
| 825 | 868 | ||
| 826 | return pixelwise ? pixels : ((pixels + unit - 1) / unit); | 869 | return pixelwise ? height : height / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)); |
| 827 | } | 870 | } |
| 828 | 871 | ||
| 829 | /* Return the number of columns of W's body. Don't count columns | 872 | /* Return the number of columns/pixels of W's body. Don't count columns |
| 830 | occupied by the scroll bar or the vertical bar separating W from its | 873 | occupied by the scroll bar or the divider/vertical bar separating W |
| 831 | right sibling. On window-systems don't count fringes or display | 874 | from its right sibling or margins. On window-systems don't count |
| 832 | margins either. */ | 875 | fringes either. Round down to nearest integer when not working |
| 876 | pixelwise. */ | ||
| 833 | int | 877 | int |
| 834 | window_body_width (struct window *w, bool pixelwise) | 878 | window_body_width (struct window *w, bool pixelwise) |
| 835 | { | 879 | { |
| 836 | struct frame *f = XFRAME (WINDOW_FRAME (w)); | 880 | struct frame *f = XFRAME (WINDOW_FRAME (w)); |
| 837 | 881 | ||
| 838 | int pixels = (w->pixel_width | 882 | int width = (w->pixel_width |
| 839 | - WINDOW_RIGHT_DIVIDER_WIDTH (w) | 883 | - WINDOW_RIGHT_DIVIDER_WIDTH (w) |
| 840 | - (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) | 884 | - (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) |
| 841 | ? WINDOW_SCROLL_BAR_AREA_WIDTH (w) | 885 | ? WINDOW_SCROLL_BAR_AREA_WIDTH (w) |
| 842 | : ((!FRAME_WINDOW_P (f) | 886 | : ((!FRAME_WINDOW_P (f) |
| 843 | && !WINDOW_RIGHTMOST_P (w) | 887 | && !WINDOW_RIGHTMOST_P (w) |
| 844 | && !WINDOW_RIGHT_DIVIDER_WIDTH (w) | 888 | && !WINDOW_RIGHT_DIVIDER_WIDTH (w)) |
| 845 | && !WINDOW_FULL_WIDTH_P (w)) | 889 | /* A vertical bar is either 1 or 0. */ |
| 846 | /* According to Eli this is either 1 or 0. */ | 890 | ? 1 : 0)) |
| 847 | ? 1 : 0)) | ||
| 848 | - WINDOW_MARGINS_WIDTH (w) | 891 | - WINDOW_MARGINS_WIDTH (w) |
| 849 | - (FRAME_WINDOW_P (f) | 892 | - (FRAME_WINDOW_P (f) |
| 850 | ? WINDOW_FRINGES_WIDTH (w) | 893 | ? WINDOW_FRINGES_WIDTH (w) |
| 851 | : 0)); | 894 | : 0)); |
| 852 | int unit = FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w)); | ||
| 853 | 895 | ||
| 854 | return pixelwise ? pixels : ((pixels + unit - 1) / unit); | 896 | return pixelwise ? width : width / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w)); |
| 855 | } | 897 | } |
| 856 | 898 | ||
| 857 | DEFUN ("window-body-height", Fwindow_body_height, Swindow_body_height, 0, 2, 0, | 899 | DEFUN ("window-body-height", Fwindow_body_height, Swindow_body_height, 0, 2, 0, |
| 858 | doc: /* Return the height, in lines, of WINDOW's text area. | 900 | doc: /* Return the height of WINDOW's text area. |
| 859 | WINDOW must be a live window and defaults to the selected one. | 901 | WINDOW must be a live window and defaults to the selected one. Optional |
| 860 | 902 | argument PIXELWISE non-nil means return the height of WINDOW's text area | |
| 861 | Optional argument PIXELWISE non-nil means return the height in pixels. | 903 | in pixels. The return value does not include the mode line or header |
| 862 | 904 | line or any horizontal divider. | |
| 863 | The returned height does not include the mode line or header line. On a | 905 | |
| 864 | graphical display, the height is expressed as an integer multiple of the | 906 | If PIXELWISE is nil, return the largest integer smaller than WINDOW's |
| 865 | default character height if PIXELWISE is nil. | 907 | pixel height divided by the character height of WINDOW's frame. This |
| 866 | 908 | means that if a line at the bottom of the text area is only partially | |
| 867 | If PIXELWISE is nil and a line at the bottom of the text area is only | 909 | visible, that line is not counted. */) |
| 868 | partially visible, that counts as a whole line; to exclude | ||
| 869 | partially-visible lines, use `window-text-height'. */) | ||
| 870 | (Lisp_Object window, Lisp_Object pixelwise) | 910 | (Lisp_Object window, Lisp_Object pixelwise) |
| 871 | { | 911 | { |
| 872 | return make_number (window_body_height (decode_live_window (window), | 912 | return make_number (window_body_height (decode_live_window (window), |
| @@ -874,19 +914,16 @@ partially-visible lines, use `window-text-height'. */) | |||
| 874 | } | 914 | } |
| 875 | 915 | ||
| 876 | DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 2, 0, | 916 | DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 2, 0, |
| 877 | doc: /* Return the width, in columns, of WINDOW's text area. | 917 | doc: /* Return the width of WINDOW's text area. |
| 878 | WINDOW must be a live window and defaults to the selected one. | 918 | WINDOW must be a live window and defaults to the selected one. Optional |
| 879 | 919 | argument PIXELWISE non-nil means return the width in pixels. The return | |
| 880 | Optional argument PIXELWISE non-nil means return the width in pixels. | 920 | value does not include any vertical dividers, fringes or marginal areas, |
| 881 | 921 | or scroll bars. | |
| 882 | The return value does not include any vertical dividers, fringe or | 922 | |
| 883 | marginal areas, or scroll bars. On a graphical display, the width is | 923 | If PIXELWISE is nil, return the largest integer smaller than WINDOW's |
| 884 | expressed as an integer multiple of the default character width if | 924 | pixel width divided by the character width of WINDOW's frame. This |
| 885 | PIXELWISE is nil. | 925 | means that if a column at the right of the text area is only partially |
| 886 | 926 | visible, that column is not counted. */) | |
| 887 | If PIXELWISE is nil and a column at the right of the text area is only | ||
| 888 | partially visible, that counts as a whole column; to exclude | ||
| 889 | partially-visible columns, use `window-text-width'. */) | ||
| 890 | (Lisp_Object window, Lisp_Object pixelwise) | 927 | (Lisp_Object window, Lisp_Object pixelwise) |
| 891 | { | 928 | { |
| 892 | return make_number (window_body_width (decode_live_window (window), | 929 | return make_number (window_body_width (decode_live_window (window), |
| @@ -895,7 +932,7 @@ partially-visible columns, use `window-text-width'. */) | |||
| 895 | 932 | ||
| 896 | DEFUN ("window-mode-line-height", Fwindow_mode_line_height, | 933 | DEFUN ("window-mode-line-height", Fwindow_mode_line_height, |
| 897 | Swindow_mode_line_height, 0, 1, 0, | 934 | Swindow_mode_line_height, 0, 1, 0, |
| 898 | doc: /* Return the height in pixel of WINDOW's mode-line. | 935 | doc: /* Return the height in pixels of WINDOW's mode-line. |
| 899 | WINDOW must be a live window and defaults to the selected one. */) | 936 | WINDOW must be a live window and defaults to the selected one. */) |
| 900 | (Lisp_Object window) | 937 | (Lisp_Object window) |
| 901 | { | 938 | { |
| @@ -904,7 +941,7 @@ WINDOW must be a live window and defaults to the selected one. */) | |||
| 904 | 941 | ||
| 905 | DEFUN ("window-header-line-height", Fwindow_header_line_height, | 942 | DEFUN ("window-header-line-height", Fwindow_header_line_height, |
| 906 | Swindow_header_line_height, 0, 1, 0, | 943 | Swindow_header_line_height, 0, 1, 0, |
| 907 | doc: /* Return the height in pixel of WINDOW's header-line. | 944 | doc: /* Return the height in pixels of WINDOW's header-line. |
| 908 | WINDOW must be a live window and defaults to the selected one. */) | 945 | WINDOW must be a live window and defaults to the selected one. */) |
| 909 | (Lisp_Object window) | 946 | (Lisp_Object window) |
| 910 | { | 947 | { |
| @@ -913,7 +950,7 @@ WINDOW must be a live window and defaults to the selected one. */) | |||
| 913 | 950 | ||
| 914 | DEFUN ("window-right-divider-width", Fwindow_right_divider_width, | 951 | DEFUN ("window-right-divider-width", Fwindow_right_divider_width, |
| 915 | Swindow_right_divider_width, 0, 1, 0, | 952 | Swindow_right_divider_width, 0, 1, 0, |
| 916 | doc: /* Return the width of WINDOW's right divider. | 953 | doc: /* Return the width in pixels of WINDOW's right divider. |
| 917 | WINDOW must be a live window and defaults to the selected one. */) | 954 | WINDOW must be a live window and defaults to the selected one. */) |
| 918 | (Lisp_Object window) | 955 | (Lisp_Object window) |
| 919 | { | 956 | { |
| @@ -922,7 +959,7 @@ WINDOW must be a live window and defaults to the selected one. */) | |||
| 922 | 959 | ||
| 923 | DEFUN ("window-bottom-divider-width", Fwindow_bottom_divider_width, | 960 | DEFUN ("window-bottom-divider-width", Fwindow_bottom_divider_width, |
| 924 | Swindow_bottom_divider_width, 0, 1, 0, | 961 | Swindow_bottom_divider_width, 0, 1, 0, |
| 925 | doc: /* Return the width of WINDOW's bottom divider. | 962 | doc: /* Return the width in pixels of WINDOW's bottom divider. |
| 926 | WINDOW must be a live window and defaults to the selected one. */) | 963 | WINDOW must be a live window and defaults to the selected one. */) |
| 927 | (Lisp_Object window) | 964 | (Lisp_Object window) |
| 928 | { | 965 | { |
| @@ -7101,6 +7138,8 @@ syms_of_window (void) | |||
| 7101 | DEFSYM (Qabove, "above"); | 7138 | DEFSYM (Qabove, "above"); |
| 7102 | DEFSYM (Qbelow, "below"); | 7139 | DEFSYM (Qbelow, "below"); |
| 7103 | DEFSYM (Qclone_of, "clone-of"); | 7140 | DEFSYM (Qclone_of, "clone-of"); |
| 7141 | DEFSYM (Qfloor, "floor"); | ||
| 7142 | DEFSYM (Qceiling, "ceiling"); | ||
| 7104 | 7143 | ||
| 7105 | staticpro (&Vwindow_list); | 7144 | staticpro (&Vwindow_list); |
| 7106 | 7145 | ||