Subject: bug#45844: 27.1; unwanted raising of other frame when emacs is in the backgound and switch-to-buffer is used in a dedicated frame

From: martin rudalics <[email-masked]>
Date: Wed, 13 Jan 2021 19:07:59 +0100

> (run-with-timer
 > 3 nil
 > (lambda ()
 > (switch-to-buffer "*test*")))

You are asking for the impossible.  'switch-to-buffer' with a dedicated
window on an unsplittable frame will inevitably trigger 'pop-to-buffer'
as documented in the Elisp manual:

      Sometimes, the selected window may not be suitable for displaying
      the buffer.  This happens if the selected window is a minibuffer
      window, or if the selected window is strongly dedicated to its
      buffer (*note Dedicated Windows::).  In such cases, the command
      normally tries to display the buffer in some other window, by
      invoking ‘pop-to-buffer’ (see below).

And 'pop-to-buffer' makes a new frame because it cannot use the selected
one, raises that frame and even requests input focus for it.

I haven't much to recommend for how to handle such situations.  You can
try the following:

- Make an invisible frame when you start running the timer, maybe giving
   it a non-nil ‘no-focus-on-map’ parameter.

- Use 'display-buffer' to show *test* in that frame and make that frame
   visible, preferably using an 'inhibit-switch-frame' alist entry.

In either case it will be up to your WM whether it will raise that frame
and give it focus.  Often it does both, "stealing" another application's
focus.

martin