@ToniLeigh says "focus stealing is bad UX."
@JackAidley says that not switching to a new application can be annoying.
While I agree with @ToniLeigh that "focus stealing is bad", it is many places. On Mac OS-X. On Windows. Many people think that Apple haas good UX, but I have been plagued by focus stealing on MacOS today.
I think that part of the problem is that people treat focus stealing like a UX issue. User experience. User Interface. The responsibility of the application programmer.
Maybe so, but more important, in my opinion, is the fact that focus stealing is a potential security hole. Focus stealing can lead to data corruption and destruction. It can lead to secrets being exposed.
I.e. focus stealing needs to be treated like an OS issue. A window manager issue. A system software issue. We must not simply blame bad application programmers for stealing focus: we must blame the platform they are running on, for allowing focus to be stolen.
Note: here I consider a web browser system software, not an application, because a web browser is a platform on which software from different sources can run.
Nevertheless, @JackAidley says that not switching to a new application can be annoying. And he is correct: It is a pain to click a button that opens a new window or aa dialog box, and then have to transfer focus by doing something like clicking in the title bar and then clicking on a button. And it is not really good practice to say "Any mouseclick in a new window/widget changes focus", especially not if apps can be opened in front of other apps.
But there is a middle ground.
Focus is a security property. We must never allow focus to be moved from software in one privilege domain to software in another privilege domain, unless the user accepts and expects such a transfer of focus. But we don't want that transfer of focus to be painful.
When you open a new app - when you click on a button, etc. - we may say that there is an implicit transfer of focus. If the new app window or widget opens immediately, great, you expected that transfer.
But oftentimes the new app does not open immediately. So the user transfers focus somewhere else. And then gets bitten when the new app window or widget finally opens, and steals focus.
I.e. part of the problem is that there can be a race condition. Which is a subset of a larger issue, that the transfer of focus can be asynchronous. This is by no means the whole problem, but if we can't solve this simple aspect of the problem, we will probably not be able to solve the rest of it.
Part of the problem is that there is a race, a window, between clicking on a button and the new app saying "Hey, I want focus now!". That window is often so small as to be unnoticeable, but when it is large enough for the user to switch away, then focus stealing becomes exceptionally painful.
So we have to solve this like any other problem in concurrent or parallel programming: we need to close the window. The SW system where the button is being clicked needs to agree to give up focus. The SW system that the button click is triggering needs to agree to accept focus.
I.e. focus needs to be transferred, with explicit cooperation of sender, receiver, and user. Not requested and granted, by only sender. Not stolen. Given. Transferred.
Initially focus is in SW domain 1.
User does something that triggers SW domain 2 to be started. Eventually, but not immediately.
Focus is transferred from SW domain 1 to an intermediate state, waiting for SW domain 2 to be ready to accept focus.
In the intermediate state, user input may be an error. Or it may be buffered for eventual delivery, if you like type ahead. But typeahead is dangerous here.
Eventually SW domain 2 is up and ready to accept input. So now the transfer of focus is complete.
If SW domain 2 is slow to start, the user can explicitly transfer away from the intermediate state, and transfer focus back some other SW domain, SW domain 3, or even SW domain 1.
If the user has transferred focus away, then when SW domain 2 eventually starts, it does not automatically receive focus. It may have to notify the user, e.g. by bouncing an icon, and the user will have to explicitly transfer focus back.
I.e. focus transfer is easy and implicit when you start a new app - but only if user has not transferred focus away while the new app was starting. If the user has transferred focus elsewhere, then transferring focus back to the new app must be more explicit.
It is best if SW domain 1 knows the identity of SW domain 2, where focus is to be eventually transferred. It is impractical, in general, for SW domain 2 to know all of the possible SW domains 1 that can transfer focus to it. It may not even be practical for SW domain 1 to know who the recipient is going to be - e.g. consider a button that starts an AppleScript or shell script or ... - but it sure would be nice if it focus could be passed along, like a token, like a capability, from SWC domain 1, through any intervening scripts, to SW domain 2.
If SW domain 1 knows that it has transferred focus away to SW domain 2, then an explicit attempt to transfer back to SW domain 1 might be delegated, thereby raising SW domain 2, which may have delegated to SW domain 3, ... to some dialog box that is waiting for a button click. If the sender does not know about the transfer, then you can get into ugly situations where the user switches back to the original sender, and tries to type, but cannot, error bells ringing - until the user walks through the window and widget hierarchy to find an open dialog box. I.e. if the SW domains know that certain actions should transfer focus, then we can automatically go to the currently active domain in a "focus path".
But if SW doesn't know - if it treats all buttons the same, some being local actions that do not require focus transfer, some being actions that start dependent apps to which the user might want to transfer focus - well, it is safer not to transfer focus than to transfer.
I.e. some buttons or user actions are marked as "Focus Transfer Expected", and some as "No Focus Transfer". In the latter, an explicit action by the user is need to switch to any new window. In the former, focus is transferred from sender SW domain 1 to the intermediate state to receiver SW domain 2, with no special actions by the user. But the user can explicitly change focus.
There is no asynchronous transfer of focus between SW domain 1 and SW domain 2. Asynchronous transfer requires explicit user action.
The user is, of course, able to transfer focus around explicitly whenever they want.
(Or, you may think of it as "asynchronous transfer of focus is a special privilege", normally given only to special software such as the OS or window manager. Something like a browser may be considered as having the right to transfer focus asynchronously between the domains it manages, but not to domains outside its control. I.e. privilege domains are hierarchically nested, for the purposes of asynchronous transfer of focus, as so many other things. Ideally, the same hierarchy applies.)
(Looming issue: how can the user explicitly control focus? There must be some user actions, e.g. meta+mouse-click, that will always allow the user to take control. This is really part of the "secure input channel" for windowing GUI systems. The problem is that there are few standards for such gauranteed behavior.)
"You can't give away what you don't have" ==> focus is transferred cooperatively, not taken asynchronously. So a shell script or AppleScript, running in the background, without focus, cannot open apps that can steal focus. But running in the foreground such a script can open an app to which focus can be transferred. Again, focus would be transferred through an intermediate state - and special operations would be provided to transfer focus to that which is being opened, or not.
E.g. for MacOS's "open" https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/open.1.html, focus transfer would be a parameter to the open command used by shell scripts.
Probably similar for UNIX-style fork, exec, and spawn system or library calls. Even at such a low level. This is part of the OS.
(Probably would have to deprecate the UNIX behavior where both parent and child can read from the same file descriptor concurrently. That is the low level equivalent of focus stealing.)
===> Funny: I just got bitten by focus stealing as I was writing this - in Chrome, on MacOS. The Rescuetime activity monitor opened a new webpage and received typing intended for this.
This is not rocket science!!!! But it is concurrent programming.
I conjecture that focus stealing became so prevalent because many windowing systems evolved on relatively underpowered computers, often without multitasking. Think early windows or Mac. X-Windows historically had more options for forbidding focus stealing because the early UNIX workstations were concurrent from day 1. But even on W-Windows, the usability advantages of focus transfer won out in many environments, like the fvwm window manager.
So long as the argument is "Focus Stealing, Yes or No", we will make no progress.
We must recognize
(1) implicit focus transfer has usability advantages. Nobody wants to have to take special actions every time they open a new app.
(2) but focus stealing overall is a security hole, and only secondarily an app design issue.
If we fix the security hole in a way that allows (1), then we have a chance.