On May 1, 2021, at 3:31 PM, Eli Zaretskii <eliz@gnu.org> wrote:

From: JD Smith <jdtsmith@gmail.com>
Date: Sat, 1 May 2021 14:46:31 -0400

I’m working on a small “in mode-line” scroll bar, and have implemented mouse events for it, which are working well.  When I interact using the mouse with the mode line of a non-selected window, I need to have that window temporarily selected, so I can calculate its line offsets and move within it.  But (just as for regular scrollbars), I’d like to retain the originally active window afterwards.

Please explain in more detail why do you think you need to select the
window.  What are those "line offsets", and why "move within it"
requires to select the window?

Sure, thanks.  I compute line positions at a number of points (window-start, window-end, and point-max) inside a mode line :eval form.  To compute line numbers at these positions, for speed in very long files, I’m actually using:

(defun mlscroll-fast-line-number-at-pos (pos)
  (save-excursion
    (goto-char pos)
    (string-to-number (format-mode-line "%l"))))

The operative bits of the “move within” look like:

   (when (/= targ start)
      (forward-line (- targ start))
      (recenter))

During normal automatic mode-line update, the selected window is automatically bound correctly while the mode line string is computed (without updating the mode line face, I might add!).  But during the mouse event callback, I must use the starting window of the mouse event (a press) as the window to target, since the user could click on any of them. 

I believe I can re-task all of the “computing lines” code to take a window argument, i.e. to avoid actually selecting the window itself.  But less clear is how to move forward and back a given number of lines (forward-line) and recenter in an unselected window, without selecting it temporarily and causing the mode line face flashing.