diff options
| author | Martin Rudalics | 2011-06-11 16:06:16 +0200 |
|---|---|---|
| committer | Martin Rudalics | 2011-06-11 16:06:16 +0200 |
| commit | 6198ccd0b2e8cebc14415e13765de6bb758ec786 (patch) | |
| tree | fd3a913e20dc8e70f667d7ced7111bd27e64c8e7 /lisp | |
| parent | 1ab0dee5ca2b1368770aac0f796959c95f18ed89 (diff) | |
| download | emacs-6198ccd0b2e8cebc14415e13765de6bb758ec786.tar.gz emacs-6198ccd0b2e8cebc14415e13765de6bb758ec786.zip | |
Window configuration, balancing and fit-to-buffer rewrites.
* window.c (delete_deletable_window): Re-add.
(Fset_window_configuration): Rewrite to handle dead buffers and
consequently deletable windows.
(window_tree, Fwindow_tree): Remove. Supply functionality in
window.el.
(compare_window_configurations): Simplify code.
* window.el (window-tree-1, window-tree): New functions, moving
the latter to window.el.
(bw-get-tree, bw-get-tree-1, bw-find-tree-sub)
(bw-find-tree-sub-1, bw-l, bw-t, bw-r, bw-b, bw-dir, bw-eqdir)
(bw-refresh-edges): Remove.
(balance-windows-1, balance-windows-2): New functions.
(balance-windows): Rewrite in terms of window tree functions,
balance-windows-1 and balance-windows-2.
(bw-adjust-window): Remove.
(balance-windows-area-adjust): New function with functionality of
bw-adjust-window but using resize-window.
(set-window-text-height): Rewrite doc-string. Use
normalize-live-window and resize-window.
(enlarge-window-horizontally, shrink-window-horizontally): Rename
argument to DELTA.
(window-buffer-height): New function.
(fit-window-to-buffer, shrink-window-if-larger-than-buffer):
Rewrite using new window resize routines.
(kill-buffer-and-window, mouse-autoselect-window-select): Use
ignore-errors instead of condition-case.
(quit-window): Call delete-frame instead of delete-windows-on
for the only buffer on frame.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ChangeLog | 25 | ||||
| -rw-r--r-- | lisp/window.el | 754 |
2 files changed, 379 insertions, 400 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 611531330cc..7c258be6d9b 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,28 @@ | |||
| 1 | 2011-06-11 Martin Rudalics <rudalics@gmx.at> | ||
| 2 | |||
| 3 | * window.el (window-tree-1, window-tree): New functions, moving | ||
| 4 | the latter to window.el. | ||
| 5 | (bw-get-tree, bw-get-tree-1, bw-find-tree-sub) | ||
| 6 | (bw-find-tree-sub-1, bw-l, bw-t, bw-r, bw-b, bw-dir, bw-eqdir) | ||
| 7 | (bw-refresh-edges): Remove. | ||
| 8 | (balance-windows-1, balance-windows-2): New functions. | ||
| 9 | (balance-windows): Rewrite in terms of window tree functions, | ||
| 10 | balance-windows-1 and balance-windows-2. | ||
| 11 | (bw-adjust-window): Remove. | ||
| 12 | (balance-windows-area-adjust): New function with functionality of | ||
| 13 | bw-adjust-window but using resize-window. | ||
| 14 | (set-window-text-height): Rewrite doc-string. Use | ||
| 15 | normalize-live-window and resize-window. | ||
| 16 | (enlarge-window-horizontally, shrink-window-horizontally): Rename | ||
| 17 | argument to DELTA. | ||
| 18 | (window-buffer-height): New function. | ||
| 19 | (fit-window-to-buffer, shrink-window-if-larger-than-buffer): | ||
| 20 | Rewrite using new window resize routines. | ||
| 21 | (kill-buffer-and-window, mouse-autoselect-window-select): Use | ||
| 22 | ignore-errors instead of condition-case. | ||
| 23 | (quit-window): Call delete-frame instead of delete-windows-on | ||
| 24 | for the only buffer on frame. | ||
| 25 | |||
| 1 | 2011-06-10 Martin Rudalics <rudalics@gmx.at> | 26 | 2011-06-10 Martin Rudalics <rudalics@gmx.at> |
| 2 | 27 | ||
| 3 | * loadup.el (top-level): Load window before files for the sake | 28 | * loadup.el (top-level): Load window before files for the sake |
diff --git a/lisp/window.el b/lisp/window.el index 2811baf706d..ace82826e67 100644 --- a/lisp/window.el +++ b/lisp/window.el | |||
| @@ -2077,6 +2077,47 @@ WINDOW can be any window and defaults to the selected window." | |||
| 2077 | (defsubst frame-root-window-p (window) | 2077 | (defsubst frame-root-window-p (window) |
| 2078 | "Return non-nil if WINDOW is the root window of its frame." | 2078 | "Return non-nil if WINDOW is the root window of its frame." |
| 2079 | (eq window (frame-root-window window))) | 2079 | (eq window (frame-root-window window))) |
| 2080 | |||
| 2081 | (defun window-tree-1 (window &optional next) | ||
| 2082 | "Return window tree rooted at WINDOW. | ||
| 2083 | Optional argument NEXT non-nil means include windows right | ||
| 2084 | siblings in the return value. | ||
| 2085 | |||
| 2086 | See the documentation of `window-tree' for a description of the | ||
| 2087 | return value." | ||
| 2088 | (let (list) | ||
| 2089 | (while window | ||
| 2090 | (setq list | ||
| 2091 | (cons | ||
| 2092 | (cond | ||
| 2093 | ((window-vchild window) | ||
| 2094 | (cons t (cons (window-edges window) | ||
| 2095 | (window-tree-1 (window-vchild window) t)))) | ||
| 2096 | ((window-hchild window) | ||
| 2097 | (cons nil (cons (window-edges window) | ||
| 2098 | (window-tree-1 (window-hchild window) t)))) | ||
| 2099 | (t window)) | ||
| 2100 | list)) | ||
| 2101 | (setq window (when next (window-next window)))) | ||
| 2102 | (nreverse list))) | ||
| 2103 | |||
| 2104 | (defun window-tree (&optional frame) | ||
| 2105 | "Return the window tree of frame FRAME. | ||
| 2106 | FRAME must be a live frame and defaults to the selected frame. | ||
| 2107 | The return value is a list of the form (ROOT MINI), where ROOT | ||
| 2108 | represents the window tree of the frame's root window, and MINI | ||
| 2109 | is the frame's minibuffer window. | ||
| 2110 | |||
| 2111 | If the root window is not split, ROOT is the root window itself. | ||
| 2112 | Otherwise, ROOT is a list (DIR EDGES W1 W2 ...) where DIR is nil | ||
| 2113 | for a horizontal split, and t for a vertical split. EDGES gives | ||
| 2114 | the combined size and position of the subwindows in the split, | ||
| 2115 | and the rest of the elements are the subwindows in the split. | ||
| 2116 | Each of the subwindows may again be a window or a list | ||
| 2117 | representing a window split, and so on. EDGES is a list \(LEFT | ||
| 2118 | TOP RIGHT BOTTOM) as returned by `window-edges'." | ||
| 2119 | (setq frame (normalize-live-frame frame)) | ||
| 2120 | (window-tree-1 (frame-root-window frame) t)) | ||
| 2080 | 2121 | ||
| 2081 | (defun other-window (count &optional all-frames) | 2122 | (defun other-window (count &optional all-frames) |
| 2082 | "Select another window in cyclic ordering of windows. | 2123 | "Select another window in cyclic ordering of windows. |
| @@ -3184,201 +3225,125 @@ The selected window remains selected. Return the new window." | |||
| 3184 | 3225 | ||
| 3185 | (defalias 'split-window-horizontally 'split-window-side-by-side) | 3226 | (defalias 'split-window-horizontally 'split-window-side-by-side) |
| 3186 | 3227 | ||
| 3187 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 3228 | ;;; Balancing windows. |
| 3188 | ;;; `balance-windows' subroutines using `window-tree' | 3229 | |
| 3189 | 3230 | ;; The following routine uses the recycled code from an old version of | |
| 3190 | ;;; Translate from internal window tree format | 3231 | ;; `resize-subwindows'. It's not very pretty, but coding it the way the |
| 3191 | 3232 | ;; new `resize-subwindows' code does would hardly make it any shorter or | |
| 3192 | (defun bw-get-tree (&optional window-or-frame) | 3233 | ;; more readable (FWIW we'd need three loops - one to calculate the |
| 3193 | "Get a window split tree in our format. | 3234 | ;; minimum sizes per window, one to enlarge or shrink windows until the |
| 3194 | 3235 | ;; new parent-size matches, and one where we shrink the largest/enlarge | |
| 3195 | WINDOW-OR-FRAME must be nil, a frame, or a window. If it is nil, | 3236 | ;; the smallest window). |
| 3196 | then the whole window split tree for `selected-frame' is returned. | 3237 | (defun balance-windows-2 (window horizontal) |
| 3197 | If it is a frame, then this is used instead. If it is a window, | 3238 | "Subroutine of `balance-windows-1'. |
| 3198 | then the smallest tree containing that window is returned." | 3239 | WINDOW must be an iso-combination." |
| 3199 | (when window-or-frame | 3240 | (let* ((first (window-child window)) |
| 3200 | (unless (or (framep window-or-frame) | 3241 | (sub first) |
| 3201 | (windowp window-or-frame)) | 3242 | (number-of-children 0) |
| 3202 | (error "Not a frame or window: %s" window-or-frame))) | 3243 | (parent-size (window-new-total window)) |
| 3203 | (let ((subtree (bw-find-tree-sub window-or-frame))) | 3244 | (total-sum parent-size) |
| 3204 | (when subtree | 3245 | found failed size sub-total sub-delta sub-amount rest) |
| 3205 | (if (integerp subtree) | 3246 | (while sub |
| 3206 | nil | 3247 | (setq number-of-children (1+ number-of-children)) |
| 3207 | (bw-get-tree-1 subtree))))) | 3248 | (when (window-size-fixed-p sub horizontal) |
| 3208 | 3249 | (setq total-sum | |
| 3209 | (defun bw-get-tree-1 (split) | 3250 | (- total-sum (window-total-size sub horizontal))) |
| 3210 | (if (windowp split) | 3251 | (set-window-new-normal sub 'ignore)) |
| 3211 | split | 3252 | (setq sub (window-right sub))) |
| 3212 | (let ((dir (car split)) | ||
| 3213 | (edges (car (cdr split))) | ||
| 3214 | (childs (cdr (cdr split)))) | ||
| 3215 | (list | ||
| 3216 | (cons 'dir (if dir 'ver 'hor)) | ||
| 3217 | (cons 'b (nth 3 edges)) | ||
| 3218 | (cons 'r (nth 2 edges)) | ||
| 3219 | (cons 't (nth 1 edges)) | ||
| 3220 | (cons 'l (nth 0 edges)) | ||
| 3221 | (cons 'childs (mapcar #'bw-get-tree-1 childs)))))) | ||
| 3222 | |||
| 3223 | (defun bw-find-tree-sub (window-or-frame &optional get-parent) | ||
| 3224 | (let* ((window (when (windowp window-or-frame) window-or-frame)) | ||
| 3225 | (frame (when (windowp window) (window-frame window))) | ||
| 3226 | (wt (car (window-tree frame)))) | ||
| 3227 | (when (< 1 (length (window-list frame 0))) | ||
| 3228 | (if window | ||
| 3229 | (bw-find-tree-sub-1 wt window get-parent) | ||
| 3230 | wt)))) | ||
| 3231 | |||
| 3232 | (defun bw-find-tree-sub-1 (tree win &optional get-parent) | ||
| 3233 | (unless (windowp win) (error "Not a window: %s" win)) | ||
| 3234 | (if (memq win tree) | ||
| 3235 | (if get-parent | ||
| 3236 | get-parent | ||
| 3237 | tree) | ||
| 3238 | (let ((childs (cdr (cdr tree))) | ||
| 3239 | child | ||
| 3240 | subtree) | ||
| 3241 | (while (and childs (not subtree)) | ||
| 3242 | (setq child (car childs)) | ||
| 3243 | (setq childs (cdr childs)) | ||
| 3244 | (when (and child (listp child)) | ||
| 3245 | (setq subtree (bw-find-tree-sub-1 child win get-parent)))) | ||
| 3246 | (if (integerp subtree) | ||
| 3247 | (progn | ||
| 3248 | (if (= 1 subtree) | ||
| 3249 | tree | ||
| 3250 | (1- subtree))) | ||
| 3251 | subtree | ||
| 3252 | )))) | ||
| 3253 | |||
| 3254 | ;;; Window or object edges | ||
| 3255 | |||
| 3256 | (defun bw-l (obj) | ||
| 3257 | "Left edge of OBJ." | ||
| 3258 | (if (windowp obj) (nth 0 (window-edges obj)) (cdr (assq 'l obj)))) | ||
| 3259 | (defun bw-t (obj) | ||
| 3260 | "Top edge of OBJ." | ||
| 3261 | (if (windowp obj) (nth 1 (window-edges obj)) (cdr (assq 't obj)))) | ||
| 3262 | (defun bw-r (obj) | ||
| 3263 | "Right edge of OBJ." | ||
| 3264 | (if (windowp obj) (nth 2 (window-edges obj)) (cdr (assq 'r obj)))) | ||
| 3265 | (defun bw-b (obj) | ||
| 3266 | "Bottom edge of OBJ." | ||
| 3267 | (if (windowp obj) (nth 3 (window-edges obj)) (cdr (assq 'b obj)))) | ||
| 3268 | |||
| 3269 | ;;; Split directions | ||
| 3270 | |||
| 3271 | (defun bw-dir (obj) | ||
| 3272 | "Return window split tree direction if OBJ. | ||
| 3273 | If OBJ is a window return 'both. If it is a window split tree | ||
| 3274 | then return its direction." | ||
| 3275 | (if (symbolp obj) | ||
| 3276 | obj | ||
| 3277 | (if (windowp obj) | ||
| 3278 | 'both | ||
| 3279 | (let ((dir (cdr (assq 'dir obj)))) | ||
| 3280 | (unless (memq dir '(hor ver both)) | ||
| 3281 | (error "Can't find dir in %s" obj)) | ||
| 3282 | dir)))) | ||
| 3283 | |||
| 3284 | (defun bw-eqdir (obj1 obj2) | ||
| 3285 | "Return t if window split tree directions are equal. | ||
| 3286 | OBJ1 and OBJ2 should be either windows or window split trees in | ||
| 3287 | our format. The directions returned by `bw-dir' are compared and | ||
| 3288 | t is returned if they are `eq' or one of them is 'both." | ||
| 3289 | (let ((dir1 (bw-dir obj1)) | ||
| 3290 | (dir2 (bw-dir obj2))) | ||
| 3291 | (or (eq dir1 dir2) | ||
| 3292 | (eq dir1 'both) | ||
| 3293 | (eq dir2 'both)))) | ||
| 3294 | |||
| 3295 | ;;; Building split tree | ||
| 3296 | |||
| 3297 | (defun bw-refresh-edges (obj) | ||
| 3298 | "Refresh the edge information of OBJ and return OBJ." | ||
| 3299 | (unless (windowp obj) | ||
| 3300 | (let ((childs (cdr (assq 'childs obj))) | ||
| 3301 | (ol 1000) | ||
| 3302 | (ot 1000) | ||
| 3303 | (or -1) | ||
| 3304 | (ob -1)) | ||
| 3305 | (dolist (o childs) | ||
| 3306 | (when (> ol (bw-l o)) (setq ol (bw-l o))) | ||
| 3307 | (when (> ot (bw-t o)) (setq ot (bw-t o))) | ||
| 3308 | (when (< or (bw-r o)) (setq or (bw-r o))) | ||
| 3309 | (when (< ob (bw-b o)) (setq ob (bw-b o)))) | ||
| 3310 | (setq obj (delq 'l obj)) | ||
| 3311 | (setq obj (delq 't obj)) | ||
| 3312 | (setq obj (delq 'r obj)) | ||
| 3313 | (setq obj (delq 'b obj)) | ||
| 3314 | (add-to-list 'obj (cons 'l ol)) | ||
| 3315 | (add-to-list 'obj (cons 't ot)) | ||
| 3316 | (add-to-list 'obj (cons 'r or)) | ||
| 3317 | (add-to-list 'obj (cons 'b ob)) | ||
| 3318 | )) | ||
| 3319 | obj) | ||
| 3320 | |||
| 3321 | ;;; Balance windows | ||
| 3322 | 3253 | ||
| 3323 | (defun balance-windows (&optional window-or-frame) | 3254 | (setq failed t) |
| 3324 | "Make windows the same heights or widths in window split subtrees. | 3255 | (while (and failed (> number-of-children 0)) |
| 3256 | (setq size (/ total-sum number-of-children)) | ||
| 3257 | (setq failed nil) | ||
| 3258 | (setq sub first) | ||
| 3259 | (while (and sub (not failed)) | ||
| 3260 | ;; Ignore subwindows that should be ignored or are stuck. | ||
| 3261 | (unless (resize-subwindows-skip-p sub) | ||
| 3262 | (setq found t) | ||
| 3263 | (setq sub-total (window-total-size sub horizontal)) | ||
| 3264 | (setq sub-delta (- size sub-total)) | ||
| 3265 | (setq sub-amount | ||
| 3266 | (window-sizable sub sub-delta horizontal)) | ||
| 3267 | ;; Register the new total size for this subwindow. | ||
| 3268 | (set-window-new-total sub (+ sub-total sub-amount)) | ||
| 3269 | (unless (= sub-amount sub-delta) | ||
| 3270 | (setq total-sum (- total-sum sub-total sub-amount)) | ||
| 3271 | (setq number-of-children (1- number-of-children)) | ||
| 3272 | ;; We failed and need a new round. | ||
| 3273 | (setq failed t) | ||
| 3274 | (set-window-new-normal sub 'skip))) | ||
| 3275 | (setq sub (window-right sub)))) | ||
| 3325 | 3276 | ||
| 3326 | When called non-interactively WINDOW-OR-FRAME may be either a | 3277 | (setq rest (% total-sum number-of-children)) |
| 3327 | window or a frame. It then balances the windows on the implied | 3278 | ;; Fix rounding by trying to enlarge non-stuck windows by one line |
| 3328 | frame. If the parameter is a window only the corresponding window | 3279 | ;; (column) until `rest' is zero. |
| 3329 | subtree is balanced." | 3280 | (setq sub first) |
| 3330 | (interactive) | 3281 | (while (and sub (> rest 0)) |
| 3331 | (let ( | 3282 | (unless (resize-subwindows-skip-p window) |
| 3332 | (wt (bw-get-tree window-or-frame)) | 3283 | (set-window-new-total sub 1 t) |
| 3333 | (w) | 3284 | (setq rest (1- rest))) |
| 3334 | (h) | 3285 | (setq sub (window-right sub))) |
| 3335 | (tried-sizes) | 3286 | |
| 3336 | (last-sizes) | 3287 | ;; Fix rounding by trying to enlarge stuck windows by one line |
| 3337 | (windows (window-list nil 0))) | 3288 | ;; (column) until `rest' equals zero. |
| 3338 | (when wt | 3289 | (setq sub first) |
| 3339 | (while (not (member last-sizes tried-sizes)) | 3290 | (while (and sub (> rest 0)) |
| 3340 | (when last-sizes (setq tried-sizes (cons last-sizes tried-sizes))) | 3291 | (unless (eq (window-new-normal sub) 'ignore) |
| 3341 | (setq last-sizes (mapcar (lambda (w) | 3292 | (set-window-new-total sub 1 t) |
| 3342 | (window-edges w)) | 3293 | (setq rest (1- rest))) |
| 3343 | windows)) | 3294 | (setq sub (window-right sub))) |
| 3344 | (when (eq 'hor (bw-dir wt)) | ||
| 3345 | (setq w (- (bw-r wt) (bw-l wt)))) | ||
| 3346 | (when (eq 'ver (bw-dir wt)) | ||
| 3347 | (setq h (- (bw-b wt) (bw-t wt)))) | ||
| 3348 | (bw-balance-sub wt w h))))) | ||
| 3349 | |||
| 3350 | (defun bw-adjust-window (window delta horizontal) | ||
| 3351 | "Wrapper around `adjust-window-trailing-edge' with error checking. | ||
| 3352 | Arguments WINDOW, DELTA and HORIZONTAL are passed on to that function." | ||
| 3353 | ;; `adjust-window-trailing-edge' may fail if delta is too large. | ||
| 3354 | (while (>= (abs delta) 1) | ||
| 3355 | (condition-case nil | ||
| 3356 | (progn | ||
| 3357 | (adjust-window-trailing-edge window delta horizontal) | ||
| 3358 | (setq delta 0)) | ||
| 3359 | (error | ||
| 3360 | ;;(message "adjust: %s" (error-message-string err)) | ||
| 3361 | (setq delta (/ delta 2)))))) | ||
| 3362 | 3295 | ||
| 3363 | (defun bw-balance-sub (wt w h) | 3296 | (setq sub first) |
| 3364 | (setq wt (bw-refresh-edges wt)) | 3297 | (while sub |
| 3365 | (unless w (setq w (- (bw-r wt) (bw-l wt)))) | 3298 | ;; Record new normal sizes. |
| 3366 | (unless h (setq h (- (bw-b wt) (bw-t wt)))) | 3299 | (set-window-new-normal |
| 3367 | (if (windowp wt) | 3300 | sub (/ (if (eq (window-new-normal sub) 'ignore) |
| 3368 | (progn | 3301 | (window-total-size sub horizontal) |
| 3369 | (when w | 3302 | (window-new-total sub)) |
| 3370 | (let ((dw (- w (- (bw-r wt) (bw-l wt))))) | 3303 | (float parent-size))) |
| 3371 | (when (/= 0 dw) | 3304 | ;; Recursively balance each subwindow's subwindows. |
| 3372 | (bw-adjust-window wt dw t)))) | 3305 | (balance-windows-1 sub horizontal) |
| 3373 | (when h | 3306 | (setq sub (window-right sub))))) |
| 3374 | (let ((dh (- h (- (bw-b wt) (bw-t wt))))) | 3307 | |
| 3375 | (when (/= 0 dh) | 3308 | (defun balance-windows-1 (window &optional horizontal) |
| 3376 | (bw-adjust-window wt dh nil))))) | 3309 | "Subroutine of `balance-windows'." |
| 3377 | (let* ((childs (cdr (assq 'childs wt))) | 3310 | (if (window-child window) |
| 3378 | (cw (when w (/ w (if (bw-eqdir 'hor wt) (length childs) 1)))) | 3311 | (let ((sub (window-child window))) |
| 3379 | (ch (when h (/ h (if (bw-eqdir 'ver wt) (length childs) 1))))) | 3312 | (if (window-iso-combined-p sub horizontal) |
| 3380 | (dolist (c childs) | 3313 | (balance-windows-2 window horizontal) |
| 3381 | (bw-balance-sub c cw ch))))) | 3314 | (let ((size (window-new-total window))) |
| 3315 | (while sub | ||
| 3316 | (set-window-new-total sub size) | ||
| 3317 | (balance-windows-1 sub horizontal) | ||
| 3318 | (setq sub (window-right sub)))))))) | ||
| 3319 | |||
| 3320 | (defun balance-windows (&optional window-or-frame) | ||
| 3321 | "Balance the sizes of subwindows of WINDOW-OR-FRAME. | ||
| 3322 | WINDOW-OR-FRAME is optional and defaults to the selected frame. | ||
| 3323 | If WINDOW-OR-FRAME denotes a frame, balance the sizes of all | ||
| 3324 | subwindows of that frame's root window. If WINDOW-OR-FRAME | ||
| 3325 | denots a window, balance the sizes of all subwindows of that | ||
| 3326 | window." | ||
| 3327 | (interactive) | ||
| 3328 | (let* ((window | ||
| 3329 | (cond | ||
| 3330 | ((or (not window-or-frame) | ||
| 3331 | (frame-live-p window-or-frame)) | ||
| 3332 | (frame-root-window window-or-frame)) | ||
| 3333 | ((or (window-live-p window-or-frame) | ||
| 3334 | (window-child window-or-frame)) | ||
| 3335 | window-or-frame) | ||
| 3336 | (t | ||
| 3337 | (error "Not a window or frame %s" window-or-frame)))) | ||
| 3338 | (frame (window-frame window))) | ||
| 3339 | ;; Balance vertically. | ||
| 3340 | (resize-window-reset (window-frame window)) | ||
| 3341 | (balance-windows-1 window) | ||
| 3342 | (resize-window-apply frame) | ||
| 3343 | ;; Balance horizontally. | ||
| 3344 | (resize-window-reset (window-frame window) t) | ||
| 3345 | (balance-windows-1 window t) | ||
| 3346 | (resize-window-apply frame t))) | ||
| 3382 | 3347 | ||
| 3383 | (defun window-fixed-size-p (&optional window direction) | 3348 | (defun window-fixed-size-p (&optional window direction) |
| 3384 | "Return t if WINDOW cannot be resized in DIRECTION. | 3349 | "Return t if WINDOW cannot be resized in DIRECTION. |
| @@ -3391,13 +3356,25 @@ nil (i.e. any), `height' or `width'." | |||
| 3391 | '((height . width) (width . height)))))))) | 3356 | '((height . width) (width . height)))))))) |
| 3392 | 3357 | ||
| 3393 | ;;; A different solution to balance-windows. | 3358 | ;;; A different solution to balance-windows. |
| 3394 | |||
| 3395 | (defvar window-area-factor 1 | 3359 | (defvar window-area-factor 1 |
| 3396 | "Factor by which the window area should be over-estimated. | 3360 | "Factor by which the window area should be over-estimated. |
| 3397 | This is used by `balance-windows-area'. | 3361 | This is used by `balance-windows-area'. |
| 3398 | Changing this globally has no effect.") | 3362 | Changing this globally has no effect.") |
| 3399 | (make-variable-buffer-local 'window-area-factor) | 3363 | (make-variable-buffer-local 'window-area-factor) |
| 3400 | 3364 | ||
| 3365 | (defun balance-windows-area-adjust (window delta horizontal) | ||
| 3366 | "Wrapper around `resize-window' with error checking. | ||
| 3367 | Arguments WINDOW, DELTA and HORIZONTAL are passed on to that function." | ||
| 3368 | ;; `resize-window' may fail if delta is too large. | ||
| 3369 | (while (>= (abs delta) 1) | ||
| 3370 | (condition-case nil | ||
| 3371 | (progn | ||
| 3372 | (resize-window window delta horizontal) | ||
| 3373 | (setq delta 0)) | ||
| 3374 | (error | ||
| 3375 | ;;(message "adjust: %s" (error-message-string err)) | ||
| 3376 | (setq delta (/ delta 2)))))) | ||
| 3377 | |||
| 3401 | (defun balance-windows-area () | 3378 | (defun balance-windows-area () |
| 3402 | "Make all visible windows the same area (approximately). | 3379 | "Make all visible windows the same area (approximately). |
| 3403 | See also `window-area-factor' to change the relative size of | 3380 | See also `window-area-factor' to change the relative size of |
| @@ -3459,7 +3436,9 @@ specific buffers." | |||
| 3459 | ;; Make sure negligible differences don't accumulate to | 3436 | ;; Make sure negligible differences don't accumulate to |
| 3460 | ;; become significant. | 3437 | ;; become significant. |
| 3461 | (setq carry (+ carry areadiff)) | 3438 | (setq carry (+ carry areadiff)) |
| 3462 | (bw-adjust-window win diff horiz) | 3439 | ;; This used `adjust-window-trailing-edge' before and uses |
| 3440 | ;; `resize-window' now. Error wrapping is still needed. | ||
| 3441 | (balance-windows-area-adjust win diff horiz) | ||
| 3463 | ;; (sit-for 0.5) | 3442 | ;; (sit-for 0.5) |
| 3464 | (let ((change (cons win (window-edges win)))) | 3443 | (let ((change (cons win (window-edges win)))) |
| 3465 | ;; If the same change has been seen already for this window, | 3444 | ;; If the same change has been seen already for this window, |
| @@ -4314,13 +4293,15 @@ documentation for additional customization information." | |||
| 4314 | 4293 | ||
| 4315 | (defun set-window-text-height (window height) | 4294 | (defun set-window-text-height (window height) |
| 4316 | "Set the height in lines of the text display area of WINDOW to HEIGHT. | 4295 | "Set the height in lines of the text display area of WINDOW to HEIGHT. |
| 4317 | HEIGHT doesn't include the mode line or header line, if any, or | 4296 | WINDOW must be a live window. HEIGHT doesn't include the mode |
| 4318 | any partial-height lines in the text display area. | 4297 | line or header line, if any, or any partial-height lines in the |
| 4298 | text display area. | ||
| 4319 | 4299 | ||
| 4320 | Note that the current implementation of this function cannot | 4300 | Note that the current implementation of this function cannot |
| 4321 | always set the height exactly, but attempts to be conservative, | 4301 | always set the height exactly, but attempts to be conservative, |
| 4322 | by allocating more lines than are actually needed in the case | 4302 | by allocating more lines than are actually needed in the case |
| 4323 | where some error may be present." | 4303 | where some error may be present." |
| 4304 | (setq window (normalize-live-window window)) | ||
| 4324 | (let ((delta (- height (window-text-height window)))) | 4305 | (let ((delta (- height (window-text-height window)))) |
| 4325 | (unless (zerop delta) | 4306 | (unless (zerop delta) |
| 4326 | ;; Setting window-min-height to a value like 1 can lead to very | 4307 | ;; Setting window-min-height to a value like 1 can lead to very |
| @@ -4328,36 +4309,21 @@ where some error may be present." | |||
| 4328 | ;; windows 1-line tall, which means that there's no more space for | 4309 | ;; windows 1-line tall, which means that there's no more space for |
| 4329 | ;; the modeline. | 4310 | ;; the modeline. |
| 4330 | (let ((window-min-height (min 2 height))) ; One text line plus a modeline. | 4311 | (let ((window-min-height (min 2 height))) ; One text line plus a modeline. |
| 4331 | (if (and window (not (eq window (selected-window)))) | 4312 | (resize-window window delta))))) |
| 4332 | (save-selected-window | ||
| 4333 | (select-window window 'norecord) | ||
| 4334 | (enlarge-window delta)) | ||
| 4335 | (enlarge-window delta)))))) | ||
| 4336 | 4313 | ||
| 4337 | 4314 | (defun enlarge-window-horizontally (delta) | |
| 4338 | (defun enlarge-window-horizontally (columns) | 4315 | "Make selected window DELTA columns wider. |
| 4339 | "Make selected window COLUMNS wider. | ||
| 4340 | Interactively, if no argument is given, make selected window one | 4316 | Interactively, if no argument is given, make selected window one |
| 4341 | column wider." | 4317 | column wider." |
| 4342 | (interactive "p") | 4318 | (interactive "p") |
| 4343 | (enlarge-window columns t)) | 4319 | (enlarge-window delta t)) |
| 4344 | 4320 | ||
| 4345 | (defun shrink-window-horizontally (columns) | 4321 | (defun shrink-window-horizontally (delta) |
| 4346 | "Make selected window COLUMNS narrower. | 4322 | "Make selected window DELTA columns narrower. |
| 4347 | Interactively, if no argument is given, make selected window one | 4323 | Interactively, if no argument is given, make selected window one |
| 4348 | column narrower." | 4324 | column narrower." |
| 4349 | (interactive "p") | 4325 | (interactive "p") |
| 4350 | (shrink-window columns t)) | 4326 | (shrink-window delta t)) |
| 4351 | |||
| 4352 | (defun window-buffer-height (window) | ||
| 4353 | "Return the height (in screen lines) of the buffer that WINDOW is displaying." | ||
| 4354 | (with-current-buffer (window-buffer window) | ||
| 4355 | (max 1 | ||
| 4356 | (count-screen-lines (point-min) (point-max) | ||
| 4357 | ;; If buffer ends with a newline, ignore it when | ||
| 4358 | ;; counting height unless point is after it. | ||
| 4359 | (eobp) | ||
| 4360 | window)))) | ||
| 4361 | 4327 | ||
| 4362 | (defun count-screen-lines (&optional beg end count-final-newline window) | 4328 | (defun count-screen-lines (&optional beg end count-final-newline window) |
| 4363 | "Return the number of screen lines in the region. | 4329 | "Return the number of screen lines in the region. |
| @@ -4395,80 +4361,99 @@ in some window." | |||
| 4395 | (goto-char (point-min)) | 4361 | (goto-char (point-min)) |
| 4396 | (1+ (vertical-motion (buffer-size) window)))))) | 4362 | (1+ (vertical-motion (buffer-size) window)))))) |
| 4397 | 4363 | ||
| 4398 | (defun fit-window-to-buffer (&optional window max-height min-height) | 4364 | (defun window-buffer-height (window) |
| 4365 | "Return the height (in screen lines) of the buffer that WINDOW is displaying." | ||
| 4366 | (with-current-buffer (window-buffer window) | ||
| 4367 | (max 1 | ||
| 4368 | (count-screen-lines (point-min) (point-max) | ||
| 4369 | ;; If buffer ends with a newline, ignore it when | ||
| 4370 | ;; counting height unless point is after it. | ||
| 4371 | (eobp) | ||
| 4372 | window)))) | ||
| 4373 | |||
| 4374 | ;;; Resizing buffers to fit their contents exactly. | ||
| 4375 | (defun fit-window-to-buffer (&optional window max-height min-height override) | ||
| 4399 | "Adjust height of WINDOW to display its buffer's contents exactly. | 4376 | "Adjust height of WINDOW to display its buffer's contents exactly. |
| 4400 | WINDOW defaults to the selected window. | 4377 | WINDOW can be any live window and defaults to the selected one. |
| 4401 | Optional argument MAX-HEIGHT specifies the maximum height of the | 4378 | |
| 4402 | window and defaults to the maximum permissible height of a window | 4379 | Optional argument MAX-HEIGHT specifies the maximum height of |
| 4403 | on WINDOW's frame. | 4380 | WINDOW and defaults to the height of WINDOW's frame. Optional |
| 4404 | Optional argument MIN-HEIGHT specifies the minimum height of the | 4381 | argument MIN-HEIGHT specifies the minimum height of WINDOW and |
| 4405 | window and defaults to `window-min-height'. | 4382 | defaults to `window-min-height'. Both, MAX-HEIGHT and MIN-HEIGHT |
| 4406 | Both, MAX-HEIGHT and MIN-HEIGHT are specified in lines and | 4383 | are specified in lines and include the mode line and header line, |
| 4407 | include the mode line and header line, if any. | 4384 | if any. |
| 4408 | 4385 | ||
| 4409 | Return non-nil if height was orderly adjusted, nil otherwise. | 4386 | Optional argument OVERRIDE non-nil means override restrictions |
| 4410 | 4387 | imposed by `window-min-height' and `window-min-width' on the size | |
| 4411 | Caution: This function can delete WINDOW and/or other windows | 4388 | of WINDOW. |
| 4412 | when their height shrinks to less than MIN-HEIGHT." | 4389 | |
| 4390 | Return the number of lines by which WINDOW was enlarged or | ||
| 4391 | shrunk. If an error occurs during resizing, return nil but don't | ||
| 4392 | signal an error. | ||
| 4393 | |||
| 4394 | Note that even if this function makes WINDOW large enough to show | ||
| 4395 | _all_ lines of its buffer you might not see the first lines when | ||
| 4396 | WINDOW was scrolled." | ||
| 4413 | (interactive) | 4397 | (interactive) |
| 4414 | ;; Do all the work in WINDOW and its buffer and restore the selected | 4398 | ;; Do all the work in WINDOW and its buffer and restore the selected |
| 4415 | ;; window and the current buffer when we're done. | 4399 | ;; window and the current buffer when we're done. |
| 4416 | (let ((old-buffer (current-buffer)) | 4400 | (setq window (normalize-live-window window)) |
| 4417 | value) | 4401 | ;; Can't resize a full height or fixed-size window. |
| 4418 | (with-selected-window (or window (setq window (selected-window))) | 4402 | (unless (or (window-size-fixed-p window) |
| 4419 | (set-buffer (window-buffer)) | 4403 | (window-full-height-p window)) |
| 4420 | ;; Use `condition-case' to handle any fixed-size windows and other | 4404 | ;; `with-selected-window' should orderly restore the current buffer. |
| 4421 | ;; pitfalls nearby. | 4405 | (with-selected-window window |
| 4422 | (condition-case nil | 4406 | ;; We are in WINDOW's buffer now. |
| 4423 | (let* (;; MIN-HEIGHT must not be less than 1 and defaults to | 4407 | (let* ( ;; Adjust MIN-HEIGHT. |
| 4424 | ;; `window-min-height'. | 4408 | (min-height |
| 4425 | (min-height (max (or min-height window-min-height) 1)) | 4409 | (if override |
| 4426 | (max-window-height | 4410 | (window-min-size window nil window) |
| 4427 | ;; Maximum height of any window on this frame. | 4411 | (max (or min-height window-min-height) |
| 4428 | (min (window-height (frame-root-window)) (frame-height))) | 4412 | window-safe-min-height))) |
| 4429 | ;; MAX-HEIGHT must not be larger than max-window-height and | 4413 | (max-window-height |
| 4430 | ;; defaults to max-window-height. | 4414 | (window-total-size (frame-root-window window))) |
| 4431 | (max-height | 4415 | ;; Adjust MAX-HEIGHT. |
| 4432 | (min (or max-height max-window-height) max-window-height)) | 4416 | (max-height |
| 4433 | (desired-height | 4417 | (if (or override (not max-height)) |
| 4434 | ;; The height necessary to show all of WINDOW's buffer, | 4418 | max-window-height |
| 4435 | ;; constrained by MIN-HEIGHT and MAX-HEIGHT. | 4419 | (min max-height max-window-height))) |
| 4436 | (max | 4420 | ;; Make `desired-height' the height necessary to show |
| 4437 | (min | 4421 | ;; all of WINDOW's buffer, constrained by MIN-HEIGHT |
| 4438 | ;; For an empty buffer `count-screen-lines' returns zero. | 4422 | ;; and MAX-HEIGHT. |
| 4439 | ;; Even in that case we need one line for the cursor. | 4423 | (desired-height |
| 4440 | (+ (max (count-screen-lines) 1) | 4424 | (max |
| 4441 | ;; For non-minibuffers count the mode line, if any. | 4425 | (min |
| 4442 | (if (and (not (window-minibuffer-p)) mode-line-format) | 4426 | (+ (count-screen-lines) |
| 4443 | 1 0) | 4427 | ;; For non-minibuffers count the mode line, if any. |
| 4444 | ;; Count the header line, if any. | 4428 | (if (and (not (window-minibuffer-p window)) |
| 4445 | (if header-line-format 1 0)) | 4429 | mode-line-format) |
| 4446 | max-height) | 4430 | 1 |
| 4447 | min-height)) | 4431 | 0) |
| 4448 | (delta | 4432 | ;; Count the header line, if any. |
| 4449 | ;; How much the window height has to change. | 4433 | (if header-line-format 1 0)) |
| 4450 | (if (= (window-height) (window-height (frame-root-window))) | 4434 | max-height) |
| 4451 | ;; Don't try to resize a full-height window. | 4435 | min-height)) |
| 4452 | 0 | 4436 | (desired-delta |
| 4453 | (- desired-height (window-height)))) | 4437 | (- desired-height (window-total-size window))) |
| 4454 | ;; Do something reasonable so `enlarge-window' can make | 4438 | (delta |
| 4455 | ;; windows as small as MIN-HEIGHT. | 4439 | (if (> desired-delta 0) |
| 4456 | (window-min-height (min min-height window-min-height))) | 4440 | (min desired-delta |
| 4457 | ;; Don't try to redisplay with the cursor at the end on its | 4441 | (window-max-delta window nil window)) |
| 4458 | ;; own line--that would force a scroll and spoil things. | 4442 | (max desired-delta |
| 4459 | (when (and (eobp) (bolp) (not (bobp))) | 4443 | (- (window-min-delta window nil window)))))) |
| 4460 | (set-window-point window (1- (window-point)))) | 4444 | ;; This `condition-case' shouldn't be necessary, but who knows? |
| 4461 | ;; Adjust WINDOW's height to the nominally correct one | 4445 | (condition-case nil |
| 4462 | ;; (which may actually be slightly off because of variable | 4446 | (if (zerop delta) |
| 4463 | ;; height text, etc). | 4447 | ;; Return zero if DELTA became zero in the proces. |
| 4464 | (unless (zerop delta) | 4448 | 0 |
| 4465 | (enlarge-window delta)) | 4449 | ;; Don't try to redisplay with the cursor at the end on its |
| 4466 | ;; `enlarge-window' might have deleted WINDOW, so make sure | 4450 | ;; own line--that would force a scroll and spoil things. |
| 4467 | ;; WINDOW's still alive for the remainder of this. | 4451 | (when (and (eobp) (bolp) (not (bobp))) |
| 4468 | ;; Note: Deleting WINDOW is clearly counter-intuitive in | 4452 | ;; It's silly to put `point' at the end of the previous |
| 4469 | ;; this context, but we can't do much about it given the | 4453 | ;; line and so maybe force horizontal scrolling. |
| 4470 | ;; current semantics of `enlarge-window'. | 4454 | (set-window-point window (line-beginning-position 0))) |
| 4471 | (when (window-live-p window) | 4455 | ;; Call `resize-window' with OVERRIDE argument equal WINDOW. |
| 4456 | (resize-window window delta nil window) | ||
| 4472 | ;; Check if the last line is surely fully visible. If | 4457 | ;; Check if the last line is surely fully visible. If |
| 4473 | ;; not, enlarge the window. | 4458 | ;; not, enlarge the window. |
| 4474 | (let ((end (save-excursion | 4459 | (let ((end (save-excursion |
| @@ -4486,25 +4471,15 @@ when their height shrinks to less than MIN-HEIGHT." | |||
| 4486 | (forward-line 0)) | 4471 | (forward-line 0)) |
| 4487 | (point)))) | 4472 | (point)))) |
| 4488 | (set-window-vscroll window 0) | 4473 | (set-window-vscroll window 0) |
| 4474 | ;; This loop might in some rare pathological cases raise | ||
| 4475 | ;; an error - another reason for the `condition-case'. | ||
| 4489 | (while (and (< desired-height max-height) | 4476 | (while (and (< desired-height max-height) |
| 4490 | (= desired-height (window-height)) | 4477 | (= desired-height (window-total-size)) |
| 4491 | (not (pos-visible-in-window-p end))) | 4478 | (not (pos-visible-in-window-p end))) |
| 4492 | (enlarge-window 1) | 4479 | (resize-window window 1 nil window) |
| 4493 | (setq desired-height (1+ desired-height)))) | 4480 | (setq desired-height (1+ desired-height))))) |
| 4494 | ;; Return non-nil only if nothing "bad" happened. | 4481 | (error (setq delta nil))) |
| 4495 | (setq value t))) | 4482 | delta)))) |
| 4496 | (error nil))) | ||
| 4497 | (when (buffer-live-p old-buffer) | ||
| 4498 | (set-buffer old-buffer)) | ||
| 4499 | value)) | ||
| 4500 | |||
| 4501 | (defun window-safely-shrinkable-p (&optional window) | ||
| 4502 | "Return t if WINDOW can be shrunk without shrinking other windows. | ||
| 4503 | WINDOW defaults to the selected window." | ||
| 4504 | (with-selected-window (or window (selected-window)) | ||
| 4505 | (let ((edges (window-edges))) | ||
| 4506 | (or (= (nth 2 edges) (nth 2 (window-edges (previous-window)))) | ||
| 4507 | (= (nth 0 edges) (nth 0 (window-edges (next-window)))))))) | ||
| 4508 | 4483 | ||
| 4509 | (defun shrink-window-if-larger-than-buffer (&optional window) | 4484 | (defun shrink-window-if-larger-than-buffer (&optional window) |
| 4510 | "Shrink height of WINDOW if its buffer doesn't need so many lines. | 4485 | "Shrink height of WINDOW if its buffer doesn't need so many lines. |
| @@ -4512,42 +4487,28 @@ More precisely, shrink WINDOW vertically to be as small as | |||
| 4512 | possible, while still showing the full contents of its buffer. | 4487 | possible, while still showing the full contents of its buffer. |
| 4513 | WINDOW defaults to the selected window. | 4488 | WINDOW defaults to the selected window. |
| 4514 | 4489 | ||
| 4515 | Do not shrink to less than `window-min-height' lines. Do nothing | 4490 | Do not shrink WINDOW to less than `window-min-height' lines. Do |
| 4516 | if the buffer contains more lines than the present window height, | 4491 | nothing if the buffer contains more lines than the present window |
| 4517 | or if some of the window's contents are scrolled out of view, or | 4492 | height, or if some of the window's contents are scrolled out of |
| 4518 | if shrinking this window would also shrink another window, or if | 4493 | view, or if shrinking this window would also shrink another |
| 4519 | the window is the only window of its frame. | 4494 | window, or if the window is the only window of its frame. |
| 4520 | 4495 | ||
| 4521 | Return non-nil if the window was shrunk, nil otherwise." | 4496 | Return non-nil if the window was shrunk, nil otherwise." |
| 4522 | (interactive) | 4497 | (interactive) |
| 4523 | (when (null window) | 4498 | (setq window (normalize-live-window window)) |
| 4524 | (setq window (selected-window))) | 4499 | ;; Make sure that WINDOW is vertically combined and `point-min' is |
| 4525 | (let* ((frame (window-frame window)) | 4500 | ;; visible (for whatever reason that's needed). The remaining issues |
| 4526 | (mini (frame-parameter frame 'minibuffer)) | 4501 | ;; should be taken care of by `fit-window-to-buffer'. |
| 4527 | (edges (window-edges window))) | 4502 | (when (and (window-iso-combined-p window) |
| 4528 | (if (and (not (eq window (frame-root-window frame))) | 4503 | (pos-visible-in-window-p (point-min) window)) |
| 4529 | (window-safely-shrinkable-p window) | 4504 | (fit-window-to-buffer window (window-total-size window)))) |
| 4530 | (pos-visible-in-window-p (point-min) window) | 4505 | |
| 4531 | (not (eq mini 'only)) | ||
| 4532 | (or (not mini) | ||
| 4533 | (let ((mini-window (minibuffer-window frame))) | ||
| 4534 | (or (null mini-window) | ||
| 4535 | (not (eq frame (window-frame mini-window))) | ||
| 4536 | (< (nth 3 edges) | ||
| 4537 | (nth 1 (window-edges mini-window))) | ||
| 4538 | (> (nth 1 edges) | ||
| 4539 | (frame-parameter frame 'menu-bar-lines)))))) | ||
| 4540 | (fit-window-to-buffer window (window-height window))))) | ||
| 4541 | |||
| 4542 | (defun kill-buffer-and-window () | 4506 | (defun kill-buffer-and-window () |
| 4543 | "Kill the current buffer and delete the selected window." | 4507 | "Kill the current buffer and delete the selected window." |
| 4544 | (interactive) | 4508 | (interactive) |
| 4545 | (let ((window-to-delete (selected-window)) | 4509 | (let ((window-to-delete (selected-window)) |
| 4546 | (buffer-to-kill (current-buffer)) | 4510 | (buffer-to-kill (current-buffer)) |
| 4547 | (delete-window-hook (lambda () | 4511 | (delete-window-hook (lambda () (ignore-errors (delete-window))))) |
| 4548 | (condition-case nil | ||
| 4549 | (delete-window) | ||
| 4550 | (error nil))))) | ||
| 4551 | (unwind-protect | 4512 | (unwind-protect |
| 4552 | (progn | 4513 | (progn |
| 4553 | (add-hook 'kill-buffer-hook delete-window-hook t t) | 4514 | (add-hook 'kill-buffer-hook delete-window-hook t t) |
| @@ -4558,10 +4519,9 @@ Return non-nil if the window was shrunk, nil otherwise." | |||
| 4558 | (delete-window)))) | 4519 | (delete-window)))) |
| 4559 | ;; If the buffer is not dead for some reason (probably because | 4520 | ;; If the buffer is not dead for some reason (probably because |
| 4560 | ;; of a `quit' signal), remove the hook again. | 4521 | ;; of a `quit' signal), remove the hook again. |
| 4561 | (condition-case nil | 4522 | (ignore-errors |
| 4562 | (with-current-buffer buffer-to-kill | 4523 | (with-current-buffer buffer-to-kill |
| 4563 | (remove-hook 'kill-buffer-hook delete-window-hook t)) | 4524 | (remove-hook 'kill-buffer-hook delete-window-hook t)))))) |
| 4564 | (error nil))))) | ||
| 4565 | 4525 | ||
| 4566 | (defun quit-window (&optional kill window) | 4526 | (defun quit-window (&optional kill window) |
| 4567 | "Quit WINDOW and bury its buffer. | 4527 | "Quit WINDOW and bury its buffer. |
| @@ -4584,10 +4544,9 @@ Otherwise, bury WINDOW's buffer, see `bury-buffer'." | |||
| 4584 | ;; try to delete it. | 4544 | ;; try to delete it. |
| 4585 | (let* ((window (or window (selected-window))) | 4545 | (let* ((window (or window (selected-window))) |
| 4586 | (frame (window-frame window))) | 4546 | (frame (window-frame window))) |
| 4587 | (if (eq window (frame-root-window frame)) | 4547 | (if (frame-root-window-p window) |
| 4588 | ;; WINDOW is alone on its frame. `delete-windows-on' | 4548 | ;; WINDOW is alone on its frame. |
| 4589 | ;; knows how to handle that case. | 4549 | (delete-frame frame) |
| 4590 | (delete-windows-on buffer frame) | ||
| 4591 | ;; There are other windows on its frame, delete WINDOW. | 4550 | ;; There are other windows on its frame, delete WINDOW. |
| 4592 | (delete-window window))) | 4551 | (delete-window window))) |
| 4593 | ;; Otherwise, switch to another buffer in the selected window. | 4552 | ;; Otherwise, switch to another buffer in the selected window. |
| @@ -4597,7 +4556,6 @@ Otherwise, bury WINDOW's buffer, see `bury-buffer'." | |||
| 4597 | (if kill | 4556 | (if kill |
| 4598 | (kill-buffer buffer) | 4557 | (kill-buffer buffer) |
| 4599 | (bury-buffer buffer)))) | 4558 | (bury-buffer buffer)))) |
| 4600 | |||
| 4601 | 4559 | ||
| 4602 | (defvar recenter-last-op nil | 4560 | (defvar recenter-last-op nil |
| 4603 | "Indicates the last recenter operation performed. | 4561 | "Indicates the last recenter operation performed. |
| @@ -4689,7 +4647,6 @@ by `recenter-positions'." | |||
| 4689 | (move-to-window-line (round (* recenter-last-op (window-height)))))))))) | 4647 | (move-to-window-line (round (* recenter-last-op (window-height)))))))))) |
| 4690 | 4648 | ||
| 4691 | (define-key global-map [?\M-r] 'move-to-window-line-top-bottom) | 4649 | (define-key global-map [?\M-r] 'move-to-window-line-top-bottom) |
| 4692 | |||
| 4693 | 4650 | ||
| 4694 | ;;; Scrolling commands. | 4651 | ;;; Scrolling commands. |
| 4695 | 4652 | ||
| @@ -4837,7 +4794,6 @@ With arg N, put point N/10 of the way from the true end." | |||
| 4837 | (end-of-buffer arg)) | 4794 | (end-of-buffer arg)) |
| 4838 | (recenter '(t))) | 4795 | (recenter '(t))) |
| 4839 | (select-window orig-window)))) | 4796 | (select-window orig-window)))) |
| 4840 | |||
| 4841 | 4797 | ||
| 4842 | (defvar mouse-autoselect-window-timer nil | 4798 | (defvar mouse-autoselect-window-timer nil |
| 4843 | "Timer used by delayed window autoselection.") | 4799 | "Timer used by delayed window autoselection.") |
| @@ -4891,62 +4847,60 @@ means suspend autoselection." | |||
| 4891 | If the mouse position has stabilized in a non-selected window, select | 4847 | If the mouse position has stabilized in a non-selected window, select |
| 4892 | that window. The minibuffer window is selected only if the minibuffer is | 4848 | that window. The minibuffer window is selected only if the minibuffer is |
| 4893 | active. This function is run by `mouse-autoselect-window-timer'." | 4849 | active. This function is run by `mouse-autoselect-window-timer'." |
| 4894 | (condition-case nil | 4850 | (ignore-errors |
| 4895 | (let* ((mouse-position (mouse-position)) | 4851 | (let* ((mouse-position (mouse-position)) |
| 4896 | (window | 4852 | (window |
| 4897 | (condition-case nil | 4853 | (ignore-errors |
| 4898 | (window-at (cadr mouse-position) (cddr mouse-position) | 4854 | (window-at (cadr mouse-position) (cddr mouse-position) |
| 4899 | (car mouse-position)) | 4855 | (car mouse-position))))) |
| 4900 | (error nil)))) | 4856 | (cond |
| 4901 | (cond | 4857 | ((or (menu-or-popup-active-p) |
| 4902 | ((or (menu-or-popup-active-p) | 4858 | (and window |
| 4903 | (and window | 4859 | (not (coordinates-in-window-p (cdr mouse-position) window)))) |
| 4904 | (not (coordinates-in-window-p (cdr mouse-position) window)))) | 4860 | ;; A menu / popup dialog is active or the mouse is on the scroll-bar |
| 4905 | ;; A menu / popup dialog is active or the mouse is on the scroll-bar | 4861 | ;; of WINDOW, temporarily suspend delayed autoselection. |
| 4906 | ;; of WINDOW, temporarily suspend delayed autoselection. | 4862 | (mouse-autoselect-window-start mouse-position nil t)) |
| 4907 | (mouse-autoselect-window-start mouse-position nil t)) | 4863 | ((eq mouse-autoselect-window-state 'suspend) |
| 4908 | ((eq mouse-autoselect-window-state 'suspend) | 4864 | ;; Delayed autoselection was temporarily suspended, reenable it. |
| 4909 | ;; Delayed autoselection was temporarily suspended, reenable it. | 4865 | (mouse-autoselect-window-start mouse-position)) |
| 4910 | (mouse-autoselect-window-start mouse-position)) | 4866 | ((and window (not (eq window (selected-window))) |
| 4911 | ((and window (not (eq window (selected-window))) | 4867 | (or (not (numberp mouse-autoselect-window)) |
| 4912 | (or (not (numberp mouse-autoselect-window)) | 4868 | (and (> mouse-autoselect-window 0) |
| 4913 | (and (> mouse-autoselect-window 0) | 4869 | ;; If `mouse-autoselect-window' is positive, select |
| 4914 | ;; If `mouse-autoselect-window' is positive, select | 4870 | ;; window if the window is the same as before. |
| 4915 | ;; window if the window is the same as before. | 4871 | (eq window mouse-autoselect-window-window)) |
| 4916 | (eq window mouse-autoselect-window-window)) | 4872 | ;; Otherwise select window if the mouse is at the same |
| 4917 | ;; Otherwise select window if the mouse is at the same | 4873 | ;; position as before. Observe that the first test after |
| 4918 | ;; position as before. Observe that the first test after | 4874 | ;; starting autoselection usually fails since the value of |
| 4919 | ;; starting autoselection usually fails since the value of | 4875 | ;; `mouse-autoselect-window-position' recorded there is the |
| 4920 | ;; `mouse-autoselect-window-position' recorded there is the | 4876 | ;; position where the mouse has entered the new window and |
| 4921 | ;; position where the mouse has entered the new window and | 4877 | ;; not necessarily where the mouse has stopped moving. |
| 4922 | ;; not necessarily where the mouse has stopped moving. | 4878 | (equal mouse-position mouse-autoselect-window-position)) |
| 4923 | (equal mouse-position mouse-autoselect-window-position)) | 4879 | ;; The minibuffer is a candidate window if it's active. |
| 4924 | ;; The minibuffer is a candidate window if it's active. | 4880 | (or (not (window-minibuffer-p window)) |
| 4925 | (or (not (window-minibuffer-p window)) | 4881 | (eq window (active-minibuffer-window)))) |
| 4926 | (eq window (active-minibuffer-window)))) | 4882 | ;; Mouse position has stabilized in non-selected window: Cancel |
| 4927 | ;; Mouse position has stabilized in non-selected window: Cancel | 4883 | ;; delayed autoselection and try to select that window. |
| 4928 | ;; delayed autoselection and try to select that window. | 4884 | (mouse-autoselect-window-cancel t) |
| 4929 | (mouse-autoselect-window-cancel t) | 4885 | ;; Select window where mouse appears unless the selected window is the |
| 4930 | ;; Select window where mouse appears unless the selected window is the | 4886 | ;; minibuffer. Use `unread-command-events' in order to execute pre- |
| 4931 | ;; minibuffer. Use `unread-command-events' in order to execute pre- | 4887 | ;; and post-command hooks and trigger idle timers. To avoid delaying |
| 4932 | ;; and post-command hooks and trigger idle timers. To avoid delaying | 4888 | ;; autoselection again, set `mouse-autoselect-window-state'." |
| 4933 | ;; autoselection again, set `mouse-autoselect-window-state'." | 4889 | (unless (window-minibuffer-p (selected-window)) |
| 4934 | (unless (window-minibuffer-p (selected-window)) | 4890 | (setq mouse-autoselect-window-state 'select) |
| 4935 | (setq mouse-autoselect-window-state 'select) | 4891 | (setq unread-command-events |
| 4936 | (setq unread-command-events | 4892 | (cons (list 'select-window (list window)) |
| 4937 | (cons (list 'select-window (list window)) | 4893 | unread-command-events)))) |
| 4938 | unread-command-events)))) | 4894 | ((or (and window (eq window (selected-window))) |
| 4939 | ((or (and window (eq window (selected-window))) | 4895 | (not (numberp mouse-autoselect-window)) |
| 4940 | (not (numberp mouse-autoselect-window)) | 4896 | (equal mouse-position mouse-autoselect-window-position)) |
| 4941 | (equal mouse-position mouse-autoselect-window-position)) | 4897 | ;; Mouse position has either stabilized in the selected window or at |
| 4942 | ;; Mouse position has either stabilized in the selected window or at | 4898 | ;; `mouse-autoselect-window-position': Cancel delayed autoselection. |
| 4943 | ;; `mouse-autoselect-window-position': Cancel delayed autoselection. | 4899 | (mouse-autoselect-window-cancel t)) |
| 4944 | (mouse-autoselect-window-cancel t)) | 4900 | (t |
| 4945 | (t | 4901 | ;; Mouse position has not stabilized yet, resume delayed |
| 4946 | ;; Mouse position has not stabilized yet, resume delayed | 4902 | ;; autoselection. |
| 4947 | ;; autoselection. | 4903 | (mouse-autoselect-window-start mouse-position window)))))) |
| 4948 | (mouse-autoselect-window-start mouse-position window)))) | ||
| 4949 | (error nil))) | ||
| 4950 | 4904 | ||
| 4951 | (defun handle-select-window (event) | 4905 | (defun handle-select-window (event) |
| 4952 | "Handle select-window events." | 4906 | "Handle select-window events." |