diff options
| author | Martin Rudalics | 2014-02-21 09:02:05 +0100 |
|---|---|---|
| committer | Martin Rudalics | 2014-02-21 09:02:05 +0100 |
| commit | 8dd3e94fb6b780ac2bf5d07795df376a296ef5b5 (patch) | |
| tree | af14870e616ff0a4c8f3fc6dec5d32069bfcb70e | |
| parent | afe1e4c8eb4b4ef62569bd272507ecd5ffd51a2f (diff) | |
| download | emacs-8dd3e94fb6b780ac2bf5d07795df376a296ef5b5.tar.gz emacs-8dd3e94fb6b780ac2bf5d07795df376a296ef5b5.zip | |
Fix handling of window-min-height/-width (Bug#16738).
* window.el (window--dump-window, window--dump-frame): New
functions.
(window--min-size-1): Account for window dividers. When
window-resize-pixelwise is nil, delay rounding till after the
sum of the window components has been calculated.
(window--min-delta-1, window--max-delta-1): When PIXELWISE is
nil make sure at least one text line and two text columns remain
fully visible.
(window-resize): Signal an error when window-resize-apply fails.
(window--resize-child-windows): Fix calculation of by how many
pixels a window can still be shrunk via window-new-normal.
(adjust-window-trailing-edge): Call window--resizable with
correct TRAIL argument.
| -rw-r--r-- | lisp/ChangeLog | 17 | ||||
| -rw-r--r-- | lisp/window.el | 180 | ||||
| -rw-r--r-- | src/ChangeLog | 4 | ||||
| -rw-r--r-- | src/window.c | 10 |
4 files changed, 158 insertions, 53 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 7eb88ebd968..51c52be172f 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,20 @@ | |||
| 1 | 2014-02-21 Martin Rudalics <rudalics@gmx.at> | ||
| 2 | |||
| 3 | Fix handling of window-min-height/-width (Bug#16738). | ||
| 4 | * window.el (window--dump-window, window--dump-frame): New | ||
| 5 | functions. | ||
| 6 | (window--min-size-1): Account for window dividers. When | ||
| 7 | window-resize-pixelwise is nil, delay rounding till after the | ||
| 8 | sum of the window components has been calculated. | ||
| 9 | (window--min-delta-1, window--max-delta-1): When PIXELWISE is | ||
| 10 | nil make sure at least one text line and two text columns remain | ||
| 11 | fully visible. | ||
| 12 | (window-resize): Signal an error when window-resize-apply fails. | ||
| 13 | (window--resize-child-windows): Fix calculation of by how many | ||
| 14 | pixels a window can still be shrunk via window-new-normal. | ||
| 15 | (adjust-window-trailing-edge): Call window--resizable with | ||
| 16 | correct TRAIL argument. | ||
| 17 | |||
| 1 | 2014-02-21 Michael Albinus <michael.albinus@gmx.de> | 18 | 2014-02-21 Michael Albinus <michael.albinus@gmx.de> |
| 2 | 19 | ||
| 3 | * net/tramp.el (tramp-check-cached-permissions): | 20 | * net/tramp.el (tramp-check-cached-permissions): |
diff --git a/lisp/window.el b/lisp/window.el index c4854f02399..357d49d02a2 100644 --- a/lisp/window.el +++ b/lisp/window.el | |||
| @@ -1012,6 +1012,84 @@ FRAME defaults to the selected frame." | |||
| 1012 | (window--side-check frame) | 1012 | (window--side-check frame) |
| 1013 | (window--atom-check frame)) | 1013 | (window--atom-check frame)) |
| 1014 | 1014 | ||
| 1015 | ;; Dumping frame/window contents. | ||
| 1016 | (defun window--dump-window (&optional window erase) | ||
| 1017 | "Dump WINDOW to buffer *window-frame-dump*. | ||
| 1018 | WINDOW must be a valid window and defaults to the selected one. | ||
| 1019 | Optional argument ERASE non-nil means erase *window-frame-dump* | ||
| 1020 | before writing to it." | ||
| 1021 | (setq window (window-normalize-window window)) | ||
| 1022 | (with-current-buffer (get-buffer-create "*window-frame-dump*") | ||
| 1023 | (when erase (erase-buffer)) | ||
| 1024 | (insert | ||
| 1025 | (format "%s parent: %s\n" window (window-parent window)) | ||
| 1026 | (format "pixel left: %s top: %s size: %s x %s new: %s\n" | ||
| 1027 | (window-pixel-left window) (window-pixel-top window) | ||
| 1028 | (window-size window t t) (window-size window nil t) | ||
| 1029 | (window-new-pixel window)) | ||
| 1030 | (format "char left: %s top: %s size: %s x %s new: %s\n" | ||
| 1031 | (window-left-column window) (window-top-line window) | ||
| 1032 | (window-total-size window t) (window-total-size window) | ||
| 1033 | (window-new-total window)) | ||
| 1034 | (format "normal: %s x %s new: %s\n" | ||
| 1035 | (window-normal-size window t) (window-normal-size window) | ||
| 1036 | (window-new-normal window))) | ||
| 1037 | (when (window-live-p window) | ||
| 1038 | (let ((fringes (window-fringes window)) | ||
| 1039 | (margins (window-margins window))) | ||
| 1040 | (insert | ||
| 1041 | (format "body pixel: %s x %s char: %s x %s\n" | ||
| 1042 | (window-body-width window t) (window-body-height window t) | ||
| 1043 | (window-body-width window) (window-body-height window)) | ||
| 1044 | (format "width left fringe: %s left margin: %s right margin: %s\n" | ||
| 1045 | (car fringes) (or (car margins) 0) (or (cdr margins) 0)) | ||
| 1046 | (format "width right fringe: %s scroll-bar: %s divider: %s\n" | ||
| 1047 | (cadr fringes) | ||
| 1048 | (window-scroll-bar-width window) | ||
| 1049 | (window-right-divider-width window)) | ||
| 1050 | (format "height header-line: %s mode-line: %s divider: %s\n" | ||
| 1051 | (window-header-line-height window) | ||
| 1052 | (window-mode-line-height window) | ||
| 1053 | (window-bottom-divider-width window))))) | ||
| 1054 | (insert "\n"))) | ||
| 1055 | |||
| 1056 | (defun window--dump-frame (&optional window-or-frame) | ||
| 1057 | "Dump WINDOW-OR-FRAME to buffer *window-frame-dump*. | ||
| 1058 | WINDOW-OR-FRAME can be a frame or a window and defaults to the | ||
| 1059 | selected frame. When WINDOW-OR-FRAME is a window, dump that | ||
| 1060 | window's frame. The buffer *window-frame-dump* is erased before | ||
| 1061 | dumping to it." | ||
| 1062 | (interactive) | ||
| 1063 | (let* ((window | ||
| 1064 | (cond | ||
| 1065 | ((or (not window-or-frame) | ||
| 1066 | (frame-live-p window-or-frame)) | ||
| 1067 | (frame-root-window window-or-frame)) | ||
| 1068 | ((or (window-live-p window-or-frame) | ||
| 1069 | (window-child window-or-frame)) | ||
| 1070 | window-or-frame) | ||
| 1071 | (t | ||
| 1072 | (frame-root-window)))) | ||
| 1073 | (frame (window-frame window))) | ||
| 1074 | (with-current-buffer (get-buffer-create "*window-frame-dump*") | ||
| 1075 | (erase-buffer) | ||
| 1076 | (insert | ||
| 1077 | (format "frame pixel: %s x %s cols/lines: %s x %s units: %s x %s\n" | ||
| 1078 | (frame-pixel-width frame) (frame-pixel-height frame) | ||
| 1079 | (frame-total-cols frame) (frame-text-lines frame) ; (frame-total-lines frame) | ||
| 1080 | (frame-char-width frame) (frame-char-height frame)) | ||
| 1081 | (format "frame text pixel: %s x %s cols/lines: %s x %s\n" | ||
| 1082 | (frame-text-width frame) (frame-text-height frame) | ||
| 1083 | (frame-text-cols frame) (frame-text-lines frame)) | ||
| 1084 | (format "tool: %s scroll: %s fringe: %s border: %s right: %s bottom: %s\n\n" | ||
| 1085 | (tool-bar-height frame t) | ||
| 1086 | (frame-scroll-bar-width frame) | ||
| 1087 | (frame-fringe-width frame) | ||
| 1088 | (frame-border-width frame) | ||
| 1089 | (frame-right-divider-width frame) | ||
| 1090 | (frame-bottom-divider-width frame))) | ||
| 1091 | (walk-window-tree 'window--dump-window frame t t)))) | ||
| 1092 | |||
| 1015 | ;;; Window sizes. | 1093 | ;;; Window sizes. |
| 1016 | (defun window-total-size (&optional window horizontal round) | 1094 | (defun window-total-size (&optional window horizontal round) |
| 1017 | "Return the total height or width of WINDOW. | 1095 | "Return the total height or width of WINDOW. |
| @@ -1140,55 +1218,46 @@ of WINDOW." | |||
| 1140 | ;; windows such that the new (or resized) windows can get a | 1218 | ;; windows such that the new (or resized) windows can get a |
| 1141 | ;; size less than the user-specified `window-min-height' and | 1219 | ;; size less than the user-specified `window-min-height' and |
| 1142 | ;; `window-min-width'. | 1220 | ;; `window-min-width'. |
| 1143 | (let ((frame (window-frame window)) | 1221 | (let* ((char-size (frame-char-size window t)) |
| 1144 | (fringes (window-fringes window)) | 1222 | (fringes (window-fringes window)) |
| 1145 | (scroll-bars (window-scroll-bars window))) | 1223 | (pixel-width |
| 1224 | (+ (window-safe-min-size window t t) | ||
| 1225 | (car fringes) (cadr fringes) | ||
| 1226 | (window-scroll-bar-width window) | ||
| 1227 | (window-right-divider-width window)))) | ||
| 1146 | (if pixelwise | 1228 | (if pixelwise |
| 1147 | (max | 1229 | (max |
| 1148 | (+ (window-safe-min-size window t t) | 1230 | (if window-resize-pixelwise |
| 1149 | (car fringes) (cadr fringes) | 1231 | pixel-width |
| 1150 | (cond | 1232 | ;; Round up to next integral of columns. |
| 1151 | ((memq (nth 2 scroll-bars) '(left right)) | 1233 | (* (ceiling pixel-width char-size) char-size)) |
| 1152 | (nth 1 scroll-bars)) | ||
| 1153 | ((memq (frame-parameter frame 'vertical-scroll-bars) | ||
| 1154 | '(left right)) | ||
| 1155 | (frame-parameter frame 'scroll-bar-width)) | ||
| 1156 | (t 0))) | ||
| 1157 | (if (window--size-ignore-p window ignore) | 1234 | (if (window--size-ignore-p window ignore) |
| 1158 | 0 | 1235 | 0 |
| 1159 | (window-min-pixel-width))) | 1236 | (window-min-pixel-width))) |
| 1160 | (max | 1237 | (max |
| 1161 | (+ window-safe-min-width | 1238 | (ceiling pixel-width char-size) |
| 1162 | (ceiling (car fringes) (frame-char-width frame)) | ||
| 1163 | (ceiling (cadr fringes) (frame-char-width frame)) | ||
| 1164 | (cond | ||
| 1165 | ((memq (nth 2 scroll-bars) '(left right)) | ||
| 1166 | (nth 1 scroll-bars)) | ||
| 1167 | ((memq (frame-parameter frame 'vertical-scroll-bars) | ||
| 1168 | '(left right)) | ||
| 1169 | (ceiling (or (frame-parameter frame 'scroll-bar-width) 14) | ||
| 1170 | (frame-char-width))) | ||
| 1171 | (t 0))) | ||
| 1172 | (if (window--size-ignore-p window ignore) | 1239 | (if (window--size-ignore-p window ignore) |
| 1173 | 0 | 1240 | 0 |
| 1174 | window-min-width))))) | 1241 | window-min-width))))) |
| 1175 | (pixelwise | 1242 | ((let ((char-size (frame-char-size window)) |
| 1176 | (max | 1243 | (pixel-height |
| 1177 | (+ (window-safe-min-size window nil t) | 1244 | (+ (window-safe-min-size window nil t) |
| 1178 | (window-header-line-height window) | 1245 | (window-header-line-height window) |
| 1179 | (window-mode-line-height window)) | 1246 | (window-mode-line-height window) |
| 1180 | (if (window--size-ignore-p window ignore) | 1247 | (window-bottom-divider-width window)))) |
| 1181 | 0 | 1248 | (if pixelwise |
| 1182 | (window-min-pixel-height)))) | 1249 | (max |
| 1183 | (t | 1250 | (if window-resize-pixelwise |
| 1184 | ;; For the minimum height of a window take any mode- or | 1251 | pixel-height |
| 1185 | ;; header-line into account. | 1252 | ;; Round up to next integral of lines. |
| 1186 | (max (+ window-safe-min-height | 1253 | (* (ceiling pixel-height char-size) char-size)) |
| 1187 | (if header-line-format 1 0) | 1254 | (if (window--size-ignore-p window ignore) |
| 1188 | (if mode-line-format 1 0)) | 1255 | 0 |
| 1189 | (if (window--size-ignore-p window ignore) | 1256 | (window-min-pixel-height))) |
| 1190 | 0 | 1257 | (max (ceiling pixel-height char-size) |
| 1191 | window-min-height)))))))) | 1258 | (if (window--size-ignore-p window ignore) |
| 1259 | 0 | ||
| 1260 | window-min-height)))))))))) | ||
| 1192 | 1261 | ||
| 1193 | (defun window-sizable (window delta &optional horizontal ignore pixelwise) | 1262 | (defun window-sizable (window delta &optional horizontal ignore pixelwise) |
| 1194 | "Return DELTA if DELTA lines can be added to WINDOW. | 1263 | "Return DELTA if DELTA lines can be added to WINDOW. |
| @@ -1323,9 +1392,10 @@ WINDOW can be resized in the desired direction. The function | |||
| 1323 | (unless (eq sub window) | 1392 | (unless (eq sub window) |
| 1324 | (setq delta | 1393 | (setq delta |
| 1325 | (min delta | 1394 | (min delta |
| 1326 | (- (window-size sub horizontal pixelwise 'floor) | 1395 | (max (- (window-size sub horizontal pixelwise 'ceiling) |
| 1327 | (window-min-size | 1396 | (window-min-size |
| 1328 | sub horizontal ignore pixelwise))))) | 1397 | sub horizontal ignore pixelwise)) |
| 1398 | 0)))) | ||
| 1329 | (setq sub (window-right sub)))) | 1399 | (setq sub (window-right sub)))) |
| 1330 | (if noup | 1400 | (if noup |
| 1331 | delta | 1401 | delta |
| @@ -1400,9 +1470,11 @@ by which WINDOW can be shrunk." | |||
| 1400 | (t | 1470 | (t |
| 1401 | (setq delta | 1471 | (setq delta |
| 1402 | (+ delta | 1472 | (+ delta |
| 1403 | (- (window-size sub horizontal pixelwise 'floor) | 1473 | (max |
| 1404 | (window-min-size | 1474 | (- (window-size sub horizontal pixelwise 'ceiling) |
| 1405 | sub horizontal ignore pixelwise)))))) | 1475 | (window-min-size |
| 1476 | sub horizontal ignore pixelwise)) | ||
| 1477 | 0))))) | ||
| 1406 | (setq sub (window-right sub)))) | 1478 | (setq sub (window-right sub)))) |
| 1407 | ;; For an ortho-combination throw DELTA when at least one | 1479 | ;; For an ortho-combination throw DELTA when at least one |
| 1408 | ;; child window is fixed-size. | 1480 | ;; child window is fixed-size. |
| @@ -2317,9 +2389,11 @@ instead." | |||
| 2317 | ;; Otherwise, resize all other windows in the same combination. | 2389 | ;; Otherwise, resize all other windows in the same combination. |
| 2318 | (window--resize-siblings window delta horizontal ignore)) | 2390 | (window--resize-siblings window delta horizontal ignore)) |
| 2319 | (when (window--resize-apply-p frame horizontal) | 2391 | (when (window--resize-apply-p frame horizontal) |
| 2320 | (window-resize-apply frame horizontal) | 2392 | (if (window-resize-apply frame horizontal) |
| 2321 | (window--pixel-to-total frame horizontal) | 2393 | (progn |
| 2322 | (run-window-configuration-change-hook frame))) | 2394 | (window--pixel-to-total frame horizontal) |
| 2395 | (run-window-configuration-change-hook frame)) | ||
| 2396 | (error "Failed to apply resizing %s" window)))) | ||
| 2323 | (t | 2397 | (t |
| 2324 | (error "Cannot resize window %s" window))))) | 2398 | (error "Cannot resize window %s" window))))) |
| 2325 | 2399 | ||
| @@ -2560,7 +2634,7 @@ already set by this routine." | |||
| 2560 | (setq best-value most-negative-fixnum) | 2634 | (setq best-value most-negative-fixnum) |
| 2561 | (while sub | 2635 | (while sub |
| 2562 | (when (and (consp (window-new-normal sub)) | 2636 | (when (and (consp (window-new-normal sub)) |
| 2563 | (not (zerop (car (window-new-normal sub)))) | 2637 | (not (<= (car (window-new-normal sub)) 0)) |
| 2564 | (> (cdr (window-new-normal sub)) best-value)) | 2638 | (> (cdr (window-new-normal sub)) best-value)) |
| 2565 | (setq best-window sub) | 2639 | (setq best-window sub) |
| 2566 | (setq best-value (cdr (window-new-normal sub)))) | 2640 | (setq best-value (cdr (window-new-normal sub)))) |
| @@ -2576,7 +2650,7 @@ already set by this routine." | |||
| 2576 | best-window | 2650 | best-window |
| 2577 | (if (= (car (window-new-normal best-window)) best-delta) | 2651 | (if (= (car (window-new-normal best-window)) best-delta) |
| 2578 | 'skip ; We can't shrink best-window any further. | 2652 | 'skip ; We can't shrink best-window any further. |
| 2579 | (cons (1- (car (window-new-normal best-window))) | 2653 | (cons (- (car (window-new-normal best-window)) best-delta) |
| 2580 | (- (/ (float (window-new-pixel best-window)) | 2654 | (- (/ (float (window-new-pixel best-window)) |
| 2581 | parent-total) | 2655 | parent-total) |
| 2582 | (window-normal-size best-window horizontal)))))))) | 2656 | (window-normal-size best-window horizontal)))))))) |
| @@ -2941,7 +3015,7 @@ move it as far as possible in the desired direction." | |||
| 2941 | (window--resize-reset frame horizontal) | 3015 | (window--resize-reset frame horizontal) |
| 2942 | ;; Try to enlarge LEFT first. | 3016 | ;; Try to enlarge LEFT first. |
| 2943 | (setq this-delta (window--resizable | 3017 | (setq this-delta (window--resizable |
| 2944 | left delta horizontal nil nil nil nil pixelwise)) | 3018 | left delta horizontal nil 'after nil nil pixelwise)) |
| 2945 | (unless (zerop this-delta) | 3019 | (unless (zerop this-delta) |
| 2946 | (window--resize-this-window | 3020 | (window--resize-this-window |
| 2947 | left this-delta horizontal nil t 'before | 3021 | left this-delta horizontal nil t 'before |
| @@ -2970,7 +3044,7 @@ move it as far as possible in the desired direction." | |||
| 2970 | ;; Try to enlarge RIGHT. | 3044 | ;; Try to enlarge RIGHT. |
| 2971 | (setq this-delta | 3045 | (setq this-delta |
| 2972 | (window--resizable | 3046 | (window--resizable |
| 2973 | right (- delta) horizontal nil nil nil nil pixelwise)) | 3047 | right (- delta) horizontal nil 'before nil nil pixelwise)) |
| 2974 | (unless (zerop this-delta) | 3048 | (unless (zerop this-delta) |
| 2975 | (window--resize-this-window | 3049 | (window--resize-this-window |
| 2976 | right this-delta horizontal nil t 'after | 3050 | right this-delta horizontal nil t 'after |
diff --git a/src/ChangeLog b/src/ChangeLog index ae35ff6cce2..2b631dfc5f9 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | 2014-02-21 Martin Rudalics <rudalics@gmx.at> | ||
| 2 | |||
| 3 | * window.c (Fwindow_scroll_bar_width): New function. | ||
| 4 | |||
| 1 | 2014-02-21 Paul Eggert <eggert@cs.ucla.edu> | 5 | 2014-02-21 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 6 | ||
| 3 | Pacify GCC when configuring with --enable-gcc-warnings. | 7 | Pacify GCC when configuring with --enable-gcc-warnings. |
diff --git a/src/window.c b/src/window.c index b2c97d52157..0f62838d672 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -974,6 +974,15 @@ WINDOW must be a live window and defaults to the selected one. */) | |||
| 974 | return (make_number (WINDOW_BOTTOM_DIVIDER_WIDTH (decode_live_window (window)))); | 974 | return (make_number (WINDOW_BOTTOM_DIVIDER_WIDTH (decode_live_window (window)))); |
| 975 | } | 975 | } |
| 976 | 976 | ||
| 977 | DEFUN ("window-scroll-bar-width", Fwindow_scroll_bar_width, | ||
| 978 | Swindow_scroll_bar_width, 0, 1, 0, | ||
| 979 | doc: /* Return the width in pixels of WINDOW's vertical scrollbar. | ||
| 980 | WINDOW must be a live window and defaults to the selected one. */) | ||
| 981 | (Lisp_Object window) | ||
| 982 | { | ||
| 983 | return (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (decode_live_window (window)))); | ||
| 984 | } | ||
| 985 | |||
| 977 | DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0, | 986 | DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0, |
| 978 | doc: /* Return the number of columns by which WINDOW is scrolled from left margin. | 987 | doc: /* Return the number of columns by which WINDOW is scrolled from left margin. |
| 979 | WINDOW must be a live window and defaults to the selected one. */) | 988 | WINDOW must be a live window and defaults to the selected one. */) |
| @@ -7363,6 +7372,7 @@ pixelwise even if this option is nil. */); | |||
| 7363 | defsubr (&Swindow_header_line_height); | 7372 | defsubr (&Swindow_header_line_height); |
| 7364 | defsubr (&Swindow_right_divider_width); | 7373 | defsubr (&Swindow_right_divider_width); |
| 7365 | defsubr (&Swindow_bottom_divider_width); | 7374 | defsubr (&Swindow_bottom_divider_width); |
| 7375 | defsubr (&Swindow_scroll_bar_width); | ||
| 7366 | defsubr (&Swindow_inside_edges); | 7376 | defsubr (&Swindow_inside_edges); |
| 7367 | defsubr (&Swindow_inside_pixel_edges); | 7377 | defsubr (&Swindow_inside_pixel_edges); |
| 7368 | defsubr (&Swindow_inside_absolute_pixel_edges); | 7378 | defsubr (&Swindow_inside_absolute_pixel_edges); |