diff --git a/lisp/window.el b/lisp/window.el index fd1c617d6b..81a770ff32 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -4140,6 +4140,23 @@ window--in-subtree-p (throw 'done t) (setq parent (window-parent parent)))))))) +(defun window-at-pos (x y &optional frame) + "Return live window at position X, Y on specified FRAME. +X and Y are counted in pixels from the origin at 0, 0 of FRAME's +native frame. FRAME must specify a live frame and defaults to +the selected one. Return nil if no such window can be found." + (setq frame (window-normalize-frame frame)) + (catch 'window + (walk-window-tree + (lambda (window) + (let ((edges (window-edges window nil nil t))) + (when (and (>= x (nth 0 edges)) (< x (nth 2 edges)) + (>= y (nth 1 edges)) (< y (nth 3 edges))) + (throw 'window window)))) + frame nil nil))) + +(defvar delete-window-use-posn-at-point t) + (defun delete-window (&optional window) "Delete WINDOW. WINDOW must be a valid window and defaults to the selected one. @@ -4162,7 +4179,7 @@ delete-window (let* ((frame (window-frame window)) (function (window-parameter window 'delete-window)) (parent (window-parent window)) - atom-root) + atom-root posn-at-point-x posn-at-point-y window-at-posn-at-point) (window--check frame) (catch 'done ;; Handle window parameters. @@ -4211,10 +4228,22 @@ delete-window (t ;; Can't do without resizing fixed-size windows. (window--resize-siblings window (- size) horizontal t))) + (when delete-window-use-posn-at-point + ;; Remember WINDOW's position at point. + (let ((edges (window-edges window nil nil t)) + (posn-at-point (nth 2 (posn-at-point nil window)))) + (when posn-at-point + (setq posn-at-point-x (+ (nth 0 edges) (car posn-at-point)) + posn-at-point-y (+ (nth 1 edges) (cdr posn-at-point)))))) ;; Actually delete WINDOW. (delete-window-internal window) (window--pixel-to-total frame horizontal) - (when (and frame-selected + (when (and posn-at-point-x posn-at-point-y + (setq window-at-posn-at-point + (window-at-pos posn-at-point-x posn-at-point-y frame))) + ;; Select window at WINDOW's position at point. + (select-window window-at-posn-at-point)) + (when (and frame-selected (window-parameter (frame-selected-window frame) 'no-other-window)) ;; `delete-window-internal' has selected a window that should