On Wed, Oct 11, 2017 at 1:16 PM, Robert Weiner wrote: > > ​Martin wrote:​ > >> Take the position of the event-end (if it's a frame) and translate it >> into absolute screen coordinates (the Elisp manual should give you >> enough clues to do that). Or, try ‘mouse-absolute-pixel-position’ - it >> should give you the screen position of the mouse at that time so you can >> ignore the event completely. >> >> Then walk all your windows and compare that position with whatever >> ‘window-absolute-pixel-edges’ returns for that window. If you have two >> or more positives, run ‘frame-list-z-order’ and compare the result >> against those windows' frames. No hands, IMHO. >> ​​ >> > ​​ ​ Eli wrote: ​​ Why cannot you compute the frame at button release using the a ​​ lgorithm proposed by Martin, given the mouse position at button release?​ > >> ​​ >> > I w > ​​ > rote: > ​ > ​​ > frame-list-z-order is Emacs 26 only; I need something that works with > older versions.​ > ​​ > ​​ > I'll see if I can make this work under Emacs 26 and then we can > contemplate a solution that would apply to earlier versions. > ​​ > Thanks for the reminder. It does still seem to me that there should be a > function that takes a mouse position and returns > ​​ > the top-most Emacs window that the position is in or nil. I'll work on it. > ​​ ​​​And now there is such a function. It was easier than I expected thanks to Martin's pointers. Now how can we make this work (replacing frame-list-z-order) for Emacs versions prior to 26? -- Bob (defun window-at-absolute-pixel-position (&optional position) "Return the top-most Emacs window at optional POSITION ((X . Y) in pixels) or mouse position. If POSITION is not in a window, return nil. Considers all windows on the the same terminal display as the selected frame." (interactive) (setq position (or position (mouse-absolute-pixel-position))) (let* ((top-to-bottom-frames (frame-list-z-order)) (pos-x (car position)) (pos-y (cdr position)) edges left top right bottom frame in-frame window) ;; First find top-most frame containing position. (while (and (not in-frame) top-to-bottom-frames) (setq frame (car top-to-bottom-frames) top-to-bottom-frames (cdr top-to-bottom-frames)) ;; Check that in-frame is valid with frame-live-p since under macOS ;; when position is outside a frame, in-frame could be invalid and ;; frame-visible-p would trigger an error in that case. (when (and (frame-live-p frame) (frame-visible-p frame)) (setq edges (frame-edges frame) left (nth 0 edges) top (nth 1 edges) right (nth 2 edges) bottom (nth 3 edges)) (when (and (>= pos-x left) (<= pos-x right) (>= pos-y top) (<= pos-y bottom)) (setq in-frame frame)))) ;; If in-frame is found, find which of its windows contains ;; position and return that. The window-at call below requires ;; character coordinates relative to in-frame, so compute them. (setq pos-x (/ (- pos-x left) (frame-char-width in-frame)) pos-y (/ (- pos-y top) (frame-char-height in-frame)) window (window-at pos-x pos-y in-frame)) (if (called-interactively-p 'interactive) (message "%s at absolute pixel position %s" (or window "No Emacs window") position)) window))